Venkat Subramanian

351 Reputation

13 Badges

13 years, 213 days

MaplePrimes Activity


These are replies submitted by

@acer 

I think any opimizer or nonlinearsolver should take the required tolerance as input and return the current-best objective, iterate.
@acer, I can confirm that this approach works with nonlinear constraints + dsolve/numeric/parameters + sqp. thanks again

@acer 

There is no point in doing optimization to 1e-16 accuracy when we are trying to increase nvar(number of stages), solving ODEs/DAEs to 1e-6 accuracy.

I like your answer and it works.

Note that for some weird reason, for this problem stiff=true in the call to dsolve/numeric works without tweaking anything in the dsolve command or optimization command.  

Knowing where it fails can help. For example, ideally NLPSolve should have given the answer that "objective was solved to 1e-6 precision, but not beyond that", instead of just returning "initial point satisfies first-order optimality condition".

fsolve has the same issue as well, and if I am not wrong, we can't force it to solve to a prescribed precision.

@acer, as again, thanks lot. I believe that you can fix almost any issues!

Adding abstol=1e-12, reltol=1e-12 to dsolve/numeric calls solves the problem for this model. (Thanks to Allan Wittkopf)

He had also suggested using Digits:=18 inside ss (I am not a big fan of this)

With default tolerances use of, maxstep = 0.05 (assuming that your maximum time horizon is 0.1 with nvar = 10)seems to work as well.

fdiff or the procedures used by NLPSolve should be made more robust.

@dharr 

Your code is not using dsolve numeric in parametric form. I will be posting the use of parametric form working with NLPSolve (thanks to Allan Wittkopf).

As I said, we don't want analytical solutions.

Also, one parameter optimization is different from multiple parameters (scalar vs vector).

To be clear, I am not looking for an answer for the model. My goal was to use NLPSolve with dsolve/numeric/parameters with sqp. 
 

@dharr 

thanks

When dsolve numeric is replaced with the RK2 method, the code works. Typically, dsolve numeric will be faster than writing for loops to do numerical integration of ODEs.

This is why I think that the issue is with dsolve/numeric.
 

restart:

 

Test code written by Dr. Venkat Subramanian at UT Austin, 05/31/2023. This code uses CVP approach (piecwise constant) to perform optimal control. NLPSolve combination with RK2 approach to integrate ODEs (constant step size) works well for this problem.

Digits:=15;

15

 

eqodes:=[diff(ca(t),t)=-(u+u^2/2)*1.0*ca(t),diff(cb(t),t)=1.0*u*ca(t)-0.1*cb(t)];

[diff(ca(t), t) = -1.0*(u+(1/2)*u^2)*ca(t), diff(cb(t), t) = 1.0*u*ca(t)-.1*cb(t)]

soln:=dsolve({op(eqodes),ca(0)=alpha,cb(0)=beta},type=numeric,'parameters'=[alpha,beta,u],compile=true,savebinary=true):

RK2:=proc(alpha,beta,NN,u,dt)#this procedure can be made efficient in vector form
local j,c1mid,c2mid,c10,c20,c1,c2;
c10:=alpha;c20:=beta;
for j from 1 to NN do
  c1mid:=c10+dt/NN*(-(u+u^2/2)*c10):
  c2mid:=c20+dt/NN*(u*c10)-0.1*dt/NN*c20:
  c1:=c10/2+c1mid/2+dt/NN/2*(-(u+u^2/2)*c1mid):
  c2:=c20/2+c2mid/2+dt/NN/2*(u*c1mid)-0.1*dt/NN/2*c2mid:
  c10:=c1:c20:=c2:
  od:
[c10,c20];
end proc:

soln('parameters'=[1,0,0.1]);soln(0.1);

[alpha = 1., beta = 0., u = .1]

[t = .1, ca(t) = HFloat(0.9895549324188543), cb(t) = HFloat(0.009898024276129616)]

RK2(1,0,20,0.1,0.1);#reasonable accuracy with just 20 time steps of RK2

[.989554933045397, 0.989802232901406e-2]

ss0:=proc(x)
interface(warnlevel=0):
#if  type(x[1],numeric)
if  type(x,Vector)
then

local z1,n1,i,c10,c20,dt,u;
global soln,nvar;
dt:=evalf(1.0/nvar):
c10:=1.0:c20:=0.0:
for i from 1 to nvar do
u:=x[i]:
soln('parameters'=[c10,c20,u]):
z1:=soln(dt):
c10:=subs(z1,ca(t)):c20:=subs(z1,cb(t)):
od:
-c20;
 else 'procname'(args):

end if:

end proc:

ss:=proc(x)#based on RK2
interface(warnlevel=0):
#if  type(x[1],numeric)
if  type(x,Vector)
then

local z1,n1,i,c10,c20,dt,u,NN;
global soln,nvar;
dt:=evalf(1.0/nvar):
NN:=20;
c10:=1.0:c20:=0.0:
for i from 1 to nvar do
u:=x[i]:
z1:=RK2(c10,c20,NN,u,dt):
c10:=z1[1]:c20:=z1[2]:
od:
-c20;
 else 'procname'(args):

end if:

end proc:

nvar:=3;#code works for nvar:=3, but not for nvar:=2

3

ic0:=Vector(nvar,[seq(0.1,i=1..nvar)],datatype=float[8]);

Vector(3, {(1) = .1000000000000000, (2) = .1000000000000000, (3) = .1000000000000000})

 

ss(ic0);

HFloat(-0.09025778155141699)

bl := Vector(nvar,[seq(0.,i=1..nvar)]);bu := Vector(nvar,[seq(5.,i=1..nvar)]);

Vector(3, {(1) = 0., (2) = 0., (3) = 0.})

Vector[column](%id = 36893490450763924652)

infolevel[all]:=1;

1

Optimization:-NLPSolve(nvar,ss,[],initialpoint=ic0,[bl,bu]);

NLPSolve: calling NLP solver

NLPSolve: using method=sqp

NLPSolve: number of problem variables 3

NLPSolve: number of nonlinear inequality constraints 0

NLPSolve: number of nonlinear equality constraints 0

NLPSolve: number of general linear constraints 0

[-.531367180853919, Vector(3, {(1) = .8116892515974860, (2) = 1.189817750741097, (3) = 2.426110609252688})]

nvar:=2;#code works for nvar:=3, but not for nvar:=2

2

ic0:=Vector(nvar,[seq(0.1,i=1..nvar)],datatype=float[8]);

Vector(2, {(1) = .1000000000000000, (2) = .1000000000000000})

 

ss(ic0);

HFloat(-0.09025762200103044)

bl := Vector(nvar,[seq(0.,i=1..nvar)]);bu := Vector(nvar,[seq(5.,i=1..nvar)]);

Vector(2, {(1) = 0., (2) = 0.})

Vector[column](%id = 36893490450763939460)

infolevel[all]:=1;

1

Optimization:-NLPSolve(nvar,ss,[],initialpoint=ic0,[bl,bu]);

NLPSolve: calling NLP solver

NLPSolve: using method=sqp

NLPSolve: number of problem variables 2

NLPSolve: number of nonlinear inequality constraints 0

NLPSolve: number of nonlinear equality constraints 0

NLPSolve: number of general linear constraints 0

[-.523759339206159, Vector(2, {(1) = .9103276760025985, (2) = 1.925973211795306})]

 

nvar:=5;#code works for nvar:=3, but not for nvar:=2

5

ic0:=Vector(nvar,[seq(0.1,i=1..nvar)],datatype=float[8]);

Vector(5, {(1) = .1000000000000000, (2) = .1000000000000000, (3) = .1000000000000000, (4) = .1000000000000000, (5) = .1000000000000000})

 

ss(ic0);

HFloat(-0.09025786314622318)

bl := Vector(nvar,[seq(0.,i=1..nvar)]);bu := Vector(nvar,[seq(5.,i=1..nvar)]);

Vector(5, {(1) = 0., (2) = 0., (3) = 0., (4) = 0., (5) = 0.})

Vector[column](%id = 36893490450873412892)

infolevel[all]:=1;

1

Optimization:-NLPSolve(nvar,ss,[],initialpoint=ic0,[bl,bu]);

NLPSolve: calling NLP solver

NLPSolve: using method=sqp

NLPSolve: number of problem variables 5

NLPSolve: number of nonlinear inequality constraints 0

NLPSolve: number of nonlinear equality constraints 0

NLPSolve: number of general linear constraints 0

[-.537292701143927, Vector(5, {(1) = .7437459723532210, (2) = .9015469842007691, (3) = 1.149056357665623, (4) = 1.629519387333676, (5) = 3.220718773451731})]

infolevel[all]:=0:

#Note that results from nvar =2 are good initial guesses for nvar =4, etc, but it is not implemented in this code.

# objective is approaching convergence with 16 stages for control variable.

for j from 1 to 4 do
nvar:=2^j:
ic0:=Vector(nvar,[seq(0.1,i=1..nvar)],datatype=float[8]);
bl := Vector(nvar,[seq(0.,i=1..nvar)]);bu := Vector(nvar,[seq(5.,i=1..nvar)]);
obj[j]:=Optimization:-NLPSolve(nvar,ss,[],initialpoint=ic0,[bl,bu]):
print(2^j,obj[j][1]):
gc();
od:

2, -.523759339206158692

4, -.535093353250732817

8, -.540523213471601371

16, -.542691160681018525

[seq(obj[4][2][i],i=1..16)];#Control values

[HFloat(0.6844327854667692), HFloat(0.7213390420309091), HFloat(0.762134925769591), HFloat(0.8075994009309487), HFloat(0.8587549491734409), HFloat(0.9169717511913674), HFloat(0.9841099356697114), HFloat(1.0627974101121582), HFloat(1.1569237891930957), HFloat(1.2724091321519309), HFloat(1.4190145332788868), HFloat(1.6140310681691525), HFloat(1.89202739512972), HFloat(2.3355791576022167), HFloat(3.214921631547972), HFloat(5.0)]

 


 

Download testRk2.mw

@dharr 

I am a long-time Maple user, and I would appreciate it if you can provide any code/answer without the shortcuts/etc as much as possible. Also, for any procedures please don't add any inputs/variables/descriptions/variable types/ etc unless they are critically needed to make the code work for that purpose.

One of the charms of Maple is its symbolic capability, and keeping the codes/commands minimal and getting the results we seek are the best options for people like me who still miss the classic worksheet and old Maple GUIs.

Thanks

Venkat

 

@dharr 

As stated early, I am only interested in the sqp and gradient-based method. Nonlinear simplex cannot handle bounds.
My interest lies in sqp as I have to be able to able to change nvar as input to a procedure to predict the objective, and possibly nonlinear constraints as an objective

@vv 

The question was specifically to make NLPSolve work with sqp (gradient approach). 

I am aware of Direct Search package, Global Optimization package from Maple (current version from Optimus and the previous and more robust version which includes the reduced gradient approach (from Pintos) from the early Maple days. 
The code works for me for nvar = 3. I added cmaple to my windows path for a different reason. I am not sure if that made a difference. I am also aware of the analytical solution for a given constant u in a time horizon. 

The goal is to be able to use dsolve numeric/parametric form with sqp approach in Maple. 

The problem statement is given below

dca/dt = -(u+u^2/2)*ca

dcb/dt = u*ca - 0.1*cb

t = 0, ca = 1, cb = 0
Maximize cb(1) subject to the bounds 0 < u< 5.

There is an exact analytical solution for this (Pontyragin's principle). 
This is a reactor problem (with 0.1 replaced by 0) in the second equation introduced/taught by Dr. Larry Biegler at CMU

@vv 

thanks. Matrix form is supposed to be more efficient, but not documented well. 

@tomleslie 

Not sure about your question about nvar,

ss is defined as a procedure which works for any value of nvar = 2,3,4,5 etc

You can ignore the second call for nvar.

If needed you can set nvar:=2 at the top and run the code for just one call. I just showed this so that I can do a loop for nvar and get the objective for different values of nvar as 2,4,8, 16, etc

 

@minoush82 

I didn't read what happened to your posts, etc.

This is just in support of @acer to make sure he doesn't disappear from this forum.
I often times wondered how he had the time to even help with some very non-significant questions (from my pov), for example, to make a plot prettier, add/modify fonts/shapes, etc.

@acer is technically very good (not just for improving the aesthetics aspects of Maple) and helped me in publishing a peer-reviewed paper for us and is probably one of the very few here who can optimize Maple codes to run at a speed/RAM comparable to C++.
Please check, 
https://www.mapleprimes.com/questions/234050-Will-Anyone-Be-Able-To-Speed-Up-This

FWIW, Maple can compete with even some commercial industrial solvers, I will be posting on the same soon. This wouldn't have been possible without the forum members like @acer, and Maple folks like Allan Wittkopf, Erik Postma, etc

 

@rlopez 

We recently submitted an arxiv paper for a DAE solver in Maple 

(https://www.mapleprimes.com/questions/235335-Will-Anyone-Be-Able-To-Speed-Up-This)

Arxiv accepts only codes submitted to github. Github currently does not accept Maple files. Perhaps, Maplesoft should move in that direction by interacting with Github?

thanks

The following simple change for finite difference approximation (fourth order as opposed to second order)

for i from 2 to N-1 do
for j from 2 to M-1 do
eq[i,j]:=diff(c[i](t),t)=(16*c[i+1,j](t)-30*c[i,j](t)+16*c[i-1,j](t)-c[i-2,j](t)-c[i+2,j](t))/12/h^2+(16*c[i,j+1](t)-30*c[i,j](t)+16*c[i,j-1](t)-c[i,j-2](t)-c[i,j+2](t))/12/h^2-phi^2*c[i,j](t)^2;
od:od:

helps the code converge faster in x (around N =32 gives 1e-6 error as opposed to N = 64 or 128 for second-order approximation) for example 5. 

Of course, this may not work for all the cases/models (convection, nonlinear diffusivities, singular corners, etc causing unrealistic oscillations), but Maple can be used to develop and try different approximations for spatial derivatives (weak form, collocation, etc).
 


 

If the solver works or fails for any index-1 DAE that you are testing. 

1 2 3 4 5 6 7 Last Page 1 of 17