A very strange problem
4 views (last 30 days)
Show older comments
Hi friends!
After spending an hour on a seemingly simple problem I was not able to figour out what is wrong and this is why
I am bothering you, Consider the following commands:
D0=1;D1=1;
f='@(dt)[(-D0)*dt^0.5+(-D0*D1)*dt^1.5/2;1/2*(-1+(1)+(2*D1+2*D0^2)*dt/2)]';
f=vectorize(f);f=str2func(f);f(1)
which gives me an error saying that "Unrecognized function or variable 'D0'.". But, when I copy the second line and run it, it works!!! To get what I mean the following is what happend on my command window exactly (see also a printscreen of my command window attached)
>> D0=1;D1=1;
f=@(dt)[(-D0).*dt.^0.5+(-D0.*D1).*dt.^1.5./2;1./2.*(-1+(1)+(2.*D1+2.*D0.^2).*dt./2)];
f=vectorize(f);
f=str2func(f);
f(1)
Unrecognized function or variable 'D0'.
Error in code2>@(dt)[(-D0).*dt.^0.5+(-D0.*D1).*dt.^1.5./2;1./2.*(-1+(1)+(2.*D1+2.*D0.^2).*dt./2)]
>> f=@(dt)[(-D0).*dt.^0.5+(-D0.*D1).*dt.^1.5./2;1./2.*(-1+(1)+(2.*D1+2.*D0.^2).*dt./2)];
>> f(1)
ans =
-1.5
1
I find this really crazy and am impatiently looking forward to hear from you.
Thanks in advance!
Babak
4 Comments
Steven Lord
on 14 Jan 2022
If your functions are that long, change your text files to MATLAB function files and use function handles to those files. This could also allow you to extract out common code segments into helper functions that can be called by one or more of your large function files.
Accepted Answer
John D'Errico
on 14 Jan 2022
Edited: John D'Errico
on 14 Jan 2022
I suppose this is a subtle problem that bears explanation.
D0=1;D1=1;
f='@(dt)[(-D0)*dt^0.5+(-D0*D1)*dt^1.5/2;1/2*(-1+(1)+(2*D1+2*D0^2)*dt/2)]';
That does NOT create a function handle named f. It is a string. Next, you do this:
f=vectorize(f)
That just produces a new string. Still not a function.
f=str2func(f)
So finally, f exists as a function handle. WHEW!
f(1)
But what happened? str2func creates a function handle, returning a result. But str2func does not have D0 in its workspace. So when you try to use f, in the form of f(1), things fail. f does not know the value of D0 or D1, because they do not exist in the workspace of the function str2func.
However, if I do this:
f= @(dt)[(-D0)*dt^0.5+(-D0*D1)*dt^1.5/2;1/2*(-1+(1)+(2*D1+2*D0^2)*dt/2)]
f =
function_handle with value:
@(dt)[(-D0)*dt^0.5+(-D0*D1)*dt^1.5/2;1/2*(-1+(1)+(2*D1+2*D0^2)*dt/2)]
f(1)
ans =
-1.5
1
now f works, because D0 and D1 were available to f when I created that function handle. It encapsulates them in the workspace internal to the function handle, and all is good. However, f is not "vectorized", as a function of the variable dt.
Anyway, a problem exists, because f returns a vector. you would need to carefully define what that result will be when dt is itself a vector or an array. And as importantly, suppose dt was a row vector, versus a column vector? That code for f, if you blindly throw the vectorize function at it, will produce some screwy results. Magical functions like vectorize are not that intelligent.
Instead, it is far better to vectorize the code yourself. So I might do this, in a way that is insensitive to the shape of dt as a row or column vector.
fvect = @(dt)[(-D0)*dt(:).^0.5+(-D0*D1)*dt(:).^1.5/2 , 1/2*(-1+(1)+(2*D1+2*D0^2)*dt(:)/2)].'
fvect(1)
ans =
-1.5
1
fvect(1:5)
ans =
-1.5 -2.8284 -4.3301 -6 -7.8262
1 2 3 4 5
fvect((1:5)')
ans =
-1.5 -2.8284 -4.3301 -6 -7.8262
1 2 3 4 5
So fvect has been carefully vectorized to produce a result that is consistent with f when called with scalar input, but when called with a vector input, it produces a 2xn array.
Finally, because fvect was constructed directly, it fully encapsulates the values of D0 and D1 as they were found in the workspace when fvect was created.
But expecting vectorize to successfully do that is a bit too much, certainly to know the values of D0 and D1.
More Answers (2)
KSSV
on 14 Jan 2022
f='@(D0,D1,dt)[(-D0)*dt^0.5+(-D0*D1)*dt^1.5/2;1/2*(-1+(1)+(2*D1+2*D0^2)*dt/2)]';
f=vectorize(f);
f=str2func(f);
D0=1;D1=1;dt=1 ;
f(D0,D1,dt) % you need to input three variables to the function
Matt J
on 14 Jan 2022
An alternative solution is to download afslim() from,
D0=1;D1=1;
f='@(dt)[(-D0)*dt^0.5+(-D0*D1)*dt^1.5/2;1/2*(-1+(1)+(2*D1+2*D0^2)*dt/2)]';
f=afslim(vectorize(f),D0,D1)
f(1)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!