Out of memory. The likely cause is an infinite recursion within the program.

11 views (last 30 days)
function [out] = Vout(t)
D=5;% feet
H=10;% feet
yi=7;% ft (initial water level)
ysp=5;% ft
DT=30; % seconds amount of time b/t adjustments
BAND=1;% ft
tmax=6000; %seconds
%kI=not used
Vimax=100; %gallons per minute
Vimax=Vimax/448.8;
% Viout= 40;
% Viout = Viout/448.8;
%compute cross-sectional area of tank
A=pi*D^2/4; %ft^2
%compute upper and lower limits of band
UL=ysp+BAND/2;LL=ysp-BAND/2; %ft
%determine initial valve position
if yi>UL
VP=0;
elseif yi<LL
VP=1;
else
VP=1-(yi-LL)/BAND;
end
t = linspace(0,tmax,tmax);
t(1)=0;n=1;y(1)=yi;
while t(n)<=tmax
volume_in=VP*Vimax*DT; %ft^3
volume_out=Vout(t(n))*DT; %ft^3
dv=volume_in-volume_out; %ft^3
dy=dv/A; %ft
y(n+1)=y(n)+dy; %ft
t(n+1)=t(n)+DT;
%determine new valve position
if y(n+1)>UL
VP=0;
elseif y(n+1)<LL
VP=1;
else
VP=1-(y(n+1)-LL)/BAND;
end
n=n+1;
end
plot(t,y)
When I run it. It gives me this error:
Out of memory. The likely cause is an infinite recursion within the program.
Error in Vout (line 27)
t = linspace(0,tmax,tmax);
Why? how I can fix it?
Thank you

Answers (2)

Steven Lord
Steven Lord on 18 Jul 2019
Your first call to Vout calls itself on this line:
volume_out=Vout(t(n))*DT; %ft^3
That second call to Vout calls itself.
That third call to Vout calls itself.
...
Given that the first element of t is 0 and n is 1, this keeps calling Vout with 0 as the input. Perhaps you need to add code to handle that case without recursively calling Vout in that case, or perhaps calling Vout recursively is not what you intended.
  4 Comments
Steven Lord
Steven Lord on 18 Jul 2019
I used that phrase first; what I intended was "Determine how to compute volume_out in some way that avoids the recursive call."

Sign in to comment.


Walter Roberson
Walter Roberson on 18 Jul 2019
Your function is named Vout but inside it you have
volume_out=Vout(t(n))*DT;
Which involves the function you are defining as part of defining the function.
Most of the time, you should not invoke the function you are defining from inside the function.
Sometimes it is convenient to do so for backwards compatibility with argument sequences, which would be obvious in the code by a bunch of nargin or varargin checking.
There is also a valid mathematical use for deliberately defining a function in terms of itself. For example you can define factorial(n) sort of like n*factorial(n-1). This technique of deliberately breaking up the work and calling the function itself to do part of the problem is known as Recursion.
There are mathematical equivalences between recursion and looping, and there are computer languages such as Scheme that do some really interesting things with recursion. So using recursion deliberately is completely valid... But not common in procedural languages.
But here is the thing: in order to use recursion, the code needs to be aware that it is using recursion and it needs to be deliberately programmed with a stop condition: there has to be a test in the code that recognizes that a subproblem is small enough to be completely solved without having to call the function again. For example for factorial the code would need to know to stop upon reaching 0 or 1 (and possibly to error for negative or noninteger)
Thus I cannot at the moment tell you that it was definitely wrong for you to invoke Vout within Vout, as you might have been using recursion. However I can say that if you are using recursion then you forgot put in a stop condition, so your code would try to run forever.

Categories

Find more on Entering Commands in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!