nested function problem solving

Hi, I have created a nested function where many functions that call each other, and they all contribute to main fun R. However, it doesnt work (Not enough input arguments). Do you have any clue why? Thanks!
function R=revenue_nested(price,ro,g,eff,x,N,k1)
totaloutflow
storage1
depth1
function T=totaloutflow(x,N)
T=x(1:N)+x(N+1:2*N);
end
function S=storage1(init_s,inFlow,x,N)
S(1) = init_s(1) + inFlow(1)-x(1)-x(N+1);
for ii = 2:N
S(ii) = S(ii-1) + inFlow(ii)-x(ii)-x(N+ii);
end
end
function HH=depth1(S,alpha_par,b_par)
HH= (S/alpha_par).^(1/b_par);
end
R= -sum(price.*((HH*ro*g*eff).*x(1:N))/k1);
end

Respuestas (1)

Stephen23
Stephen23 el 29 de Mayo de 2018
Editada: Stephen23 el 29 de Mayo de 2018
This is how you define the function totaloutflow:
T=totaloutflow(x,N)
It has two input arguments, both of which are required.
This is how you call the function totaloutflow:
totaloutflow
Where are the input arguments? There are none, thus the error. The same for the other functions.
With nested functions for each variable you have a choice between:
  1. to pass it as an input/output argument, or
  2. to access it directly from the main function's workspace (which means that it has to exist in the parent workspace, and is not defined as an input/output variable).
E.g. to define a nested function that accesses x, passes N, and writes T:
x = ...
T = [];
...
totaloutflow(1)
...
totaloutflow(2)
...
totaloutflow(3)
...
function totaloutflow(N)
T = x(1:N) + x(N + 1:2 * N);
end
...
So far you have not defined init_s, inFlow, alpha_bar, or b_bar anywhere, so I cannot suggest how you should fix the rest of your code.

4 comentarios

sensation
sensation el 29 de Mayo de 2018
Editada: sensation el 29 de Mayo de 2018
Hi Stephen, and thanks for your tips! the variables values are defined in the main program as:
inFlow = 1000*rand(10,3);
price=100*rand(10,1);
outFlow=inFlow/2;
alpha_par=[10000,11000,15000];
b_par=[3,2,2];
init_s=[283550000,293550000,303550000];
ro=1000;
g=9.81;
eff=0.9;
x0 = [outFlow; zeros(size(outFlow))];
k1 = 60*60*1000000;
[N,M] = size(inFlow);
and I want to call here the nested function as:
for i = 1:M
R(:,i)=revenue_nested(price(:,1),ro,g,eff,x0(:,i),N,k1,init_s,inFlow,alpha_par,b_par);
end
My updated nested fun is:
function R=revenue_nested(price,ro,g,eff,x,N,k1,init_s,inFlow,alpha_par,b_par,S)
totaloutflow(x,N)
storage1(init_s,inFlow,x,N)
depth1(S,alpha_par,b_par)
function T=totaloutflow(x,N)
T=x(1:N)+x(N+1:2*N);
end
function S=storage1(init_s,inFlow,x,N)
S(1) = init_s(1) + inFlow(1)-x(1)-x(N+1);
for ii = 2:N
S(ii) = S(ii-1) + inFlow(ii)-x(ii)-x(N+ii);
end
end
function HH=depth1(S,alpha_par,b_par)
HH= (S/alpha_par).^(1/b_par);
end
R= -sum(price.*((HH*ro*g*eff).*x(1:N))/k1);
end
Stephen23
Stephen23 el 29 de Mayo de 2018
Editada: Stephen23 el 29 de Mayo de 2018
@sensation: Thank you for the updated info, that is great. My answer told you how to fix your code: you need to decide which variables you want to pass as input/output arguments, and which ones by accessing from the parent workspace. It is your algorithm, so you will have to decide this.
To be honest, it is not clear to me why you want to use nested functions: so far everything you have shown could be easily achieved using local functions and passing all data as input/output arguments (which you also seem to be a lot more comfortable with). Can you explain the need to use nested functions?
Passing the data as input/output arguments would be simple:
T = totaloutflow(x,N);
S = storage1(init_s,inFlow,x,N);
HH = depth1(S,alpha_par,b_par);
R = -sum(price.*((HH*ro*g*eff).*x(1:N))/k1);
and all of the functions could be simply written as local functions (you could keep them as nested functions, but there would be no point).
If you really want to use nested functions then read my answer again. Note the example I gave in my answer: how is T defined? Compare this with your code.
sensation
sensation el 29 de Mayo de 2018
Hi Stephen. Thanks for your tips. Beforehand I created many local functions (saved as separate files) as you suggested. It run but the HH was constant (linear) in R and it should not be like that. I wanted to have HH depending on x values so when I run:
[x(:,i),fval(:,i)] = fmincon(@(x0)revenue(price(:,1),HH,ro,g,eff,x0,N,k1),x0(1:2*N,i),A,b(:,i),Aeq,beq(:,i),LB(:,i),UB(:,i),[],options);
I want to get optimized x values. These are the same values that act first in T, then in S, then in HH and finally in R. That was the reason why I think that here I should go for a nested function. I could also maybe create many local functions but do you know how I can call then depth and storage within the revenue,R (so I optimize x in each of those functions)? Thanks!
Stephen23
Stephen23 el 29 de Mayo de 2018
"Beforehand I created many local functions (saved as separate files) as you suggested."
I suggested using local functions. Local functions are saved in one file. I did not suggest that you should put all of the functions into separate files (although it may be possible, depending on your algorithm (which I know nothing about)). You can learn about the different kinds of functions here:
"I want to get optimized x values."
"HH ... should depend on x that we optimize."
Aha, and you are calling fmincon to perform some optimization on x. If you want HH to depend on a variable that changes with the optimization then you could use nested functions to define that variable, but you would have to remove it from the anonymous function definition input arguments (otherwise it will just be a constant).
To be honest I have trouble keeping track of your examples, which ones you are now using, or what is not working. It would help if you put them into one file (as they should be) and uploaded that in a new comment.

Iniciar sesión para comentar.

Categorías

Más información sobre Scope Variables and Generate Names en Centro de ayuda y File Exchange.

Preguntada:

el 29 de Mayo de 2018

Comentada:

el 29 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