Why fmincon gives different optimal vector after adding equality constraint that describes output of fmincon before adding the constraint?

Hello guys, I'm new to MathWorks but I think I have a decent experience with MATLAB.
So, I have a function called MaxDiversification which, in addition to other inputs, takes a structured array of inequality and equality constraints for my problem. When I run the code I get a vector, w, of weights for a portfolio, and the portfolio return, R, for that set vector of weights, i.e. R = Mu'*w where Mu is a vector of expected returns for each asset.
Now here's my problem: when I add the constraint Mu'*w = R to the structured array... where R is the output from before... and then run MaxDiversification, I get a different weights vector w. WHY?
I'm adding this constraint because I want to test the function before running it with other portfolio returns R and getting the corresponding optimal vectors w.
The code for the function is given below. I believe ENB and the functions MinimumTorsion and PrincipalComp don't affect the optimization of w so I didn't mention anything about them.
function [w, ENB, MinRet] = MaxDiversification2(Mu, w_0, S, Constr, method)
switch method
case 'MT'
w = fmincon(@exp_term1, w_0, Constr.A, Constr.b, Constr.Aeq, Constr.beq);
ENB = MinimumTorsion(w,S);
MinRet = Mu'*w;
case 'PCA'
w = fmincon(@exp_term2, w_0, Constr.A, Constr.b, Constr.Aeq, Constr.beq);
ENB = PrincipalComp(w, S);
MinRet = Mu'*w;
end
% exp_term1
function y = exp_term1(w)
Sigma = S;
volatilities = diag(Sigma).^(1/2);
corr = diag(1./volatilities)*Sigma*diag(1./volatilities);
[eigvec,eigval] = eig(corr);
gamma = sqrt(eigval);
c = eigvec*gamma*eigvec';
n = size(Sigma, 2);
d = eye(n);
pi_1 = eye(n);
abserror_pi = norm(d,'fro');
niter = 0;
while abserror_pi > 10^-14
niter = niter + 1;
if niter == 8000
break
end
pi_0 = pi_1;
u = (d*(c*c')*d)^0.5;
q = (u\d)*c;
d = diag(diag(q*c));
pi_1 = d*q;
abserror_pi = norm(pi_1- pi_0,'fro')/n;
end
pi = pi_1;
clear pi_1
t_MT = diag(volatilities)*pi*(c\diag(1./volatilities));
dist_MT = ((t_MT'\w).*(t_MT*Sigma*w))/(w'*Sigma*w);
y = -exp(-dist_MT'*log(dist_MT));
end
% exp_term2
function y = exp_term2(w)
load S
Sigma = S;
[eigvec, eigval] = eig(Sigma);
[~, ind] = sort(diag(eigval),'descend');
eigvec = eigvec(:,ind);
flip = eigvec(1,:) < 0;
eigvec(:,flip) = -eigvec(:,flip);
dist_PC = (eigvec'*w).*(eigvec'*Sigma*w)/(w'*Sigma*w);
y = -exp(-dist_PC'*log(dist_PC));
end
end
end

 Accepted Answer

I can think of a a few possible reasons,
  1. Floating point arithmetic? You haven't said how big or small the differences are.
  2. One or both of the optimizations didn't actually complete. I notice there is not exitflag check in your code.
  3. Your solution space is non-unique. Did you compare the objective function value reached and whether constraints are satisfied for both cases?
  4. You have local minima and one or both optimizations got stuck at sub-optimal points.

1 Comment

After evaluating my code through the 4 possibilities you mentioned I realised that the third is correct. I'm dealing with a non-unique solution space. I realised this through inputting different initial weights for the fmincon function and getting different final weights.
Thank you, Matt

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!