Contents
Deep Breakdown
What it tells me (Situation Awareness): The tangent antiderivative is less intuitive than sine or cosine. It comes from rewriting and applying the quotient-logarithm rule: . The result is (equivalently, since ). In DA/DS, tangent integrals appear less frequently than sine/cosine, but they do appear in information-geometric calculations, certain entropy expressions, and when computing normalizing constants of distributions related to the Cauchy distribution (which is related to ). They also appear as intermediate steps when solving differential equations for neural network activation landscapes.
Flowchart
Real-world use
Where it is used
Intermediate steps in differential equations involving angular variables, information geometry (the Fisher metric on certain manifolds involves tangent integrals), deriving the hyperbolic tangent connection to natural logarithms, and verifying that activation functions are related to via integration.
Problem it solves
Tangent has no simple polynomial-style antiderivative. Without this formula, you would need to rediscover the -substitution every time. Knowing the result () enables quick computation of definite integrals over tangent functions.
How it solves the problem
.
Let , :
(using ).
Example in a business
A Bayesian model uses a half-Cauchy prior on a scale parameter : , which after a change of variables relates to . This appears in the normalizing constant of the half-Cauchy distribution, widely used as a weakly informative prior on variance parameters in hierarchical models (Stan's recommended default).
The formula, piece by piece
Each symbol:
- : a ratio, not directly integrable by power rules
- : the universal chain rule compensation
- : the natural logarithm; appears because is a quotient (triggers the quotient-log rule)
- : secant ; absolute value ensures the log is defined; everywhere it is defined
- Equivalent form:
The formula in words
"The antiderivative of tangent is the natural log of the absolute value of secant (or equivalently, the negative log of absolute cosine), divided by . The logarithm appears because tangent is a ratio of sine over cosine, and integrating a ratio of a function over itself gives a logarithm."
Critical Concepts
- Domain: is undefined at ; the antiderivative is only valid on intervals that avoid these poles.
- Two equivalent forms: . Both are correct; use whichever is more convenient.
- Connection to : (hyperbolic analogue; no absolute value needed since always).
- Not from basic power rule: tangent requires the substitution and the logarithmic integral .
- Definite integral caution: the integrand must not pass through a pole (where ) within the integration range.
Step-by-step calculation (tiny example)
Compute and .
Step 1: Identify a and b For : , .
Step 2: Apply the formula .
Step 3: Verify by differentiating
Step 4: Evaluate a definite integral
Code examples
Beginner example (Python)
import numpy as np
from scipy import integrate
def tan_antiderivative(x: float, a: float, b: float) -> float:
"""F(x) = (1/a)*ln|sec(ax+b)|. Undefined at cos(ax+b)=0."""
if abs(a) < 1e-12:
raise ValueError("a = 0.")
cos_val = np.cos(a * x + b)
if abs(cos_val) < 1e-12:
raise ValueError("Pole: cos(ax+b) = 0 at this x.")
return (1.0 / a) * np.log(abs(1.0 / cos_val)) # ln|sec| = -ln|cos|
def tan_definite(lo: float, hi: float, a: float, b: float) -> float:
return tan_antiderivative(hi, a, b) - tan_antiderivative(lo, a, b)
# Test cases (avoid poles: tan(x) has poles at pi/2, 3pi/2, ...)
cases = [
(0.0, np.pi/6, 1.0, 0.0), # int tan(x) from 0 to pi/6
(0.0, np.pi/4, 1.0, 0.0), # int tan(x) from 0 to pi/4
(0.0, np.pi/8, 2.0, 0.0), # int tan(2x) from 0 to pi/8
]
for lo, hi, a, b in cases:
analytic = tan_definite(lo, hi, a, b)
numerical, _ = integrate.quad(lambda x, aa=a, bb=b: np.tan(aa*x+bb), lo, hi)
print(f"int_({lo:.3f},{hi:.4f}) tan({a}x+{b:.2f}): "
f"analytic={analytic:.6f}, numerical={numerical:.6f}, "
f"match={abs(analytic-numerical)<1e-6}")
# tanh analogue: int tanh(x) dx = ln(cosh(x)) + C
print("\n=== Hyperbolic analogue: int tanh(x) dx ===")
tanh_antiderivative = lambda x: np.log(np.cosh(x))
lo, hi = -1.0, 2.0
tanh_analytic = tanh_antiderivative(hi) - tanh_antiderivative(lo)
tanh_numerical, _ = integrate.quad(np.tanh, lo, hi)
print(f"int_({lo},{hi}) tanh(x): analytic={tanh_analytic:.6f}, numerical={tanh_numerical:.6f}")Beginner example (R)
tan_antiderivative <- function(x, a, b) {
if (abs(a) < 1e-12) stop("a = 0.")
(1 / a) * log(abs(1 / cos(a * x + b)))
}
tan_definite <- function(lo, hi, a, b) {
tan_antiderivative(hi, a, b) - tan_antiderivative(lo, a, b)
}
cases <- list(c(0, pi/6, 1, 0), c(0, pi/4, 1, 0))
for (tc in cases) {
lo <- tc[1]; hi <- tc[2]; a <- tc[3]; b <- tc[4]
analytic <- tan_definite(lo, hi, a, b)
numerical <- integrate(function(x) tan(a*x+b), lower=lo, upper=hi)$value
cat(sprintf("int_(%5.3f,%5.3f) tan(%gx): analytic=%.6f, num=%.6f, match=%s\n", lo, hi, a, analytic, numerical, isTRUE(all.equal(analytic, numerical, tol=1e-7))))
}
# tanh analogue
tanh_analytic <- log(cosh(2)) - log(cosh(-1))
tanh_numerical <- integrate(tanh, lower=-1, upper=2)$value
cat(sprintf("\nint tanh(x) from -1 to 2: analytic=%.6f, num=%.6f\n", tanh_analytic, tanh_numerical))Professional example (Python)
"""
tanh activation integral: int tanh(x) dx = ln(cosh(x)) + C.
The hyperbolic analogue of tan's formula. This matters because:
1. tanh is a standard neural network activation function.
2. The integral of tanh appears in the ELBO (Evidence Lower BOund)
for variational autoencoders: computing int q(z)*ln p(x|z) dz often
involves integrating over tanh-activated layers.
3. For regularization: the integral of |tanh(w)| w.r.t. w provides a
smooth L1-like sparsity measure.
We demonstrate the formula and connect to activation-layer analysis.
"""
import numpy as np
from scipy import integrate
def tanh_antiderivative(x: np.ndarray) -> np.ndarray:
"""int tanh(x) dx = ln(cosh(x)) + C."""
return np.log(np.cosh(x))
def tanh_energy(lo: float, hi: float) -> float:
"""int_lo^hi tanh(x) dx = ln(cosh(hi)) - ln(cosh(lo))."""
return float(tanh_antiderivative(hi) - tanh_antiderivative(lo))
# Verify analytically vs numerically
test_ranges = [(-2.0, 2.0), (0.0, 3.0), (-1.0, 1.0)]
print("=== tanh integral verification ===")
for lo, hi in test_ranges:
analytic = tanh_energy(lo, hi)
numerical, _ = integrate.quad(np.tanh, lo, hi)
print(f" int_({lo:+.1f},{hi:+.1f}) tanh: "
f"analytic={analytic:.6f}, numerical={numerical:.6f}, "
f"match={abs(analytic-numerical)<1e-8}")
# Pre-activation distribution: for a layer with weights w, input z ~ N(0,1),
# the mean absolute activation E[|tanh(w*z)|] is computed by integration.
print("\n=== Mean |tanh(w*z)| for z ~ N(0,1) ===")
from scipy.stats import norm
for w in [0.5, 1.0, 2.0, 5.0]:
# Numerical: E[|tanh(w*z)|] = int |tanh(w*z)| * phi(z) dz
mean_abs, _ = integrate.quad(lambda z, ww=w: abs(np.tanh(ww * z)) * norm.pdf(z), -10, 10)
print(f" w={w:.1f}: E[|tanh(w*z)|] = {mean_abs:.4f}")
print("[As w increases, tanh saturates and E[|tanh|] -> 1]")Source: domain knowledge