Problem with str2func and error with valid function name

I have to concatenate a defined number of strings into one, then to convert this string into a function that I memorize. Then I have to give input to this new function to calculate many values.
As you'll see below I use str2func to do that. When I test this function, Matlab warns me that my function is unvalid, so my program doesn't work right at its beginning, however after many tries I don't know which other way to use.
Here is the code
function [value]=squareAndSum(stringFunc,x,y)
%x and y are two vectors, stringFunc the string we want to convert %into a function
%this function must calculate the value of this new fonction for %each y and use it to update value
value=0;
totalDots=length(y);
fh=str2func(stringFunc);
yApprox=zeros(totalDots);
for i=1:1:totalDots
yApprox(i)=fh(x(i));
squared=(y(i)-yApprox(i))*(y(i)-yApprox(i));
value=value+squared;
end;
When I test it with x=[1 ; 2 ; 3 ; 4], y=[5 ; 6 ; 7 ; 8] and stringFunc = '2*cos', Matlab displays :
Warning: The input to STR2FUNC "2*cos" is not a valid function name. This will generate an error in a future release.
> In squareAndSum at 6
??? Undefined function or method '2*cos' for input arguments of type 'double'.
Error in ==> squareAndSum at 9
yApprox(i)=fh(x(i));
With stringFunc = 'cos' however it works, of course, but I really need to concatenate different strings to create a new function for my work. (and I have very little time...)
Sorry if the question seems rather simple, I am quite new with Matlab.
Thanks in advance for your help

 채택된 답변

Walter Roberson
Walter Roberson 2012년 2월 11일

1 개 추천

but note that that will only work if you have a defined variable name to apply the function to, which you do not have in the case of '2*cos' so you will need to consider passing a different string as stringFunc

댓글 수: 9

So, instead of using only '2*cos', I should do :
fh=(stringFunc + 'x(i)');
and then affect to y this fh in the loop like this
fh=str2func(stringFunc+'x(i)');
yApprox=zeros(totalDots);
for i=1:1:totalDots
yApprox(i)=fh(x(i));
squared=(y(i)-yApprox(i))*(y(i)-yApprox(i));
value=value+squared;
end;
Or should I affect the x(i) another way ?
Sorry I've made a copy/paste error, I'd rather mean in the loop :
yApprox = fh;
after having included the expression of fh into the loop
If you tack on the 'x(i)' on the end, then what are you going to do if the passed string is (say) 'sin + cos' ? And if the function desired to apply is (say) 3 * x^2 + 2 * cos(x) + x then what string should the user pass in? '3*^2+2*cos+' perhaps ??
You are constructing an anonymous function. The variable is a "dummy variable" just like your variable "stringFunc" is a dummy variable for the purpose of your function: that is, it acts as a place holder for a value being passed in. The value being passed in will be x(i), but that doesn't mean that your dummy variable name should be x(i) -- indeed, that is not a valid dummy variable name. A dummy variable name has to be a simple variable name.
http://www.mathworks.com/help/techdoc/matlab_prog/f4-70115.html
yApprox = fh;
would mean that you want to copy the function handle _itself_ to yApprox.
Your earlier syntax was correct:
yApprox(i)=fh(x(i));
would mean apply the function handle stored in the variable fh, to the argument x(i)
It is nearly 3AM here, and I need to go to sleep.
Have the string passed down _already_ include the variable name 'x'. Do not tack anything at all on to the end of the string. Just put the '@(x)' on to the beginning of the string, and make the result in to an anonymous function. As noted in the link I gave earlier, if you have a new enough MATLAB version you can do that by applying str2func() to the overall string, if you have an older MATLAB you will need to eval() the string.
fh - str2func(['@(x) ' stringFunc]);
In the loop,
yApprox(i) = fh(x(i));
To use this, the user would pass down (e.g.) '2*cos(x)' . If there is no 'x' variable in what the user passes down and what the user passes down does not evaluate to a constant, then there will be problems. Which means you should probably put in a try/catch block around the function evaluation.
Above, the line
fh - str2func(['@(x) ' stringFunc]);
should be
fh = str2func(['@(x) ' stringFunc]);
Yes, I noticed but thanks a lot !
In fact, this precise expression doesn't seem to work but I explore your link, I am testing the void parenthesis
Remember if you do not have a new enough MATLAB version then you need to use eval instead of str2func:
fh = eval(['@(x) ' stringFunc '(x)']);

댓글을 달려면 로그인하십시오.

추가 답변 (4개)

Walter Roberson
Walter Roberson 2012년 2월 11일

0 개 추천

If your government has not asked the Canadian Embassy to contact me, then this isn't an emergency.
A R
A R 2012년 2월 11일
After these first answers, I understand that the problem is that I don't really see how to define x(i) as the variable which enable to calculate 2*cos(x(i))
I tried this :
function [value]=squareAndSum(stringFunc,x,y)
%x and y are two vectors
value=0;
totalDots=length(y);
yApprox=zeros(totalDots);
for i=1:1:totalDots
newString=[stringFunc '(x(i))'];
fh=str2func(newString);
yApprox(i)=fh;
squared=(y(i)-yApprox(i))*(y(i)-yApprox(i));
value=value+squared;
end;
But the message is the same because this time, x(i) is understood as a part of the expression of the new function
A R
A R 2012년 2월 11일

0 개 추천

To Walter Roberson :
yes, I want to do something like that except that it is more simple : the variable x is always at the end. Taking something close to your example, it would be '3^2+2*cos' gives 3^2+2*cos(x), you see x will be always the last one included
I understood most of your explanation, but if my syntax is correct, does it means, as you've just said, that it is not my dummy function but my dummy variable which is unvalid ?
So I should name (say) variable = x(i) and then do yApprox = fh(variable);
?

댓글 수: 2

I've just tested and this doesn't work either...
If you only have one x and it is at the end, then
fh = str2func(['@(x) ' stringFunc '(x)']);
You would not use @()
You do not need to assign x(i) to a variable:
yApprox(i)=fh(x(i));

댓글을 달려면 로그인하십시오.

A R
A R 2012년 2월 11일
I finally figured it out !! Thank you very much Walter Roberson !
Here is the corrected code :
function [value]=squareAndSum(stringFunc,x,y)
%x and y are two vectors
value=0;
totalDots=length(y);
yApprox=zeros(totalDots);
for i=1:1:totalDots
newString = [stringFunc '(x)'];
fh = str2func(['@(x)' newString]);
yApprox(i) = fh(x(i));
squared=(y(i)-yApprox(i))*(y(i)-yApprox(i));
value=value+squared;
end;
which gives with my previous example :
>> squareAndSum(stringFunc, x,y)
ans =
229.3076
Thanks again !

카테고리

도움말 센터File Exchange에서 Characters and Strings에 대해 자세히 알아보기

질문:

A R
2012년 2월 11일

편집:

2013년 10월 8일

Community Treasure Hunt

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

Start Hunting!

Translated by