how to evaluate a function in string with parfor?

Hi everybody, I have a problem evaluating the value of a function in string with parfor. Before I started using parfor, I used "eval", which worked quite well. I know "eval" does not work well with parfor and the one recommended the most online is "feval". However, I do not know how to use it. More specifically, i am doing genetic programming with the following code randomly generating a function for each individual.
parfor v = 1:8;
popu{v} = gpols_init(popusize,maxtreedepth,symbols);
tree{v} = popu{v}.chrom{jf}.tree;
aa{1,jf,v} = tree_stringrc(tree{v},1,symbols);
end
The output in "aa" looks like the following.
val(:,:,1) =
'XX(iv,1)' '(XX(iv,9))/(XX(iv…' '(((XX(iv,7))*exp(…' '(XX(iv,1))*sqrt(X…' '((XX(iv,2))*log((…'
what I need to do is to evaluate the value of each expression, which I do not know how to do. I will appreciate if someone could help me with it. Thanks. Best, J.

3 Kommentare

Stephen23
Stephen23 am 14 Nov. 2017
Bearbeitet: Stephen23 am 14 Nov. 2017
If your code "worked quite well", why do you need to use parfor?
How do you generate the random functions? Have you considered using function handles?
Julie G
Julie G am 14 Nov. 2017
Bearbeitet: Walter Roberson am 17 Nov. 2017
The reason is I have to run quite a lot simulations and parfor would save a lot of time. I tried "function handles" with the following code
str = 'a{1,jf,v}';
fh = str2func(str)
but still it had problems like the following.
Warning: The input to STR2FUNC "a{1,jf,v}" is not a valid function name. This will generate an error in a future release.
In parallel_function>make_general_channel/channel_general (line 914)
In remoteParallelFunction (line 38)
Warning: The input to STR2FUNC "a{1,jf,v}" is not a valid function name. This will generate an error in a future release.
In parallel_function>make_general_channel/channel_general (line 914)
In remoteParallelFunction (line 38)
Warning: The input to STR2FUNC "a{1,jf,v}" is not a valid function name. This will generate an error in a future release.
In parallel_function>make_general_channel/channel_general (line 914)
In remoteParallelFunction (line 38)
Stephen23
Stephen23 am 14 Nov. 2017
Bearbeitet: Stephen23 am 14 Nov. 2017
@Julie G: Why not generate those functions entirely using function handles, and avoid using strings entirely? Have you considered exclusively staying in the realm of function handles?
Also: what is XX ?

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

OCDER
OCDER am 14 Nov. 2017

0 Stimmen

For str2func, you also need to include the "@(var1, var2, var3, ...)" string. This is used to tell Matlab what part of the string are variables, while the rest of the string are treated as function names and math operators.
XX = rand(10); %What is XX? I'm assuming it's a matrix
iv = 10; %Assuming this is just an index of XX
aa{1,1,1} = 'XX(iv,1) * sin(XX(iv,1))'; %Example string of a function. XX and iv are variables.
FuncHandle = str2func(['@(XX, iv)' aa{1,1,1}]);%Define "XX" and "iv" as variable names in the string using @(XX, iv).
Output = FuncHandle(XX, iv); %Evaluate the string as function.

11 Kommentare

Julie G
Julie G am 15 Nov. 2017
Bearbeitet: Stephen23 am 15 Nov. 2017
Hi Lee, sorry for not making my question clear. please forget about the "XX" thing. The main point is that i have a lot of functions stored in a cell array. As these functions are randomly generated, they are not in a common form (i have a set of variables X=[x(:,1),x(:,2),x(:,3),x(:,4),x(:,5),x(:,6),x(:,7),x(:,8),x(:,9),x(:,10)]. each function randomly chooses some of these variables to construct a function). The following functions give some examples of the functions generated.
val(:,:,5) =
'x(iv,9)' 'x(iv,3)' '((((x(iv,9))*sqrt…' 'x(iv,3)' 'x(iv,2)'
val(:,:,6) =
'(((x(iv,10))*sqrt…' 'x(iv,9)' '(x(iv,1))*exp(x(i…' 'x(iv,3)' '((((x(iv,9))*log(…'
I know to use "str2func" and "feval" I need to include "@(var1, var2, var3, ...)". However, as i have quite a lot of functions which are not in common format, it seems unlikely to do it for every function. Do you have any idea about how to evaluate these functions? Thanks Best, J.
Stephen23
Stephen23 am 15 Nov. 2017
Bearbeitet: Stephen23 am 15 Nov. 2017
"I need to include "@(var1, var2, var3, ...)". However, as i have quite a lot of functions which are not in common format, it seems unlikely to do it for every function."
You could easily add the complete list of variables to every function. It does not matter if they are not used inside that function. Simply providing all variables would be a trivially easy solution. Basically this is perfectly okay:
@(x,y,z) x+y; % z is not used: this is okay.
"Do you have any idea about how to evaluate these functions?"
Function handles are the by far the best way to handle functions. You should convert to function handle, or even better work exclusively with function handles. Note also that feval is not required to evaluate function handles: the whole point of function handles is that they can be called, just like any other function:
>> fun = @(x,y,z) x+y;
>> fun(1,2,4)
ans = 3
You could possibly simplify your code by putting all of the values into one variable, and then also providing a logical mask to select which elements of that variable get used. In this way you can easily adjust for different numbers of values without changing your functions. But it really depends on your requirements, which so far you have told us nothing about.
Hi Stephen, thanks for your help. i did what you suggested. however, still, there is an error. The code and error message are shown below.
for jf = 1:popusize;
tree{v} = popu(v).chrom{1,jf}.tree;
ab{1,jf,v} = tree_stringrc(tree{v},1,symbols);
fh = str2func(['@(x(:,1),x(:,2),x(:,3),x(:,4),x(:,5),x(:,6),x(:,7),x(:,8),x(:,9),x(:,10)' ab{1,jf,v}]);
end
Error using pf (line 170) Error: Unbalanced or unexpected parenthesis or bracket.
it went well when i ran the code without
fh = str2func(['@(x(:,1),x(:,2),x(:,3),x(:,4),x(:,5),x(:,6),x(:,7),x(:,8),x(:,9),x(:,10)' ab{1,jf,v}]);
But the error message appeared when i ran with "fh". So, i think this error came from "fh". however, i checked a lot and did not find any unbalance in the parenthesis or bracket. Can you please help with this? Thanks. Best, J.
Stephen23
Stephen23 am 15 Nov. 2017
Bearbeitet: Stephen23 am 15 Nov. 2017
@Julie G: Note that x(:,1), x(:,2), etc are not variables (they are indexing into variables). So the way you have defined your function makes no sense because a function must be defined with variables as the input arguments, not some operation on a variable (like indexing).
You appear to have only one variable x, so you could try this:
str2func(['@(x)','ab{1,jf,v}']);
But I notice that x is not used inside that function definition. This means that whatever value you supply to that function will be unused. If you want to use the input variable's values then it must be the name of a variable used within that function's workspace. See my last comment for complete working examples: do you see how I defined x, y, and z as input variables of that function, and used x and y within that function?
I would highly recommend that you read the MATLAB documentation for function handles and anonymous functions, because your current approach of guessing how to write MATLAB code is very inefficient and will just waste your time. You should also read the str2func help.
Julie G
Julie G am 16 Nov. 2017
Thanks Stephen. I changed my variables to x1,x2,..., and now it works. Thanks a lot.
Stephen23
Stephen23 am 16 Nov. 2017
@Julie G: Note that numbered variables are usually a sign that indexing should be to access the variable contents. If you just put one x variable as an input argument you can easily use indexing within the function itself.
Julie G
Julie G am 16 Nov. 2017
OK, i will try what you said. By the way, do you know how to run "parfor" in unix? Currently, the "parfor" script runs well in my person PC in a parallel fashion. however, after i submit it to unix, it seems the script runs in a "for" loop (not in parallel). The time of run with unix is even more than that with my PC. Can you help me with this? Thanks. J.
Hi Julie, I think your default setup in Unix prevents the automatic creation of parallel pool upon encountering the first parfor statement. To change this, do this once (more info here ) :
ps = parallel.Settings;
ps.Pool.AutoCreate = true;
Or, before the parfor, add a parpool statement to manually open a parallel pool:
parpool(N) %Sets up N number of parallel workers
parfor j =1:M
...
end
Julie G
Julie G am 17 Nov. 2017
Hi Donald Lee. By "parfor j = 1:M", do you actually mean "parfor j = 1:N"? Thanks.
Julie G
Julie G am 17 Nov. 2017
Hi Donald. i added "parpool(12)" to my matlab file. but error message appeared in unix as below.
{Undefined variable "com" or class "com.mathworks.toolbox.distcomp.pmode.SessionInfo.NULL_SESSION_INFO".
Error in parpool (line 82) sessionInfo = com.mathworks.toolbox.distcomp.pmode.SessionInfo.NULL_SESSION_INFO;
Error in gp1 (line 156) parpool(12);
}
can you help with this? Thanks.
J.
OCDER
OCDER am 17 Nov. 2017
This could be caused if starting matlab with the -nojvm option. Here's a similar Q&A thread for this error. https://www.mathworks.com/matlabcentral/answers/230285-parpool-r2014a-fails-on-linux

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Gefragt:

am 14 Nov. 2017

Kommentiert:

am 17 Nov. 2017

Community Treasure Hunt

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

Start Hunting!

Translated by