8  Parameters

The variety of shapes of the nine pattern-book functions means that, often, one or another will be suitable for the modeling situation in hand.

Combining the functions to create a greater diversity of shapes is the subject of Chapter Section 9.

Even if the shape of the function used is appropriate, the pattern still needs to be “adjusted” so that the units of output and input are well matched to the phenomenon being modeled. Let’s consider data from the outbreak of COVID-19 as an example. Figure 8.1 shows, day-by-day, the number of officially confirmed COVID-19 cases as the in the US in March 2020.

During the outbreak, case numbers increased with time. As time went on, the rate of case-number increase itself grew faster and faster. This is the same pattern provided by the exponential function.

Alongside the case-number data Figure 8.1 shows the function \(\text{cases}(t) \equiv e^t\) plotted as a \(\color{magenta}{\text{magenta}}\) curve.

There is an obvious mismatch between the data and the function \(e^t\). Does this mean the COVID pattern is not exponential?

This chapter will introduce how modelers stretch and shift the individual patter-book functions so that they can be used in models of real-world situations such as the outbreak of COVID-19.

8.1 Matching numbers to quantities

The coordinate axes in Figure 8.1 represent quantities. On the horizontal axis is time, measured in days. The vertical axis is denominated in “10000 cases,” meaning that the numbers on the vertical scale should be multiplied by 10000 to get the number of cases.

The exponential function takes as input a pure number and produces an output that is also a pure number. This is true for all the pattern-book functions. Since the graph axes don’t show pure numbers, it is no surprise then that the pattern-book exponential function doesn’t align with the COVID case data.

Recall that pure numbers, like 17.32, do not have units. Quantities, on the other hand, usually do have units, as in 17.3 days or 34 meters.

If we want the input to the model function \(\text{cases}(t)\) to be denominated in days, we will have to convert \(t\) to a pure pure number (e.g. 10, not “10 days”) before the quantity is handed off as the argument to \(\exp()\). We do this by introducing a parameter.

In every case, these parameters are arranged to translate a with-units quantity into a pure number suitable as an input to the pattern-book function. Similarly, parameters will translate the pure-number output from the pattern-book function into a quantity with units.

The standard parameterization for the exponential function is \(e^{kt}\). The parameter \(k\) will be a quantity with units of “per-day.” Suppose we set \(k=0.2\) per day. Then \(k\, t{\LARGE\left.\right|}_{t=10 days} = 2\). This “2” is a pure number because the units on the 0.2 (“per day”) and on the 10 (days) cancel out: \[0.2\, \text{day}^{-1} \cdot 10\, \text{days} = 2\ .\] The use of a parameter like \(k\) does more than handle the formality of converting input quantities into pure numbers. Having a choice for \(k\) allows us to stretch or compress the function to align with the data. Figure 8.2 plots the modeling version of the exponential function to the COVID-case data:

8.2 Parallel scales

At the heart of how we use the pattern-book functions to model the relationship between quantities is the idea of conversion between one scale and another. Consider these everyday objects: a thermometer and a ruler.

Each object presents a read-out of what’s being measured—temperature or length—on two different scales. At the same time, the objects provide a way to convert one scale to another.

A function gives the output for any given input. We represent the input value as a position on a number line—which we call an “axis”—and the output as a position on another output line, almost always drawn perpendicular to one another. But the two number lines can just as well be parallel to one another. To evaluate the function, find the input value on the input scale and read off the corresponding output.

We can translate the correspondance between one scale and the other into the form of a straight-line function. For instance, if we know the temperature in Fahrenheit (\(^\circ\)F) and want to convert it to Celsius (\(^\circ C\)) we have the following function: \[C(F) \equiv {\small\frac{5}{9}}(F-32)\ .\] Similarly, converting inches to centimeters can be accomplished with \[\text{cm(inches)} \equiv 2.54 \, (\text{inches}-0)\ .\] Both of these scale conversion functions have the form of the straight-line function, which can be written as \[f(x) \equiv a x + b\ \ \ \text{or, equivalently as}\ \ \ \ f(x) \equiv a(x-x_0)\ ,\] where \(a\), \(b\), and \(x_0\) are parameters.

In Section Section 8.3, we will use the \(ax + b\) form of scale conversion, to scale the input to pattern-book functions, but we could equally well have used \(a(x-x_0)\).

In Section Section 8.4 we will introduce a second scale conversion function, for the output from pattern-book functions. That scaling will also be in the form of a straight-line function: \(A x + B\). The use of the lower-case parameter names (\(a\), \(b\)) versus the upper-case parameter names (\(A\), \(B\)) will help us distinguish the two different uses for scale conversion, namely input scaling versus output scaling.

8.3 Input scaling

Figure 8.3 is based on the data frame RI-tide which is a minute-by-minute record of the tide level in Providence, Rhode Island (USA) for the period April 1 to 5, 2010. The level variable is measured in meters; the hour variable gives the time of the measurement in hours after midnight at the start of April 1.

The pattern-book \(\sin()\) and the function \(\color{magenta}{\text{level}}\color{blue}{(hour)}\) have similar shapes, so it seems reasonable to model the tide data as a sinusoid. However, the scale of the axes is different on the two graphs.

To model the tide with a sinusoid, we need to modify the sinusoid to change the scale of the input and output. First, let’s look at how to accomplish the input scaling. Specifically, we want the pure-number input \(t\) to the sinusoid be a function of the quantity \(hour\). Our framework for this re-scaling is the straight-line function. We will replace the pattern-book input \(t\) with a function \[t(\color{blue}{hour}) \equiv a\, \color{blue}{hour} + b\ .\]

The challenge is to find values for the parameters \(a\) and \(b\) that will transform the \(\color{blue}{\mathbf{\text{blue}}}\) horizontal axis into the black horizontal axis, like this:

By comparing the two axes, we can estimate that \(\color{blue}{10} \rightarrow 4\) and \(\color{blue}{100} \rightarrow 49\). With these two coordinate points, we can find the straight-line function that turns \(\color{blue}{\mathbf{\text{blue}}}\) into black by plotting the coordinate pairs \((\color{blue}{0},1)\) and \((\color{blue}{100}, 51)\) and finding the straight-line function that connects the points.

You can calculate for yourself that the function that relates \(\color{blue}{\mathbf{\text{blue}}}\) to black is \[t(\color{blue}{time}) = \underbrace{\frac{1}{2}}_a \color{blue}{time} \underbrace{-1\LARGE\strut}_b\]

Replacing the pure number \(t\) as the input to pattern-book \(\sin(t)\) with the transformed \(\frac{1}{2} \color{blue}{time}\) we get a new function: \[g(\color{blue}{time}) \equiv \sin\left(\strut {\small\frac{1}{2}}\color{blue}{time} - 1\right)\ .\] Figure 11.6 plots \(g()\) along with the actual tide data.

8.4 Output scaling

Just as the natural input needs to be scaled before it reaches the pattern-book function, so the output from the pattern-book function needs to be scaled before it presents a result suited for interpreting in the real world.

The overall result of input and output scaling is to tailor the pattern-book function so that it is ready to be used in the real world.

Let’s return to Figure 11.6 which shows that the function \(g(\color{blue}{time})\), which scales the input to the pattern-book sinusoid, has a much better alignment to the tide data. Still, the vertical axes of the two graphs in the figure are not the same.

This is the job for output scaling, which takes the output of \(g(\color{blue}{time})\) (bottom graph) and scales it to match the \(\color{magenta}{level}\) axis on the top graph. That is, we seek to align the black vertical scale with the \(\color{magenta}{\mathbf{\text{magenta}}}\) vertical scale. To do this, we note that the range of the \(g(\color{blue}{time})\) is -1 to 1, whereas the range of the tide-level is about 0.5 to 1.5. The output scaling will take the straight-line form \[{\color{magenta}{\text{level}}}({\color{blue}{time}}) = A\, g({\color{blue}{time}}) + B\] or, in graphical terms

We can figure out parameters \(A\) and \(B\) by finding the straight-line function that connects the coordinate pairs \((-1, \color{magenta}{0.5})\) and \((1, \color{magenta}{1.5})\) as in Figure 8.7.

You can confirm for yourself that the function that does the job is \[{\color{magenta}{\text{level}}} = 0.5 g({\color{blue}{time}}) + 1\ .\]

Putting everything together, that is, scaling both the input to pattern-book \(\sin()\) and the output from pattern-book \(\sin()\), we get

\[{\color{magenta}{\text{level}}}({\color{blue}{time}}) = \underbrace{0.5}_A \sin\left(\underbrace{\small\frac{1}{2}}_a {\color{blue}{time}} \underbrace{-1}_b\right) + \underbrace{1}_B\]

8.5 A procedure for building models

We’ve been using pattern-book functions as the intermediaries between input scaling and output scaling, using this format.

\[f(x) \equiv A e^{ax + b} + B\ .\] We can use the other pattern-book functions—the gaussian, the sigmoid, the logarithm, the power-law functions—in the same way. That is, the basic framework for modeling is this:

\[\text{model}(x) \equiv A\, {g_{pattern\_book}}(ax + b) + B\ ,\] where \(g_{pattern\_book}()\) is one of the pattern-book functions. To construct a basic model, you task has two parts:

  1. Pick the specific pattern-book function whose shape resembles that of the relationship you are trying to model. For instance, we picked \(e^x\) for modeling COVID cases versus time (at the start of the pandemic). We picked \(\sin(x)\) for modeling tide levels versus time.

  2. Find numerical values for the parameters \(A\), \(B\), \(a\), and \(b\). In Chapter ?chap-fitting-by-eye we will show you some ways to make this part of the task easier.

It is remarkable that models of a very wide range of real-world relationships between pairs of quantities can be constructed by picking one of a handful of functions, then scaling the input and the output. As we move on to other Blocks in MOSAIC Calculus, you will see how to generalize this to potentially complicated relationships among more than two quantities. That is a big part of the reason you’re studying calculus.

8.6 Other formats for scaling

Often, modelers choose to use input scaling in the form \(a (x - x_0)\) rather than \(a x + b\). The two are completely equivalent when \(x_0 = - b/a\). The choice between the two forms is largely a matter of convention. But almost always the output scaling is written in the format \(A y + B\).

For the COVID case-number data shown in Figure 8.2, we found that a reasonable match to the data can be had by input- and output-scaling the exponential: \[\text{cases}(t) \equiv \underbrace{573}_A e^{\underbrace{0.19}_a\ t}\ .\]

You might wonder why the parameters \(B\) and \(b\) aren’t included in the model. One reason is that cases and the exponential function already have the same range: zero and upwards. So there is no need to shift the output with a parameter B.

Another reason has to do with the algebraic properties of the exponential function. Specifically, \[e^{a x + b}= e^b e^{ax} = {\cal A} e^{ax}\] where \({\cal A} \equiv e^b\).

In the case of exponentials, writing the input scaling in the form \(e^{a(x-x_0)}\) can provide additional insight.

A bit of symbolic manipulation of the model can provide some additional insight. As you know, the properties of exponentials and logarithms are such that \[A e^{at} = e^{\log(A)} e^{at} = e^{a t + \log(A)} = e^{a\left(\strut t + \log(A)/a\right)} = e^{a(t-t_0)}\ ,\] where \[t_0 = - \log(A)/a = - \log(593)/0.19 = -33.6\ .\] You can interpret \(t_0\) as the starting point of the pandemic. When \(t = t_0\), the model output is \(e^{k 0} = 1\): the first case. According to the parameters we matched to the data for March, the pandemic’s first case would have happened about 33 days before March 1, which is late January. We know from other sources of information, the outbreak began in late January. It is remarkable that even though the curve was constructed without any data from January or even February, the data from March, translated through the curve-fitting process, pointed to the start of the outbreak. This is a good indication that the exponential form for the model is fundamentally correct.

8.7 Parameterization conventions

There are conventions for the symbols used for input-scaling parameterization of the pattern-book functions. Knowing these conventions makes it easier to read and assimilate mathematical formulas. In several cases, there is more than one conventional option. For instance, the sinusoid has a variety of parameterization forms that get used depending on which feature of the function is easiest to measure. ?tbl-param that are used in practice.

Some standard forms of input scaling parameterizations

Function Written form Parameter 1 Parameter 2
Exponential \(e^{kt}\) \(k\) Not used
Exponential \(e^{t/\tau}\) \(\tau\) “time constant” Not used
Exponential \(2^{t/\tau_2}\) \(\tau_2\) “doubling time” Not used
Exponential \(2^{-\tau_{1/2}}\) \(-\tau_{1/2}\) “half life” Not used
Power-law \([x - x_0]^p\) \(x_0\) x-intercept exponent
Sinusoid \(\sin\left(\frac{2 \pi}{P} (t-t_0)\right)\) \(P\) “period” \(t_0\) “time shift”
Sinusoid \(\sin(\omega t + \phi)\) \(\omega\) “angular frequency” \(\phi\) “phase shift”
Sinusoid \(\sin(2 \pi \omega t + \phi)\) \(\omega\) “frequency” \(\phi\) “phase shift”
Gaussian dnorm(x, mean, sd) “mean” (center) sd “standard deviation”
Sigmoid pnorm(x, mean, sd) “mean” (center) sd “standard deviation”
Straight-line \(mx + b\) \(m\) “slope” \(b\) “y-intercept”
Straight-line \(m (x-x_0)\) \(m\) “slope” \(x_0\) “center”

8.8 Drill

Part 1 What is the period of the function \(\sin(6\pi t)\)?

1/3 1/2 2 3 6

Part 2 What is the period of \(g(t)\)? \[g(t) \equiv \frac{5}{\sin(2 \pi t)}\]

  1. 1
  2. 5
  3. \(2 \pi/5\)
  4. \(5/2\pi\)
  5. \(g(t)\) isn’t periodic.

Part 3 What is the period of \(g(t)\)? \[g(t) \equiv \text{dnorm}\left(\frac{2\pi}{5}(t-3)\right)\]

  1. 1
  2. 5
  3. \(2 \pi/5\)
  4. \(5/2\pi\)
  5. \(g(t)\) isn’t periodic.

Part 4 One of the following choices is the standard deviation of the function graphed in Figure 8.8. Which one?

0 1 2 3 4

Part 5 What is the value of the parameter “mean” for the function shown in Figure 11.11?

  1. -2
  2. -1
  3. 0.5
  4. 1
  5. 2
  6. “mean” is not a parameter of this function.

Part 6 What is the value of the parameter “sd” for the function shown in ?fig-m06-01?

  1. -2
  2. -1
  3. 0.5
  4. 1
  5. 2
  6. “sd” is not a parameter of this function.

Part 7 What is the value of the parameter “mean” for the function shown in ?fig-m06-02?

  1. -2
  2. -1
  3. 0.5
  4. 1
  5. 2
  6. “mean” is not a parameter of this function.

Part 8 What is the value of the parameter “sd” for the function shown in ?fig-m06-02

  1. -2
  2. -1
  3. 0.5
  4. 1
  5. 2
  6. “sd” is not a parameter of this function.

8.9 Exercises

Exercise 8.01

Each of the following plots shows a basic modeling function whose input scaling has the form \(x - x_0\). Your job is to figure out from the graph what is the numerical value of \(x_0\). (Hint: For simplicity, \(x_0\) in the questions will always be an integer.)

Part A In plot (A), what is \(x_0\)?

-2 -1 0 1 2

Part B In plot (B), what is \(x_0\)?

-2 -1 0 1 2

Part C In plot (C), what is \(x_0\)?

-2 -1 0 1 2

Part D In plot (D), what is \(x_0\)?

-2 -1 0 1 2

Part E In plot (E), what is \(x_0\)?

-2 -1 0 1 2

Exercise 8.02

Each of the graphs shows two horizontal scales, one drawn on the edge graphics frame (black) and one drawn slighly above that (blue). Which horizontal scale (black or blue) corresponds to the pattern-book function shown in the graph?

Part A For graph (A), which scale corresponds to the pattern-book function?

black blue neither both

Part B For graph (B), which scale corresponds to the pattern-book function?

black blue neither both

Part C For graph (C), which scale corresponds to the pattern-book function?

black blue neither both

Exercise 8.03

Find the straight-line function that will give the value on the bottom (black) scale for each point \(x\) on the top (blue) scale. The function will take the top(blue)-scale reading as input and produce the bottom(black)-scale reading as output, that is: \[\text{black}(x) \equiv a (x - x_0)\]

Part A For Graph A, which function maps blue \(x\) to the value on the black scale?

\(\frac{1}{3} x\)\(3\, x\)\(x + 3\)\(x - 3\)

Part B For Graph B, which function maps blue \(x\) to the value on the black scale?

\(-\frac{2}{3}\,x\)\(\frac{3}{2} x\)\(\frac{2}{3} x\)\(-\frac{3}{2}x\)

Part C For Graph C, which function maps blue \(x\) to the value on the black scale?

\(\frac{1}{2}(x - 2)\)\(3\, x\)\(2\,x\)\(2\,(x + 2)\)

Part D For Graph D, which function maps blue \(x\) to the value on the black scale?

  1. \(\frac{2}{3} (x + 3)\)
  2. \(\frac{3}{2} (x - 3)\)
  3. \(\frac{3}{2} (x+1)\)
  4. \(\frac{3}{2}(x - 2)\)

Exercise 8.04

The graph shows a linear combination of two sinusoids, one of period 0.6 and the other of period 2. There is also a baseline shift. That is, the graph shows the function:

\[A_1 \sin\left(\frac{2\pi}{2}t\right) + A_2 \sin\left(\frac{2\pi}{0.6} (t-.3)\right) + A_3\]

Part A What is \(A_3\)?

-4 -2 0 2 4

Part B What is \(A_1\)?

0 1 2 3.5

Part C What is \(A_2\)?

0 1 2 3.5

Exercise 8.05

The Bargain Basement store wants to sell its goods quickly. Consequently, they reduce each product’s price \(P\) by 5% per day.

Part A If a jacket costs $80 today, how much will it cost in \(t\) days?

\(P = 80 - 5t\)\(P = 80 - 4t\)\(P = 80 - 0.05t\)\(P = 80 (0.05)^t\)\(P = 80 (0.95)^t\)

You will need to use an R console to answer the next question. A hint: the answer is related to the answer from the previous question. Remember, to raise a number to a power, you can use an expression like 0.95^7.

Part B You decided that you like the $80 jacket, but you have a budget of only $60. How long should you wait before coming back to the Bargain Basement store.?

3 days 4 days 5 days 6 days

Part C The answer to the first question is an exponential function, even if at first it doesn’t look like it. Which of these is the same function but written in the standard \(e^{kt}\) format?

  1. \(80 \exp( \ln(0.95) t)\)
  2. \(0.95 \exp(80 t)\)
  3. \(80 \exp(-\ln(0.95) t)\)
  4. \(0.95 \exp(\ln(80) t)\)

Exercise 8.06

The three functions created by the statements below are different in important ways. Explain what those differences are.

f1 <- makeFun(sin((2*pi/P)*t) ~ t)
f2 <- makeFun(sin((2*pi/6)*t) ~ t)
f3 <- makeFun(sin((2*pi/P)*t) ~ t, P=6)

Exercise 8.07

Watch this movie showing the growth of a colony of E. coli. Each rod is one bacterium.

Bacteria exhibit exponential growth under optimal conditions. In general, if the rate of growth depends on some quantity (here bacteria) then the exponential is the best first guess at a model. In the movie, notice that the rate of expansion depends on the number of bacteria present; the more E.coli, the faster the rate of growth. This is true for any exponential process: the instantaneous rate of growth or decay depends on the amount currently present.

If the experiment were continued indefinitely, the number of bacteria would eventually outgrow the petri dish or deplete their food source. When this happens, we say the bacteria have approached the carrying capacity of their environment. When the population is constrained in this way, a sigmoid would be a more appropriate model to start your modeling process. So, the deciding factor between exponential and sigmoid really depends upon whether 1) we assume a constrained or unconstrained environment, and 2) we let the bacteria reach the carrying capacity of the petri dish or not.

  1. Is there any obvious sign that the bacteria are reaching the carrying capacity of their environment before the end of the movie?

  2. Estimate the doubling time of the number of bacteria as they are growing exponentially. Do this by figuring out how long it takes the area of the colony to double (roughly). Hint: You’ll need to use the time marker in the bottom left corner of the movie.

  3. Estimate the doubling time in another way, by observing an individual bacterium. At any point in the movie, choose a bacterium at random. Watch it until it splits in two then, immediately, note the time. Watch some more until one of the two children split. The time difference between the mother’s split and the child’s split is the doubling time.

  4. Compare the doubling time for a mother in the center of a large colony to the doubling time of a mother on the edge of the colony. Is there any clear sign that growth in the more crowded part of the colony is slower than in the suburbs?

Credit: Math 141Z/142Z 2021-2022 development team.

Exercise 8.08

Here are four frames from a movie showing (through a microscope) the growth of E. coli. bacteria.

  1. In each frame, count the number of bacteria.
  2. Construct a data frame recording the time stamp and the number of bacteria in each frame. The unit of observation is a frame. You can use a command like this, replacing the count with your own numbers:
Ecoli <- tibble::tribble(
  ~ time, ~ count,
  100, 36,
  150, 289,
  200, 1683,
  250, 2945
)
  1. Make a point plot of the number of bacteria versus time. Use linear, logarithmic or semi-logarithmic axes as most appropriate to show a simple pattern.

A. Which type of axes shows the pattern most simply?

B. Is the pattern most consistent with linear growth, exponential growth, or power-law growth.

C. From your graph, find the parameter that describes the growth rate: - If linear growth, the slope of the line (give units) - If exponential growth, the doubling time (give units) - If power law, the exponent (which will not have units).

Exercise 8.09

The diagram shows how the intensity of light from the sun depends on distance \(r\). Wikipedia link The intensity is the number of photons per unit area. Imagining each red line to be the path followed by one photon, the intensity can be calculated by the area of the surfaces at distance \(r\), \(2r\), and \(3r\).

Part A Which of these functional forms best models intensity \(\cal I\) as a function of distance \(r\)?

  1. Proportional: \(\cal I(r)\equiv ar+b\)
  2. Power-law: \(\cal I(r)\equiv Ar^p\)
  3. Exponential \(\cal I(r)\equiv Ae^{kr}+C\)
  4. Sine: \(\cal I(r)\equiv A\sin \left(\frac{2\pi}{p}(r-r_0)\right)+B\)
  5. Sigmoid \(\cal I(r)\equiv A\cdot pnorm(r,mean,sd)+B\)
  6. Gaussian \(\cal I(r)\equiv A\cdot dnorm(r,mean,sd)+B\)

Exercise 8.10

The performance \(p\) of a worker depends on the level of stimulation/stress \(s\) imposed by the task. This phenomenon has come to be known as the Yerkes-Dodson Stress Performance Curve, and you’ve probably experienced this yourself. If a task is not stimulating enough people become inactive/bored and performance is negatively impacted. If tasks are over stimulating (stressful), people become anxious, fatigued, and burn-out. The overall pattern is shown by the diagram.

Part A Which of these functional forms best imitates the Yerkes-Dodson stress performance curve?

  1. Proportional: \(p(s) \equiv as+b\)
  2. Power-law: \(p(s) \equiv As^p\)
  3. Exponential \(p(s) \equiv Ae^{kt}+C\)
  4. Sine: \(p(s) \equiv A\sin\left(\frac{2\pi}{p}(t-t_0)\right)+B\)
  5. Sigmoid \(p(s) \equiv A\cdot pnorm(s,mean,sd)+B\)
  6. Gaussian \(p(s) \equiv A\cdot dnorm(s,mean,sd)+B\)

A manager must balance workloads between too much and too little stimulation to get peak performance out of each team member.

Exercise 8.11

The graph shows the proportion \(P\) of the US cell-phone users who own a smart phone as a function of the year \(y\).

As a rule, when a quantity grows exponentially but is ultimately limited to some maximum level, the sigmoid is the choice for modeling. The proportion of smartphone owners grew exponentially during the early 2000’s. As the number of smartphones increased, the broader familiarity with and advertisement of smartphones also increased, which help sustain this exponential growth. However, adoption has slowed as smartphone penetration reaches the maximum carrying capacity. In other words, once everyone has a smartphone, the proportion of smartphone owners cannot increase—everyone already owns a smartphone. So, eventually the exponential growth must taper-off. According to several datasets, this inflection point occurred sometime between 2013 and 2014. This behavior is visible in the graphic below showing US smartphone penetration between Jan 2005 and Oct 2020 with raw data shown from 2010 to 2015.

Part A During the initial, exponential phase of smartphone penetration, what was the doubling time for penetration? (Note that the horizontal axis labels have 1/4 year inbetween them.)

About 2% About 6 months About 18 months About 24 months.

Part B Referring to the black sigmoid curve, what is the mean parameter?

Jan. 2010 Oct. 2010 July 2012 50%

Part C Referring to the black sigmoid curve, what is the standard deviation parameter?

Jan. 2010 Jan. 2011 Jan. 2014 19 months

Credit: 2021-2022 Math141Z/Math142Z development team.