How to use subs() instead of eval()?

6 views (last 30 days)
Michael Levin
Michael Levin on 25 Apr 2020
Commented: Stephen23 on 25 Apr 2020
I've got some code where the user enters a string form of a function (like "z*z+5) in complex variable z, takes a symbolic derivative, and evalutes iteratively it for some different values of z. Like a root-finding method:
for (k=1:50)
z = z - eval(formula)/eval(derivative) / (1 - ...
(eval(formula)*eval(derivative2))/(2*power(eval(derivative),2.0)));
I'm seeing a number of discussions on-line that ssuggest that I need to use subs() instead of eval(). But I'm having trouble seeing how to use them the same way:
with z=z-evalI(...) the eval returns a number and everything is cool with the expression. But subs() returns an expression, not the number, so how do I feed it into the math wihout having to use eval() on it? I tried it just using subs in the place of eval and it gives an error about the variable z being inaccessible. What am I missing?

Answers (1)

Stephen23
Stephen23 on 25 Apr 2020
Edited: Stephen23 on 25 Apr 2020
Following the Symbolic Toolbox documentation, you need to use double:
val = double(subs(...))
This page took me three seconds to find using [name of a major internet search engine]:
(note that eval is NOT listed on that page or anywhere else in the Symbolic Toolbox documentation (but double is). The undocumented side-effect of eval doing something with your symbolic expressions could be removed tomorrow without any change to the documentation at all. Use of undocumented "features" is entirely at your own risk).
  2 Comments
Michael Levin
Michael Levin on 25 Apr 2020
Looks like it still works with double() if z is a complex number. But it seems to be taking a lot longer than before. Is it plausible that double(subs()) is way slower than eval()? I understand the undocumented feature point for future releases, but getting my calculations done right now in a better timeframe (and not updating Matlab versions)l, so I'd like to undersand if I'm making a mistake somehow or if this way is really potentially slower. I'm currently using a very small piece of dummy code with the profile function:
my original function test() used eval like this:
funct = "z*z-5*z";
profile on
z=4+7i;
for (k=1:300000)
z = eval(funct);
end
profile viewer;
end
takes 5.198 seconds. This version using double(subs()):
function test_new
funct = "z*z-5*z";
profile on
z=4+7i;
funct_s = str2sym(funct);
for (k=1:300000)
z = double(subs(funct_s));
end
profile viewer;
end
takes 2232 seconds, spending most of its time in something called mupadmex (not sure what that is). What am I missing?
Stephen23
Stephen23 on 25 Apr 2020
"Is it plausible that double(subs()) is way slower than eval()?"
Yes, because it invokes the symbolic engine to correctly parse the symbolic expression (whereas eval evaluates the expression as if it were MATLAB code (which it isn't)).
Is it really required to evaluate this symbolically? I would approach this numerically if at all possible.

Sign in to comment.

Categories

Find more on Code Execution in Help Center and File Exchange

Tags

Products


Release

R2018a

Community Treasure Hunt

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

Start Hunting!