# 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)
Matt J on 24 Jan 2023
Edited: Matt J on 3 Feb 2023
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

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

### Categories

Find more on Solver Outputs and Iterative Display in Help Center and File Exchange

R2022a

### Community Treasure Hunt

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

Start Hunting!

Translated by