A very strange problem
3 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Mohammad Shojaei Arani
el 14 de En. de 2022
Comentada: Mohammad Shojaei Arani
el 15 de En. de 2022
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 comentarios
Stephen23
el 14 de En. de 2022
Editada: Stephen23
el 14 de En. de 2022
"why matlab is like this?"
Computers cannot read your mind (yet), they have to follow rules. Those rules include where variables/functions/whatever are visible (scoping) to other functions or operators. Although in theory a computer could look in every existing workspace for a variable, there are several major problems with this approach:
- workspaces change, meaning that different variables come in and out of scope, leading to unpredictable code which is almost impossible to debug.
- it would be slooooooooooow.
"I have spent some weeks and prepared extremely long function handles which are saved as text files."
Function handles store information about their scope when they are created: you can save function handles in .mat files. Converting to text or storing functions as text does not store any of this information, so your design is fundamentally lossy.
Steven Lord
el 14 de En. de 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.
Respuesta aceptada
John D'Errico
el 14 de En. de 2022
Editada: John D'Errico
el 14 de En. de 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.
5 comentarios
John D'Errico
el 14 de En. de 2022
Editada: John D'Errico
el 14 de En. de 2022
Yes it does fix your problem, as long as you put a semi-colon on the line! I left off the semi-colon at the end of the line just so you could see the result is indeed a function handle.
When you add a semi-colon to the end of the line, it prevents the display from going to the command window. This will now be fast, since the time spent lies in MATLAB formatting the results for display, in scrolling the command window, etc.
Más respuestas (2)
KSSV
el 14 de En. de 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
el 14 de En. de 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)
Ver también
Categorías
Más información sobre Matrix Indexing en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!