hi guys I have some problem
I coding some optimization one
4 variables f(x1,x2,x3,x4)
so...I was using 'fmincon'...but it doesn't work very well
here is the Question
how can I write a constraints(x) in 'fminsearch' like 'fmincon'
---------------constraints(x) form look like---------------------------
function [C, Ceq] = constraints(x)
B=1200;
N=1;
C(1)= 60-x(1) ;
C(2)= 50-x(4) ;
C(3)=-140+x(1)+x(2);
C(4)=-x(3)+x(4);
C(7)=x(3)-B*N;
C(5)=-x(2);
C(6)= x(1)*B + x(4)*x(2)*N + (x(3)-x(4))*x(2)/2*N -107000;
Ceq=[];
end
cruel life xoxo
You can't. fminsearch is for unconstrained problems.
However, you can choose a different fmincon algorithm:
'interior-point' (default)
'trust-region-reflective'
'sqp'
'sqp-legacy'
'active-set'
See fmincon Algorithms. Use optimoptions to set the Algorithm option at the command line.
Related
I have some troubles to understand how to implement the following MIQP (Mixed Integer Quadratic Programming) with linear constraints in Matlab calling Gurobi.
Let me explain in a schematic way my setting.
(1) x is the unknown and it is a column vector with size 225x1.
(2) The objective function (which should be minimised wrto x) looks like
which can be rewritten as
I have a Matlab script computing alpha, Q,c (Q,c sparse) when some_known_parameters1 are given:
function [alpha, Q,c]=matrix_objective_function(some_known_parameters1)
%...
end
(3) The constraints are linear in x, include equalities and inequalities, and are written in the form
I have a Matlab script computing Aeq,beq,Aineq,bineq (Aeq,Aineq sparse) when some_known_parameters2 is given:
function [Aeq,beq,Aineq,bineq]=constraints(some_known_parameters2)
%...
end
(4) Some components of x are restricted to be in {0,1}. I have a Matlab script producing a string of letters B (binary), C (continous) when some_known_parameters3 is given:
function type=binary_continuous(some_known_parameters3)
%...
end
Now, I need to put together (1)-(4) using Gurobi. I am struggling to understand how. I found this example but it looks very cryptic to me. Below I report some lines I have attempted to write, but they are incomplete and I would like your help to complete them.
clear
rng default
%Define some_known_parameters1,
some_known_parameters2,some_known_parameters3 [...]
%1) generate alpha,Q,c,Aeq,beq,Aineq,bineq,type with Q,c,Aeq, Aineq sparse
[alpha, Q,c]=matrix_objective_function(some_known_parameters1)
[Aeq,beq,Aineq,bineq]=constraints(some_known_parameters2)
type=binary_continuous(some_known_parameters3)
%2) Set up Gurobi
clear model;
model.A=[Aineq; Aeq];
model.rhs=full([bineq(:); beq(:)]);
model.sense=[repmat('<', size(Aineq,1),1); repmat('=', size(Aeq,1),1)];
model.Q=Q; %not sure?
model.alpha=alpha; %not sure?
model.c=c; %not sure?
model.vtype=type;
result=gurobi(model); %how do I get just the objective function here without the minimiser?
Questions:
(1) I'm not sure about
model.Q=Q;
model.alpha=alpha;
model.c=c;
I'm just trying to set the matrices of the objective function using the letters provided here but it gives me error. The example here seems to me doing
model.Q=Q;
model.obj=c;
But then how do I set alpha? Is it ignoring it because it does not change the set of solutions?
(2) How do I get as output stored in a matrix just the minimum value of the objective function without the corresponding x?
(1) You're right, there's no need to pass the constant alpha since it doesn't affect the optimal solution. Gurobi's MATLAB API only accepts sparse matrices. Furthermore model.obj is always the c vector in the problem statement:
model.Q = sparse(Q);
model.obj = c;
(2) To get the optimal objective value, you first need to pass your model to gurobi and solve it. Then you can access it via the objval attribute:
results = gurobi(model);
val = results.objval + alpha
Dear community of stack overflow. Is it possible to improve the speed of this code in Matlab? Can I use vectorization? Note that I have to use in every loop the "vpasolve" or "fsolve" function.
Here is the code which calls the function with a double loop:
for i=1:1000
for j=1:1000
SilA(i,j)=SolW(i,j);
end
end
Here is the function which is called by the above code. Can I vectorize the input of w, xi and make the code run faster?
function [ffw] = SolW(w,xi)
format long e;
z=0;mm=0.46;sop=80;
epit=0.1;voP=80.;
rho=2.1;aposC=0.1;aposD=0.1;
parEh=0.2*10^6;parEv=0.2*10^6;parGv=0.074*10^6;
parpos=0.35;hp=0.2;Ep=30*10^6;
parposV=0.20;ll=0.15;dd=2*ll;
C11=(parEh*(parEv-parEh*parpos^2)/((1+parpos)*(parEv-parEv*parpos-2*parEh*parpos^2)))*(1+2*1i*aposD);
C13=(parEh*parEv*parpos/((parEv-parEv*parpos-2*parEh*parpos^2)))*(1+2*1i*aposD);
C33=((1-parpos)*parEv^2/(parEv-parEv*parpos-2*parEh*parpos^2))*(1+2*1i*aposD);
C44=parGv*(1+2*1i*aposD);
DD=(Ep*hp^3)/(12*(1-parposV^2));
a1=C44;
a2=C33;
c1=(C13+C44)*1i*xi;
c2=(C13+C44)*1i*xi;
b1=rho*w^2-C11*xi^2;
b2=rho*w^2-C44*xi^2;
syms xr
rsol=vpasolve((a1*xr+b1).*(a2*xr+b2)-c1*c2*xr==0,xr);
rsol=eval(rsol);
r=[-sqrt(rsol)];
r1=r(1,:);
r2=r(2,:);
Fdf1=sop*sqrt(2*pi/(1i*epit*xi))*exp(1i*(xi*voP+w)^2/(2*epit*xi));
BC11=C44*(r1-1i*xi*c2*r1/(a2*r1^2+b2));
BC21=(C13*1i*xi)-((C33*c2*r1^2)/(a2*r1^2+b2))+(DD*xi^4-mm*w^2+1i*aposC*w)*c2*r1/(a2*r1^2+b2);
BC12=C44*(r2-1i*xi*c2*r2/(a2*r2^2+b2));
BC22=(C13*1i*xi)-((C33*c2*r2^2)/(a2*r2^2+b2))+(DD*xi^4-mm*w^2+1i*aposC*w)*c2*r2/(a2*r2^2+b2);
syms As1 As2;
try
[Ass1,Ass2]=vpasolve(BC11*As1+BC12*As2==0,BC21*As1+BC22*As2+Fdf1==0,As1,As2);
A1=eval(Ass1);
A2=eval(Ass2);
catch
A1=0.0;
A2=0.0;
end
Bn1=-(c2*r1/(a2*r1^2+b2))*A1;
Bn2=-(c2*r2/(a2*r2^2+b2))*A2;
ffw=Bn1*exp(r1*z)+Bn2*exp(r2*z);
end
Everything in your function but the calls to vpasolve, and try.... can be vectorize.
First, all this does not depend on w or xi, so could be computed once only:
format long e;
z=0;mm=0.46;sop=80;
epit=0.1;voP=80.;
rho=2.1;aposC=0.1;aposD=0.1;
parEh=0.2*10^6;parEv=0.2*10^6;parGv=0.074*10^6;
parpos=0.35;hp=0.2;Ep=30*10^6;
parposV=0.20;ll=0.15;dd=2*ll;
C11=(parEh*(parEv-parEh*parpos^2)/((1+parpos)*(parEv-parEv*parpos-2*parEh*parpos^2)))*(1+2*1i*aposD);
C13=(parEh*parEv*parpos/((parEv-parEv*parpos-2*parEh*parpos^2)))*(1+2*1i*aposD);
C33=((1-parpos)*parEv^2/(parEv-parEv*parpos-2*parEh*parpos^2))*(1+2*1i*aposD);
C44=parGv*(1+2*1i*aposD);
DD=(Ep*hp^3)/(12*(1-parposV^2));
a1=C44;
a2=C33;
From what I know, eval is slow, and I'm pretty sure that you don't need it:
rsol=eval(rsol);
Here is an example of vectorization. You should first generate all indices combination using meshgrid, and then use the . to noticed matlab to use element wise operations:
[I, J] = meshgrid(1:1000, 1:1000)
c1=(C13+C44)*1i.*xi;
c2=(C13+C44)*1i.*xi;
b1=rho.*w.^2 - C11.*xi.^2;
b2=rho.*w.^2-C44.*xi.^2;
But you won't be able to vectorize vpasolve, and try.... litteraly, without changing it to something else. vpasolve is probably the bottleneck of you computation (verify this using matlab profiler), so optimizing as proposed above will probably not reduce your computation time much.
Then you have several solutions:
use parfor if you have access to it to parallelize your computations, which depending on your architecture, could give you a 4x speedup or so.
it may be possible to linearize your equations and solve them all in one operation. Anyway, using a linear solver will be probably much faster than using vpasolve. This will probably give you the fastest speedup (guessing factor 10 -100 ?)
because you have continuous data, you could reduce the number of steps, if you dare loosing precision.
Hope this helps
In the above program everything can be vectorized as #beesleep said above.
For example:
[I, J] = meshgrid(1:1000, 1:1000)
c1=(C13+C44)*1i.*xi;
c2=(C13+C44)*1i.*xi;
b1=rho.*w.^2 - C11.*xi.^2;
b2=rho.*w.^2-C44.*xi.^2;
The vpasolve part ,i.e.,
syms xr
rsol=vpasolve((a1*xr+b1).*(a2*xr+b2)-c1*c2*xr==0,xr);
rsol=eval(rsol);
r=[-sqrt(rsol)];
r1=r(1,:);
r2=r(2,:);
can also be vectorized by using fsolve as it is shown here:
fun=#(Xr) (a1.*Xr+b1).*(a2.*Xr+b2)-c1.*c2.*Xr
x01=-ones(2*Nxi);
x02=ones(2*Nxi);
options.Algorithm= 'trust-region-reflective'
options.JacobPattern=speye(4*Nxi^2);
options.PrecondBandWidth=0;
[rsol1]=fsolve(fun,x01,options);
[rsol2]=fsolve(fun,x02,options);
The other part, i.e,
syms As1 As2;
try
[Ass1,Ass2]=vpasolve(BC11*As1+BC12*As2==0,BC21*As1+BC22*As2+Fdf1==0,As1,As2);
A1=eval(Ass1);
A2=eval(Ass2);
catch
A1=0.0;
A2=0.0;
end
since contains linear equations and in each row has two dependent equations can be solved as it is shown here:
funAB1=#(As1) BC11.*As1+BC12.*((-Fdf2-BC21.*As1)./BC22);
x0AB=ones(2*Nxi)+1i*ones(2*Nxi);
options.Algorithm= 'trust-region-reflective';
options.JacobPattern=speye(4*Nxi^2);
options.PrecondBandWidth=0;
[A1]=fsolve(funAB1,x0AB,options);
A2=((-Fdf2-BC21.*A1)./BC22);
However, both can also be solved analytically, i.e.,
AAr=a1.*a2;
BBr=a1.*b2+b1.*a2-c1.*c2;
CCr=b1.*b2;
Xr1=(-BBr+sqrt(BBr^.2-4.*AAr.*CCr))./(2.*AAr);
Xr2=(-BBr-sqrt(BBr^.2-4.*AAr.*CCr))./(2.*AAr);
r1=-sqrt(Xr1(:,:));
r2=-sqrt(Xr2(:,:));
I wanted to know a specific thing about Matlab fsolve technique. As shown in the code, there are two non-linear equations. I can normally solve them but I want to optimise the process. It is observed that there is a common term 2*x(1)^2 - 3*x(2)^3 in both of these equations. The question is, can I declare a separate term for the common part and use the fsolve(as in the commented part)? If yes, can anyone please tell me the way to do.
function f = sym4(x)
f(1)= 8*x(1)^2 -12*x(1)^3 +x(1)*x(2)+ x(2)^2-1;
f(2)= 2*x(1)^3 - 3*x(1)^4 +x(2)-3;
% z = 2*x(1)^2 - 3*x(2)^3;
%
% f(1)= 4*z + x(2)^2 + x(1)*x(2) -1;
% f(2)= x*z +x(2)-3;
end
Yes, you can use intermediate variables, which may be somewhat faster because the common term is only evaluated once. As horchler pointed out, you should check your indexes.
I'm trying to differentiate WhittakerM function.
To solve the WhittakerM equation we have:
dsolve( 'D2y+(-1/4+Landa/r+(1/4-(L+1/2)^2)/r^2)*y=0' ,'r')
C1*WhittakerM(Landa,L+1/2,r)+C2*WhittakerW(Landa,L+1/2,r)
from the boundary condition I only need WhittakerM(Landa,L+1/2,r)/rthat 1/ris added for the condition of the problem. I'm trying to defferentiate it then substitute in some points, but there are some errorin subsand diff.
Landa=1;L=0; % # for simplicity
R1=inline('WhittakerM(Landa,L+1/2,r)/r','r');
Rp1=diff(R1,r);
r=1:0.01:20;
R1sub=eval(R1,r);
Rp1sub=eval(Rp1,r);
Do u have any idea?
Regardless of the errors above (honestly I do not fully understand what you are trying to achieve with the substitution), using the symbolic toolbox might be a good start here:
syms r
%defines a symbolic function
R1(r)=whittakerM(landa,l+1/2,r)/r
%differentiate
Rp1=diff(R1,r);
%evaluate
Rp1_e=Rp1(1:0.01:20)
I set my options to
options=optimset('LevenbergMarquardt', 'on')
and then employ lsqcurvefit like below,
[x,resnorm,residual,exitflag,output] = lsqcurvefit(#myfun, [0.01 0.3], xdata, ydata, [-inf -inf], [inf inf], options)
but the problem is that I don't now why I will get for output :
output =
firstorderopt: 3.4390e-07
iterations: 4
funcCount: 15
cgiterations: 0
algorithm: 'large-scale: trust-region reflective Newton'
message: [1x425 char]
Does this mean Matlab did not use the algorithm Levenberg Marquardt?
But I did set my options to levenberg Marquardt algorithm!!!
I'd appreciate any help.
Sometimes a specific algorithm is not suitable for a specific configuration of an optimization problem. In these cases Matlab "falls back" to its default optimization algorithm.
It might be the case that for your specific problem/configuration Matlab is unable to use Levenberg-Marquardt algorithm.
Read the docs carefully to see if this is the case.
I can't say for certain, but the constaints ([-inf -inf], [inf inf]) could be your problem. The documentation for lsqcurvefit strictly says the LMA cannot be used for constrained problems. If constraints are included, it will fall back to trust-region.
Yes, your constraints are mathematically equivalent to 'no constaints', but I have no idea how the MATLAB function itself will interpret those. I tried to recreate the problem on my end, but optimset('LevenbergMarquardt', 'on') has been deprecated and generates an error (implying you have a relatively old version). Even when using the new syntax (optimset('Algorithm', 'levenberg-marquardt')), it behaves correctly on my end (using 2011b). To not have constraints, the correct approach is to use empty matrices (i.e. []).
Yes, the question is a month old, but someone else may find the answer useful.