How to actually maximize a function with many variables
4 views (last 30 days)
Show older comments
Hello. I have these two functions:
lik = @(x) -(log(x(1,1))*mb2(1,1)+log(x(1,2))*mb2(1,2)+log(x(1,3))*mb2(1,3)+log(x(1,4))*mb2(1,4)...
+log(x(2,1))*mb2(2,1)+log(x(2,2))*mb2(2,2)+log(x(2,3))*mb2(2,3)+log(x(2,4))*mb2(2,4)...
+log(x(3,1))*mb2(3,1)+log(x(3,2))*mb2(3,2)+log(x(3,3))*mb2(3,3)+log(x(3,4))*mb2(3,4)...
+log(x(4,1))*mb2(4,1)+log(x(4,2))*mb2(4,2)+log(x(4,3))*mb2(4,3)+log(x(4,4))*mb2(4,4));
lik2 = @(y) -(log(y(1,1))*mb(1,1)+log(y(1,2))*mb(1,2)+log(y(1,3))*mb(1,3)+log(y(1,4))*mb(1,4)...
+log(y(2,1))*mb(2,1)+log(y(2,2))*mb(2,2)+log(y(2,3))*mb(2,3)+log(y(2,4))*mb(2,4)...
+log(y(3,1))*mb(3,1)+log(y(3,2))*mb(3,2)+log(y(3,3))*mb(3,3)+log(y(3,4))*mb(3,4)...
+log(y(4,1))*mb(4,1)+log(y(4,2))*mb(4,2)+log(y(4,3))*mb(4,3)+log(y(4,4))*mb(4,4)...
+log(y(1,5))*mb(1,5)+log(y(1,6))*mb(1,6)+log(y(1,7))*mb(1,7)+log(y(1,8))*mb(1,8)...
+log(y(2,5))*mb(2,5)+log(y(2,6))*mb(2,6)+log(y(2,7))*mb(2,7)+log(y(2,8))*mb(2,8)...
+log(y(3,5))*mb(3,5)+log(y(3,6))*mb(3,6)+log(y(3,7))*mb(3,7)+log(y(3,8))*mb(3,8)...
+log(y(4,5))*mb(4,5)+log(y(4,6))*mb(4,6)+log(y(4,7))*mb(4,7)+log(y(4,8))*mb(4,8));
Where mb and mb2 are matrices of positive integers. The solution to this, x and y, are matrices of numbers between 0 and 1, but it is very important to me to be as accurate as possible (the logs are there because of that), and I am only getting 'Local minimum possible' when using fmincon, instead of 'Local minimum found'. I change x0 and y0 and sometimes get a better solution, but it still does not show 'Local minimum found'. Here are the constraints and the fmincom I am using:
% Maximizing with constraints:
x0 = mb2*(1/100);
Aeq = [1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0; ... % Make each line of x sum to one.
0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0; ...
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0; ...
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1];
beq = ones(4,1);
lb = zeros(4,4);
ub = ones(4,4);
nonlcon = @cons_am;
options = optimoptions(@fmincon,'steptolerance',1.0000e-13,'constraintTolerance',1.0000e-09,'optimalitytolerance',1.0e-16,'MaxFunctionEvaluations',100000);
[x, xval, exitflag] = fmincon(lik,x0,[],[],Aeq,beq,lb,ub,nonlcon,options);
y0 = mb*(1/100);
Aeq2 = [1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;...
0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;...
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;...
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0;...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0;...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0;...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1];
beq2 = ones(8,1);
lb2 = zeros(4,8);
ub2 = ones(4,8);
nonlcon2 = @cons_am2;
options2 = optimoptions(@fmincon,'steptolerance',1.0000e-13,'constraintTolerance',1.0000e-09,'optimalitytolerance',1.0e-16,'MaxFunctionEvaluations',100000);
[y, yval, exitflag2] = fmincon(lik2,y0,[],[],Aeq2,beq2,lb2,ub2,nonlcon2,options2);
function [c, ceq] = cons_am2(y)
mu = [0.032051282051282 0.0000;0.33974358974359 0.140127388535032;0.455128205128205 0.407643312101911;0.173076923076923 0.452229299363057];
c(1)=3-(0.5873*(mu(1,1)*y(1,1)+mu(2,1)*y(2,1)+mu(3,1)*y(3,1)+mu(4,1)*y(4,1))/(mu(1,2)*y(1,5)+mu(2,2)*y(2,5)+mu(3,2)*y(3,5)+mu(4,2)*y(4,5)));
c(2)= (0.5873*(mu(1,1)*y(1,2)+mu(2,1)*y(2,2)+mu(3,1)*y(3,2)+mu(4,1)*y(4,2))/(mu(1,2)*y(1,6)+mu(2,2)*y(2,6)+mu(3,2)*y(3,6)+mu(4,2)*y(4,6)))-3;
c(3)=1-(0.5873*(mu(1,1)*y(1,2)+mu(2,1)*y(2,2)+mu(3,1)*y(3,2)+mu(4,1)*y(4,2))/(mu(1,2)*y(1,6)+mu(2,2)*y(2,6)+mu(3,2)*y(3,6)+mu(4,2)*y(4,6)));
c(4)= (0.5873*(mu(1,1)*y(1,3)+mu(2,1)*y(2,3)+mu(3,1)*y(3,3)+mu(4,1)*y(4,3))/(mu(1,2)*y(1,7)+mu(2,2)*y(2,7)+mu(3,2)*y(3,7)+mu(4,2)*y(4,7)))-1;
c(5)=(1/3)-(0.5873*(mu(1,1)*y(1,3)+mu(2,1)*y(2,3)+mu(3,1)*y(3,3)+mu(4,1)*y(4,3))/(mu(1,2)*y(1,7)+mu(2,2)*y(2,7)+mu(3,2)*y(3,7)+mu(4,2)*y(4,7)));
c(6)= (0.5873*(mu(1,1)*y(1,4)+mu(2,1)*y(2,4)+mu(3,1)*y(3,4)+mu(4,1)*y(4,4))/(mu(1,2)*y(1,8)+mu(2,2)*y(2,8)+mu(3,2)*y(3,8)+mu(4,2)*y(4,8)))-(1/3);
ceq = [];
end
function [c, ceq] = cons_am(x)
mu = [0.032051282051282 0.0000;0.33974358974359 0.140127388535032;0.455128205128205 0.407643312101911;0.173076923076923 0.452229299363057];
c(1)=3-(0.5873*(mu(1,1)*x(1,1)+mu(2,1)*x(2,1)+mu(3,1)*x(3,1)+mu(4,1)*x(4,1))/(mu(1,2)*x(1,1)+mu(2,2)*x(2,1)+mu(3,2)*x(3,1)+mu(4,2)*x(4,1)));
c(2)= (0.5873*(mu(1,1)*x(1,2)+mu(2,1)*x(2,2)+mu(3,1)*x(3,2)+mu(4,1)*x(4,2))/(mu(1,2)*x(1,2)+mu(2,2)*x(2,2)+mu(3,2)*x(3,2)+mu(4,2)*x(4,2)))-3;
c(3)=1-(0.5873*(mu(1,1)*x(1,2)+mu(2,1)*x(2,2)+mu(3,1)*x(3,2)+mu(4,1)*x(4,2))/(mu(1,2)*x(1,2)+mu(2,2)*x(2,2)+mu(3,2)*x(3,2)+mu(4,2)*x(4,2)));
c(4)= (0.5873*(mu(1,1)*x(1,3)+mu(2,1)*x(2,3)+mu(3,1)*x(3,3)+mu(4,1)*x(4,3))/(mu(1,2)*x(1,3)+mu(2,2)*x(2,3)+mu(3,2)*x(3,3)+mu(4,2)*x(4,3)))-1;
c(5)=(1/3)-(0.5873*(mu(1,1)*x(1,3)+mu(2,1)*x(2,3)+mu(3,1)*x(3,3)+mu(4,1)*x(4,3))/(mu(1,2)*x(1,3)+mu(2,2)*x(2,3)+mu(3,2)*x(3,3)+mu(4,2)*x(4,3)));
c(6)= (0.5873*(mu(1,1)*x(1,4)+mu(2,1)*x(2,4)+mu(3,1)*x(3,4)+mu(4,1)*x(4,4))/(mu(1,2)*x(1,4)+mu(2,2)*x(2,4)+mu(3,2)*x(3,4)+mu(4,2)*x(4,4)))-(1/3);
ceq = [];
end
If anyone has any suggestions I would be very grateful. I am buffled for not being able to get it to work properly. In case some context works: I have two samples from an experiment, I am trying to choose between two hypothesis by running a Neyman-Pearson test. The functions to maximize are the maximum likelihoods, and the constraints are there to restrict the likelihood to some intervals of my interest. Thanks again.
6 Comments
Stephen23
on 27 Jul 2018
"...writing all that long ugly thing helps me see the problem more clearly."
Learn to write simpler code, such as vectorized code that OCDER showed you. Complex code has more bugs and is harder to debug.
A good rule of thumb: any time you copy-and-paste code then you are doing something wrong.
Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!