Symbolic computations making fmincon painfully slow.... smart/convenient way to avoid invoking symbolic toolbox at each iteration?

2 views (last 30 days)
Hey everyone,
I'm using fmincon to solve a constrained minimization problem. The issue I'm running into is that, in order to obtain my objective function, I need to call another function (fpi_model) that requires time-consuming symbolic manipulation. Each call of the function that requires the use of symbolic toolbox takes a few seconds, which amounts to hours and hours (sometimes days!) as fmincon searches for a solution (I've tried various algorithms, they all take quite a while). I summarize the relevant code below (some if it is trimmed for brevity... let me know if the issue is not clear). What I need is a way to avoid invoking the symbolic toolbox at each iteration, while (ideally) keeping the code I have relatively intact. Is there a smart/concise/clean way to do this? Any other ideas more generally for speeding this up?
Thanks in advance.
Code:
fmincon call:
f=@(p)fpi_calibration(p,gx1(:,:,1),hx1(:,:,1),vd_p,vd_m,sd,i,param(1),m);
p_t(:,i+1) = fmincon(f,p0,A,b,Aeq(:,:,i+1),beq(:,i+1),lb,ub,[],options);
fpi_calibration (relevant portion):
%AR parameters
paramc.rhoa = p(11);
paramc.rhow = p(12);
paramc.rhor = p(13);
paramc.rhoi = p(14);
paramc.rhob = p(15);
[fync, fxnc, fypnc, fxpnc] = fpi_model(paramc,m);
[gxc1,hxc1]=gx_hx(fync,fxnc,fypnc,fxpnc);
if m==1
hxf=hxc1(1:nxc,1:nxc);
for j=1:nyc
gxf(j,:)=gxc1(3+5*j,1:nxc);
end
else
hxf=hxc1(1:nxc,1:nxc);
for j=1:nyc
gxf(j,:)=gxc1(6+j,1:nxc);
end
end
%Displaying new gx,hx,eta
disp('p=');
disp(p);
%Variance decomposition
[Vyr,Vxr,Vy,Vx] = vardecomp_tlp(gxf,hxf,eta_pc,eta_mc);
%Function
y = (Vy(2,1)/sum(Vy(2:7,1))-vdp(1,1)*(1-vdm(1,1)))^2+...
(Vy(3,1)/sum(Vy(2:7,1))-vdp(1,2)*(1-vdm(1,1)))^2+...
(Vy(4,1)/sum(Vy(2:7,1))-vdp(1,3)*(1-vdm(1,1)))^2+...
(Vy(5,1)/sum(Vy(2:7,1))-vdp(1,4)*(1-vdm(1,1)))^2+...
(Vy(6,1)/sum(Vy(2:7,1))-vdp(1,5)*(1-vdm(1,1)))^2+...
(Vyr(8,2)-vdm(1,2))^2+...
(Vyr(9,3)-vdm(1,3))^2+...
(Vyr(10,4)-vdm(1,4))^2+...
(Vyr(11,5)-vdm(1,5))^2+...
(sum(Vy(2:7,1))-sd(1)^2)^2+... %Variance of Y
(sum(Vy(2:6,2))+Vy(8,2)-sd(2)^2)^2+... %Variance of C
(sum(Vy(2:6,3))+Vy(9,3)-sd(3)^2)^2+... %Variance of L
(sum(Vy(2:6,4))+Vy(10,4)-sd(4)^2)^2+... %Variance of CU
(sum(Vy(2:6,5))+Vy(11,5)-sd(5)^2)^2+... %Variance of U
(sum(Vx(2:6,6))-sd(6)^2)^2+... %Variance of W
(sum(Vx(2:6,7))-sd(7)^2)^2; %Variance of R
fpi_model:
%Declare symbolic vars
syms s1 s2 s3 s4 ....
YY = [s1 s2 ...]
YYP = [...]
XX = [...]
XXP = [...]
%Declare model
f(1)=...
f(2)=...
...
%Check Computation of Steady-State Numerically
fnum = double(subs(f, [YY XX YYP XXP], [ss, ss]));
%Log-linear approx
log_var = [YY XX YYP XXP];
f = subs(f, log_var, exp(log_var));
%Differentiate
fx = jacobian(f,XX);
fy = jacobian(f,YY);
fxp = jacobian(f,XXP);
fyp = jacobian(f,YYP);
%Plug back into levels
fx = subs(fx, log_var, log(log_var));
fy = subs(fy, log_var, log(log_var));
fxp = subs(fxp, log_var, log(log_var));
fyp = subs(fyp, log_var, log(log_var));
%Numerical
fxn = double(subs(fx, [YY XX YYP XXP], [ss, ss]));
fyn = double(subs(fy, [YY XX YYP XXP], [ss, ss]));
fxpn = double(subs(fxp, [YY XX YYP XXP], [ss, ss]));
fypn = double(subs(fyp, [YY XX YYP XXP], [ss, ss]));

Answers (1)

Walter Roberson
Walter Roberson on 8 Aug 2013
I have not examined your code in detail.
In general, if the form of equations is not changing, just the linear coefficients, then you put in variables for those linear coefficients, run through the calculations once, and then use matlabFunction() to convert the symbolic expression into an anonymous function that has parameters for the coefficients.

Community Treasure Hunt

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

Start Hunting!