Calculus Formulas in LaTeX, Python and Rust
✅ Copy-ready code for calculus formulas in LaTeX, Python and Rust. For each formula, you'll see how to write it in LaTeX and how to calculate it in code. 😻
Every snippet runs on its own with no extra libraries, and the expected output is written in the comments. Use the tabs to switch between LaTeX, Python and Rust. To run a Rust snippet, save it as main.rs and run rustc main.rs, or paste it into the Rust Playground.
📚 Math Formulas in Code series
- Part 1: Algebra Formulas: exponents, logarithms, quadratics, lines and sequences
- Part 2: Linear Algebra Formulas: vectors, matrices and a neural network layer
- Part 3: Descriptive Statistics Formulas: mean, median, spread and correlation
- Part 4: Inferential Statistics Formulas: tests, confidence intervals, probability and regression
- Part 5: Calculus Formulas (you are here): derivatives, integrals and numerical methods
Just click the copy button in the top right corner of each code block!
Summary Overview
| # | Formula | Example |
|---|---|---|
| 1 | Limits by Getting Closer | |
| 2 | Numerical Derivative | |
| 3 | Second Derivative | |
| 4 | Newton's Method | |
| 5 | Gradient Descent | minimum of |
| 6 | Riemann Sum | |
| 7 | Trapezoid Rule | |
| 8 | Simpson's Rule | |
| 9 | Taylor Series | |
| 10 | Euler's Method |
1. Limits by Getting Closer
Limits by Getting Closer
Formula:
Putting
Where it's used: understanding limits, the idea behind derivatives and integrals.
$$
\lim_{x \to 0} \frac{\sin x}{x} = 1
$$import math
def f(x: float) -> float:
return math.sin(x) / x
print(round(f(0.1), 6)) # 0.998334
print(round(f(0.01), 6)) # 0.999983
print(round(f(0.001), 6)) # 1.0fn f(x: f64) -> f64 {
x.sin() / x
}
fn main() {
println!("{:.6}", f(0.1)); // 0.998334
println!("{:.6}", f(0.01)); // 0.999983
println!("{:.6}", f(0.001)); // 1.000000
}2. Numerical Derivative
Numerical Derivative
Formula:
The second form, the central difference, is more accurate than stepping forward only. Here
Where it's used: checking derivatives you worked out by hand, and gradient checking when debugging neural networks.
$$
f'(x) = \lim_{h \to 0} \frac{f(x + h) - f(x)}{h} \approx \frac{f(x + h) - f(x - h)}{2h}
$$def derivative(f, x: float, h: float = 1e-5) -> float:
return (f(x + h) - f(x - h)) / (2 * h)
print(round(derivative(lambda x: x**2, 3), 4)) # 6.0fn derivative(f: impl Fn(f64) -> f64, x: f64, h: f64) -> f64 {
(f(x + h) - f(x - h)) / (2.0 * h)
}
fn main() {
println!("{:.4}", derivative(|x| x * x, 3.0, 1e-5)); // 6.0000
}3. Second Derivative
Second Derivative
Formula:
Here
Where it's used: checking concavity, the second derivative test, and the Hessian in optimisation.
$$
f''(x) \approx \frac{f(x + h) - 2f(x) + f(x - h)}{h^2}
$$def second_derivative(f, x: float, h: float = 1e-4) -> float:
return (f(x + h) - 2 * f(x) + f(x - h)) / h**2
print(round(second_derivative(lambda x: x**3, 2), 4)) # 12.0fn second_derivative(f: impl Fn(f64) -> f64, x: f64, h: f64) -> f64 {
(f(x + h) - 2.0 * f(x) + f(x - h)) / (h * h)
}
fn main() {
println!("{:.4}", second_derivative(|x| x * x * x, 2.0, 1e-4)); // 12.0000
}4. Newton's Method
Newton's Method
Formula:
Each step follows the tangent line down to where it crosses zero. Here
Where it's used: finding roots of equations, and how calculators work out square roots.
$$
x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}
$$def newton(f, df, x0: float, steps: int = 20) -> float:
x = x0
for _ in range(steps):
x = x - f(x) / df(x)
return x
root = newton(lambda x: x**2 - 2, lambda x: 2 * x, x0=1.0)
print(round(root, 6)) # 1.414214fn newton(f: impl Fn(f64) -> f64, df: impl Fn(f64) -> f64, x0: f64, steps: usize) -> f64 {
let mut x = x0;
for _ in 0..steps {
x -= f(x) / df(x);
}
x
}
fn main() {
let root = newton(|x| x * x - 2.0, |x| 2.0 * x, 1.0, 20);
println!("{:.6}", root); // 1.414214
}5. Gradient Descent
Gradient Descent
Formula:
Each step moves downhill against the slope.
Where it's used: training machine learning models, which do the same thing with millions of parameters.
$$
x := x - \alpha \, f'(x) \qquad f(x) = (x - 3)^2
$$def gradient_descent(df, x0: float, alpha: float = 0.1, steps: int = 100) -> float:
x = x0
for _ in range(steps):
x = x - alpha * df(x)
return x
print(round(gradient_descent(lambda x: 2 * (x - 3), x0=0.0), 4)) # 3.0fn gradient_descent(df: impl Fn(f64) -> f64, x0: f64, alpha: f64, steps: usize) -> f64 {
let mut x = x0;
for _ in 0..steps {
x -= alpha * df(x);
}
x
}
fn main() {
println!("{:.4}", gradient_descent(|x| 2.0 * (x - 3.0), 0.0, 0.1, 100)); // 3.0000
}6. Riemann Sum
Riemann Sum
Formula:
This version uses the midpoint
Where it's used: understanding an integral as the area of many thin rectangles.
$$
\int_{a}^{b} f(x) \, dx \approx \sum_{i=1}^{n} f(m_i) \, \Delta x, \qquad \Delta x = \frac{b - a}{n}
$$def midpoint_sum(f, a: float, b: float, n: int = 1000) -> float:
dx = (b - a) / n
return sum(f(a + (i + 0.5) * dx) for i in range(n)) * dx
print(round(midpoint_sum(lambda x: x**2, 0, 2), 4)) # 2.6667fn midpoint_sum(f: impl Fn(f64) -> f64, a: f64, b: f64, n: usize) -> f64 {
let dx = (b - a) / n as f64;
(0..n).map(|i| f(a + (i as f64 + 0.5) * dx)).sum::<f64>() * dx
}
fn main() {
println!("{:.4}", midpoint_sum(|x| x * x, 0.0, 2.0, 1000)); // 2.6667
}7. Trapezoid Rule
Trapezoid Rule
Formula:
Trapezoids follow the curve more closely than rectangles. Here
Where it's used: integrating data from measurements, such as the area under a ROC curve.
$$
\int_{a}^{b} f(x) \, dx \approx \frac{\Delta x}{2} \Big[ f(x_0) + 2 \sum_{i=1}^{n-1} f(x_i) + f(x_n) \Big]
$$import math
def trapezoid(f, a: float, b: float, n: int = 1000) -> float:
dx = (b - a) / n
inner = sum(f(a + i * dx) for i in range(1, n))
return dx / 2 * (f(a) + 2 * inner + f(b))
print(round(trapezoid(math.sin, 0, math.pi), 4)) # 2.0use std::f64::consts::PI;
fn trapezoid(f: impl Fn(f64) -> f64, a: f64, b: f64, n: usize) -> f64 {
let dx = (b - a) / n as f64;
let inner: f64 = (1..n).map(|i| f(a + i as f64 * dx)).sum();
dx / 2.0 * (f(a) + 2.0 * inner + f(b))
}
fn main() {
println!("{:.4}", trapezoid(|x| x.sin(), 0.0, PI, 1000)); // 2.0000
}8. Simpson's Rule
Simpson's Rule
Formula:
Simpson's rule fits curves instead of straight lines, so it is very accurate.
Where it's used: accurate numerical integration in science and engineering.
$$
\int_{a}^{b} f(x) \, dx \approx \frac{\Delta x}{3} \Big[ f(x_0) + 4 \sum_{i \text{ odd}} f(x_i) + 2 \sum_{i \text{ even}} f(x_i) + f(x_n) \Big]
$$import math
def simpson(f, a: float, b: float, n: int = 100) -> float:
dx = (b - a) / n # n must be even
total = f(a) + f(b)
for i in range(1, n):
total += (4 if i % 2 == 1 else 2) * f(a + i * dx)
return dx / 3 * total
print(round(simpson(math.exp, 0, 1), 6)) # 1.718282fn simpson(f: impl Fn(f64) -> f64, a: f64, b: f64, n: usize) -> f64 {
let dx = (b - a) / n as f64; // n must be even
let mut total = f(a) + f(b);
for i in 1..n {
let weight = if i % 2 == 1 { 4.0 } else { 2.0 };
total += weight * f(a + i as f64 * dx);
}
dx / 3.0 * total
}
fn main() {
println!("{:.6}", simpson(|x| x.exp(), 0.0, 1.0, 100)); // 1.718282
}9. Taylor Series
Taylor Series
Formula:
Each new term is the previous one times
Where it's used: how computers calculate
$$
e^{x} = \sum_{n=0}^{\infty} \frac{x^{n}}{n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots
$$def exp_taylor(x: float, terms: int = 15) -> float:
total, term = 0.0, 1.0
for n in range(terms):
total += term
term *= x / (n + 1)
return total
print(round(exp_taylor(1), 6)) # 2.718282fn exp_taylor(x: f64, terms: usize) -> f64 {
let (mut total, mut term) = (0.0, 1.0);
for n in 0..terms {
total += term;
term *= x / (n as f64 + 1.0);
}
total
}
fn main() {
println!("{:.6}", exp_taylor(1.0, 15)); // 2.718282
}10. Euler's Method
Euler's Method
Formula:
Euler's method solves a differential equation one small step
Where it's used: simulating growth and decay, physics, and how neural ODEs work.
$$
y_{n+1} = y_n + h \, f(t_n, y_n) \qquad \frac{dy}{dt} = y, \; y(0) = 1
$$def euler(f, t0: float, y0: float, h: float, steps: int) -> float:
t, y = t0, y0
for _ in range(steps):
y = y + h * f(t, y)
t = t + h
return y
print(round(euler(lambda t, y: y, 0, 1, 0.001, 1000), 4)) # 2.7169fn euler(f: impl Fn(f64, f64) -> f64, t0: f64, y0: f64, h: f64, steps: usize) -> f64 {
let (mut t, mut y) = (t0, y0);
for _ in 0..steps {
y += h * f(t, y);
t += h;
}
y
}
fn main() {
println!("{:.4}", euler(|_t, y| y, 0.0, 1.0, 0.001, 1000)); // 2.7169
}