- How many different functions are there?
- Does each function always take the same number of input arguments?
- Where are these functions defined: as local functions, or in their own files?
- In your example matrix
Alternatives for eval when executing functions in matrix
7 views (last 30 days)
Show older comments
I'm trying to find a better way to run my code so that I can parallelize it (using parfor).
Here is my setup:
I have a matrix that holds functions for me to run.
A = [myfun(data), myfun1(data, B), myfun2(data,C);
myfun1(data,B1), myfun2(data,C2), myfun(data) ....]
Each row holds a series of functions that I want to evaluate with each function having different parameters. So in the above matrix I'd like to run myfun(data), myfun1(data,B), myfun2(data,c) compute stats on the data and then move on to row2 and evaluate the next 3 functions, compute stats and repeat for each row in the matrix.
What I am currently doing do to this is iterating through the matrix and running eval(String(A(i,j))). Now my matrix is very large so I would like to parallize the actions and run segments of the matrix concurrently using 'parfor' however parfor will not run with an eval command in the loop.
Is there another way I can do this?
7 Comments
Answers (2)
Jan
on 29 May 2018
Edited: Jan
on 29 May 2018
Use feval instead.
If you post the relevant part of your code, it would be very easy to suggest the modification explicitly. But it would be tedious, to invent some code to show you the difference. But it is something like:
feval('myfun2', data, C)
It is smarter to create a cell array of function handles instead of providing the function names as strings.
But the most efficient solution would be to modify the function such, that they accept a vector or cell array of inputs. With this vectorization the loop is not needed anymore.
You can get more help, if you post the relevant code, including "myfun", "myfun2", etc.
Note: Using eval impedes the JIT acceleration massively. It injects variables and functions dynamically into the current workspace, and this can slow down the processing by up to a factor of 100 - even in code lines, which do not contain the evil eval commands. The rule is simple: Do not use eval, because there is a smarter, nicer and faster solution in general.
1 Comment
Walter Roberson
on 29 May 2018
For using parfor you should construct a cell array of function handles. To handle the extra parameters mentioned, parameterize the functions
Guillaume
on 29 May 2018
As others have said, using function handles instead of eval would be much better. Here is one approach:
fns = {@(data) myfun1(data), @(data) myfun2(data), @(data) myfun3(data, arg1), @(data) myfun4(data, arg1, arg2)}; %list of functions with their fixed arguments
makechain = @(row) @(data) fns{row(1)}(fns{row(2)}(fns{row(3)}(fns{row(4)}(data)))); %create new function that is chaining a permutation of fns
functionperms = cellfun(@(row) makechain(row), num2cell(perms(1:4), 2), 'UniformOutput', false); %create all permutations of function chains
results = cell(size(functionperms));
parfor pidx = 1:numel(functionperms)
results{pidx} = functionperms{pidx}(data);
end
Notes:
- I don't have the parallel toolbox so can test the parfor
- Because there are only 4 functions, I just hardcoded the 4 functions chain as the makechain anonymous function. With more functions, I would have built the chain with a recursive m file.
- In your original eval(string(A(i, j)), the conversion to string looks like a workaround because you don't know how to extract values from a cell array. eval(A{i, j}) would be simpler. {} is used to extract data from cell arrays.
0 Comments
See Also
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!