- 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 ビュー (過去 30 日間)
古いコメントを表示
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?
回答 (2 件)
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
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
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.
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Creating and Concatenating Matrices についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!