1 Lab 0: Data Loading

We use multiple real datasets:

data(AirPassengers)
data(nottem)
data(sunspots)
data(EuStockMarkets)

ap <- AirPassengers
temp <- nottem
ss <- sunspots
stocks <- EuStockMarkets[,1]

2 Lab 1: Modified Exponential Curve Fitting

We explore curve fitting techniques using a modified exponential model:

t <- 1:length(ap)
y <- as.numeric(ap)

fit_exp <- lm(log(y) ~ t)
a <- exp(coef(fit_exp)[1])
b <- exp(coef(fit_exp)[2])
fitted_exp <- a*b^t

plot(t, y, pch=16, col="blue", cex=0.7,
     main="Exponential Fit (points = actual)",
     xlab="t (months)", ylab="Passengers")
lines(t, fitted_exp, col="red", lwd=2)
legend("topleft", legend=c("Actual (points)", "Fitted (curve)"),
       col=c("blue","red"), pch=c(16,NA), lty=c(NA,1), lwd=c(NA,2), bty="n")

y2 <- as.numeric(nottem)
t2 <- 1:length(y2)

fit2 <- lm(log(y2 - min(y2) + 1) ~ t2)  # shift to avoid log(<=0)
a2 <- exp(coef(fit2)[1]); b2 <- exp(coef(fit2)[2])
fitted2 <- a2*b2^t2 + min(y2) - 1

plot(t2, y2, pch=16, col="blue", cex=0.6,
     main="Exponential Fit on nottem (shows misfit)",
     xlab="t", ylab="Temperature")
lines(t2, fitted2, col="red", lwd=2)

3 Lab 2: Gompertz Curve

We study the Gompertz curve, a flexible growth model often used in time series analysis:


3.1 Theory in Time Series Context

The Gompertz curve is a type of sigmoid function, expressed as:

\[ y_t = A \cdot \exp\left(-B \cdot \exp(-C \cdot t)\right) \]

Where: - \(y_t\) — observed value at time \(t\)
- \(A\) — upper asymptote (maximum attainable value)
- \(B\) — displacement parameter (shifts the curve along the time axis)
- \(C\) — growth rate parameter (controls speed of growth)

3.1.1 Key Properties:

  • Growth is asymmetric: slow at the beginning, rapid in the middle, and tapering off near the upper limit.
  • Suitable for time series forecasting where saturation effects are expected.
  • Often applied to epidemic curves (infection spread), market penetration models, and biological growth processes.
# ---------- SAFE GOMPERTZ FIT ----------

t <- 1:length(y)

# Scale time to avoid overflow
t_scaled <- t / max(t)

gompertz_model <- nls(
  y ~ K * exp(-A * exp(-b * t_scaled)),
  start = list(
    K = max(y) * 1.2,
    A = 5,
    b = 5
  ),
  algorithm = "port",
  lower = c(K = max(y), A = 0.001, b = 0.001),
  upper = c(K = 10000, A = 100, b = 100),
  control = nls.control(maxiter = 500, warnOnly = TRUE)
)

summary(gompertz_model)
## 
## Formula: y ~ K * exp(-A * exp(-b * t_scaled))
## 
## Parameters:
##   Estimate Std. Error t value Pr(>|t|)    
## K 2159.991   1751.060    1.23  0.21943    
## A    2.954      0.751    3.94  0.00013 ***
## b    0.691      0.283    2.44  0.01579 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 44.9 on 141 degrees of freedom
## 
## Algorithm "port", convergence message: relative convergence (4)
fitted_gom <- predict(gompertz_model)

plot(ap, col="darkgreen", lwd=2,
     main="Gompertz Curve Fit (Stable Version)")
lines(fitted_gom, col="orange", lwd=2)
legend("topleft",
       legend=c("Observed","Gompertz Fit"),
       col=c("darkgreen","orange"),
       lwd=2, bty="n")