[Tutor] recursion sort of

Jennifer Cianciolo jciancio@indiana.edu
Fri May 30 17:21:01 2003


> [My apologies for posting so much on this; it's an interesting
problem!]


that's ok with me!! :)

it's going to take me a while to decipher your suggestions, but I do
understand the problem you pointed out with time.  

If you don't mind my sticking with what I had before for another
moment, this is what I did before I got your message, because I
realized (duh) that I am not interested in nt (the TOTAL of n1 + n2)
I'm interested in the dynamics of n1 and n2 (we can imagine they're
two different clones), specifially what will make them oscillate
WITHIN the population (nt can stay constant all the time for all I
care)

this is the little change

def run(n1, n2):
     cycle = 1
     while 1:
         print n1  #change here
         print n2  #change here
         if n1>=800:
             w1=0.1
             nnew1=n1*2*w1
         elif n1<=799:
             w1=1.5
             nnew1=n1*2*w1
         if n2>=800:
             w2=0.3
             nnew2=n2*2*w2
         elif n2<=799:
             w2=1.1
             nnew2=n2*2*w2
         n1=int(n1*2*w1)    
         n2=int(n2*2*w2)  
         n1=n1+nnew1    #added (I think)
         n2=n2+nnew2    #added     
         cycle +=1   

if there are typos... believe it or not I'm manually copying these in.
 One computer with internet... one with python... 
don't ask.

but what this does is make n1 wave up and down and n2 wave up and down
(like a sin curve, but I don't want to make it happen by asking to
make a sin curve!)
It's terribly hard to copy and paste the output of this though to
graph in excel...


I'll see what I can figure out about your suggustions
thanks again!

Jen










> 
> I think the problem is one of assignment; the program is trying to
> simulate the advance of time in the simulation by doing
reassignments to
> the n1 and n2 variables.
> 
> The problem, though, is that this doesn't make it clean to simulate
both
> populations at the same time.  Nor is it trivially to go "back in
time"
> without saving previous results in some kind of list.
> 
> 
> 
> What the program ends up doing is something very serial --- it's
> simulating the first population up to a certain point in time, and
then
> simulating the second population up to another certain point in
time, and
> the main problem is that we simply don't know how much time has
passed.
> 
> 
> >def run(n1, n2):
> >     while n1>=501:
> >         w=1
> >         n1=n1*w
> >     while n1<=500:
> >         w=0.2
> >         n1=n1*W
> 
> 
> At this point, how do we know how many iterations of life our
population
> has gone through?
> 
> 
> >     while n2>=501:
> >         w=0.8
> >         n2=n2*w
> >     while n2<=500:
> >         w=0.4
> >         n2=n2*W
> 
> And the same question applies here.  There's no guarantee that the
> simulation of n2 goes through the same number of time steps as the
> simulation of the n1.
> 
> 
> 
> And that's what makes the next calculation meaningless:
> 
> >     nt=n2+n1
> >     print nt
> 
> Conceptually, I'm guessing that we'd like 'nt' to sum up those two
> populations, but without guaranteeing that n2 and n1 have run for
equal
> amounts of time, this won't give a useful answer.
> 
> 
> 
> 
> If we really want to do this simulation with loops and reassignment,
the
> iterating variable should probably be time, not population size:
> 
> ###
> def simulate(number_of_steps, p1_initial, p2_initial):
>     """Simulates 'number_of_steps' steps of two populations."""
>     p1, p2 = p1_inital, p2_initial
> 
>     for time in range(number_of_steps):
>         print "Time", time
>         print "Population 1:", p1
>         print "Population 2:", p2
> 
>         p1 = calculate_new_p1(p1)  ## This needs to be defined
somewhere.
>         p2 = calculate_new_p2(p2)  ## So does this.
> ###
> 
> The structure of this pseudocode is equivalent to Magnus's example.
> (It's also designed in a way that will make it difficult to make it
loop
> infinitely.  *grin*)
> 
> 
> 
> 
> 
> But an alternative approach is to model our population growth by
using
> functions.  For example:
> 
> 
> ###
> def f(time):
>     if time == 0:
>         return 0
>     return f(time-1) + 1
> ###
> 
> 
> is a function that's represents a linear growth, sorta like:
> 
>              /
>            /
>          /
>        /
>      /
> ---------------------> time
>      0 1 2 3 4
> 
> 
> 
> 
> Another one we can do is:
> 
> ###
> def g(time):
>     return 2 * math.sin(time / 3.0)
> ###
> 
> 
> which looks a little bit more bouncy:
> 
> 
>         ..        ..
>        .  .      .
>       .    .    .
>             .  .
>              ..
> 
> 
> What's nice about modeling populations with functions is that we can
> compose them together: we can make a new function that is a
combination of
> the two others:
> 
> 
> ###
> >>> import math
> >>> def f(time):
> ...     if time == 0:
> ...         return 0
> ...     return f(time-1) + 1
> ...
> >>> def g(time):
> ...     return 2 * math.sin(time / 3.0)
> ...
> >>> def compose_add(function1, function2):
> ...     def new_function(time):
> ...         return function1(time) + function2(time)
> ...     return new_function
> ...
> >>> fg = compose_add(f, g)
> ###
> 
> 
> 
> 'fg' is a function that represents the sum of the functions 'f' and
'g'.
> If we graph these together, we'll see that the behavior of fg is
sort of a
> blend between f and g, exhibiting both linear growth but with a
slight
> oscillating component.
> 
> 
> ###
> >>> for i in range(20):
> ...     print i, fg(i)
> ...
> 0 0.0
> 1 1.65438939359
> 2 3.23673960614
> 3 4.68294196962
> 4 5.94387580273
> 5 6.9908159155
> 6 7.81859485365
> 7 8.44617176348
> 8 8.91454525327
> 9 9.28224001612
> 10 9.61886407425
> 11 9.99744590282
> 12 10.4863950094
> 13 11.1419709975
> 14 12.0020901658
> 15 13.0821514507
> 16 14.3733412169
> 17 15.8436035165
> 18 17.4411690036
> 19 19.1002540198
> ###
> 
> 
> 
> And this is sorta neat, for 10 lines of code.  *grin* And it becomes
easy
> to use this to start adding other functions together:
> 
> ###
> >>> ff = compose_add(f, f)
> >>> ff(0)
> 0
> >>> ff(1)
> 2
> >>> ff(2)
> 4
> >>> ff(3)
> 6
> >>> ff(4)
> 8
> ###
> 
> 
> If you have any questions on this, please feel free to ask!
> 
> 
> _______________________________________________
> Tutor maillist  -  Tutor@python.org
> http://mail.python.org/mailman/listinfo/tutor
> 
> 
>