Trying to supply fsolve with system's Jacobian but receiving error ''check for incorrect argument data type"

조회 수: 19 (최근 30일)
Hello,
I am trying to solve a system of approximately 600 non-linear equations in MATLAB with the help of fsolve. While I managed to get the programme I am writing to provide a solution to said system, I am currently attempting to supply the system's Jacobian to fsolve, in order to improve efficiency as well as accuracy. However, so far I have been prevented from doing so by the following error:
Check for incorrect argument data type or missing argument in call to function 'jacobian'.
Error in fun_name (line 509)
JAC = jacobian(xss,x);
Error in
File_name>@(x)fun_name(x,inputs) (line 712)
sol = @(x)fun_name(x,inputs)
Error in fsolve (line 269)
[fuser,JAC] = feval(funfcn{3},x,varargin{:});
Error in File_name(line 731)
[xss(ITER,:),x(ITER,:),exitflag,output,jacobian] = fsolve(sol,x0,options);
Here is the relevant (simplified) code I used:
clear;
close all;
%%% CALIBRATION, ETC. %%%
options = optimoptions('fsolve','Display','iter','Algorithm','Levenberg-Marquardt','MaxFunEval',1.0e+08,...
'SpecifyObjectiveGradient',true,'Jacobian','on');
maxiter = 3; % could be anything
%%% Section initialising endogenous variables and any variables that become
%%% updated so that solution values from each iteration can be saved
for ITER=1:maxiter
% Vector of initialised variables
if ITER == 1
x0 = [list of initialised endogenous variables]; % about 600
elseif ITER > 1
x0 = xss(ITER-1,:); % Use the current solution as initial guess for the next period
end
sol = @(x)fun_name(x,inputs); % function handle in separate file [this is the (line 712) mentioned in the error]
a = sym('EV',[1 593]); % EV = Endogenous Variables; create a symbolic vector
FUN = sol(a);
[xss(ITER,:),x(ITER,:),exitflag,output,jacobian] = fsolve(sol,x0,options); % [This is the (line 731) mentioned in the error]
% Some more (unrelated) code
end
The function containing the equations and the udpate mechanism is then as follows:
function [xss,JAC] = fun_name(x,inputs)
% A. Endogenous variables. For instance:
A = x(1:a_given_length); CT = a_given_length;
B = x(CT+1:CT+another_length); CT = CT+another_length;
.
.
.
%%% B. Section with updating procedures for certain variables %%%
% Reshape any matrices that have been vectorised at beginning of function
%%% C. Equations. For instance:
xss1 = A.*B; xss{1} = xss1;
.
.
.
xss = horzcat(xss{:});
% Supplying the system's Jacobian
if nargout(@fun_name) > 1
JAC = jacobian(xss,x); % This is the (line 509) mentioned in the error
end
% some more code, including e.g.
assignin('base','A',A);
% to save updated values from each iteration
end
Having tried to debug the programme, I think I know what the issue is: while the function 'jacobian' requires symbolic inputs, due to some mistake I am making in the code the function ends up being called at JAC with 'double'-type data as inputs. I checked this by running
class(x)
and
class(xss)
before it, and I saw both are 'double'. Having placed a breakpoint at JAC = jacobian(xss,x); the first time it is reached, however, I also noticed that my attempt at creating symbolic variables through a and FUN does create a symbolic JAC matrix of the required dimensions, but when fsolve comes around both xss and x are already both of type 'double' again. How can I get fsolve to solve with its Jacobian in this settings? And, on a related note, is it worth doing so in my case? On my laptop it takes approximately 3 minutes to solve three iterations, so if it takes a long time to create the symbolic variables then I might not see enough gains anyway. And would there be a 'visible' improvement in terms of solution accuracy, in your opinion? Thank you all for the help!

채택된 답변

Matt J
Matt J 2021년 9월 14일
편집: Matt J 2021년 9월 14일
It is not clear (from what you posted), why you are using symbolic variable manipulation at all. fsolve is a numerical solver, not a symbolic solver.
If you need the Symbolic Math Toolbox to derive the analytical expression for some part of the Jacobian calculation, that's fine. However, you should not be repeating the symbolic analysis in every iteration of fsolve. The normal and efficient workflow is to derive any symbolic formulas that you need once and once only, and to do it prior to the optimization. Before running hte optimization, you would use matlabFunction() to convert your symbolic functions to an ordinary numerical function which the objective function code fun_name() can then use.
  댓글 수: 7
Matt J
Matt J 2021년 9월 17일
편집: Matt J 2021년 9월 17일
There's nothing really solid that I can say while only seeing part of the code. From what is shown, it looks like all the operation done with yor unknown variables are linear. If so, then this is really a system of linear equations. Instead of fsolve, you should really be putting it in matrix-vector form A*x=b and solving it as x=A\b.
Mark
Mark 2021년 9월 18일
I see -- as I said, unfortunately I cannot share more of the code. Thank you anyways: your suggestions were useful in making the programme run, at least!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Calculus에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by