str2func and anonymous functions

8 views (last 30 days)
Patrick Mboma
Patrick Mboma on 14 Mar 2015
Commented: Patrick Mboma on 15 Mar 2015
Dear all,
I posed a problem earlier and it was not answered. I guess I did not pose the problem well. I try again as my understanding of the issues has improved.
Consider the following function
function test=mytest(a,b,c,ss,anonym)
if nargin<5
anonym=true;
end
if anonym
test=@(x)a(3,:)*x^2+b(4)*x+c(1)-ss;
else
test=str2func('@(x)a(3,:)*x^2+b(4)*x+c(1)-ss');
end
end
It has two modes. When the anonym flag is set to true, the function handle returned is constructed through the anonymous function directly. When the flag is false, the function handle is constructed through a string.
I was hoping those two formulations would be equivalent. They are not!!!
try running
a=rand(10,1);b=rand(10,1);c=rand(10,1); ss=rand;
f1=mytest(a,b,c,ss,true)
f2=mytest(a,b,c,ss,false)
and then
f1(1)
f2(1)
The first one works, the second does not. Why?
While all the relevant variables appear in the workspace of f1, only "a" appears in the workspace of f2. Somehow, matlab treats "b", "c" and "ss" as functions I guess. On the other hand, "a" is in the workspace of f2, I guess because it is indexed as a matrix...
But, although it works, the first formulation also has problems of its own. The workspace of f1, which I access via tmp=functions(f1) is multiple. tmp.workspace{2}.test is identical to f1 itself and so it has the same number of workspaces and this goes on and on...
If the anonymous function is created outside a function, it has only one workspace.
I would like to use the second formulation (str2func), which only has one workspace, as it is the only alternative I have. The most direct route would be to declared all the inputs but then f2 will have to be called as f2(x,a,b,c,ss), which I am trying to avoid. Has anyone faced a similar problem or does anyone know the solution? Is there anyway to force some variables into the workspace of f2?
Thanks,
  4 Comments
Geoff Hayes
Geoff Hayes on 14 Mar 2015
Patrick - without knowing how you are using this function it is difficult to provide a solution. Why not just nest your test function within that function that defines the a, b, c, and ss?
Patrick Mboma
Patrick Mboma on 14 Mar 2015
Hi Geoff,
This is my current implementation and I was hoping I could improve it in terms of performance. It is called memoization, I think.

Sign in to comment.

Answers (1)

Titus Edelhofer
Titus Edelhofer on 14 Mar 2015
Hi,
the str2func does not work in this case, as you observed. But the documentation does not really suggest, that it should work... Nvertheless, you can achieve something similar by evaluating the string instead of using str2func:
test=eval('@(x)a(3,:)*x^2+b(4)*x+c(1)-ss');
instead of the line with str2func should work as you expect it to work. Although generally speaking, I'm no fan of eval, if you really have to create an anonymous function by creating some string in advance, I guess this is the only way.
Titus
  3 Comments
Titus Edelhofer
Titus Edelhofer on 14 Mar 2015
Hi Patrick,
I'm pretty sure, that the two workspaces "look" as if they have doubled the memory, but as long as within mytest you don't change a, b etc, they do point to the same variable in memory. Please give it a try and make the variables a, b etc. rather large and follow the memory consumption ...
Titus
Patrick Mboma
Patrick Mboma on 15 Mar 2015
Hi Titus,
The problem is that there is no reason for the second workspace to be there in the first place. The information is useless and not only that, it uses memory as discussed here .
That creating an anonymous function inside a function or outside results in different behavior seems strange to me. But that is the current implementation I have now. And in all likelihood, it seems that I might have to stick to it for now.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!