Multiple function handles in cells, sum function handles in 1 cell
이전 댓글 표시
I want to multiply functions (V_fun and EW_fun in the code below) that I have stored in 2 cells.
V_init = 0.5;
for i = 3:5 % compute sojourn time for row 1
V_fun{i} = @(x) V_init*x(i-2);
EW_fun{i} = @(x) ES(1,i)*(1+0.5*(1+SCV(1,i))*0.9*V_fun{i}*ES(1,i)/(1-0.9*V_fun{i}*ES(1,i)));
V_init = @(x) V_fun{i};
fun{i} = @(x) V_fun{i}*EW_fun{i};
end
V_init = 1;
for j = 6:8 % compute sojourn time for row 2
V_fun{j} = @(x) 0.5*(1-x(1))*V_init*x(j-2);
EW_fun{j} = @(x) ES(2,j-3)*(1+0.5*(1+SCV(2,j-3))*0.9*V_fun{j}*ES(2,j-3)/(1-0.9*V_fun{j}*ES(2,j-3)));
V_init = @(x) V_fun(j);
end
V_init = @(x) 0.5*x(1)*(1-x(2))*(1-x(5));
for i = 9:10 % compute sojourn time for row 3
V_fun{i} = @(x) V_init*x(i-2);
EW_fun{i} = @(x) ES(3,i-5)*(1+0.5*(1+SCV(1,i-5))*0.9*V_fun{i}*ES(1,i-5)/(1-0.9*V_fun{i}*ES(1,i-5)));
V_init = @(x) V_fun{i};
end
V_fun{11} = @(x) 0.5*x(1)*x(2)*(1-x(3))*(1-x(6))*(1-x(8))*x(9);
EW_fun{11} = @(x) ES(4,5)*(1+0.5*(1+SCV(4,5))*0.9*V_fun{11}*ES(4,5)/(1-0.9*V_fun{11}*ES(4,5)));
% fun{11} = @(x) V_fun{11}*EW_fun{11};
V_fun{12} = @(x) 0.5*x(1)*x(2)*x(3)*x(10);
EW_fun{12} = @(x) ES(5,5)*(1+0.5*(1+SCV(5,5))*0.9*V_fun{12}*ES(5,5)/(1-0.9*V_fun{12}*ES(5,5)));
fun = cellfun(@(g,h) @(x) g(x).*f(x),V_fun,EW_fun,'UniformOutput',false);
It runs without error. But when I call 'fun{1}(1)' for example, it gave error:
Index exceeds array bounds.
Error in trial1b>@(x)g(x).*f(x)
Further, I want to sum the elements of 'fun', I tried
S = {};
for k = 3 : numel(fun)
S = @(x) S(x) + fun{k}(x);
end
and
funMin = @(x) sum([fun{:}(x)]);
but those did not work.
How to multiply the 2 functions in the 2 cells correctly? And how to sum the element of the multiplication between these 2 functions?
댓글 수: 7
Using many anonymous functions seems to be an overly complex approach: why not just use numeric arrays and indexing? Then the summation would be trivial.
EDIT: in fact, the more I look at this code, the less sense it makes. For example:
1. you overwrite V_init with a function handle:
V_init = 0.5;
for i = 3:5 % compute sojourn time for row 1
...
V_init = @(x) V_fun{i};
...
end
but nowhere in your code do you call that function handle, you seem to keep treating it as an array.
2. you never define any functions in the first two cells of V_fun or EW_fun, so multiplying non-existent functions is unlikely to be very effective (btw. this is likely to be the cause of the first error). It is also a major point you would need to consider in your algorithm.
3. The function(?) f is undefined (I guess you meant h):
fun = cellfun(@(g,h) @(x) g(x).*f(x),...
4. In multiple locations you try to multiply a function handle with a numeric, e.g.: 0.9*V_fun{i}. Numerics can be multiplied with numerics, logicals, chars, but not with function handles (you need to call the function handle first).
5. Many of the anonymous functions' input arguments remain unused:
EW_fun{i} = @(x) ES(1,i)*(1+0.5*(1+SCV(1,i))*0.9*V_fun{i}*ES(1,i)/(1-0.9*V_fun{i}*ES(1,i)));
% ^ unused
V_init = @(x) V_fun{i};
% ^ unused
fun{i} = @(x) V_fun{i}*EW_fun{i};
% ^ unused
V_init = @(x) V_fun(j);
% ^ unused
V_init = @(x) V_fun{i};
% ^ unused
While this is not an error, given the nature of your calculations it should be checked.
7. Even if you manage to fix all of those (and any other) bugs, your code will be very inefficient compared to simple MATLAB code using numeric arrays, as well as being difficult to understand and maintain.
Basically you should throw this code away and start again. Do not write lots and lots of code (without testing anything) and then just expect it to run: write one line and then test it.
Do not start with the next line until that line does what you need it to do.
I very much doubt that your approach with anonymous functions is a good one. Most likely you should just write a proper function and use basic MATLAB arrays, indexing, and vectorized code.
"I need to find the minimum value of the function using fmincon or fminsearch"
For that you do not need one thousand functions, just one is required.
Oki Almas Amalia
2019년 7월 17일
Oki Almas Amalia
2019년 7월 17일
Stephen23
2019년 7월 17일
"I was testing it too in every part and it worked without error until I call the function."
Even after the very first loop testing the cell arrays of functions your code throws errors, so I do not understand how you continued to write more loops before the first one was working properly. Try these after the first loop and let me know if they "work without error" as you claim:
fun{1}(1:10)
fun{3}(1:10)
I get errors due to points 2. and 4. of my earlier comment. How did you test your first loop?
Oki Almas Amalia
2019년 7월 17일
1. Write a script (then convert it later to a function when you need to use it with fmincon or fminsearch): https://www.mathworks.com/help/matlab/matlab_prog/scripts-and-functions.html
2. Use arrays and indexing and vectorization: https://www.mathworks.com/help/matlab/matlab_prog/vectorization.html
3. Test each line as you write it. This does not just mean running some code, but using input values and checking that the output values are correct.
4. Read the documentation for every operator, no matter how trivial you think that operator is.
5. If you have any questions, something is not working as expected, or you are not sure about something, please ask us.
6. You might like to read this too: https://www.mathworks.com/matlabcentral/answers/228557-experts-of-matlab-how-did-you-learn-any-advice-for-beginner-intermediate-users
Oki Almas Amalia
2019년 7월 17일
답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Whos에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
