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.
I need to find the minimum value of the function using fmincon or fminsearch in the later part. I tried to use numeric arrays but the error is :
Nonscalar arrays of function handles are not allowed; use cell arrays instead.
Error in trial1b (line 30)
V_fun(i) = @(x) V_init*x(i-2);
So I thought I cannot store the functions in numeric array and should use cell arrays instead.
Thank you for your comment. I was testing it too in every part and it worked without error until I call the function. Also, in each cell it contains variable x as it's multiplication between functions.
Anyway, thank you for the answer for this rubbish code.
"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?
What I meant was that no errors appearing and I got this from first loop :
Capture.PNG
I understand that I need to re-do it. Thank you for pointing out things. I am still learning. Thank you.
Stephen23
Stephen23 2019년 7월 17일
편집: Stephen23 2019년 7월 17일
@Oki Almas Amalia: some tips for getting started:
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.
Thank you so much for the complete answers. Thanks to you the code now works well.

댓글을 달려면 로그인하십시오.

답변 (0개)

카테고리

질문:

2019년 7월 17일

댓글:

2019년 7월 17일

Community Treasure Hunt

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

Start Hunting!

Translated by