For loop within a function f

Hello all,
I'm trying to get the following function by using a for loop:
f=@(x) ((0.0011*(x(2:1*N)-x(1:N-1)))'*exp(-0.0078*x(Battery_num*N+1:Battery_num*N+N-1)))*Battery_cost/20 + ((0.0011*(x((N+2):2*N)-x((N+1):(2*N-1))))'*exp(-0.0078*x(Battery_num*N+N-1+1:Battery_num*N+2*(N-1))))*Battery_cost/20+...
((0.0011*(x((2*N+2):(3*N))-x((2*N+1):(3*N-1))))'*exp(-0.0078*x(Battery_num*N+2*(N-1)+1:Battery_num*N+3*(N-1))))*Battery_cost/20 + ((0.0011*(x((3*N+2):(4*N))-x((3*N+1):(4*N-1))))'*exp(-0.0078*x(Battery_num*N+3*(N-1)+1:Battery_num*N+4*(N-1))))*Battery_cost/20;
I have found the pattern with i and j however I don;t know how to get the sum of it, as I get an error because of the x presence.
here is my code:
j=1;
for i=0:Battery_num-1
f=@(x)((0.0011*(x(2+i*N:j*N)-x(2-1+i*N:j*N-1)))' *exp(-0.0078*x(Battery_num*N+1+i*(N-1):Battery_num*N+j*(N-1))))*Battery_cost/20;
j=j+1;
So finally the question is how to add the values for each i. I hope my question is clear
thank you in advance!

5 comentarios

Bob Thompson
Bob Thompson el 8 de Mayo de 2018
If you turn f into an array with indexing then you can sum the values after the for loop is complete.
j=1;
for i=0:Battery_num-1
f(i) = @(x)...
end
summation = sum(f);
Nikolas Spiliopoulos
Nikolas Spiliopoulos el 8 de Mayo de 2018
Thanks for the answer,
the problem is I get an error "Nonscalar arrays of function handles are not allowed; use cell arrays instead."
Bob Thompson
Bob Thompson el 8 de Mayo de 2018
Are you actually getting numeric answers out of f? If not, then yes, you would need to use f{i} to produce a cell array.
Also, if you are not getting numeric answers then I don't know how you are going to get a summation. If they are numbers then you should just be able to convert them using cell2num().
thanks again for the answer! Actually I'm not getting numeric answers because I have the variable x inside. I tried what you said with f{i}. It puts the funtion in a cell array however, it doesn't put the i and j for each iteration. I would expect to see something like that:
(0.0011*(x(2:1*N)-x(1:N-1)))'*exp(-0.0078*x(Battery_num*N+1:Battery_num*N+N-1)))*Battery_cost/20
But i don't. Thanks again
dpb
dpb el 9 de Mayo de 2018
If you try to create a function array, then you have the same issue as in the original of how to execute it; that syntax is to dereference the particular function out of the array with curlies "{}" followed by the function arguments in parens "()"

Iniciar sesión para comentar.

Respuestas (2)

dpb
dpb el 9 de Mayo de 2018

0 votos

f=@(x)((0.0011*(x(2+i*N:j*N)-x(2-1+i*N:j*N-1)))' *exp(-0.0078*x(Battery_num*N+1+i*(N-1):Battery_num*N+j*(N-1))))*Battery_cost/20;
The above defines the function, it doesn't evaluate it. The function should be written as
fnf=@(x,i,j) ((0.0011*(x(2+i*N:j*N)-x(2-1+i*N:j*N-1)))' *exp(-0.0078*x(Battery_num*N+1+i*(N-1):Battery_num*N+j*(N-1))))*Battery_cost/20;
and then used as
f(i,j)=fnf(x,i,j);
for whatever combinations of i,j it is that you want.
Judicious rewriting to use "dot" operators could probably let you rewrite the function in a vectorized form to eliminate the loop; just should be to get the desired result is indeterminate for lack of complete code from which to try to decipher the intent.

9 comentarios

thanks you for your answer. I'm not sure if i understood right but here what I did, but i get an error that I haven't defined x:
fnf=@(x,i,j) ((0.0011*(x(2+i*N:j*N)-x(2-1+i*N:j*N-1)))' *exp(-0.0078*x(Battery_num*N+1+i*(N-1):Battery_num*N+j*(N-1))))*Battery_cost/20;
j=1;
for i=0:Battery_num-1
f(i,j)=fnf(x,i,j);
j=j+1;
end
where Battery_num is 4.
The first iteration I want to be:
f=@(x) ((0.0011*(x(2:1*N)-x(1:N-1)))'*exp(-0.0078*x(Battery_num*N+1:Battery_num*N+N-1)))*Battery_cost/20
so I can sum up all of them at the end. Thanks!
dpb
dpb el 9 de Mayo de 2018
Again, the last line defines another anonymous function f instead of evaluating the anon function fnf with the subscripts i,j and the array x passed to it as the definition requires.
The value of Battery_num is embedded in the function from its value at the time the function handle is created; if it is variable then it, too, should be an argument.
As noted before, you haven't told us specifically what it is you're trying to sum over. Also NB: that as you defined the subscript in the anonymous function that x(2+i*N:j*N) that 2+i*N will have to be >= j*N or the subscript index vector will return null and that depending upon what i,j are, you'll get a varying length vector.
I really doubt any of this is what you're really after but you won't tell us that so we can provide a workable solution it seems...
Thanks you for the detailed answer. I"ll try to make it clear. I want to get a function like this:
f=@(x) ((0.0011*(x(2:1*N)-x(1:N-1)))'*exp(-0.0078*x(Battery_num*N+1:Battery_num*N+N-1)))*Battery_cost/20 + ((0.0011*(x((N+2):2*N)-x((N+1):(2*N-1))))'*exp(-0.0078*x(Battery_num*N+N-1+1:Battery_num*N+2*(N-1))))*Battery_cost/20+...
% ((0.0011*(x((2*N+2):(3*N))-x((2*N+1):(3*N-1))))'*exp(-0.0078*x(Battery_num*N+2*(N-1)+1:Battery_num*N+3*(N-1))))*Battery_cost/20 + ((0.0011*(x((3*N+2):(4*N))-x((3*N+1):(4*N-1))))'*exp(-0.0078*x(Battery_num*N+3*(N-1)+1:Battery_num*N+4*(N-1))))*Battery_cost/20;
So I found the pattern that give me these values (for each i,j) which is the following:
j=1;
for i=0:Battery_num-1
f{i+1}=@(x) ((0.0011*(x(2+i*N:j*N)-x(2-1+i*N:j*N-1)))' *exp(-0.0078*x(Battery_num*N+1+i*(N-1):Battery_num*N+j*(N-1))))*Battery_cost/20;
j=j+1;
end
So for each i,j I expect to get 4 f{}, and afterwards I could sum up them. The problem is that I have the variable x, which makes the things a bit complicated, so I don't really know if it's possible.
I hope now it is more clear. Thanks a lot anyway!!
dpb
dpb el 9 de Mayo de 2018
I don't care what "function like" you're trying to get, I'm asking what is the end result from first principles you're after; irrespective of the "how" to compute it. I believe your approach is way over-thinking the problem if we knew what the actual problem itself was without the obfuscation of trying to debug non-working code.
Given you have a particular functional form; what are constants in it and what aren't and which of the variables are to be varied over what values to be included in the summation? Knowing that, then we can look at how to code it, but we need the problem definition clearly enunciated first.
Nikolas Spiliopoulos
Nikolas Spiliopoulos el 9 de Mayo de 2018
Editada: Nikolas Spiliopoulos el 9 de Mayo de 2018
ok I want to get an function f that follows the following pattern:
f=@(x) ((0.0011*(x(2:1*N)-x(1:N-1)))'*exp(-0.0078*x(Battery_num*N+1:Battery_num*N+N-1)))*Battery_cost/20 + ((0.0011*(x((N+2):2*N)-x((N+1):(2*N-1))))'*exp(-0.0078*x(Battery_num*N+N-1+1:Battery_num*N+2*(N-1))))*Battery_cost/20+...
% ((0.0011*(x((2*N+2):(3*N))-x((2*N+1):(3*N-1))))'*exp(-0.0078*x(Battery_num*N+2*(N-1)+1:Battery_num*N+3*(N-1))))*Battery_cost/20 + ((0.0011*(x((3*N+2):(4*N))-x((3*N+1):(4*N-1))))'*exp(-0.0078*x(Battery_num*N+3*(N-1)+1:Battery_num*N+4*(N-1))))*Battery_cost/20;
the function above is for 4 terms (term1+term2+term3+term4). I want to generaliaze it with a for loop which applies for n terms (let's say 50).
Batter_num, Battery_cost, N are constant and x is an unknown variable
I mean term1:
((0.0011*(x(2:1*N)-x(1:N-1)))'*exp(-0.0078*x(Battery_num*N+1:Battery_num*N+N-1)))*Battery_cost/20
term2:
((0.0011*(x((N+2):2*N)-x((N+1):(2*N-1))))'*exp(-0.0078*x(Battery_num*N+N-1+1:Battery_num*N+2*(N-1))))*Battery_cost/20
and so on.
Stephen23
Stephen23 el 9 de Mayo de 2018
Editada: Stephen23 el 9 de Mayo de 2018
"the function above is for 4 terms (term1+term2+term3+term4). "
Apparently these are the "four terms" that Nikolas Spiliopoulos mentions (I arranged them onto four lines for clarity, and edited them for consistency):
f = @(x)
((0.0011*(x((0*N+2):(1*N))-x((0*N+1):(1*N-1))))'*exp(-0.0078*x(Battery_num*N+0*(N-1)+1:Battery_num*N+1*(N-1))))*Battery_cost/20...+
((0.0011*(x((1*N+2):(2*N))-x((1*N+1):(2*N-1))))'*exp(-0.0078*x(Battery_num*N+1*(N-1)+1:Battery_num*N+2*(N-1))))*Battery_cost/20...+
((0.0011*(x((2*N+2):(3*N))-x((2*N+1):(3*N-1))))'*exp(-0.0078*x(Battery_num*N+2*(N-1)+1:Battery_num*N+3*(N-1))))*Battery_cost/20...+
((0.0011*(x((3*N+2):(4*N))-x((3*N+1):(4*N-1))))'*exp(-0.0078*x(Battery_num*N+3*(N-1)+1:Battery_num*N+4*(N-1))))*Battery_cost/20;
If you are want to define an arbitrary number of "terms" then either vectorize your code or use a loop (implicit or explicit). Certainly adding more and more terms like this would be a poor way to write code, so you are right to ask.
dpb
dpb el 9 de Mayo de 2018
I've not tried to compute what the subscripts in terms (x(2:1*N)-x(1:N-1)), x(N+2):2*N)-x((N+1):(2*N-1)) actually turn into numerically (we've no idea what N is here, for starters), but I can't help but believe that storing the array x as either a 2D maybe or even a cell array to simplify the lookup of the proper sequence wouldn't go a long ways towards removing much of the complexity and then be able to write legible (and more importantly working) code.
As is, I still can't fathom what it is your end result is actually supposed to be, sorry...
Nikolas Spiliopoulos
Nikolas Spiliopoulos el 9 de Mayo de 2018
thanks again for all the comments! f is an objective function in an optimization problem, so I'm trying to find a way to update it when some parameters change. Thanks anyway for your effort!

Iniciar sesión para comentar.

Stephen23
Stephen23 el 9 de Mayo de 2018
Editada: Stephen23 el 9 de Mayo de 2018

0 votos

The answer to your question is already in the title to your question: "For loop within a function f" The attmempts that you showed are the other way around: you define a function inside a loop, but you need a loop inside a function. It is not possible to put a loop inside an anonymous function, so you will need to define a function in a file, e.g. as a nested function:
function out = myfun(x)
out = 0;
for k = 1:Battery_num
out = out + (0.0011*(x(2+(k-1)*N:k*N)-x(2-1+(k-1)*N:k*N-1)))' * ...
exp(-0.0078*x(Battery_num*N+1+(k-1)*(N-1):Battery_num*N+k*(N-1)))) * ...
Battery_cost/20;
end
end
Alternatively it may be possible to vectorize your code, in which case using an anonymous function will still be possible. If you told use the sizes of all of the variables then we might be able to help you with vectorizing the code.

4 comentarios

Nikolas Spiliopoulos
Nikolas Spiliopoulos el 9 de Mayo de 2018
thanks for the reply ! however I get an error "not enough input arguments"
Stephen23
Stephen23 el 9 de Mayo de 2018
Editada: Stephen23 el 9 de Mayo de 2018
@Nikolas Spiliopoulos: I cannot guess what code you are running, or how you are calling it. If you want help with an error then upload all relevant code by clicking the paperclip button and show the complete error message. This means all of the red text.
Nikolas Spiliopoulos
Nikolas Spiliopoulos el 9 de Mayo de 2018
Stephen23
Stephen23 el 9 de Mayo de 2018
Editada: Stephen23 el 9 de Mayo de 2018
myfun has one input argument x. When you call it from the command line, you will need to supply a value for this argument, e.g.
myfun(1) % or whatever value of |x| you want to use
If you do not supply x then MATLAB has no idea what value to use for the x inside the function. Thus the error.

Iniciar sesión para comentar.

Categorías

Más información sobre Loops and Conditional Statements en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

el 8 de Mayo de 2018

Comentada:

el 9 de Mayo de 2018

Community Treasure Hunt

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

Start Hunting!

Translated by