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