Contents
Deep Breakdown
What it tells me (Situation Awareness): The exponential function is its own derivative and its own antiderivative (up to a constant). When the exponent is an affine expression , the antiderivative gains a factor of from the chain rule compensation, just like the affine power rule. In DA/DS, this formula is everywhere: computing the moment generating function of distributions, integrating the Gaussian kernel in density estimation, computing expected discounted values in finance (discount factor ), evaluating the normalizing constant of the exponential distribution, and computing the CDF of any distribution with exponential decay.
Flowchart
Real-world use
Where it is used
Whenever an integrand contains a natural exponential with a linear argument: normalizing constants of exponential distributions, Gaussian integrals after completing the square, discount factors in revenue forecasting, survival function integrals , and moment generating functions for exponential families.
Problem it solves
The exponential function is the only function that is its own derivative. This makes it very easy to integrate: the antiderivative of differs only by the factor. Without this formula, you would need u-substitution every single time, slowing down work on any problem involving exponential decay or growth.
How it solves the problem
Let , , so :
Verification:
Example in a business
Customer churn follows an exponential distribution with rate per month. The expected number of customers still active after months is . Total customer-months of service from time 0 to : . This feeds directly into total revenue and LTV calculations for any subscription business.
The formula, piece by piece
Each symbol:
- : Euler's number, the base of the natural logarithm,
- : the linear exponent; scales the growth/decay rate, is an offset
- : the coefficient of in the exponent; appears in the denominator as chain rule compensation
- : the compensating factor (if , growth is faster so the integral is smaller; if , growth is slower so the integral is larger)
- : constant of integration Special cases:
- : (the classic)
- :
- :
The formula in words
"The antiderivative of to the power is the same function, divided by the coefficient that multiplies in the exponent. The division by is the compensation for the extra that would appear when you differentiate the result back via the chain rule."
Critical Concepts
- Self-similar: integrates to itself. The only modification for is the factor.
- Sign matters: . The negative sign is in the .
- Improper integrals: (finite for ). This is the normalizing constant of the exponential distribution.
- Gaussian connection: (Gaussian integral) — this is NOT directly this formula because the exponent is , not linear.
- Moment generating function: for uses for .
Step-by-step calculation (tiny example)
Compute and .
Step 1: Identify a and b , .
Step 2: Apply the formula . Result: .
Step 3: Verify by differentiating
Step 4: Evaluate the definite integral
Code examples
Beginner example (Python)
import numpy as np
from scipy import integrate
def exp_antiderivative(x: float, a: float, b: float) -> float:
"""F(x) = (1/a) * exp(ax + b). Undefined for a=0."""
if abs(a) < 1e-12:
raise ValueError("a = 0: integrand is constant e^b, not affine exponential.")
return (1.0 / a) * np.exp(a * x + b)
def exp_definite(lo: float, hi: float, a: float, b: float) -> float:
"""int_lo^hi e^(ax+b) dx = F(hi) - F(lo)."""
return exp_antiderivative(hi, a, b) - exp_antiderivative(lo, a, b) # Test cases
cases = [ (0.0, 1.0, 1.0, 0.0), # int e^x from 0 to 1 = e - 1
(0.0, 2.0, -3.0, 1.0), # int e^(-3x+1) from 0 to 2
(0.0, np.inf, -2.0, 0.0), # int e^(-2x) from 0 to inf = 1/2
]
for lo, hi, a, b in cases:
analytic = exp_definite(lo, hi, a, b)
numerical, _ = integrate.quad(lambda x, aa=a, bb=b: np.exp(aa*x+bb), lo, hi)
print(f"int_({lo},{hi}) e^({a}x+{b}): " f"analytic={analytic:.6f}, numerical={numerical:.6f}, " f"match={abs(analytic-numerical)<1e-6}") # Exponential distribution normalizing constant: int_0^inf lambda*e^(-lambda*x)
dx = 1
LAMBDA = 0.5
norm_const, _ = integrate.quad(lambda t: LAMBDA * np.exp(-LAMBDA * t), 0, np.inf)
print(f"\nExp({LAMBDA}) normalizing: int_0^inf lambda*e^(-lambda*t) dt = {norm_const:.6f} (should be 1.0)")Beginner example (R)
exp_antiderivative <- function(x, a, b) { if (abs(a) < 1e-12) stop("a = 0: not a valid affine exponential.") (1 / a) * exp(a * x + b)
}
exp_definite <- function(lo, hi, a, b) { exp_antiderivative(hi, a, b) - exp_antiderivative(lo, a, b)
} # Test cases
cases <- list(c(0, 1, 1, 0), c(0, 2, -3, 1))
for (tc in cases) { lo <- tc[1]; hi <- tc[2]; a <- tc[3]; b <- tc[4]
analytic <- exp_definite(lo, hi, a, b)
numerical <- integrate(function(x) exp(a*x+b), lower=lo, upper=hi)$value
cat(sprintf("int_(%g,%g) exp(%gx+%g): analytic=%.6f, num=%.6f, match=%s\n", lo, hi, a, b, analytic, numerical, isTRUE(all.equal(analytic, numerical, tol=1e-7))))
} # Normalizing constant of Exp(lambda=0.5)
lambda_val <- 0.5
norm <- integrate(function(t) lambda_val * exp(-lambda_val * t), 0, Inf)$value
cat(sprintf("\nExp(0.5) normalizing constant: %.6f (should be 1.0)\n", norm))Professional example (Python)
"""
Exponential integral
for subscription revenue forecasting
with churn. Model:
customers active at time t follow exponential decay. N(t) = N_0 * exp(-lambda * t) [exponential distribution of churn] Total revenue from time 0 to T: R(T) = r * int_0^T N_0 * exp(-lambda * t)
dt = r * N_0 * (1/lambda) * (1 - exp(-lambda * T)) This uses the formula: int e^(at+b)
dt = (1/a)*e^(at+b) + C
with a = -lambda, b = 0. We also compute the LTV (limit as T -> infinity):
LTV = r * N_0 / lambda
"""
import numpy as np
from scipy import integrate
def total_revenue(initial_customers: float, revenue_per_customer_month: float, monthly_churn_rate: float, months: float) -> float:
"""Closed-form: R(T) = r * N0 * (1/lambda) * (1 - exp(-lambda*T))."""
lam = monthly_churn_rate
return (revenue_per_customer_month * initial_customers * (1.0 / lam) * (1.0 - np.exp(-lam * months)))
def total_revenue_numerical(initial_customers: float, revenue_per_customer_month: float, monthly_churn_rate: float, months: float) -> float:
"""Numerical verification via scipy.quad."""
lam = monthly_churn_rate
result, _ = integrate.quad( lambda t: revenue_per_customer_month * initial_customers * np.exp(-lam * t), 0, months )
return result # Scenario parameters
N_0 = 10_000.0 # initial customer base
REVENUE_PER_MONTH = 25.0 # EUR per customer per month
CHURN_RATE = 0.04 # 4% monthly churn rate
MONTHS_12 = 12.0
MONTHS_24 = 24.0
print(f"=== Subscription Revenue Forecast ===")
print(f"Initial customers: {N_0:,.0f}")
print(f"Revenue/customer/month: EUR {REVENUE_PER_MONTH:.2f}")
print(f"Monthly churn: {CHURN_RATE:.1%}")
print()
for months in [MONTHS_12, MONTHS_24]:
analytic = total_revenue(N_0, REVENUE_PER_MONTH, CHURN_RATE, months)
numerical = total_revenue_numerical(N_0, REVENUE_PER_MONTH, CHURN_RATE, months)
match = abs(analytic - numerical) < 0.01
print(f"{months:.0f}-month revenue: EUR {analytic:>12,.2f} (numerical={numerical:,.2f}, match={match})") # LTV: limit as T -> infinity
ltv = REVENUE_PER_MONTH * N_0 / CHURN_RATE
print(f"\nTotal LTV (T->inf): EUR {ltv:>12,.2f}")
print(f"[Formula: r * N0 * int_0^inf e^(-lambda*t) dt = r * N0 / lambda]") # Sensitivity: effect of churn rate on LTV
print(f"\n=== LTV Sensitivity to Churn Rate ===")
for churn in [0.02, 0.04, 0.06, 0.08, 0.10]:
ltv_s = REVENUE_PER_MONTH * N_0 / churn
print(f" Churn={churn:.0%}: LTV = EUR {ltv_s:>10,.0f}")Source: 1300 p. 250