You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
I am confused by the error: "Error evaluating inline model function"
2 views (last 30 days)
Show older comments
myfunc=inline('fitting(c,x)','c','x');
c0=[1.5,1.5];
c=nlinfit(x,y,myfunc,c0)
function ytotal = fitting(c,x)
xspan = x;
y0 = zeros(2,1);
[~,ye] = ode45(@eq2, xspan, y0);
ytotal = ye(:,1).*(1+0.2181) + ye(:,2) + 0.0667.*ye(:,2).*(c(1)-ye(:,1).*(1+0.2181))./(1+0.0667.*ye(:,2));
end
function dy=eq2(x,y)
global c
%y(1)=CE,y(2)=LE
dy=zeros(2,1);
dy(1)=0.9728.*(2.5-(1 + 0.2181).*y(1)-y(2)-0.0667.*y(2).*(c(1)-y(1).*(1 + 0.2181))./(1 + 0.0667.*y(2))).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))-0.5766.*y(1);
dy(2)=0.5596.*(2.5-(1+0.2181).*y(1)-y(1)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))).*(c(2)-y(2)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2)))-0.5646.*y(2);
end
When I run the program, the error came out as below.
Error using nlinfit (line 207)
Error evaluating inline model function.
Error in youhuachuli1228 (line 65)
c=nlinfit(x,y,myfunc,c0)
Caused by:
Error using inlineeval (line 14)
Error in inline expression ==> fitting(c,x)
Undefined function 'fitting' for input arguments of type 'double'.
I think the problem is that the function 'fitting(c,x)' is in type of syms instead of 'double'. But I don't know how to fix it. Does anyone have any ideas?
Accepted Answer
Walter Roberson
on 31 Dec 2022
When you use inline() the expression is evaluated in the base workspace. Any function mentioned must be resolved from the base workspace. That effectively prohibits local functions and nested functions. 'fitting' would have to have its own fitting.m file instead of defined in the same file.
The function fitting is not symbolic at all.
You also failed to initialize the global variable c.
Do not use inline() unless someone imposes using it as a job requirement (for example a homework example showing how inline breaks and so should be avoided)
global is not recommended.
54 Comments
Stephen23
on 31 Dec 2022
"Then are there any other function that can replace inline() here? "
Did you consider following what the MATLAB documentation recommends and using an anonymous function?
Jinglei
on 31 Dec 2022
Thank you. I tried it in both of the following ways,
myfunc=@(x) fitting(c,x);
c0=[1.5,1.5];
c=nlinfit(x,y,myfunc,c0)
or
c0=[1.5,1.5];
c=nlinfit(x,y,fitting(c,x),c0)
However, it still went wrong and several errors came out. Could you please show me the way to fix it?
Stephen23
on 31 Dec 2022
"However, it still went wrong and several errors came out."
You did not define the x and y inputs to NLINFIT(). What values do you want to use for x and y ?
Jinglei
on 31 Dec 2022
Edited: Jinglei
on 31 Dec 2022
Values for x and y have been given in previous commands as below.
global c
x = [0
5
10
15
20
25
30
35
40
45
50
55
60
65
70
80
90
100
110
120
150
500
1000
5000
10000
];
y = [0
0.17917
NaN
NaN
0.44143
NaN
0.68912
NaN
NaN
NaN
0.76926
NaN
NaN
NaN
NaN
0.78383
NaN
0.7984
NaN
1.06795
0.90768
NaN
NaN
NaN
NaN
];
Jinglei
on 31 Dec 2022
It won't be that good result but shouldn't go wrong. I used those NaN to make more points on the line so that the line will look smoother.
Torsten
on 31 Dec 2022
Edited: Torsten
on 31 Dec 2022
Your fitting function will return NaN and the solver will quit.
x = [0
5
20
30
50
80
100
120
150
];
y = [0
0.17917
0.44143
0.68912
0.76926
0.78383
0.7984
1.06795
0.90768
];
myfunc=@fitting;%inline('fitting(c,x)','c','x');
c0=[1.5,1.5];
c=nlinfit(x,y,myfunc,c0)
c = 1×2
0.1720 0.8251
%c = lsqcurvefit(myfunc,c0,x,y)
ytotal = fitting(c,x);
hold on
plot(x,ytotal)
plot(x,y,'o')
hold off
function ytotal = fitting(c,x)
xspan = x;
y0 = zeros(2,1);
[~,ye] = ode45(@(x,y)eq2(x,y,c), xspan, y0);
ytotal = ye(:,1).*(1+0.2181) + ye(:,2) + 0.0667.*ye(:,2).*(c(1)-ye(:,1).*(1+0.2181))./(1+0.0667.*ye(:,2));
end
function dy=eq2(x,y,c)
%y(1)=CE,y(2)=LE
dy=zeros(2,1);
dy(1)=0.9728.*(2.5-(1+0.2181).*y(1)-y(2)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))-0.5766.*y(1);
dy(2)=0.5596.*(2.5-(1+0.2181).*y(1)-y(1)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))).*(c(2)-y(2)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2)))-0.5646.*y(2);
end
Torsten
on 1 Jan 2023
Do you have any other suggestions to solve the problem?
Is there any problem left ? The code is working - although the results could be better.
Jinglei
on 1 Jan 2023
No,it's not working. Several errors were found and the result couldn't be achieved. The code I ran succesfully is as follow:
myfunc=inline('c(1)+c(2).*x','c','x');
c0=[1.5,1.5];
c=nlinfit(x,y,myfunc,c0)
However, when I changed 'c(1)+c(2).*x' into 'fitting(c,x)' or the commands I stated before, errors happened again. For instance, for the following codes,
myfunc=@(x) fitting(c,x);
c0=[1.5,1.5];
c=nlinfit(x,y,myfunc,c0)
The errors are as below.
Error using nlinfit (line 213)
Error evaluating model function '@(x)fitting(c,x)'.
Error in youhuachuli1228 (line 65)
c=nlinfit(x,y,myfunc,c0)
Caused by:
Error using youhuachuli1228>@(x)fitting(c,x)
Too many input arguments.
Which makes me really confused.
Torsten
on 1 Jan 2023
But as you can see from the output, the code above works. I don't know which wrong modifications you've done to it.
Jinglei
on 1 Jan 2023
I am sorry that I have just seen the result you pasted. But the same code just ran wrong on my Matlab. Maybe it is caused by the edition? I am not sure. I will try to fix it. Thank you for your help. I really appreciate it.
Torsten
on 1 Jan 2023
As you can see from the definition of "myfunc" and the error message you got from running your code, you haven't run the same code as pasted above.
Jinglei
on 1 Jan 2023
Thank you. I tried pasting what you pasted to my Matlab and got the c values. However, the image could not achieved and errors still existed. In addition, c values are too small to get a good fitting since as you can see, the initial values I gave are (1.5, 1.5) and they fitted the data well although not the optimal. I am not sure whether it is caused by the errors.
Jinglei
on 1 Jan 2023
Error using nlinfit (line 213)
Error evaluating model function 'fitting'.
Error in youhuachuli1228 (line 33)
c=nlinfit(x,y,myfunc,c0)
Caused by:
Index exceeds array bounds.
Torsten
on 1 Jan 2023
Edited: Torsten
on 2 Jan 2023
Since the code above works, I will no longer comment on this.
Use the code below and you won't get any syntax errors.
x = [0;5;20;30;50;80;100;120;150];
xs = 0:0.1:150;
y = [0;0.17917;0.44143;0.68912;0.76926;0.78383;0.7984;1.06795;0.90768];
myfunc=@fitting;
c0=[1.5,1.5];
ytotal0 = fitting(c0,xs);
c=nlinfit(x,y,myfunc,c0)
c = 1×2
0.1720 0.8251
xs = 0:0.1:150;
ytotal = fitting(c,xs);
%c = lsqcurvefit(myfunc,c0,x,y)
hold on
plot(x,y,'o')
plot(xs,ytotal0)
plot(xs,ytotal)
hold off
function ytotal = fitting(c,x)
xspan = x;
y0 = zeros(2,1);
[~,ye] = ode45(@(x,y)eq2(x,y,c), xspan, y0);
ytotal = ye(:,1).*(1+0.2181) + ye(:,2) + 0.0667.*ye(:,2).*(c(1)-ye(:,1).*(1+0.2181))./(1+0.0667.*ye(:,2));
end
function dy=eq2(x,y,c)
%y(1)=CE,y(2)=LE
dy=zeros(2,1);
dy(1)=0.9728.*(2.5-(1+0.2181).*y(1)-y(2)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))-0.5766.*y(1);
dy(2)=0.5596.*(2.5-(1+0.2181).*y(1)-y(1)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))).*(c(2)-y(2)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2)))-0.5646.*y(2);
end
Walter Roberson
on 1 Jan 2023
@Jinglei if you copy Torsten's code from https://www.mathworks.com/matlabcentral/answers/1886712-i-am-confused-by-the-error-error-evaluating-inline-model-function#comment_2542627 exactly as-is then do you get error messages? If so what are they, and which MATLAB release are you using?
Walter Roberson
on 1 Jan 2023
Edited: Walter Roberson
on 1 Jan 2023
You can try a number of different starting points and hope for a better answer. If you do, then you will get ode failures, and nlinfit failures. You can get a better fit, in theory, but in practice it is still quite far from where you would hope.
x = [0;5;20;30;50;80;100;120;150];
y = [0;0.17917;0.44143;0.68912;0.76926;0.78383;0.7984;1.06795;0.90768];
myfunc=@fitting;
rng(123456);
best_r = inf;
best_c = [-inf, -inf];
for iters = 1 : 50
c0 = [1.5 1.5] + randn(1,2)/5;
try
[c, r] =nlinfit(x,y,myfunc,c0);
nr = norm(r);
if nr < best_r
fprintf('improved on iteration %d\n', iters);
best_r = nr;
best_c = c;
end
catch ME
fprintf('failed iteration %d\n', iters);
end
end
improved on iteration 1
improved on iteration 3
Warning: Failure at t=1.146514e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (3.552714e-15) at time t.
failed iteration 4
improved on iteration 6
improved on iteration 7
Warning: Failure at t=2.115100e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (5.684342e-14) at time t.
failed iteration 8
improved on iteration 10
improved on iteration 11
Warning: Failure at t=6.933508e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
failed iteration 15
Warning: Failure at t=4.658234e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.136868e-13) at time t.
failed iteration 16
Warning: Failure at t=2.178430e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (5.684342e-14) at time t.
failed iteration 17
Warning: Failure at t=1.178626e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.842171e-14) at time t.
failed iteration 25
Warning: Failure at t=4.211467e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.136868e-13) at time t.
failed iteration 29
Warning: Failure at t=8.001151e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 30
Warning: Failure at t=8.857406e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.842171e-14) at time t.
failed iteration 31
Warning: Failure at t=8.085854e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 32
Warning: Failure at t=1.162031e+02. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.273737e-13) at time t.
failed iteration 33
Warning: Failure at t=5.427196e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 36
Warning: Failure at t=2.784805e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (8.881784e-16) at time t.
failed iteration 39
Warning: Failure at t=2.469110e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 44
Warning: Failure at t=6.325847e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.136868e-13) at time t.
failed iteration 47
improved on iteration 48
c = best_c
c = 1×2
1.4989 -1.8552
%c = lsqcurvefit(myfunc,c0,x,y)
ytotal = fitting(c,x);
hold on
plot(x,ytotal)
plot(x,y,'o')
hold off
function ytotal = fitting(c,x)
xspan = x;
y0 = zeros(2,1);
[t,ye] = ode15s(@(x,y)eq2(x,y,c), xspan, y0);
%protect against failure of integration
if t(end) ~= xspan(end)
ytotal = inf(numel(xspan),1);
else
ytotal = ye(:,1).*(1+0.2181) + ye(:,2) + 0.0667.*ye(:,2).*(c(1)-ye(:,1).*(1+0.2181))./(1+0.0667.*ye(:,2));
end
end
function dy=eq2(x,y,c)
%y(1)=CE,y(2)=LE
dy=zeros(2,1);
dy(1)=0.9728.*(2.5-(1+0.2181).*y(1)-y(2)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))-0.5766.*y(1);
dy(2)=0.5596.*(2.5-(1+0.2181).*y(1)-y(1)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2))).*(c(2)-y(2)-0.0667.*y(2).*(c(1)-y(1).*(1+0.2181))./(1+0.0667.*y(2)))-0.5646.*y(2);
end
Jinglei
on 1 Jan 2023
I got the line this time but errors are still there. And the result is not that good, which is worse compared with the initial values for the constant I have given. So that couldn't be correct. In addition, my matlab version is 9.4.0.813654 (R2018a). Thos errors can be seen as follows.
Error using nlinfit (line 213)
Error evaluating model function 'fitting'.
Error in youhuachuli1228 (line 33)
c=nlinfit(x,y,myfunc,c0)
Caused by:
Index exceeds array bounds.
>> fortry20230101
c =
0.1720 0.8251
>> fortry20230101
c =
0.1720 0.8251
>> fortry20230101
Error: File: fortry20230101.m Line: 6 Column: 6
Invalid text character. Check for unsupported symbol, invisible character, or pasting of non-ASCII characters.
Walter Roberson
on 1 Jan 2023
Try the iterative version I just posted, as it has some error control.
Torsten
on 1 Jan 2023
I suspect that the ODE solver is not capable to solve some intermediate integration problem with the parameters supplied. You can't do anything else but changing your initial guesses for the parameters.
Walter Roberson
on 1 Jan 2023
Edited: Walter Roberson
on 2 Jan 2023
When ode45 or ode15s cannot meet integration tolerances, then they end the session early -- in which case the size of the output might not be the same as the size of xspan . That can potentially lead to indexing problems. The t(end) ~= xspan(end) in my code checks for the case of early ending and substitutes values that nlinfilt will recognize as being very far from the desired values.
Jinglei
on 2 Jan 2023
@TorstenThank you for your explanation. Actually I used Excel before to optimize the constants, which, however, changed dramatically under different initial values. I used Matlab just to find a better result in a quicker way since Excel is relatively slow and may easily break down when processing. Here, I just can't understand that since the initial values are already better than many others especially the final chosen ones, why the program will go to a less fitted one. Under this situation, choosing better initial values would be a more tough thing.
@Walter RobersonThe matlab also told a size mismatch and gave a possible reason as the use of matrix operators (*, /, ^) instead of the corresponding elementwise operators (.*, ./, .^), which is obviously incorrect as can be seen in the code. Previously, I used ode to solve the fitting problem and got the function, which was not the optimal one since two of the parameters were not so correct based on experimental data. Therefore, I used this to find those two parameters to get the optimal curve. So I don't think this is caused by ODE. And I would like to know whether there might be any problem with nlinfit.
Walter Roberson
on 2 Jan 2023
I have attached the exact code I worked with. I tested this in R2018a.
I was getting a fat lot of error messages that I was having trouble tracking down until I realized that I did not have the Statistics and Machine Learning toolbox installed.
The code I attach here only has minor differences from what I posted before -- differences in that it specifically turns off some warning messages. It lets the nonlinear fitting fail, but catches the event and handles it smoothly.
The eventual coefficients it comes out with are still very different from what you might hope. Perhaps a different range of initial values should be searched over.
Jinglei
on 2 Jan 2023
I am so so sorry that I pasted the wrong data before and the correct data can be seen as follow,
x = [0;5;10;25;30;35;40;45;50;55;70;80;90;120];
y =[0;1.34288;1.43759;1.59058;1.59786;1.60515;1.60515;1.55415;1.54687;1.58329;1.64886;1.72171;1.72171;1.72171];
In this case, a good fitting could be achieved at c=[1.4448 1.4846].
I am really sorry for making that mistake and bother you so much @Walter Roberson@Torsten. But I really appreciate all your efforts and suggestions cause that make it possible for me to get the c values successfully although still with a lot of errors. Thank you for all your help.
One last question, for the resulting curve, I am confused why it looks like two lines instead of a smooth curve. Is this caused by my data or the function used? I asked this cause I could get a smoother curve before without using nlinfit.
Jinglei
on 3 Jan 2023
Edited: Jinglei
on 3 Jan 2023
@TorstenThank you for your help and it does become smoother. But it could be better. I mean the fitting. As you can see in the following image, the curve inflection point x value is too small based on its relationship with the experimental points, which might be caused by the c0 chosen or the fitting process.
I tried different initial c0, which did little help. So I think the code could be further improved. Anyway, it can already lead to a certain result, which is much better than before. Thank you very much for your help.
Torsten
on 3 Jan 2023
As you can see in the following image, the curve inflection point x value is too small based on its relationship with the experimental points, which might be caused by the c0 chosen or the fitting process.
Or your fitting model which seems the most plausible reason.
Jinglei
on 3 Jan 2023
Edited: Walter Roberson
on 3 Jan 2023
I used the following code finally and changed two constants into seven. I found this is much more effective than my former one. I would like to know how to make all constants larger than 0 since the result showed one constant negative. In addition, the result of running seven constants is much less fitted compared with two and I would like to know whether this is caused by some errors in the code and how to correct them.
x = [0;5;10;25;30;35;40;45;50;55;70;80;90;120];
xs = 0:0.1:120;
y = [0;1.34288;1.43759;1.59058;1.59786;1.60515;1.60515;1.55415;1.54687;1.58329;1.64886;1.72171;1.72171;1.72171];
myfunc=@fitting;
rng(123456);
best_r = inf;
best_c = [-inf, -inf, -inf, -inf, -inf, -inf, -inf];
for iters = 1 : 50
c0 = [0.9 0.4 1.5 1 0.2 1.5 0.7] + randn(1,7)/5;
ytotal0 = fitting(c0,xs);
try
[c, r] =nlinfit(x,y,myfunc,c0);
nr = norm(r);
if nr < best_r
fprintf('improved on iteration %d\n', iters);
best_r = nr;
best_c = c;
end
catch ME
fprintf('failed iteration %d\n', iters);
end
end
c = best_c
%c = lsqcurvefit(myfunc,c0,x,y)
ytotal = fitting(c,x);
hold on
plot(x,y,'o')
plot(xs,ytotal0)
plot(xs,ytotal)
hold off
function ytotal = fitting(c,x)
xspan = x;
y0 = zeros(2,1);
[t,ye] = ode15s(@(x,y)eq2(x,y,c), xspan, y0);
%protect against failure of integration
if t(end) ~= xspan(end)
ytotal = inf(numel(xspan),1);
else
ytotal = ye(:,1).*(1+0.39976) + ye(:,2);
end
end
function dy=eq2(x,y,c)
%y(1)=CE,y(2)=LE
dy=zeros(2,1);
dy(1)=c(1) .* (2.5 - (1 + c(2)) .* y(1) - y(2)) .* (c(3) - y(1) .* (1 + c(2))) - c(4) .* y(1);
dy(2)=c(5).* (2.5 - (1 + c(2)) .* y(1) - y(2)) .* (c(6) - y(2) - c(4) .* y(2) .* (c(6) - y(2))) - c(7).* y(2);
end
Walter Roberson
on 3 Jan 2023
Edited: Walter Roberson
on 3 Jan 2023
With a repair on plotting, and adding information about change from the original parameters, and tweaking the random divisor to have fewer rejected locations.
I tweaked the code so that it will not offer negative initial coordinates. The nonlinear fitting routine does not offer constraints, so you would need to switch to something like fmincon() to prevent values from going negative; I work around it here by rejecting negative results.
I did not bother to add back in the supression of the warning messages. I figure that you must have a reason for wanting to see them, since you adopted my try/catch but not my warning off code.
x = [0;5;10;25;30;35;40;45;50;55;70;80;90;120];
xs = 0:0.1:120;
y = [0;1.34288;1.43759;1.59058;1.59786;1.60515;1.60515;1.55415;1.54687;1.58329;1.64886;1.72171;1.72171;1.72171];
myfunc=@fitting;
rng(123456);
best_r = inf;
best_c = [-inf, -inf, -inf, -inf, -inf, -inf, -inf];
c0_orig = [0.9 0.4 1.5 1 0.2 1.5 0.7];
for iters = 1 : 100
c0 = max(0, c0_orig + randn(1,7)/20);
ytotal0 = fitting(c0,xs);
try
[c, r] =nlinfit(x,y,myfunc,c0);
if any(c < 0)
fprintf('rejected negative output on iteration %d\n', iters);
continue;
end
nr = norm(r);
if nr < best_r
fprintf('improved on iteration %d\n', iters);
best_r = nr;
best_c = c;
end
catch ME
fprintf('failed iteration %d\n', iters);
end
end
improved on iteration 1
Warning: Failure at t=5.214845e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
failed iteration 3
Warning: Failure at t=1.138046e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.842171e-14) at time t.
failed iteration 4
Warning: Failure at t=3.027034e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (8.881784e-16) at time t.
failed iteration 8
rejected negative output on iteration 9
Warning: Failure at t=5.172382e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
failed iteration 10
Warning: Failure at t=3.196325e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (8.881784e-16) at time t.
failed iteration 11
rejected negative output on iteration 12
rejected negative output on iteration 15
rejected negative output on iteration 16
Warning: Failure at t=5.034794e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
failed iteration 22
Warning: Failure at t=1.404348e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (3.552714e-15) at time t.
failed iteration 24
Warning: Failure at t=1.382413e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.842171e-14) at time t.
failed iteration 25
Warning: Failure at t=1.858841e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (3.552714e-15) at time t.
failed iteration 27
Warning: Failure at t=5.805013e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
failed iteration 28
rejected negative output on iteration 29
Warning: Failure at t=3.031519e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 30
Warning: Failure at t=2.133830e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 31
Warning: Failure at t=1.104143e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (3.552714e-15) at time t.
failed iteration 32
Warning: Failure at t=4.857090e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (8.881784e-16) at time t.
failed iteration 33
Warning: Failure at t=4.029846e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
failed iteration 34
Warning: Failure at t=5.848573e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 35
Warning: Failure at t=1.051578e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.842171e-14) at time t.
failed iteration 37
rejected negative output on iteration 38
Warning: Failure at t=2.364404e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 39
Warning: Failure at t=4.498947e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
failed iteration 40
rejected negative output on iteration 41
Warning: Failure at t=2.689470e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 42
Warning: Failure at t=2.677579e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 44
Warning: Failure at t=6.993425e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 46
Warning: Failure at t=2.940197e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 48
rejected negative output on iteration 49
Warning: Failure at t=8.152841e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 50
Warning: Failure at t=2.034104e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 51
Warning: Failure at t=1.137900e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (3.552714e-15) at time t.
failed iteration 52
rejected negative output on iteration 53
Warning: Failure at t=1.011267e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.842171e-14) at time t.
failed iteration 54
Warning: Failure at t=2.787820e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 55
Warning: Failure at t=3.488307e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (8.881784e-16) at time t.
failed iteration 56
rejected negative output on iteration 57
Warning: Failure at t=9.999214e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 58
Warning: Failure at t=1.551725e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.842171e-14) at time t.
failed iteration 61
Warning: Failure at t=3.421249e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 63
rejected negative output on iteration 64
rejected negative output on iteration 65
improved on iteration 66
rejected negative output on iteration 67
Warning: Failure at t=2.873194e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (8.881784e-16) at time t.
failed iteration 70
rejected negative output on iteration 71
Warning: The Jacobian at the solution is ill-conditioned, and some model parameters may not be estimated well (they are not identifiable). Use caution in making predictions.
Warning: Failure at t=5.456363e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 74
Warning: Failure at t=6.623573e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 75
Warning: Failure at t=3.539704e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 77
Warning: Failure at t=3.977617e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 78
Warning: Failure at t=8.294844e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.776357e-15) at time t.
failed iteration 79
Warning: Failure at t=6.023717e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
failed iteration 81
Warning: Failure at t=1.648890e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (3.552714e-15) at time t.
failed iteration 82
Warning: Failure at t=2.914583e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (8.881784e-16) at time t.
failed iteration 83
rejected negative output on iteration 84
rejected negative output on iteration 85
Warning: Failure at t=4.582848e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
failed iteration 87
Warning: Failure at t=4.580019e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (8.881784e-16) at time t.
failed iteration 89
rejected negative output on iteration 92
Warning: Failure at t=2.528501e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 93
rejected negative output on iteration 95
Warning: Failure at t=2.098721e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
failed iteration 97
Warning: Failure at t=1.579961e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.842171e-14) at time t.
failed iteration 98
Warning: Failure at t=1.076871e+01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.842171e-14) at time t.
failed iteration 100
c = best_c
c = 1×7
0.7129 0.3339 1.9853 0.8968 0.0325 0.9857 0.0033
change_from_original = c - c0_orig
change_from_original = 1×7
-0.1871 -0.0661 0.4853 -0.1032 -0.1675 -0.5143 -0.6967
%c = lsqcurvefit(myfunc,c0,x,y)
ytotal = fitting(c,x);
hold on
plot(x,y,'o', 'displayname', 'original')
plot(xs, ytotal0, 'displayname', 'ytotal0')
plot(x, ytotal, 'displayname', 'ytotal')
hold off
xlim auto
ylim auto
legend show
function ytotal = fitting(c,x)
xspan = x;
y0 = zeros(2,1);
[t,ye] = ode15s(@(x,y)eq2(x,y,c), xspan, y0);
%protect against failure of integration
if t(end) ~= xspan(end)
ytotal = inf(numel(xspan),1);
else
ytotal = ye(:,1).*(1+0.39976) + ye(:,2);
end
end
function dy=eq2(x,y,c)
%y(1)=CE,y(2)=LE
dy=zeros(2,1);
dy(1)=c(1) .* (2.5 - (1 + c(2)) .* y(1) - y(2)) .* (c(3) - y(1) .* (1 + c(2))) - c(4) .* y(1);
dy(2)=c(5).* (2.5 - (1 + c(2)) .* y(1) - y(2)) .* (c(6) - y(2) - c(4) .* y(2) .* (c(6) - y(2))) - c(7).* y(2);
end
Jinglei
on 4 Jan 2023
@Walter RobersonThank you for your code and it does help. The problem is that the curve between the first and second points is so straight and the connection between that with the folloing ones is not so smooth. Previously, I added some points like (1,NaN), (2,NaN) to make this area be smoother but this doesn't work in this situation maybe due to the error caused by NaN. So I would like to know how to solve this problem.
Torsten
on 4 Jan 2023
Edited: Torsten
on 4 Jan 2023
Previously, I added some points like (1,NaN), (2,NaN) to make this area be smoother but this doesn't work in this situation maybe due to the error caused by NaN. So I would like to know how to solve this problem.
Add values for x after fitting and plot the solution function with the extended xspan as already shown above.
c=nlinfit(x,y,myfunc,c0)
xs = 0:0.1:150;
ytotal = fitting(c,xs);
plot(xs,ytotal)
Jinglei
on 4 Jan 2023
Edited: Jinglei
on 4 Jan 2023
@TorstenIt works well this time. Thank you for all your help.
I have got two other questions. Firstly, how could I calculate the R2 of fitting in this case?In addition, is it possible to add several ys in this code to get five curves directly?I maen, making y a matrix with five rows. I wrote it as the following way, which, however, only showed the points without any curve.
myfunc=@fitting;
rng(123456);
best_r = inf;
best_c = [-inf, -inf, -inf, -inf, -inf, -inf, -inf];
c0_orig = [0.9 0.4 1.5 1 0.2 1.5 0.7];
for iters = 1 : 100
c0 = max(0, c0_orig + randn(1,7)/20);
ytotal0 = fitting(c0,xs);
try
[c, r] =nlinfit(x,y(:,1),y(:,2),y(:,3),y(:,4),y(:,5),myfunc,c0);
if any(c < 0)
fprintf('rejected negative output on iteration %d\n', iters);
continue;
end
nr = norm(r);
if nr < best_r
fprintf('improved on iteration %d\n', iters);
best_r = nr;
best_c = c;
end
catch ME
fprintf('failed iteration %d\n', iters);
end
end
Unrecognized function or variable 'xs'.
c = best_c
change_from_original = c - c0_orig
%c = lsqcurvefit(myfunc,c0,x,y)
ytotal = fitting(c,x);
%for adding points
hold on
plot(x,y,'o', 'displayname', 'original')
hold off
xlim auto
ylim auto
legend show
%for adding points
hold on
xs = 0:0.1:150;
ytotal = fitting(c,xs);
plot(xs,ytotal)
hold off
Jinglei
on 6 Jan 2023
Edited: Walter Roberson
on 6 Jan 2023
I editted the code again to make it work for matrix, which, however, still didn't result in five curves successfully. Does anyone know what is wrong with my code?
x = [0 0 0 0 0;5 5 5 5 5; 10 10 10 10 10;
15 15 15 15 15; 20 20 20 20 20;
25 25 25 25 25; 30 30 30 30 30;
35 35 35 35 35; 40 40 40 40 40;
45 45 45 45 45; 50 50 50 50 50;
55 55 55 55 55; 60 60 60 60 60;
70 70 70 70 70; 80 80 80 80 80;
90 90 90 90 90;120 120 120 120];
Error using vertcat
Dimensions of arrays being concatenated are not consistent.
Dimensions of arrays being concatenated are not consistent.
xs = 0:0.01:120;
y = [0 0 0 0 0;
1.342848859 1.466695386 1.495835746 1.524976105 1.189861972;
1.437555027 1.371989218 0.956739097 1.510405925 1.007734726;
1.175291792 0.993164546 0.701760952 1.561401554 1.415699757;
1.699818261 1.510405925 1.590541914 1.481265566 1.437555027;
1.590541914 1.554116464 1.539546285 1.561401554 1.459410296;
1.597827003 1.590541914 1.539546285 1.561401554 1.444840117;
1.605112093 1.590541914 1.437555027 1.510405925 1.473980476;
1.605112093 1.663392812 1.605112093 1.575971734 1.473980476;
1.554116464 1.554116464 1.539546285 1.612397183 1.401129577;
1.546831374 1.590541914 1.561401554 1.561401554 1.481265566;
1.583256824 1.568686644 1.626967363 0.053387955 1.408414667;
1.437555027 1.605112093 1.626967363 1.648822632 1.444840117;
1.648822632 1.648822632 1.707103351 1.561401554 1.546831374;
1.721673531 1.707103351 1.619682273 1.634252453 1.648822632;
1.721673531 1.707103351 1.707103351 1.692533171 1.532261195;
1.721673531 1.707103351 1.677962992 1.546831374 1.619682273
];
myfunc=@fitting;
rng(123456);
best_r = inf;
best_c = [-inf, -inf, -inf, -inf, -inf, -inf, -inf;
-inf, -inf, -inf, -inf, -inf, -inf, -inf;
-inf, -inf, -inf, -inf, -inf, -inf, -inf;
-inf, -inf, -inf, -inf, -inf, -inf, -inf;
-inf, -inf, -inf, -inf, -inf, -inf, -inf];
c0_orig = [0.9 0.4 1.5 1 0.2 1.5 0.7;
0.9 0.4 1.5 1 0.2 1.5 0.7;
0.9 0.4 1.5 1 0.2 1.5 0.7;
0.9 0.4 1.5 1 0.2 1.5 0.7;
0.9 0.4 1.5 1 0.2 1.5 0.7];
for iters = 1 : 100
c0 = max(0, c0_orig + randn(5,7)/20);
ytotal0 = fitting(c0,xs);
try
[c, r] =nlinfit(x,y,myfunc,c0);
if any(c < 0)
fprintf('rejected negative output on iteration %d\n', iters);
continue;
end
nr = norm(r);
if nr < best_r
fprintf('improved on iteration %d\n', iters);
best_r = nr;
best_c = c;
end
catch ME
fprintf('failed iteration %d\n', iters);
end
end
c = best_c
change_from_original = c - c0_orig
%c = lsqcurvefit(myfunc,c0,x,y)
ytotal = fitting(c,x);
%for adding points
hold on
plot(x,y,'o', 'displayname', 'original')
hold off
xlim auto
ylim auto
legend show
%for adding points
hold on
xs = 0:0.1:150;
ytotal = fitting(c,xs);
plot(xs,ytotal)
hold off
function ytotal = fitting(c,x)
xspan = x;
y0 = zeros(2,1);
[t,ye] = ode15s(@(x,y)eq2(x,y,c), xspan, y0);
%protect against failure of integration
if t(end) ~= xspan(end)
ytotal = inf(numel(xspan),1);
else
ytotal = ye(:,1).*(1+0.39976) + ye(:,2);
end
end
function dy=eq2(x,y,c)
%y(1)=CE,y(2)=LE
dy=zeros(2,1);
dy(1)=c(1) .* (2.5 - (1 + c(2)) .* y(1) - y(2)) .* (c(3) - y(1) .* (1 + c(2))) - c(4) .* y(1);
dy(2)=c(5).* (2.5 - (1 + c(2)) .* y(1) - y(2)) .* (c(6) - y(2) - c(4) .* y(2) .* (c(6) - y(2))) - c(7).* y(2);
end
Walter Roberson
on 6 Jan 2023
90 90 90 90 90;120 120 120 120];
You only have four 120's but 5 of all other numbers.
Jinglei
on 6 Jan 2023
Thank you. I corrected it. But this is not the big problem since the code still could not get the any result and thsoe c obtained were all -inf.
c =
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
change_from_original =
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
-Inf -Inf -Inf -Inf -Inf -Inf -Inf
Walter Roberson
on 7 Jan 2023
You cannot do that.
nlinfit() requires that the x and y values and initial model parameters must be vectors. You can call
nlinfit(x(:),y(:),myfunc,c0(:))
and then have myfunc make appropriate adjustments.
But inside myfunc you take the input and use it as tspan values for the ode. The ode*() functions require that the tspan consist of strictly monotonic values -- strictly increasing or strictly decreasing. Which your x(:) would not have, as your x has a lot of rows with duplicate columns.
If what you are trying to do is run a number of different independent fittings simultaneously, hoping that will be more efficient than running them independently, then you are going about that the wrong way. Yes, it is possible to get ode45() or ode15s() to effectively run multiple ODEs simulatenously, but (A) you need to build the code the right way; and (B) it is not at all certain to be more efficient; and (C ) it is questionable whether it would be of sufficient accuracy. @Jan in a recent post made the explicit claim that the numeric accuracy gets worse when you are running multiple not-coupled ODE simulatenously.
If you must make the attempt to run several simultaneous not-coupled ODE, then set up your equations using the Symbolic Toolbox, and then follow the work flow in the first example of odeFunction to build the anonymous function that would be passed to ode15s() or ode45(). (Make sure to build the ytotal equation too, so that you get the proper simultaneous totals.)
But really... just run them independently, the extra work to run them simultaneously is not worth the effort.
Jinglei
on 8 Jan 2023
@Walter Roberson Thank you for your explanation. I understood what you said but I would like to get five curves in one figure. Is there any method to achieve that goal by running the fitting independently?
Jinglei
on 8 Jan 2023
I just run the program with one group of my data, which, however, stopped in the middle. Those warnings and things were just like what were shown when I run successfully so I am confused of what happened for this especially considring the better data compared than others.
failed iteration 63
Warning: Failure at t=1.385053e+00. Unable to meet integration tolerances without reducing the step size below
the smallest value allowed (3.552714e-15) at time t.
> In ode15s (line 730)
In xian2mu1rawdatafor5000rat50du>fitting (line 89)
In nlinfit>@(b,x)w.*model(b,x) (line 283)
In nlinfit>LMfit (line 592)
In nlinfit (line 284)
In xian2mu1rawdatafor5000rat50du (line 47)
failed iteration 68
rejected negative output on iteration 70
Warning: Failure at t=1.187736e+01. Unable to meet integration tolerances without reducing the step size below
the smallest value allowed (2.842171e-14) at time t.
> In ode15s (line 730)
In xian2mu1rawdatafor5000rat50du>fitting (line 89)
In nlinfit>@(b,x)w.*model(b,x) (line 283)
In nlinfit>LMfit (line 592)
In nlinfit (line 284)
In xian2mu1rawdatafor5000rat50du (line 47)
failed iteration 73
Those above are part of the shown things in my matlab.
Walter Roberson
on 8 Jan 2023
The code I posted in https://www.mathworks.com/matlabcentral/answers/1886712-i-am-confused-by-the-error-error-evaluating-inline-model-function#comment_2542987 specifically disables those ode15s messages.
It appears to me that if you were to loop the code using columns of your x and y, that the resulting code would already create multiple lines in the same figure, as it already has hold on and hold off all over the place.
Jinglei
on 9 Jan 2023
@Walter Roberson Actually, I changed the code and only retain hold on and hold off with the points and the final line between and so there was only one curve in the final image. In addition, I still would like to ask about my former question about the problem when I run the code with another group of data.
hold on
xs = 0:0.1:150;
ytotal = fitting(c,xs);
plot(xs,ytotal)
hold off
Jinglei
on 17 Jan 2023
Edited: Jinglei
on 17 Jan 2023
I have got another question about the former code, which I gave as attached. I found that I could get a good curve when I used semicolon when giving the initial values for C while a matrix of 8*8 as double would be achieved as the final constants, which I couldn't understand. On the other hand, when I tried comma in the c0 matrix, no curve could be achieved. I would like to know how to fix that. In addition, when I used some other groups of data to run the code, no curve could be achieved neither. Since the data is relatively good for those situations and even worse data could lead to successful result, I am really confused about what is wrong. Could anyone offer me some help?
Walter Roberson
on 17 Jan 2023
When you talk about semicolon when giving hte initial values for C are you referring to
c0_orig = [0.0019,0.0004,0.0001,1.5,0.0012,0.0011,1.5,0.0011];
If so then notice you have
c0 = max(0, c0_orig + randn(1,8)/20);
if c0_orig were a column vector then you would get implicit expansion when you added the row vector of randn() values, which is why there would be an 8 x 8 output.
Jinglei
on 17 Jan 2023
Edited: Jinglei
on 18 Jan 2023
Got it and thank you. The thing is when I used a column vector, I can get a great fitting while nothing could be achieved when I used any row vector of the resulting matrix. I don't know what is wrong with the process.
I have found that each time when I got a certain group of constants and tried them as initial values, different result could be achieved. I know that may be caused by the randn process, which gains different values each time. But in this case, how can I get the optimal constants to get the best fitting result? Is there any method to improve the code?
Walter Roberson
on 18 Jan 2023
Do you have any constraints on the inputs? Other than that they must be non-negative?
Jinglei
on 18 Jan 2023
No,they are all the same as before except for the equations and initial values for the constants.
Walter Roberson
on 18 Jan 2023
Then in that case, there are a couple of different ways you could improve the code:
- use ga or particleswarm or other similar evolutionary algorithm that tries a wide variety of different positions, instead of looping trying different random positions
- use MultiStart instead of looping trying different random positions
- do a more detailed mathematical analysis of your equations in order to figure out boundary conditions so that you can generate random starting positions that will be valid. This might be difficult as it would require analyzing the ways in which your ode can fail.
Jinglei
on 19 Jan 2023
Got it and thank you for your help. I will give them a try and get better results.
More Answers (0)
See Also
Categories
Find more on Least Squares in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)