dose JuMP.setRHS apply for non-linear modles in julia? - julia

In the following code, RHS of NL-constraints should change. but the error happens.
ERROR: UndefVarError: setRHS not defined. could you please learn me why this error happens?. thanks for your helps
using JuMP,CPLEX, Ipopt
#parameters--------------------------------------------------------
sig=0.86;
#---------------------------------------------------------------------------
ALT= Model(optimizer_with_attributes(Juniper.Optimizer, "nl_solver"=>optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0),
"mip_solver"=>optimizer_with_attributes(CPLEx.Optimizer, "logLevel" => 0),"registered_functions" =>[Juniper.register( :f, 1, f; autodiff = true)])
)
# variables-----------------------------------------------------------------
f(x) = cdf(Normal(0, 1), x);
JuMP.register(ALT, :f, 1, f; autodiff = true);
#variable(ALT, h >= 0.1);
#variable(ALT, L >= 0.0001);
#variable(ALT, n>=2, Int);
#-------------------------------------------------------------------
#NLexpression(ALT,k7,1-f(L-sig*sqrt(n))+f(-L-sig*sqrt(n)));
#NLexpression(ALT,f2,1/k7)
#constraints--------------------------------------------------------
#NLconstraint(ALT, f(-L) <= 1/400);
#NLconstraint(ALT,rf2,f2<=10000);
#-------------------------------------------------------------------
#NLobjective(ALT, Min, f2)
optimize!(ALT)
JuMP.setRHS(rf2,getvalueNLobjective(1/k7))

You are using outdated JuMP version examples. As of today you should use set_normalized_rhs:
set_normalized_rhs(con_ref, some_rhs_value)
Note that this sets the normalized RHS that is after it has been pre-computed by JuMP. For example for #constraint(model, 2x - 5 <= 2) the normalized value is 7.
See also https://jump.dev/JuMP.jl/v0.21/constraints/#Constraint-modifications-1 for more details.

Related

How is it possible to collect NLexpression in a loop?

Would you please help me that how I can collect some NLexpressions in a loop?
I Want to keep k8 and k9 for all i=1:10 as scenarios. It means in the end of the loop, Q equal to collection of k8 and k9 under each scenario ( i ). I couldn't define a matrix and put each pair of k8 and k9 in that as an element. with considering Q the code doesn't work as well.
Many thanks for your kindly help.
using JuMP,CPUTime, Distributions, Ipopt,Juniper,Cplex
n1=1; #the least of scenarios
N=4; #number of scenarios
M=20; #number of sampling
landa=0.01;
E=0.05
T0=0;
T1=2;
T2=2;
gam2=1; gam1=1;
a1=0.5; a2=0.1; a3=50; ap=25;
c0=10;
Zn=zeros(N, 4)
Q=0;
for i in n1:N
C1=rand(100:100:300);
sig=rand(0.5:0.5:2);
f(x) = cdf(Normal(0, 1), x);
#---------------------------------------------------------------------------
ALT= Model(optimizer_with_attributes(Juniper.Optimizer, "nl_solver"=>optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0),
"mip_solver"=>optimizer_with_attributes(Cplex.Optimizer, "logLevel" => 0),"registered_functions" =>[Juniper.register( :f, 1, f; autodiff = true)])
);
# variables-----------------------------------------------------------------
JuMP.register(ALT, :f, 1, f; autodiff = true);
#variable(ALT, h >= 0.001);
#variable(ALT, L >= 0.000001);
#variable(ALT, n>=2, Int);
#---------------------------------------------------------------------------
#NLexpression(ALT,k1,h/(1-f(L-sig*sqrt(n))+f(-L - sig*sqrt(n)))); # HARL1
#NLexpression(ALT,k2,(1-(1+landa*h)*exp(-landa*h))/(landa*(1-exp(-landa*h)))); #to
#NLexpression(ALT,k3,E*n+T1*gam1+T2*gam2);
#NLexpression(ALT,k8,(C1*(k1-k2+k3)));# depend on scenario
#NLexpression(ALT,k9,(((a1+a2*n)/h)*(k1)));#depend on scenario
Q=Q+k8+k9;
#-----------------------------------------------------------------------
end
You have a couple of issues in your code.
Why are you creating a new model every loop? You cannot aggregate expressions across models like you do with Q=Q+k8+k9
You cannot add nonlinear expressions like Q=Q+k8+k9. All nonlinear expressions must occur inside macros
In general, you are not limited to the specific syntax of JuMP. You can use any Julia data structures to help. In the code below, I just push expressions into a vec
I haven't tested, so there might be typos etc, but this should point you in the right direction:
using JuMP, Distributions
E, landa, T1, T2, gam1, gam2, a1, a2 = 0.05, 0.01, 2, 2, 1, 1, 0.5, 0.1
ALT = Model()
f(x) = cdf(Normal(0, 1), x)
JuMP.register(ALT, :f, 1, f; autodiff = true)
#variable(ALT, h >= 0.001)
#variable(ALT, L >= 0.000001)
#variable(ALT, n >= 2, Int)
k8, k9 = Any[], Any[]
for i in 1:4
C1 = rand(100:100:300)
sig = rand(0.5:0.5:2)
k1 = #NLexpression(ALT, h / (1 - f(L - sig * sqrt(n)) + f(-L - sig * sqrt(n))))
k2 = #NLexpression(ALT, (1 - (1 + landa * h) * exp(-landa * h)) / (landa * (1 - exp(-landa * h))))
k3 = #NLexpression(ALT, E * n + T1 * gam1 + T2 * gam2)
push!(k8, #NLexpression(ALT, C1 * (k1 - k2 + k3))
push!(k9, #NLexpression(ALT, k9, (a1 + a2 * n) / h * k1)
end
Q = #NLexpression(ALT, sum(k for k in k8) + sum(k for k in k9))

which non-linear solver is defined for normal distribution?

would you please help me? in following code Ipopt solver is used to solve the non-linear model. but it seems this solver not is not suitable for normal distribution. would you please help me which one of non-linear solver can be useful for solving the model. Thanks very much.
using JuMP,Gurobi, Ipopt
#parameters--------------------------------------------------------
sig=0.86;
#---------------------------------------------------------------------------
ALT= Model(optimizer_with_attributes(Juniper.Optimizer, "nl_solver"=>optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0),
"mip_solver"=>optimizer_with_attributes(Gurobi.Optimizer, "logLevel" => 0),"registered_functions" =>[Juniper.register( :f, 1, f; autodiff = true)])
)
# variables-----------------------------------------------------------------
f(x) = cdf(Normal(0, 1), x);
JuMP.register(ALT, :f, 1, f; autodiff = true);
#variable(ALT, h >= 0);
#variable(ALT, L >= 0);
#variable(ALT, n, Int);
#-------------------------------------------------------------------
#NLexpression(ALT,k7,1-f(L-sig*sqrt(n))+f(-L-sig*sqrt(n)));
#constraints--------------------------------------------------------
#NLconstraint(ALT, f(-L) <= 1/400);
#-------------------------------------------------------------------
#NLobjective(ALT, Min, 1/k7)
optimize!(ALT)
this error is there
ERROR: UndefVarError: Normal not defined

How to calculate the convolution of a function with itself multiple times in Wolfram?

Excuse me I am new to Wolfram. I have seen people asking questions about how to do convolution of a function with itself in Wolfram. However, I wonder how to do it multiple times in a loop. That is to say I want to do f20* i.e. f*f*f*f*....f totaling 20 f. How to implement it?
Here is my thinking. Of course do not work....
f[x_] := Piecewise[{{0.1`, x >= 0 && x <= 10}, {0, x < 0}, {0, x > 10}}];
g = f;
n = 19;
For[i = 1, i <= n, i++, g = Convolve[f[x], g, x, y]]; Plot[
g[x], {x, -10, n*10 + 10}, PlotRange -> All]
Could anybody help me?
My new code after revising agentp's code
f[x_] := Piecewise[{{0.1, x >= 0 && x <= 10}, {0, x < 0}, {0,x > 10}}];
n = 19;
res = NestList[Convolve[#, f[x], x, y] /. y -> x &, f[x], n];
Plot[res, {x, -10, (n + 1)*10 + 10}, PlotRange -> All,PlotPoints -> 1000]
My buggy image
maybe this?
Nest[ Convolve[#, f[x], x, y] /. y -> x &, f[x] , 3]
If that's not right maybe show what you get by hand for n=2 or 3.
res = NestList[ Convolve[#, f[x], x, y] /. y -> x &, f[x] , 10];
Plot[res, {x, 0, 100}, PlotRange -> All]
this gets very slow with n, I don't have the patience to run it out to 20.
Your approach is nearly working. You just have to
make sure to copy f by value before entering the loop, because otherwise you face infinite recursion.
Assign the result of Convolve to a function which takes a parameter.
This is the code with the mentioned changes:
f[x_] := Piecewise[{{0.1, x >= 0 && x <= 10}, {0, x < 0}, {0, x > 10}}];
g[x_] = f[x];
n = 20;
For[i = 1, i <= n, i++, g[y_] = Convolve[f[x], g[x], x, y]];
Plot[g[x], {x, -10, n*10 + 10}, PlotRange -> All]
Edit: While this works, agentp's answer is more consise and i suspect also faster.

Numerical Solution for a specified parameter in NDSolve (Mathematica)

I am working on a solution to solve a Partial Differential Equation, Fick's Second Law of Diffusion to be exact.
I was able to produce a 3D Plot using the NDSolve and Plot3D functions.
Code used:
NDSolve[{D[c[t, h], t] == 1*D[c[t, h], h, h],
c[0, h] == Erfc[h/(2*81.2)],
c[t, 0] == 1,
c[t, 4000] == 3.08*^-18}, c, {t, 0, 900}, {h, 0, 274}]
Instead of a graphical representation, I would like to find numerical points of the graph at t = 900.
I would like to know how to put in t = 900 into NDSolve (or other functions) so as to generate detailed numerical points of the solution.
Try saving the solution in a variable first:
e = NDSolve[{D[c[t, h], t] == 1*D[c[t, h], h, h], c[0, h] == Erfc[h/(2*81.2)], c[t, 0] == 1, c[t, 4000] == 3.08*^-18}, c, {t, 0, 900}, {h, 0, 274}]
Then we can Evaluate this expression for our desired variables:
Evaluate[c[900, 10] /. e]
(*{0.914014}*)
Or to make it more versatile, we can use Manipulate:
Manipulate[Evaluate[c[t, h] /. e], {t, 0, 900}, {h, 0, 274}]
Update:
Considering the information I received from the comments below; we can define a function like q[t,h] which will give us the solution as a function:
q[t_, h_] := Evaluate[c[t, h] /. e]
q[900, 10]
(*{0.914014}*)

How do I write an Euler function in Mathematica?

I programmed a Euler function but misread the instructions, so now I have to make a new one, but I can't figure it out.
I have made the following automatic Euler function.
f[x_, y_] := -x y^2;
x0 = 0;
y0 = 2;
xend = 2;
steps = 20;
h = (xend - x0)/steps // N;
x = x0;
y = y0;
eulerlist = {{x, y}};
For[i = 1, i <= steps, y = f[x, y]*h + y;
x = x + h;
eulerlist = Append[eulerlist, {x, y}];
i++
]
Print[eulerlist]
But it just generates the list I have specified.
I would like to have a Euler function which is able to generate this form:
Euler[y, 2, -x y^2, {x, 0, 2}, 20]
I don't seem to get any further.
It is not clear what you are asking, but if what you want is to be able to input
Euler[y, 2, -x y^2, {x, 0, 2}, 20]
and get
{{0,2},{0.1,2.},{0.2,1.96},{0.3,1.88317},{0.4,1.77678},{0.5,1.6505},{0.6,1.51429},{0.7,1.37671},{0.8,1.24404},{0.9,1.12023},{1.,1.00728},{1.1,0.905822},{1.2,0.815565},{1.3,0.735748},{1.4,0.665376},{1.5,0.603394},{1.6,0.548781},{1.7,0.500596},{1.8,0.457994},{1.9,0.420238},{2.,0.386684}}
Then you need to write a function definition like this:
Euler[y0_, f_, {x0_, xend_}, steps_Integer?Positive] := (* body *)
Notice the underscores to denote patterns, the := to denote delayed evaluation and the pattern specification Integer?Positive.
As for the body of the function -- oh my goodness could you have picked a less Mathematica-style approach? Perhaps not. Procedural loops and Append are almost never the best way to do anything in Mathematica.
Here is a better solution.
Euler[y_, y0_, f_, {x_, x0_, xend_}, steps_Integer?Positive] :=
With[{h = N[(xend - x0)/steps], ff = Function[{x, y}, f]},
NestList[{#[[1]] + h, ff[#[[1]], #[[2]]]*h + #[[2]]} &, {x0, y0},
steps]]
Euler[y, 2, -x y^2, {x, 0, 2}, 20]
{{0, 2}, {0.1, 2.}, {0.2, 1.96}, {0.3, 1.88317}, {0.4,
1.77678}, {0.5, 1.6505}, {0.6, 1.51429}, {0.7, 1.37671}, {0.8,
1.24404}, {0.9, 1.12023}, {1., 1.00728}, {1.1, 0.905822}, {1.2,
0.815565}, {1.3, 0.735748}, {1.4, 0.665376}, {1.5, 0.603394}, {1.6,
0.548781}, {1.7, 0.500596}, {1.8, 0.457994}, {1.9, 0.420238}, {2.,
0.386684}}
If you want something that outputs Euler[y, 2, -x y^2, {x, 0, 2}, 20], then typing it into the notebook is the quickest method.

Resources