Azzera filtri
Azzera filtri

Summation of functions in a loop

11 visualizzazioni (ultimi 30 giorni)
Hi there, I would like to create functions and then sum them up in a loop. Then use an optimizer to find the minimum of the summation. The functions are the same but I need them to have independent variables.
for example: I need a "matrix" of functions
A=[@(x)(x(1)-S(1))^2, @(x)(x(2)-S(2))^2,..., @(x)(x(n)-S(n))^2]
,where S a (1xn) matrix. Then summing all of the above functions to get the minimum
x0 = [0,0,...n];
x = fminsearch(sum(A(:)),x0)
The above code does not work but I am just posting it so you get a better idea of what I am looking for. Thank you

Risposta accettata

Stephen23
Stephen23 il 2 Nov 2017
Modificato: Stephen23 il 2 Nov 2017
Creating an array of functions is a red herring. You just need one simple array, inside one function:
>> fun = @(x) sum((x-5).^2);
>> x0 = [0,0,0,0];
>> fminsearch(fun,x0)
ans =
4.9997 5.0001 5.0001 5.0002
If you really want each "function" to be different, then you still only need one matrix inside one function:
>> fun = @(x) sum([(x(1)-3)^2,(x(2)-5)^2,(x(3)-8)^2,(x(4))^2]);
>> x0 = [0,0,0,0];
>> fminsearch(fun,x0)
ans =
2.9998e+000 4.9999e+000 7.9998e+000 -1.3034e-004
Trying to create an array of functions is possible (just put them into a cell array), but will likely be a total waste of your time. After all, fminsearch only accepts one function, so why not simply define one function ?
  13 Commenti
Walter Roberson
Walter Roberson il 17 Set 2020
fun = @(x)sum(cellfun(@(f)f(x),C)); % slow and complex cellfun
The @(x) starts the definition of an anonymous function that is to have a single parameter that is to be known as x. That is followed by an expression, which is built into the anonymous function for execution. Everywhere in the expression that x appears (that is not "shadowed" by a different definition), at run-time the x is to be replaced by whatever was passed as the first parameter to the anonymous function. The handle to the anonymous function will be assigned to the variable fun
The body of the anonymous function involves sum() of some values; in particular the vector or array of values returned by a call to cellfun() .
The call to cellfun() is cellfun(@(f)f(x),C) . That call has an anonymous function definition inside it, @(f)f(x) . Every time that anonymous function stored in fun is executed, when the cellfun() is executed, a new anonymous function @(f)f(x) is built.
The logic is not
temp_inner_function = @(f)f(x)
fun = @(x)sum(cellfun(temp_inner_function,C))
That would build a single anonymous function and invoke the one function whenever fun is invoked, which is not what happens. It is important for this purpose that each time that cellfun(@(f)f(x),C) is executed, that a new anonymous function is created.
The reason it it is important that a new anonymous function is created for use by cellfun() during the execution of fun, is that when you create an anonymous function and the body of the function involves variables that are not the parameters, then the current value of those variables at the time the function is built are copied into the function handle. In the case of @(f)f(x), the value of x at the time the function is built is copied into the function handle that is being created. What is the value of x? Well since you are inside the body of a @(x) definition, the value of x will be whatever was passed as the first parameter into fun.
So, the cellfun(@(f)f(x),C) part is building an anonymous function that binds in whatever was passed as the first parameter to fun, as the value to be passed to f. And what is f? Well, because of the @(f) part, f is the first parameter that was passed to that local anonymous function. What is the first parameter that will be passed? You are inside a cellfun() and the logic of cellfun(HANDLE, EXPRESSION) (that does not have 'uniform', 0) is
for K = 1 : numel(EXPRESSION)
temp_result(K) = HANDLE(EXPRESSION{K});
end
cellfun_result = reshape(temp_result, size(EXPRESSION));
What is being passed as the EXPRESSION to cellfun()? C is being passed. What is C? Refer back to "the body of the function involves variables that are not the parameters, then the current value of those variables at the time the function is built are copied into the function handle. In the case of @(f)f(x), the value of x at the time the function is built is copied into the function handle that is being created" . So the environment is searched for C, and its value from the lines
for k = 1:numel(A), C{k}=@(x)(x(k)-A(k)).^2; end
that C will be built into the function handle that is being created to store into fun. C is a cell array of handles to anonymous functions. Following the above logic for what cellfun does, we can see that the cellfun(@(f)f(x),C) call is going to be accessing each entry inside the cell C in turn, and passing that as the value f to the anonymous function @(f)f(x) , where it is going to be invoked as a function on the value of x that was bound into the function handle as designating whatever was passed as the first parameter to fun.
The effect is as if you had done:
function sum_C_of_x(x, C)
for K = 1 : numel(C)
temp_result(K) = C{K}(x);
end
sum_C_of_x = sum(temp_result);
end
and had invoked
fun = @(x) sum_C_of_x(x,C);
fminsearch(fun, x0)
Jay Heng
Jay Heng il 23 Set 2020
Modificato: Jay Heng il 23 Set 2020
Thank you very much Stephen for your example and Walter for your detailed explanations, it is much clearer now! Good day to both of you.

Accedi per commentare.

Più risposte (1)

KL
KL il 2 Nov 2017
Modificato: KL il 2 Nov 2017
I'm not quite clear, you probably want,
A = @(x) sum((x-5).^2)
If you really intend to create array of functions, then
A = {@(x)(x(1)-5)^2;
@(x)(x(2)-5)^2;
@(x)(x(3)-5)^2;
...};
  2 Commenti
Spyros Polychronopoulos
Spyros Polychronopoulos il 2 Nov 2017
I tried
A = @(x) sum((x-5).^2)
But this will encounter for the same x. I need to have f(x1), f(x2),... and sum them up. So I need the minimum F(x1,x2,...)=sum(f(x1),f(x2),...). x1,x2,... are independent variables.
as for your second answer:
1. I can not create that cell in a loop if i try the below the I just get x(k) in the cell
for k=1:1:10
A(k)={@(x)(x(k)-5)^2};
end
2. I can not add them all up
sum(A{:})
does not work
Stephen23
Stephen23 il 3 Nov 2017
Modificato: Stephen23 il 13 Nov 2017
"I need to have f(x1), f(x2),... and sum them up. So I need the minimum F(x1,x2,...)=sum(f(x1),f(x2),...). x1,x2,... are independent variables."
But to use it with fminsearch the function can only have one input variable. The fminsearch documentation states " fun is a function that accepts a vector or array x and returns a real scalar f." Which is exactly what my answer does.
It seems like you might be confused between the MATLAB use of the word "variable", and the common mathematical usage: a "variable" in MATLAB can be an array, which has lots of values in it. For fminsearch just one array is supplied to the function: it has as many values in it as you need to define your system. If it helps you, every time you see the term "variable" used in MATLAB context just think "array of values".

Accedi per commentare.

Categorie

Scopri di più su Loops and Conditional Statements in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by