Alternatives for eval when executing functions in matrix

7 ビュー (過去 30 日間)
Ashley
Ashley 2018 年 5 月 29 日
回答済み: Guillaume 2018 年 5 月 29 日
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 件のコメント
Ashley
Ashley 2018 年 5 月 29 日
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 2018 年 5 月 29 日
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

サインインしてコメントする。

回答 (2 件)

Jan
Jan 2018 年 5 月 29 日
編集済み: Jan 2018 年 5 月 29 日
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 件のコメント
Walter Roberson
Walter Roberson 2018 年 5 月 29 日
For using parfor you should construct a cell array of function handles. To handle the extra parameters mentioned, parameterize the functions

サインインしてコメントする。


Guillaume
Guillaume 2018 年 5 月 29 日
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.

カテゴリ

Help Center および File ExchangeCreating and Concatenating Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by