Use case for eval that double/subs does not satisfy

13 次查看(过去 30 天)
This question pertains to code that I have been using in my teaching for several years. Until this summer, I've never had an issue. Students in my physiological modeling course are now getting a deprecation warning for eval() as in the code below. Since the use of eval() is embedded in a function handle that is being passed to lsqcurvefit()--which call the function iteratively--the warning is appearing numerous times when they run the code--see below. (I am still using MATLAB 2024b Update 5, and I am not yet getting this warning.)
The application is a data fitting exercise for a two-compartment model that uses lsqcurvefit() to find best fit parameters for a system of 1st order ODEs that is first solved symbolically using dsolve(). The students' code still produces the desired output (best fit parameter values contained in kfit) but in one case the student had to submit a live script with fifteen pages of warnings before this output was produced.
I have tried substituting double() for eval() as the warning suggests, but I get a fatal error when passed to lsqcurvefit() (see attached screenshot of error message).
I've searched online and I haven't been able to find a way to resolve this. Please help!
syms x1(t) x2(t) k12 k21 k20 k01
conds = [x1(0) == k01; x2(0) == 0];
eqn1 = diff(x1) == -k12*x1 + k21*x2;
eqn2 = diff(x2) == k12*x1 - (k21 + k20)*x2;
[x1sol, x2sol] = dsolve(eqn1, eqn2, conds) % displays symbolic solutions for the ODEs above
x1sol = 
x2sol = 
time = [0.03 0.07 0.10 0.13 0.17 0.23 0.30 0.37 0.50 0.75 1.00 2.00 3.00 4.00 6.00];
conc = [21.0 22.0 18.0 15.0 15.5 14.0 11.3 13.5 12.5 9.1 6.7 3.6 2.6 2.2 1.2];
% Data in the previous lines give the time & concentration of solute in the plasma compartment
% (i.e. measured values for t & x1)
% Below is the line of code with eval() that is causing the warning
fitfun = @(k, t) eval(subs(x1sol, [k01 k12 k21 k20],k));
k_init = [50, 20, .0001, 15];
kfit = lsqcurvefit(fitfun, k_init, time, conc) % When this line is run, fitfun is called iteratively
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
kfit = 1×4
24.7277 4.0073 4.2529 1.4075
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
% calculates x1 at all time points in the original data using the best set
% of model constants found by lsqcurvefit()
x1fit = fitfun(kfit, time);
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
% Plot original data vs. fitted values
plot(time, conc, 'bo-', time, x1fit,'r*--')
legend("x1 (data)", "x1 (lsqcurvefit)")
xlabel("Time (hours)")
ylabel("Concentration")
title("Plasma Compartment (Model Fitting)")
  1 个评论
Stephen23
Stephen23 2025-7-30
编辑:Stephen23 2025-7-30
For those who are interested in what the output of FITFUN looks like:
syms x1(t) x2(t) k12 k21 k20 k01
conds = [x1(0) == k01; x2(0) == 0];
eqn1 = diff(x1) == -k12*x1 + k21*x2;
eqn2 = diff(x2) == k12*x1 - (k21 + k20)*x2;
[x1sol, x2sol] = dsolve(eqn1, eqn2, conds); % displays symbolic solutions for the ODEs above
time = [0.03,0.07,0.10,0.13,0.17,0.23,0.30,0.37,0.50,0.75,1.00,2.00,3.00,4.00,6.00];
conc = [21.0,22.0,18.0,15.0,15.5,14.0,11.3,13.5,12.5,9.1,6.7,3.6,2.6,2.2,1.2];
% Data in the previous lines give the time & concentration of solute in the plasma compartment
% (i.e. measured values for t & x1)
fitfun_sans = @(k, t) subs(x1sol, [k01,k12,k21,k20],k);
fitfun_eval = @(k, t) eval(subs(x1sol, [k01,k12,k21,k20],k));
k_init = [50,20,0.0001,15];
fitfun_sans(k_init,time(1)) % note the symbolic t's hiding inside
ans = 
fitfun_eval(k_init,time(1))
Warning: The function sym/eval is deprecated and will be removed in a future release. Depending on the usage, use subs or double instead.
ans = 27.4406

请先登录,再进行评论。

采纳的回答

Stephen23
Stephen23 2025-7-30
编辑:Stephen23 2025-7-30
The suggested approach of DOUBLE works correctly, once you explicitly SUBS the value of t as well:
syms x1(t) x2(t) k12 k21 k20 k01
conds = [x1(0) == k01; x2(0) == 0];
eqn1 = diff(x1) == -k12*x1 + k21*x2;
eqn2 = diff(x2) == k12*x1 - (k21 + k20)*x2;
[x1sol, x2sol] = dsolve(eqn1, eqn2, conds); % displays symbolic solutions for the ODEs above
time = [0.03,0.07,0.10,0.13,0.17,0.23,0.30,0.37,0.50,0.75,1.00,2.00,3.00,4.00,6.00];
conc = [21.0,22.0,18.0,15.0,15.5,14.0,11.3,13.5,12.5,9.1,6.7,3.6,2.6,2.2,1.2];
% Data in the previous lines give the time & concentration of solute in the plasma compartment
% (i.e. measured values for t & x1)
fitfun = @(k,ti) double(subs(subs(x1sol, [k01,k12,k21,k20],k),t,ti));
k_init = [50,20,0.0001,15];
kfit = lsqcurvefit(fitfun, k_init, time, conc) % When this line is run, fitfun is called iteratively
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
kfit = 1×4
24.7277 4.0073 4.2529 1.4075
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
% calculates x1 at all time points in the original data using the best set
% of model constants found by lsqcurvefit()
x1fit = fitfun(kfit, time);
% Plot original data vs. fitted values
plot(time, conc, 'bo-', time, x1fit,'r*--')
legend("x1 (data)", "x1 (lsqcurvefit)")
xlabel("Time (hours)")
ylabel("Concentration")
title("Plasma Compartment (Model Fitting)")
The problem is obvious once you display the output of FITFUN without the EVAL: there is still one symbolic variable t which clearly requires a numeric value before a numeric result can be calculated. Therefore providing t with a numeric value trivially resolves the problem. The rest of your code remains unchanged.
For what it is worth, EVAL was never the documented approach for this task (EVAL is not listed as a function for the Symbolic Toolbox), so the SUBS or MATLABFUNCTION approaches have always been the documented approaches. Search this forum for discussions on why undocumented EVAL on symbolic inputs is not recommended.

更多回答(1 个)

Paul
Paul 2025-7-30
Hi Stephen,
Check out matlabFunction
syms x1(t) x2(t) k12 k21 k20 k01
conds = [x1(0) == k01; x2(0) == 0];
eqn1 = diff(x1) == -k12*x1 + k21*x2;
eqn2 = diff(x2) == k12*x1 - (k21 + k20)*x2;
[x1sol, x2sol] = dsolve(eqn1, eqn2, conds); % displays symbolic solutions for the ODEs above
time = [0.03 0.07 0.10 0.13 0.17 0.23 0.30 0.37 0.50 0.75 1.00 2.00 3.00 4.00 6.00];
conc = [21.0 22.0 18.0 15.0 15.5 14.0 11.3 13.5 12.5 9.1 6.7 3.6 2.6 2.2 1.2];
% Data in the previous lines give the time & concentration of solute in the plasma compartment
% (i.e. measured values for t & x1)
% Below is the line of code with eval() that is causing the warning
x1fun = matlabFunction(x1sol,'Vars',{'k01','k12','k21','k20',t})
x1fun = function_handle with value:
@(k01,k12,k21,k20,t)k01.*k12.*exp(t.*(k12+k20+k21+sqrt(k12.*k20.*-2.0+k12.*k21.*2.0+k20.*k21.*2.0+k12.^2+k20.^2+k21.^2)).*(-1.0./2.0)).*((k12./2.0+k20./2.0+k21./2.0+sqrt(k12.*k20.*-2.0+k12.*k21.*2.0+k20.*k21.*2.0+k12.^2+k20.^2+k21.^2)./2.0)./k12-(k20+k21)./k12).*1.0./sqrt(k12.*k20.*-2.0+k12.*k21.*2.0+k20.*k21.*2.0+k12.^2+k20.^2+k21.^2)-k01.*k12.*exp(t.*(k12+k20+k21-sqrt(k12.*k20.*-2.0+k12.*k21.*2.0+k20.*k21.*2.0+k12.^2+k20.^2+k21.^2)).*(-1.0./2.0)).*((k12./2.0+k20./2.0+k21./2.0-sqrt(k12.*k20.*-2.0+k12.*k21.*2.0+k20.*k21.*2.0+k12.^2+k20.^2+k21.^2)./2.0)./k12-(k20+k21)./k12).*1.0./sqrt(k12.*k20.*-2.0+k12.*k21.*2.0+k20.*k21.*2.0+k12.^2+k20.^2+k21.^2)
fitfun = @(k,t) x1fun(k(1),k(2),k(3),k(4),t);
%fitfun = @(k, t) eval(subs(x1sol, [k01 k12 k21 k20],k))
k_init = [50, 20, .0001, 15];
kfit = lsqcurvefit(fitfun, k_init, time, conc) % When this line is run, fitfun is called iteratively
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
kfit = 1×4
24.7277 4.0073 4.2530 1.4075
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
% calculates x1 at all time points in the original data using the best set
% of model constants found by lsqcurvefit()
x1fit = fitfun(kfit, time);
% Plot original data vs. fitted values
plot(time, conc, 'bo-', time, x1fit,'r*--')
legend("x1 (data)", "x1 (lsqcurvefit)")
xlabel("Time (hours)")
ylabel("Concentration")
title("Plasma Compartment (Model Fitting)")

类别

Help CenterFile Exchange 中查找有关 Equation Solving 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by