When using JacobianMultiplyFcn in lsqnonlin, why is Jinfo required to be numeric? How can I pass more general kinds of parameters to my JacobianMultiplyFcn?

5 views (last 30 days)
What I would like to do is use the JacobianMultiplyFcn option of lsqnonlin's trust-region-reflective algorithm where Jinfo is a struct carrying parameters to be used by the Jacobian multiply operations. Below is a simplified example.
However, an error is produced indicating that Jinfo is not allowed to be a struct. I thought the whole point of JacobianMultiplyFcn option is that an actual numeric Jacobian matrix doesn't have to be constructed. What then, is Jinfo supposed to be, and how can I accomplish what I want?
A=rand(3); A(:,end)=1;
opts=optimoptions('lsqnonlin','Algorithm','trust-region-reflective',...
'OptimalityTol',1e-20,'FunctionTol',1e-30,'StepTol',1e-20,...
'SpecifyObjective', true, 'JacobianMultiplyFcn',@jmfunc);
[x,res]=lsqnonlin(@(x)resFcn(x,A), rand(3,1), [],[],opts)
Incorrect number or types of inputs or outputs for function 'nonzeros'.

Error in lsqncommon (line 18)
if any(~isfinite(nonzeros(initVals.J)))

Error in lsqnonlin (line 260)
lsqncommon(funfcn,xCurrent,lb,ub,options,defaultopt,optimgetFlag,caller,...
function [r,Jinfo]=resFcn(x,A)
r=[A*x;x(:).^2/2]-[4;4;4;0;0;8];
Jinfo.A=A;
Jinfo.x=x;
end
function W=jmfunc(Jinfo,Y,flag)
A=Jinfo.A;
x=Jinfo.x;
switch sign(flag)
case 0
W=A'*(A*Y)+Y.*x.^2;
case 1
W = [A*Y ;x.*Y];
case -1
P=Y(1:end/2);
Q=Y(end/2+1:end);
W = A.'*P+x.*Q;
end
end

Accepted Answer

Matt J
Matt J on 25 Jan 2023
Edited: Matt J on 3 Feb 2023
I seem to be have been able to fool lsqnonlin into doing what I want by using the attached classdef. However, I still wonder, nervously, why the Optimization Toolbox is trying to prevent me from doing this.
A=rand(3); A(:,end)=1;
opts=optimoptions('lsqnonlin','Algorithm','trust-region-reflective',...
'OptimalityTol',1e-20,'FunctionTol',1e-30,'StepTol',1e-20,...
'SpecifyObjective', true, 'JacobianMultiplyFcn',@jmfunc);
[x,res]=lsqnonlin(@(x)resFcn(x,A), rand(3,1), [],[],opts)
Local minimum possible. lsqnonlin stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
x = 3×1
-0.0000 0.0000 4.0000
res = 1.5777e-30
function [r,Jinfo]=resFcn(x,A)
r=[A*x;x(:).^2/2]-[4;4;4;0;0;8];
s.A=A;
s.x=x;
Jinfo=JMInfo(s);
end
function W=jmfunc(Jinfo,Y,flag)
A=Jinfo.s.A;
x=Jinfo.s.x;
switch sign(flag)
case 0
W=A'*(A*Y)+Y.*x.^2;
case 1
W = [A*Y ;x.*Y];
case -1
P=Y(1:end/2);
Q=Y(end/2+1:end);
W = A.'*P+x.*Q;
end
end

More Answers (0)

Categories

Find more on Manual Performance Optimization in Help Center and File Exchange

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!