How to feed value to jacobian() function in my case?

I need to calculate the gradient of a user-defined object function named fcn. I choose to use jacobian() function to calculate the symbolic gradient.
take subset of parameter vector b as input, like
%******************************
% Parameterized Moments
%******************************
function fm = fcn(b)
global T T_z T_e zt et
teta =0;
zt =b(1:T_z); % Line-7 %
et =b(1+T_z:T_z+T_e);
dify =zeros(T,T);
b are pre-calculated parameters. so I write the jacobian() in the following way to call fcn
v = [zt,et]';
dfb = jacobian(fcn,v);
but Matlab told me that
Error using fcn (line 7)
Not enough input arguments.
I'm not sure if this is due to the way I write jacobian or how I define the fcn? How can I fix the error? Thank you.

2 Comments

Jan
Jan on 17 Nov 2016
Edited: Jan on 17 Nov 2016
The error message tells, that the problem is in "fcn" in line 7. The code you have posted has 6 lines only. Please reveal what is in line 7. If it is the "dify" line: Is "T" a function handle?
Yeap, I edit my code

Sign in to comment.

Answers (1)

When you call
jacobian(fcn,v)
then v must evaluate to a vector of symbolic variable names, and fcn must evaluate to a symbolic expression or symbolic function.
When fcn is a function, using it in a syntax such as
jacobian(fcn,v)
causes the function to be invoked with no arguments, exactly equivalent to
jacobian(fcn(),v)
Your fcn function does not like being called with no arguments.
To calculate the jacobian with that fcn, it appears to me you would need to use something like
global T_z T_e zt et
nT = T_z + T_e;
B = sym('B', [1, nT]);
temp = fcn(B); %zt and et are not defined until fcn is run
v = [zt,et]';
dfb = jacobian(temp, v);

10 Comments

Hi,@Walter,thank you for your help. I adjusted the code as your suggestion and the "not enough input" problem was removed. However, Matlab find another error
>> nT = T_z + T_e;
B = sym('B', [1, nT]);
temp = fcn(B); %zt and et are not defined until fcn is run
v = [zt,et]';
dfb = jacobian(fcn,v);
The following error occurred converting from sym to double:
Error using mupadmex
Error in MuPAD command: DOUBLE cannot convert the input expression into a double
array.
If the input expression contains a symbolic variable, use the VPA function instead.
Error in fcn (line 11)
dify(1,1)=zt(1)+et(1)+(1-teta)^2*et(1)+teta^2*et(1);
I'm confused that we have already convert parameter to symbolic by command
B = sym('B', [1, nT]);
Here I attach the whole fcn code.
%******************************
% Parameterized Moments
%******************************
function fm = fcn(b)
global T T_z T_e zt et
teta =0;
zt =b(1:T_z);
et =b(1+T_z:T_z+T_e);
dify =zeros(T,T);
dify(1,1)=zt(1)+et(1)+(1-teta)^2*et(1)+teta^2*et(1);
dify(2,2)=zt(1)+et(2)+(1-teta)^2*et(1)+teta^2*et(1);
dify(3,3)=zt(1)+et(3)+(1-teta)^2*et(2)+teta^2*et(1);
j=4;
while j<=T-3;
dify(j,j)=zt(j-2)+et(j)+(1-teta)^2*et(j-1)+teta^2*et(j-2); %when teta=0,we have zt(j-2)+et(j)+et(j-1)
j=j+1;
end;
dify(T-2,T-2)=zt(T-4)+et(T-2)+(1-teta)^2*et(T-3)+teta^2*et(T-4);
dify(T-1,T-1)=zt(T-4)+et(T-2)+(1-teta)^2*et(T-2)+teta^2*et(T-3);
dify(T,T) =zt(T-4)+et(T-2)+(1-teta)^2*et(T-2)+teta^2*et(T-2);
dify(1,2)=-(1-teta)^2*et(1);
j=3;
while j<=T-1;
dify(j-1,j)=-(1-teta)*et(j-1)+teta*(1-teta)*et(j-2); %Identification of transition shock v_t (C2)
j=j+1;
end;
dify(T-1,T-2)=-(1-teta)^2*et(T-2);
j=3;
while j<=T;
dify(j-2,j)=-teta*et(j-2);
j=j+1;
end;
i=2;
while i<=T;
j=i;
while j<=T;
dify(j,i-1)=dify(i-1,j);
j=j+1;
end;
i=i+1;
end;
% Final matrix %
dif(1:T,1:T) =dify;
fm=dif(:);
end
You currently have
dify =zeros(T,T);
Immediately after that, add
if isa(b, 'sym')
dify = sym(dify);
end
I add this snippet of code and what's really odd is , when I run the main program (mini_dist.m) again, Matlab threw me the exact same error as before
Error using fcn (line 7)
Not enough input arguments.
I have updated the codes as attachment. Could you kindly take a look and see what's going on? Many thanks
You went back to
dfb = jacobian(fcn,b);
That can only work if fcn is a symbolic function or symbolic expression, not if fcn is a function handle. You need the code like I showed
nT = T_z + T_e;
B = sym('B', [1, nT]);
temp = fcn(B); %zt and et are not defined until fcn is run
v = [zt,et]';
dfb = jacobian(temp, v);
Sorry, I forgot to substitute fcn with temp in my code. After that the "not enough input" error was resolved. However, another problem appeared, like
Error using mupadmex
Error in MuPAD command: Invalid variable. [stdlib::diff]
Error in sym/jacobian (line 33)
Jsym = mupadmex('symobj::jacobian',F.s,x.s);
without telling me where the error took place. You have answered a similar question before.
When you make the change from fcn to temp did you also change the b to v? You have
dfb = jacobian(fcn,b);
but your b is not a vector of variable names, it is numeric.
I have
%Optimisation procedure
[b,fun,flag] = fminunc(@cov,b0);
nT = T_z + T_e;
B = sym('B', [1, nT]);
temp = fcn(B); %zt and et are not defined until fcn is run
v = [zt,et]';
dfb = jacobian(temp, v); %Line-51%
But the error is the exact same. (my Matlab version is R2012a)
Error using mupadmex
Error in MuPAD command: Invalid variable. [stdlib::diff]
Error in sym/jacobian (line 33)
Jsym = mupadmex('symobj::jacobian',F.s,x.s);
Error in mini_dist (line 51)
dfb = jacobian(temp,v);
Odd, it worked when I tested before. I will test with your version later today
This works, since I change the input array size from [1,nT] to [nT,1]. Yet another problem emerged when I tried to calculate the gradient value using MatlabFunction. Can you kindly take a look? Since the question here is already too long, I open a new question
Your revised version is sending a numeric vector as variable names.

Sign in to comment.

Tags

Asked:

on 17 Nov 2016

Commented:

on 20 Nov 2016

Community Treasure Hunt

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

Start Hunting!