SOCR ≫ BPAD Website ≫ BPAD GitHub ≫

1 Exponential Models of Growth and Decay

Exponential functions are some of the most important and prevalent functions in biophysics, appearing most often when describing certain rates of growth and decay of living and chemical systems, but also in the functions governing certain probability distributions and mass transport across membranes, among others.

Mathematically: \[\underbrace{f(x)}_{value}=a\times b^x; \ \ \underbrace{a\in \mathbb{R}, b\in \mathbb{R}^+, b\not= 1}_{parameters}, \underbrace{x\in \mathbb{R}}_{argument}\]

But, how do we know if a process is exponential, or at least, can be approximated as one?

In general, an exponential growth process (\(b > 1\)) is a phenomena where the rate of increase of a quantity is proportional to the present value of that quantity (Hobbie & Roth, Intermediate Physics for Medicine and Biology, 2015). Conversely, an exponential decay process (\(0<b<1\)) is a phenomenon where the rate of decrease of a quantity is proportional to the present value of that quantity. Thus, it is intuitive that the dynamics of a population of sheep may be simulated by a combination of growth and decay exponential models: the present population of sheep at any point in time relies on a certain number of sheep at a previous time (and in the wild, a certain number of predators at a previous time as well).

The following applications/examples/simulations are illustrative of the different types of exponential growth/decay functions that are prevalent in biophysics.

1.1 Aside: Modeling

However, before venturing into exponential modeling, a quick aside about mathematical modeling in biology. Unlike those developed in many classical physics areas, biological models are not always developed purely from first-principles (i.e. Newton’s laws, the laws of thermodynamics). Although biologists obviously take care not to violate those laws, biological systems tend to have a level of complexity and diversity that is not always capturable in a simple equation: many aspects of biology are not even quantifiable using the instruments currently available. That being said, it is a skill honed by all scientists working in biology to be able to decide what level of simplification is necessary for the study of the phenomena in question. In many cases, different scientists are focusing on diverse aspects of a particular system, leading to diverse modeling strategies. Note how each of the following examples handles the simplification of systems as we proceed through this section: which aspects of the phenomena are the most important to capture? Which are not as important? What are the limitations of the model? In all cases, it is the underlying assumptions and priorities of the modeling scientist that leads to the final model.

1.2 Application: Simulation and SARS-CoV-2 (Coronavirus modeling)

One particularly prescient phenomenon that may be well-modeled by an exponential function is the infection rate of the novel coronavirus, SARS-CoV-2. To find out if it is a good model, we can generate a simulation of monthly data for coronavirus infections over a several month period and then compare it to real data.

However, in comparison to the real data (that UM provides here), the pure exponential model does not seem to be appropriate to represent coronavirus infections:

library(magrittr)
library(plotly)
# load UM data
# UM_covid_19_data <- 
#   read.csv('UM_COVID-19_March_2020_May_2021_Weekly_data.csv', header=T)
UM_covid_19_data <- 
  read.csv('https://umich.instructure.com/files/24236313/download?download_frd=1', header=T)

# include only the U-M testing data
UM_covid_19_data <- UM_covid_19_data[1:64,]

# order dates chronologically; as dates is in string format, 
UM_covid_19_data <- 
  UM_covid_19_data[
    order(as.Date(UM_covid_19_data$Day..Weekly.String, format = "%m/%d/%Y")), ]

# extract the dates (x) and weekly cases (y)
week_dates <- as.Date(UM_covid_19_data$Day..Weekly.String, format= "%m/%d/%Y")
data <- UM_covid_19_data$Dailypos...daily.total
time_index <- 0:length(week_dates)  # ???reverse data as times are in reversed order

# exponential model of the data
mod <- nls(data ~ exp(a + b * time_index), start = list(a = 0, b = 0))
exp_model_fit <- predict(mod, time_index)

# add fitted curve
coef(mod)
##          a          b 
## 4.21030064 0.01193809
a <- round(coef(mod)[1], 2)
b <- round(coef(mod)[2],2)
model_label <- sprintf("Exp Model: e^(%s + %s x)", a, b)

plot_ly(x = ~week_dates, y = ~data, mode = 'lines+markers', type="scatter",
        text = paste(week_dates, "days"), name = 'obs data') %>%
  add_trace(y = ~exp_model_fit[1:length(week_dates)], 
            name = model_label, mode = 'lines+markers', type="scatter") %>%
  layout(title = "Exponential Modeling of UM COVID-19 Data (Mar 2020 - May 2021)")

Or at least, it is not accurate over the time course of the pandemic given by the data:

# exponential model of PARTIAL data
L <- 9; U <- 28  # upper/lower limits
t1 <- time_index[L:U]
w1 <- week_dates[L:U]
w_ext<- week_dates[L:U+15]
d1 <- data[L:U]
d_ext <- data[L:U+15]
mod_reduced <- nls(d1 ~ exp(a + b * t1), start = list(a = 0, b = 0))

exp_modReduced_fit <- predict(mod_reduced, t1)

# Get the estimated parameters
a1 <- round(coef(mod_reduced)[1], 2)
b1 <- round(coef(mod_reduced)[2], 2)
modReduced_label <- sprintf("Red Exp Mod:\n e^(%s + %s x)", a1, b1)

# add fitted curve
plot_ly(x = ~w_ext, y = ~d_ext, mode = 'lines+markers', type="scatter",
        text = paste(w1, "days"), name = 'red obs data') %>%
    add_trace(x = ~w1, y = ~exp_modReduced_fit[1:length(w1)],
              name = modReduced_label, mode = 'lines+markers', type="scatter") %>%
    layout(title = "Exponential Modeling of UM COVID-19 Data\n (May 2020 - January 2021)")

That being said, if it closely matches a certain portion of the data, does that indicate usefulness? Take care to evaluate not only the goodness of fit of a model to the data, but other aspects including the number of data points, complexity of the model, and underlying assumptions. Clearly, it is important to look to public health experts when evaluating epidemiological data: it may not be as clear-cut as it may seem.

1.3 Application: Continuously compounded interest (growth) distribution spending (decay)

Suppose a savings account the interest rate is \(5\%\) and if the interest is credited to the account once a year (APR). Each year, the account balance increases in value by \(5\%\) of its present value. Starting out with \(\$100\), the end of the first year will add \(\$5\) credit to the account and the new balance will be \(\$ 105\). At the end of the second year, \(5\%\) of \(\$ 105\), i.e., \(\$ 5.25\) is credited to the account and the balance grows by to \(\$110.25\), etc. The annual interest compounding leads to an exponential chain-reaction (account balance increasing):

\[\underbrace{B_o=100}_{principal}; \ B_1=B_o\times (1.00+\underbrace{0.05}_{APR}); \ B_2=B_1\times (1.05)=B_o\times (1.05)^2; \\ B_3=B_2\times (1.05)=B_o\times (1.05)^3;\cdots ; B_n=B_o\times (1.05)^n . \]

Similarly, retirees that spend down their life savings by drawing \(10\%\) distribution annually and assuming the same \(5\%\) APR leads to a decay by \(5\%\) annually of the initial principal, \(\$1,000\).

library(plotly)
time_months <- 1:1200   # 12 months over 100 years
dataGrowth <- 100*(1.05)^(time_months %/% 12)
dataDecay <- 1000*(0.95)^(time_months %/% 12)
df <- data.frame(time_months, dataGrowth, dataDecay)

fig <- plot_ly(df, x = ~time_months)
fig <- fig %>% add_trace(y = ~dataGrowth, name = 'exp Growth model', 
                         mode = 'lines+markers', type="scatter")
fig <- fig %>% add_trace(y = ~dataDecay, name = 'exp Decay model', 
                         mode = 'lines+markers', type="scatter")
fig <- fig %>% layout(title = "Exponential Growth (income) & Decay (expenditure)",
                      scene = list(
                        xaxis = list(title = "Time (months)"), 
                        yaxis = list(title = "Account Values (measured quantity)") ))
fig