<jupyter_start><jupyter_text>Population modellingAs in the previous practical, many of the details and parameters from this lab come from the STELLA version at: http://www3.geosc.psu.edu/~dmb53/DaveSTELLA/Population/pop_modeling.htm  MAKE SURE TO EXECUTE THIS CELL BEFORE YOU START YOUR WORK!<jupyter_code>import numpy
import matplotlib.pyplot as pyplot
%matplotlib inline<jupyter_output><empty_output><jupyter_text>EXERCISE 1The code below is the `simple_population_model`, copied from the practical notebook. Make sure to run it in this notebook before you do anything else.<jupyter_code># Define a simple population model
def simple_population_model(Total_Time, birth_rate=0.15):
    
    # Variables
    #-----------
    # Total_Time - number of years to run the model
    # birth_rate - rate of new births per year
    # death_rate - rate of deaths per year
    death_rate=0.10
    
    # Set up time array: Use spacing based on time step (1 year) and total run time
    time = numpy.arange(0,Total_Time,step=1)
    
    # Set up population array to track change over time
    Population = numpy.zeros(len(time))
    
    # Set initial condition - Population = 100
    Population[0] = 100
    
    # Loop over time steps
    for i in range(1,len(time)):
        
        # Calculate the number of births that happened over the last year
        #   based on the population at the previous time [i-1]
        Births = birth_rate * Population[i-1]
        
        # Calculate the number of deaths that happened over the last year
        #   based on the population at the previous time [i-1]
        Deaths = death_rate * Population[i-1]
        
        # At each time [i], calculate the population now (at time = i) based on the population
        #   at the previous time [i-1] and how many births and deaths have occurred
        Population[i] = Population[i-1] + Births - Deaths
        
        # Makes sure the population is never less than zero
        if Population[i] < 0:
            Population[i] = 0
        
    return time,Population<jupyter_output><empty_output><jupyter_text>Using the `simple_population_model` from above, perform a sensitivity study using different values of birth rates:- birth rate = 15% (0.15)- birth rate = 10% (0.10)- birth rate = 5% (0.05)For each pair, plot the population (y-axis) as a function of time (x-axis) - all on one graph.**Hint**: You won't be able to see much with a linear plot, so try making a second version of the plot where you show the logarithm of the population (use numpy.log10(Population)) or where you use a logarithmic y-axis (use pyplot.yscale('log')).<jupyter_code># Set birth rate scenarios


# Loop over the birth rate values, run the model for 100 years, 
# and plot the results

    
# If you have extra time, also plot on a log scale.<jupyter_output><empty_output><jupyter_text>EXERCISE 2aAdapt the model from above (copied below **but with a new name**) to take into account the varying death rate characteristic of an S-shaped population model. (Look for the section labeled MISSING CODE.)**Hint**: Death rate will now be calculated **inside** your for loop, and it will need an if statement that checks what the Population was *one moment ago* (how do we represent that in python? `i`? `i-1`? `i+1?`).<jupyter_code># Define a new model that represents S-Shaped Population Growth
def s_shaped_population_model(Total_Time, birth_rate=0.15):
    
    # Variables
    #-----------
    # Total_Time - number of years to run the model
    # birth_rate - rate of new births per year
    # death_rate - rate of deaths per year
    
    # Set up time array: Use spacing based on time step (1 year) and total run time
    time = numpy.arange(0,Total_Time,step=1)
    
    # Set up population array to track change over time
    Population = numpy.zeros(len(time))
    
    # Set initial condition - Population = 100
    Population[0] = 100
    
    # Loop over time steps
    for i in range(1,len(time)):
        
        # Calculate the number of births that happened over the last year
        #   based on the population at the previous time [i-1]
        Births = birth_rate * Population[i-1]
        
        # What is the death rate now?
        # FILL IN MISSING CODE HERE
        
        # Calculate the number of deaths that happened over the last year
        #   based on the population at the previous time [i-1]
        Deaths = death_rate * Population[i-1]
        
        # At each time [i], calculate the population now (at time = i) based on the population
        #   at the previous time [i-1] and how many births and deaths have occurred
        Population[i] = Population[i-1] + Births - Deaths
        
        # Makes sure the population is never less than zero
        if Population[i] < 0:
            Population[i] = 0
        
    return time,Population<jupyter_output><empty_output><jupyter_text>EXERCISE 2bUse your updated model to perform a sensitivity test using the same birth rate scenarios as before (5%, 10%, 15%). Plot the population (y-axis) as a function of time (x-axis) - all on one graph. A linear scale is fine for this exercise. **Make sure you use the model called s_shaped_population_model, not simple_population_model from above.**<jupyter_code># Define array of birth rate values



# Calculate and plot results for different birth rates<jupyter_output><empty_output><jupyter_text>EXERCISE 2c- How is the system evolving *before* reaching steady state?- Why do you think the population reaches a stable level?- Can you make a guess about what the death rate might be at steady state? (Bonus: How could you test your guess?)<jupyter_code><jupyter_output><empty_output><jupyter_text>EXERCISE 3aWith these assumptions in place, we will adapt the model from Exercise 2 and **give it a new name**: `overshoot_population_model`.We will need to add a new reservoir for resources, and:1. Initialise it as an array full of zeros (**`numpy.zeros(...)`**)2. Set the intial condition (value in the first space, i.e. **`Resources[0]`**) - we will assume 5000.3. Add a new variable called **`resources_per_person`** that is calculated using `Resources` and `Population` every time we go around the loop.4. Use **`resources_per_person`** to calculate a new value for **`death_rate`** every time wego around the loop.5. Update the value in **`Resources[i]`** every time we go around the loop.6. Use an `if` statement to make sure the value of **`Resources` is never less than 0** (no negative resources)7. Add `Resources` to the list of variables that are **returned** by the function.Much of the necessary code is already in place below. Fill in the missing parts.<jupyter_code># Define a new model to represent the overshoot & collapse
def overshoot_population_model(Total_Time, birth_rate=0.15):
    
    # Variables
    #-----------
    # Total_Time - number of years to run the model
    # birth_rate - rate of new births per year
    # death_rate - rate of deaths per year
    
    # Set up time array: Use spacing based on elapsed_time and Total_Time
    time = numpy.arange(0,Total_Time,step=1)
    
    # Set up arrays to track change over time
    Population = numpy.zeros(len(time))
    
    # Set up Resources array to track change over time
    # FILL IN MISSING CODE (Hint: should look like Population code!)
    
    # Set initial condition - Population = 100
    Population[0] = 100

    # Set initial conditions - Resoures = 5000
    # FILL IN MISSING CODE (Hint: should look like Population code!)
    
    # Loop over time steps
    for i in range(1,len(time)):
        
        # Resources per person is the relationship between the two reservoirs
        # one moment ago (at i-1)
        resources_per_person = Resources[i-1]/Population[i-1]
        
        # death_rate now depends on the resources per person available
        # FILL IN MISSING CODE - we will need an if statement here!
        
        # Calculate the number of births that happened over the last year
        #   based on the population at the previous time [i-1]
        Births = birth_rate * Population[i-1]
        
        # Calculate the number of deaths that happened over the last year
        #   based on the population at the previous time [i-1]
        Deaths = death_rate * Population[i-1]
        
        # Population at time t is population the year before, plus the births, minus the deaths
        Population[i] = Population[i-1] + Births - Deaths
        
        # Population can't be less than zero!
        if Population[i] < 0:
            Population[i] = 0    

        # How many resources were used up? 1 resource for each person
        Resources_Used = 1.0 * Population[i-1]
        
        # Resources at time i is resources we had before minus the consumption
        # FILL IN MISSING CODE HERE (Hint: this should look like the population code, 
                                         # except we have no "Births" and
                                         # Resources_Used is just like "Deaths")
        
        # Resources can't be less than zero!
        # FILL IN MISSING CODE (Hint: should look like Population code!)
        
        
    return time,Population,Resources<jupyter_output><empty_output><jupyter_text>EXERCISE 3bAssuming a birth rate of 15%, run the updated model make three plots:1. Population (y-axis) as a function of time(x-axis).2. Resources (y-axis) as a function of time(x-axis).3. Population (y-axis) as a function of Resources (x-axis).<jupyter_code># run the model


# Plot the results<jupyter_output><empty_output><jupyter_text>EXERCISE 3c- How do population and resources change with time? How do they change with one another?- What is the peak value of the population, and when does it occur? (roughly, just read the approximate year off the graph)- Can you make a guess about when the death rate is higher than the birth rate, when it is equal, and when it is lower?If you want an exact answer for the second question, try using numpy.max() and numpy.argmax(). You can learn more about them in the purple section of the Week 3 practical.<jupyter_code><jupyter_output><empty_output><jupyter_text>EXERCISE 4aAdapt your model to include replenishing resources. We will do this by adding a new flux into the `Resources` reservoir, called `Resource_Inputs`.1. Copy your model from 3a here.2. Make `Resource_Inputs` an input (argument) to your function, with default value = 0.3. Updated the line starting `Resources[i] =`... to include `Resource_Inputs`.**Hint**: You can think of `Resources_Used` as being equivalent to `Deaths` and `Resource_Inputs` as equivalent to `Births`.<jupyter_code># Copy the model here and adapt as described above.<jupyter_output><empty_output><jupyter_text>EXERCISE 4bUse your adapted model to run a sensitivity test with resource inputs of 0 (the same as our previous model) and 50. Just like last time, make three plots (each showing resource inputs of 0 and 50 on the same plot):1. Population (y-axis) as a function of time(x-axis).2. Resources (y-axis) as a function of time(x-axis).2. Population (y-axis) as a function of Resources (x-axis).<jupyter_code># Run the model with 0 and 50 resource inputs per year


# Plot the results<jupyter_output><empty_output><jupyter_text>EXERCISE 4c- What is different between the two scenarios?- How does the maximum population and the year when it occurs change between these scenarios?  EXERCISE 5a**Recycling resources**This scenario explores what happens if resources are recyled. Just like in the previous exercise, this process adds to the available resources, but with the complication that the flux into Resources is a function of the flux out. In other words, the flux into resources should be a function of the resources used up at each time period.Adapt your model from Exercise 4 to include recycling of resources. Make the Recycling_Rate an argument (input) to the function.<jupyter_code><jupyter_output><empty_output><jupyter_text>EXERCISE 5bRun a sensitivity test with a recycling rate of 0 (same as in the previous exercises) and a recylcing rate of 25% (0.25). Make the same set of plots as in the previous exercises.<jupyter_code><jupyter_output><empty_output><jupyter_text>EXERCISE 5c- What is different between the two scenarios?- How does the maximum population and the year when it occurs change between these scenarios?<jupyter_code><jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07269946059093471, 'fraction_numerical': 0.013203445777312616, 'mean_word_length': 3.279021701687909, 'pattern_counts': {'":': 0, '<': 60, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '483070', 'license': 'MIT', 'n_tokens_mistral': 3612, 'n_tokens_neox': 3372, 'n_words': 1583, 'path': 'notebooks/Population_Exercises.ipynb', 'repo_name': 'jennyfisher/computing-modelling-earthsci', 'size': '12421'}