Finding close-to-linear solution

5 visualizzazioni (ultimi 30 giorni)
Tintin Milou
Tintin Milou il 16 Mag 2022
Modificato: Tintin Milou il 17 Mag 2022
I am using fsolve within fsolve. The most time spent in my code is on the inner fsolve function which matlab calls 1.5 million times.
The inner function that needs to be solved is as follows:
function F = solveE(E,c)
F = E - log(c'*exp(0.99*E));
Here, E is an Nx1 vector and c is an NxN matrix. N is typically around 400. Values for c are all positive and real. Values for E are negative and real. Is there a faster way of solving this?
Within the outer fsolve, I call this function using
E0 = fsolve(@(E) solveE(E,c),E0,options);
One thing I am already doing is to use my solution E0 as an initial guess for the next iteration (when matlab adjusts its guess for the variable that solves the outer fsolve, which then will change the value for c).
Thanks for any suggestions.

Risposta accettata

Matt J
Matt J il 16 Mag 2022
Modificato: Matt J il 16 Mag 2022
Pre-transpose c before the optimization to avoid repeatng the tranpose every iteration.
ct=c';
function outer(p,ct)
E0 = fsolve(@(E) solveE(E,ct),E0,options);
end
Also, for the inner problem, supply the Jacobian of F,
options.SpecifyObjectiveGradient=true;
E0 = fsolve(@(E) solveE(E,ct),E0,options);
function [F,J] = solveE(E,ct)
N=length(ct);
expE=exp(0.99*E)';
tmp=ct*expE(:);
F = E - log(tmp);
if nargout>1
J=eye(N)-0.99*(ct.*expE)./tmp;
end
end
  7 Commenti
Matt J
Matt J il 16 Mag 2022
Modificato: Matt J il 17 Mag 2022
One thing I am already doing is to use my solution E0 as an initial guess for the next iteration (when matlab adjusts its guess for the variable that solves the outer fsolve, which then will change the value for c).
I don't know if this is advisable. What contingency plan do you follow when the inner optimization of solveE() fails and produces a bad E0 for the next iteration?
Also, the outer call to fsolve is calling the inner function solveE() not only when updating its guess. It is also calling it in order to assist in finite difference calculations. This means that the last solution to solveE might in fact be further away from the current E This is even more likely at points wher the inner solution E is non-differentiable as a function of the outer parameters (as was shown could happen in this comment).
A safer way of selecting E0, I think, would be to round the 0.99 up to 1 and thereby approximate the inner equations as,
E-log(Ct*exp(E))=0
which is equivalent to,
exp(E)=Ct*exp(E)
After a change of variables z=exp(E), this becomes a linear least squares problem,
min ||z - Ct*z||, 0<=z<=1
which can be solved with lsqlin().
Tintin Milou
Tintin Milou il 17 Mag 2022
Modificato: Tintin Milou il 17 Mag 2022
That might help. The Jacobian works now and it cuts the running time in half. So that's pretty good!

Accedi per commentare.

Più risposte (1)

Catalytic
Catalytic il 16 Mag 2022
Modificato: Catalytic il 16 Mag 2022
Using fsolve inside of fsolve is a doubtful-sounding thing to do. Why not just combine the equations from solveE with the equations in your outer problem and solve a single system?
As a simpler example, instead of having something like this as your equation function...
function F=Equations(x,z0)
z=fsolve(@(z) z^3-x, z0);
F(1)=x+1-z;
end
...it is probably better to have this
function F=Equations(xz)
x=xz(1); z=xz(2);
F(1)=z^3-x;
F(2)=x+1-z;
end
  5 Commenti
Tintin Milou
Tintin Milou il 17 Mag 2022
It's quick per evaluation; it's just that I had 1.5 million evaluations. Having 1.5 million evaluations of the outer loop would be infeasible.
Re 2: The economic model behind the equations tells me that the functions are well behaved; mathematically, there might be a range for which the function is no longer well behaved, but values in that range wouldn't make any economic sense.
Matt J
Matt J il 17 Mag 2022
Modificato: Matt J il 17 Mag 2022
I don't know what "well-behaved" refers to here. It seems very hard to know in advance whether the result of the inner fsolve will be differentiable with respect to the outer unknowns. It certainly isn't guaranteed by the smoothness of solveE. You can see in Catalytic's example that the inner equation function @(z) z^3-x is a highly smooth, polynomial function of both z and x. Yet, solving for z leads to a non-differentiable function of x.

Accedi per commentare.

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by