Error - Failure in initial objective function evaluation. FSOLVE cannot continue.

8 views (last 30 days)
Hello all,
I am trying to solve a system of non-linear vector equations in MATLAB using fsolve.
Here is my function code:
function F = ekmodelProto(x)
global dni T L theta gam beta
n = 4;
p = ones(1, n);
x_ni = ones(n);
w = ones(1, n);
for i = 1:n
p(i) = x(i);
end
for i = n+1:n + (n.^2) - 1
for j = 1:n.^2
x_ni(j) = x(i);
end
end
for i = n+n.^2:2.*n+ n.^2
for j = 1:n
w(j) = x(i);
end
end
F = [(((gam.*(((dni.*((((p.^(1-beta)'))*((w.^beta)))))').^(-theta))*T)').^(-1/theta))-p;
((T'.*((1/p)'.*dni.*(((p.^(1-beta)'))*((w.^beta)))').^(-theta))')- x_ni;
((((x'*((w.*L)'))./L)')')-w];
end
And here is my script for getting the output:
x0 = 0.5.*ones(1, 24);
x0 = x0;
n = 4;
dni = ones(2);
T = ones(4,1);
L = ones(4,1);
theta = 4;
beta = 0.5;
gam = 1;
sol = fsolve(@ekmodelProto, x0);
For context the matrix in function F should be a n+2 x n matrix. For example, if n is 2 I expect to have a 6 x 2. This is because The first row is a vector equation equal to p which is a 1xn. The second row is equal to x_ni, which is an nxn, and the third row is equal to w which is an 1xn. I am getting the following error.
Matrix dimensions must agree.
Error in ekmodelProto (line 21)
F = [((gam.*(((dni.*((((p.^(1-beta)'))*((w.^beta)))))').^-theta)*T)')-p;
Error in fsolve (line 255)
fuser = feval(funfcn{3},x,varargin{:});
Error in getoutput2 (line 12)
sol = fsolve(@ekmodelProto, x0);
Caused by:
Failure in initial objective function evaluation. FSOLVE cannot continue.
Two errors are puzzling me. First, MATLAB is telling me that my matrix dimensions don't match up. I double checked and I can't find the error. Obviously, MATLAB is'nt lying. Second, I'm not sure why fsolve is having trouble parsing the initial guess. I am assuming it is shaped incorrectly. How should I shape it? When n = 4 I have 24 unknowns (4 p's, 16 x_ni's, and 4 w's). Is something else causing this error? (The way the function is written?)
  2 Comments
Matt J
Matt J on 23 Jul 2020
Edited: Matt J on 23 Jul 2020
A better way to write your code is as below. A few points to note:
  1. global variables are a really bad way to pass fixed parameters. A better way is to use anonymous functions, as I have done, or nested functions. See here for details.
  2. Your unknown variables are allowed to be in matrix form. By making x a 4x6 matrix, I am able to break it apart more easily into separate variables p,x_ni, and w.
  3. To make the code more efficient, readable, and easier to debug, it is better to assign some intermediate calculations to temporary variables (like expr1 below), especially those that will be reused.
dni = ones(2);
T = ones(4,1);
L = ones(4,1);
theta = 4;
beta = 0.5;
gam = 1;
fun = @(x) ekmodelProto(x,dni, T, L, theta, gam, beta);
sol = fsolve(fun, 0.5.*ones(4,6) ) ;
function F = ekmodelProto(x,dni, T, L, theta, gam, beta)
p = x(:,1);
x_ni = x(:,2:end-1);
w = x(:,end);
expr1 = dni.*(p.^(1-beta)')*(w.^beta) ;
F = [(gam.*expr1.^(-theta))*T').^(-1/theta)-p;... %double-check this
(T'.*((1/p)'.*expr1').^(-theta))'- x_ni;...
(x'*((w.*L)'))./L-w];
end
Ethan Goode
Ethan Goode on 23 Jul 2020
Thank you for the advice. I am just now using matlab more seriously, and I have more of an economics background than a coding background. I appreciate all the recommendations on how to improve the quality of my code, and I'll certainly be implementing it!

Sign in to comment.

Accepted Answer

Matt J
Matt J on 23 Jul 2020
Edited: Matt J on 23 Jul 2020
Second, I'm not sure why fsolve is having trouble parsing the initial guess.
This is not a separate error. fsolve is simply telling you that it tried to call ekmodelProto(x0) and didn't get a result (because of the matrix dimension mismatch). It is always good to first test your objective function in isolation, and particularly at x0, before feeding it to fsolve, as I have done below.
First, MATLAB is telling me that my matrix dimensions don't match up. I double checked and I can't find the error.
When I execute,
clear
global dni T L theta gam beta
x0 = 0.5.*ones(1, 24);
x0 = x0;
n = 4;
dni = ones(2);
T = ones(4,1);
L = ones(4,1);
theta = 4;
beta = 0.5;
gam = 1;
ekmodelProto(x0)
and stop the code at line 21, I find that this quantity is 4x4
K>> ((((p.^(1-beta)'))*((w.^beta))))
ans =
0.5000 0.5000 0.5000 0.5000
0.5000 0.5000 0.5000 0.5000
0.5000 0.5000 0.5000 0.5000
0.5000 0.5000 0.5000 0.5000
while dni is 2x2
K>> dni
dni =
1 1
1 1
Therefore, you cannot multiply these two matrices together, as you attempt to do in line 21
K>> dni.*((((p.^(1-beta)'))*((w.^beta))))
Matrix dimensions must agree.
  1 Comment
Ethan Goode
Ethan Goode on 23 Jul 2020
Hey! Thanks for the help. I guess I just needed someone else to look over my code! The solution was as simple as making sure dni was a 4x4.

Sign in to comment.

More Answers (0)

Categories

Find more on Programming in Help Center and File Exchange

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!