Alternatives for eval when executing functions in matrix

7 views (last 30 days)
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
Ashley
Ashley on 29 May 2018
the columns are dependent on each other but not the rows. The functions in row 1 are not dependent on row2 and the data is different for each row.
Ashley
Ashley on 29 May 2018
I apologize for the confusion, yes, the cells are filled with strings ie 'myfun(data)'.
The goal of my code is to compare how the resulting data is after applying the functions in different orders with different parameters. Essentially an exhaustive search of these permutations where each row in my matrix is one permutation.
It may be easier to reconstruct my matrix.
Thank you

Sign in to comment.

Answers (2)

Jan
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
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

Sign in to comment.


Guillaume
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.

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!