<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Table of Contents
<p><div class="lev1"><a href="#Understanding-Parameter-Fitting-by-Exploring-Viral-Load"><span class="toc-item-num">1 - </span>Understanding Parameter-Fitting by Exploring Viral Load</a></div><div class="lev2"><a href="#Student-names"><span class="toc-item-num">1.1 - </span>Student names</a></div><div class="lev2"><a href="#Learning-Goals-(Why-Are-We-Asking-You-To-Do-This?)"><span class="toc-item-num">1.2 - </span>Learning Goals (Why Are We Asking You To Do This?)</a></div><div class="lev2"><a href="#Understanding-How-We-Treat-the-Human-Immunodeficiency-Virus-(HIV)"><span class="toc-item-num">1.3 - </span>Understanding How We Treat the <a href="https
Step1:  Now, we'll tackle the "function in time" part of this model by learning how to make and use arrays to represent time.
Making intervals in time
Using numpy, we can conveniently make arrays that would represent slices in time. We'll use the np.linspace command, which takes three arguments (inputs)
Step2:  We can assign time intervals to variables
We can also try assigning that array to a variable, so we our later code can use it and refer back to it. Here, we'll
Step3:  Your Turn - 'Use np.linspace() to make a time interval for our model
Now that you've seen how to make evenly-spaced time intervals, we'll start creating an array of time slices for our viral load model. Create a single array called time that
Step4:  We can set and change parameter values to see how the model behaves
Remember how our model equation has four parameters $(A, \alpha, B, \beta )$? Below, you're going to use Python code to see what happens to the model when we try (and change) values for those parameters. Below, write  code that sets $B = 0$ and chooses non-zero values for the other three parameters.
Step5:  PREDICT BEFORE YOU PLOT
Here's that viral load equation again
Step6:  Explore the model by visualizing it
You should now have two arrays of the same length, time and viral load. In the Python cell below, verify that they're the same length (have the same number of values), then plot them.
Step7:  Explore the model by changing parameter values
Create a few more plots using different values of the four model parameters. For each new plot, 
Use a Python cell to change the model parameters however you'd like,
Re-evaluate the viral_load
Use a markdown cell to explain how the curve changed
Remember
Step8:  // Note each change you made and what you saw
Loading and Examining Experimental Data
What is this data?
We're going to use experimental data of actual viral loads provided by Kindler and Nelson (2015). They write
Step9:  You Can View a Pandas DataFrame by Executing It
Step10:  You can view the first/last few rows of data with .head() and .tail() functions
Step11:  Use data["column_name"] to View or Refer to a Column of Data
Step12:  Pandas DataFrame Columns Behave Like Numpy Arrays
Step13:  Plotting the Experimental Data
In a Python cell below, plot the viral load versus time from the hiv_data we loaded.
Step14:  Fitting Our Model To Experimental Data
Now that we've seen what the experimental data look like, we'll take our model one step further by putting the data and our model together on the same plot.
Plot the Data and Model Together
In the Python Cell below, create a plot that contains both the data and the model we were working with earlier. So, we'll superimpose the datapoints on a plot of $V(t) = A e^{(-\alpha t)} + B e^{(-\beta t)}$. You may need to adjust the model parameters until you can see both the data and model in your plot.
Step15:  THINK about Tuning the Model Parameters to Fit the Model to Data
The goal will be to tune the four parameters of $V(t) = A e^{(-\alpha t)} + B e^{(-\beta t)}$ until the model agrees with the data. It is hard to find the right needle in a four-dimensional haystack! We need a more systematic approach than just guessing. Consider and try to answer each of the following in a Markdown cell below
Step16:  Please Give Feedback on this assignment
<ASSISTANT_TASK:>
Python Code:
# Make plots inline
%matplotlib inline
# Make inline plots vector graphics instead of raster graphics
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('pdf', 'svg')
# import modules for plotting and data analysis
import matplotlib.pyplot as plt
import numpy as np
import pandas
Explanation: Table of Contents
<p><div class="lev1"><a href="#Understanding-Parameter-Fitting-by-Exploring-Viral-Load"><span class="toc-item-num">1 - </span>Understanding Parameter-Fitting by Exploring Viral Load</a></div><div class="lev2"><a href="#Student-names"><span class="toc-item-num">1.1 - </span>Student names</a></div><div class="lev2"><a href="#Learning-Goals-(Why-Are-We-Asking-You-To-Do-This?)"><span class="toc-item-num">1.2 - </span>Learning Goals (Why Are We Asking You To Do This?)</a></div><div class="lev2"><a href="#Understanding-How-We-Treat-the-Human-Immunodeficiency-Virus-(HIV)"><span class="toc-item-num">1.3 - </span>Understanding How We Treat the <a href="https://www.aids.gov/hiv-aids-basics/hiv-aids-101/what-is-hiv-aids/" target="_blank">Human Immunodeficiency Virus (HIV)</a></a></div><div class="lev2"><a href="#Setting-options-and-loading-modules"><span class="toc-item-num">1.4 - </span>Setting options and loading modules</a></div><div class="lev2"><a href="#Making-intervals-in-time"><span class="toc-item-num">1.5 - </span>Making intervals in time</a></div><div class="lev3"><a href="#We-can-use-np.linspace-to-make-time-intervals"><span class="toc-item-num">1.5.1 - </span>We can use <code>np.linspace</code> to make time intervals</a></div><div class="lev3"><a href="#We-can-assign-time-intervals-to-variables"><span class="toc-item-num">1.5.2 - </span>We can assign time intervals to variables</a></div><div class="lev3"><a href="#Your-Turn---'Use-np.linspace()-to-make-a-time-interval-for-our-model"><span class="toc-item-num">1.5.3 - </span>Your Turn - 'Use <code>np.linspace()</code> to make a time interval for our model</a></div><div class="lev2"><a href="#We-can-set-and-change-parameter-values-to-see-how-the-model-behaves"><span class="toc-item-num">1.6 - </span>We can set and change parameter values to see how the model behaves</a></div><div class="lev3"><a href="#PREDICT-BEFORE-YOU-PLOT"><span class="toc-item-num">1.6.1 - </span>PREDICT BEFORE YOU PLOT</a></div><div class="lev4"><a href="#Your-Prediction"><span class="toc-item-num">1.6.1.1 - </span>Your Prediction</a></div><div class="lev2"><a href="#Explore-the-model"><span class="toc-item-num">1.7 - </span>Explore the model</a></div><div class="lev3"><a href="#Explore-the-model-by-evaluating-the-equation"><span class="toc-item-num">1.7.1 - </span>Explore the model by evaluating the equation</a></div><div class="lev3"><a href="#Explore-the-model-by-visualizing-it"><span class="toc-item-num">1.7.2 - </span>Explore the model by visualizing it</a></div><div class="lev3"><a href="#Explore-the-model-by-changing-parameter-values"><span class="toc-item-num">1.7.3 - </span>Explore the model by changing parameter values</a></div><div class="lev2"><a href="#Loading-and-Examining-Experimental-Data"><span class="toc-item-num">1.8 - </span>Loading and Examining Experimental Data</a></div><div class="lev3"><a href="#What-is-this-data?"><span class="toc-item-num">1.8.1 - </span>What is this data?</a></div><div class="lev3"><a href="#Use-pandas.read_csv()-to-Load-the-Data"><span class="toc-item-num">1.8.2 - </span>Use <code>pandas.read_csv()</code> to Load the Data</a></div><div class="lev3"><a href="#You-Can-View-a-Pandas-DataFrame-by-Executing-It"><span class="toc-item-num">1.8.3 - </span>You Can View a Pandas DataFrame by Executing It</a></div><div class="lev3"><a href="#You-can-view-the-first/last-few-rows-of-data-with-.head()-and-.tail()-functions"><span class="toc-item-num">1.8.4 - </span>You can view the first/last few rows of data with <code>.head()</code> and <code>.tail()</code> functions</a></div><div class="lev3"><a href="#Use-data[&quot;column_name&quot;]-to-View-or-Refer-to-a-Column-of-Data"><span class="toc-item-num">1.8.5 - </span>Use <code>data["column_name"]</code> to View or Refer to a Column of Data</a></div><div class="lev3"><a href="#Pandas-DataFrame-Columns-Behave-Like-Numpy-Arrays"><span class="toc-item-num">1.8.6 - </span>Pandas DataFrame Columns Behave Like Numpy Arrays</a></div><div class="lev3"><a href="#Plotting-the-Experimental-Data"><span class="toc-item-num">1.8.7 - </span>Plotting the Experimental Data</a></div><div class="lev2"><a href="#Fitting-Our-Model-To-Experimental-Data"><span class="toc-item-num">1.9 - </span>Fitting Our Model To Experimental Data</a></div><div class="lev3"><a href="#Plot-the-Data-and-Model-Together"><span class="toc-item-num">1.9.1 - </span>Plot the Data and Model Together</a></div><div class="lev3"><a href="#THINK-about-Tuning-the-Model-Parameters-to-Fit-the-Model-to-Data"><span class="toc-item-num">1.9.2 - </span>THINK about Tuning the Model Parameters to Fit the Model to Data</a></div><div class="lev3"><a href="#Make-and-Plot-Multiple-Models-to-Find-Model-Parameters-that-Best-Fit-the-Model-to-the-Data"><span class="toc-item-num">1.9.3 - </span>Make and Plot Multiple Models to Find Model Parameters that Best Fit the Model to the Data</a></div><div class="lev2"><a href="#Please-Give-Feedback-on-this-assignment"><span class="toc-item-num">1.10 - </span>Please <a href="http://goo.gl/forms/v8oZUSLDaa" target="_blank">Give Feedback</a> on this assignment</a></div><div class="lev2"><a href="#How-to-submit-this-assignment"><span class="toc-item-num">1.11 - </span>How to submit this assignment</a></div><div class="lev2"><a href="#Source"><span class="toc-item-num">1.12 - </span>Source</a></div>
# Understanding Parameter-Fitting by Exploring Viral Load
## Student names
Work in pairs, and put the names of both people in your group here!  (If you're in a group of 3, just move your chairs so you can work together.)
## Learning Goals (Why Are We Asking You To Do This?)
- To develop an intuition about how equation-based models work
- To understand how to evaluate models by plotting them together with experimental data
- To practice predicting what the effect will be when we change the parameters of a model
- To learn how we can iterate to improve the fit of a model
## Understanding How We Treat the [Human Immunodeficiency Virus (HIV)](https://www.aids.gov/hiv-aids-basics/hiv-aids-101/what-is-hiv-aids/)
Here we explore a model of the **viral load**—the number of virions in the blood of a patient infected with [HIV](https://www.aids.gov/hiv-aids-basics/hiv-aids-101/what-is-hiv-aids/)—after the administration of an antiretroviral drug. One model for the viral load predicts that the concentration $V (t)$ of HIV in the blood at time t after the start of treatment will be:
$$ \begin{equation} V(t) = A \cdot \mathrm{exp}(-\alpha t) + B \cdot \mathrm{exp}(-\beta t) \end{equation}$$ 
When we write mathematics, $\mathrm{exp}(\dots)$ is notational shorthand for $e^{(\dots)}$. So, we can rewrite the viral load model this way:
$$  
\begin{equation}
V(t) = A e^{(-\alpha t)} + B e^{(-\beta t)}  
\end{equation}
$$
Two things to note about this particular model: 
1. Viral load **is a function of time $t$**. That's why we're writing it as $V(t) = \dots$. 
2. There are four modeling parameters (numbers) we can vary: $(A, \alpha, B, \beta )$.:
$$  
\begin{equation}
V(t) = \textbf{A} e^{(-\boldsymbol{\alpha} t)} + \textbf{B} e^{(- \boldsymbol{\beta} t)}  
\end{equation}
$$
**Note**: 
> You probably know that there are black-box software packages that do such “curve fitting” automatically. In this lab, you should do it manually, just to see how the curves respond to changes in the parameters.]
> 
> Kinder, Jesse M.; Nelson, Philip (2015-07-01). A Student's Guide to Python for Physical Modeling (Page 63). Princeton University Press. Kindle Edition. 
Doing it manually also helps build our intuition for how mathematical models behave when we visualize them.
Let's get started by setting some options and loading the modules we'll need.
## Setting options and loading modules
End of explanation
import numpy as np
np.linspace(
    0,  # where the interval starts
    1,  # where the interval ends
    11  # How many steps (elements) we want in the final array    
)
Explanation: Now, we'll tackle the "function in time" part of this model by learning how to make and use arrays to represent time.
Making intervals in time
Using numpy, we can conveniently make arrays that would represent slices in time. We'll use the np.linspace command, which takes three arguments (inputs):
Where you want the interval to start
Where you want the interval to end
How many steps there should be in the interval
We can use np.linspace to make time intervals
End of explanation
import numpy as np
# Make our array and assign it to `time`
trying_to_make_a_time_interval = np.linspace(
    0,  # where the interval starts
    1,  # where the interval ends
    11  # How many steps (elements) we want in the final array    
)
# Check that there are 11 elements in our array (which we asked for)
trying_to_make_a_time_interval.size
Explanation: We can assign time intervals to variables
We can also try assigning that array to a variable, so we our later code can use it and refer back to it. Here, we'll:
Make the same interval as before (0 to 1),
With eleven steps,
Assign it to a variable we'll call trying_to_make_a_time_interval (it helps when our names are descriptive)
Check how many items are in the array we made. (It should be 11).
End of explanation
# Create your time array here
time = np.linspace(0, 10, 101)
Explanation: Your Turn - 'Use np.linspace() to make a time interval for our model
Now that you've seen how to make evenly-spaced time intervals, we'll start creating an array of time slices for our viral load model. Create a single array called time that:
Starts at 0,
Goes to 10, and
Has 101 elements in it
End of explanation
# Make B equal to zero and set some non-zero values for the other parameters
A = 3
B = 0 
alpha = 2
beta = 5
Explanation: We can set and change parameter values to see how the model behaves
Remember how our model equation has four parameters $(A, \alpha, B, \beta )$? Below, you're going to use Python code to see what happens to the model when we try (and change) values for those parameters. Below, write  code that sets $B = 0$ and chooses non-zero values for the other three parameters.
End of explanation
# Write and evaluate viral_load = ...
viral_load = (A * np.exp(-alpha * time)) + (B * np.exp(-beta * time))
Explanation: PREDICT BEFORE YOU PLOT
Here's that viral load equation again:
$$
\begin{equation}
V(t) = \textbf{A} e^{(-\boldsymbol{\alpha} t)} + \textbf{B} e^{(- \boldsymbol{\beta} t)}
\end{equation}
$$
Just like the order-of-magnitude approximations we've been doing, thinking before we plot and evaluate helps us develop our intution about models. In your code above, you've set $B = 0$. Use the markdown cell below to predict (in words) how you think setting $B = 0$ affects the equation (and by extension, the model).
How will the equation change?
Setting $B = 0$ drops out the second term, which means the viral load is wholly determined by the first term
How does setting $B = 0$ affect the other model parameters (if at all)
With $B = 0$, the value of $Beta$ is inconsequential because its term ultimately gets multiplied by zero.
Your Prediction
When we set B = 0, we think what will happen is...
Explore the model
Explore the model by evaluating the equation
We can write the viral load function (from above) in Python, using the parameters we set above and our time array. In the cell below, write viral_load as a function of time.
Note: We can write exponentation in numpy using np.exp(). So,
$$ 
\begin{equation}
e^{(\dots)} = \tt{np.exp(\dots)}
\end{equation}
$$
End of explanation
# Verify that both arrays are the same length. 
# You can use .size, as in time.size or viral_load.size
# Then, try plotting viral_load vs. time
# Make plots inline
%matplotlib inline
# Make inline plots vector graphics instead of raster graphics
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('pdf', 'svg')
import matplotlib.pyplot as plt
# Put your plot code here
plt.plot(viral_load, time)
plt.yscale('log')
Explanation: Explore the model by visualizing it
You should now have two arrays of the same length, time and viral load. In the Python cell below, verify that they're the same length (have the same number of values), then plot them.
End of explanation
# Change the values and make a new plot
A = 10
B = -0.5
alpha = 1
beta = 1
viral_load = (A * np.exp(-alpha * time)) + (B * np.exp(-beta * time))
plt.plot(time, viral_load)
Explanation: Explore the model by changing parameter values
Create a few more plots using different values of the four model parameters. For each new plot, 
Use a Python cell to change the model parameters however you'd like,
Re-evaluate the viral_load
Use a markdown cell to explain how the curve changed
Remember: You can try negative (and non-integer) values for parameters
End of explanation
# Loading the data
hiv_data = pandas.read_csv(
    "https://raw.githubusercontent.com/ComputationalModeling/IPML-Data/master/01HIVseries/HIVseries.csv",
    header = None,
    names = ["time_in_days", "viral_load"]
)
# the data type of hiv_data is "dataframe"
type(hiv_data)
Explanation: // Note each change you made and what you saw
Loading and Examining Experimental Data
What is this data?
We're going to use experimental data of actual viral loads provided by Kindler and Nelson (2015). They write:
File HIVseries.mat contains variable "a" with two columns of data.  The first is the time in days since administration of a treatment to an HIV positive patient; the second contains the concentration of virus in that patient's blood, in arbitrary units.
HIVseries.csv and HIVseries.npy contain the same data in the same format. HIVseries.npz contains the same data in two separate arrays called time_in_days and viral_load.
Data from A. Perelson. Modelling viral and immune system dynamics. Nature Revs. Immunol. (2002) vol. 2 (1) pp. 28--36 (Box 1).
So, to summarize, the dataset hiv_data has 2 columns:
time_in_days is the number of days since an HIV-positive patient received a treatment.
viral_load is the concentraiton of the virus in that patients blood, in arbitrary units.
Use pandas.read_csv() to Load the Data
The data file we'll use is in a file format called CSV, which stands for comma-separated values. It's a commonly used format for storing 2-dimensional data, and programs like Microsoft Excel can import and export .CSV files.
The code below will use the read_csv() function from the pandas data analysis library to load the CSV file you need from the web, then store the data as a variable called hiv_data.
End of explanation
# Execute this cell (Shift + Enter) to see the data
hiv_data
Explanation: You Can View a Pandas DataFrame by Executing It
End of explanation
# If you have a pandas dataframe, you can call `head()` on it like this:
hiv_data.head()
# To see the last few rows, call `tail()` on it
hiv_data.tail()
Explanation: You can view the first/last few rows of data with .head() and .tail() functions
End of explanation
# How to view an individual column
hiv_data["time_in_days"] # or
hiv_data["viral_load"]
Explanation: Use data["column_name"] to View or Refer to a Column of Data
End of explanation
# Here's the viral load column again
hiv_data["viral_load"]
# And we can calulate its mean, max, size, and other properties
# Just like we would on a numpy array
hiv_data["viral_load"].mean()
hiv_data["viral_load"].max()
hiv_data["viral_load"].size
Explanation: Pandas DataFrame Columns Behave Like Numpy Arrays
End of explanation
# Plot viral load vs. time
plt.plot(hiv_data["time_in_days"],hiv_data["viral_load"],'ro')
plt.yscale('log')
# note that there's some very interesting double-exponential behavior here!
Explanation: Plotting the Experimental Data
In a Python cell below, plot the viral load versus time from the hiv_data we loaded.
End of explanation
# Plot the data and model together
A = 95000
B = 150000
alpha = 0.3
beta = 2.0
viral_load = (A * np.exp(-alpha * time)) + (B * np.exp(-beta * time))
plt.plot(
    time, viral_load, "r",
    hiv_data['time_in_days'], hiv_data['viral_load'], "b."
)
#plt.plot(
#    hiv_data['time_in_days'], hiv_data['viral_load'], "b."
#)
#plt.yscale('log')  # much less clear what's going on here
Explanation: Fitting Our Model To Experimental Data
Now that we've seen what the experimental data look like, we'll take our model one step further by putting the data and our model together on the same plot.
Plot the Data and Model Together
In the Python Cell below, create a plot that contains both the data and the model we were working with earlier. So, we'll superimpose the datapoints on a plot of $V(t) = A e^{(-\alpha t)} + B e^{(-\beta t)}$. You may need to adjust the model parameters until you can see both the data and model in your plot.
End of explanation
# Do whatever work you need here to determine
#   the parameter values you think work best.
# REMEMBER: You can assign each new model to a new variable,
#   like `model_01`, `model_02`, ...
# fiddle with parameters
A = 10
B = 160000 - A
alpha = .002
beta = 10
time1 = np.linspace(0, 2, 100)
slope1 = -np.log((106100 - 66435) / 2)
y_int1 = np.log(106100)
line1 = (slope1 * time1) + y_int1
slope2 = -np.log((75906 / 5))
y_int2 = np.log(4785.2)
line2 = slope2 * (time - 7) + y_int2
log_model = np.log((A * np.exp(-alpha * time)) + (B * np.exp(-beta * time)))
log_hiv_data = np.log(hiv_data["viral_load"])
plt.plot(
    hiv_data['time_in_days'], np.log(hiv_data['viral_load']), 'bo',
#     ,time, line2, 'g'
    time1, line1, 'r'
)
line1[0]
hiv_data['viral_load'].where(hiv_data['viral_load'] < 60000)
Explanation: THINK about Tuning the Model Parameters to Fit the Model to Data
The goal will be to tune the four parameters of $V(t) = A e^{(-\alpha t)} + B e^{(-\beta t)}$ until the model agrees with the data. It is hard to find the right needle in a four-dimensional haystack! We need a more systematic approach than just guessing. Consider and try to answer each of the following in a Markdown cell below:
Assuming $\beta > \alpha$, how does the trial solution behave at long times? 
If the data also behave that way, can we use the long-time behavior to determine two of the four unknown constants, then hold them fixed while adjusting the other two? 
Even two constants is a lot to adjust by hand, so let’s think some more: How does the initial value $V(0)$ depend on the four constant parameters? 
Can you vary these constants in a way that always gives the correct long-time behavior and initial value? (Kinder and Nelson, 2015, p. 62)
// Answer the questions here
Make and Plot Multiple Models to Find Model Parameters that Best Fit the Model to the Data
Kinder and Nelson (2015) recommend that you:
Carry out this analysis so that you have only one remaining free parameter, which you can adjust fairly easily. Adjust this parameter until you like what you see.
We suggest you try and save different models by assigning those models to named variables. For example, you might try:
```python
Parameters for Model 1
A = 1
B = 3
Evaluate model 1
model_01 = (A * np.exp(alpha * time)) + (B * np.exp(beta * time))
Plot model 1
plt.plot(time, model_01)
Trying new parameter values for Model 2
A = 3
B = -5
alpha = 0.5
Evaluate model 2
model_02 = (A * np.exp(alpha * time)) + (B * np.exp(beta * time))
Plot model 2
plt.plot(time, viral_load)
and so on until you find values you like
```
Use one or more Python cells below to create multiple models and decide on good parameter values.
End of explanation
from IPython.display import IFrame
IFrame('http://goo.gl/forms/v8oZUSLDaa', width=800, height=1200)
Explanation: Please Give Feedback on this assignment
End of explanation
<END_TASK>