BRAGA

02 Writing02-02 Notes02-02-287

Area (absolute)

Published 16 Apr 20268 min read
Contents
  1. 01Deep Breakdown
  2. 02Flowchart
  3. 03Real-world use
  4. 04The formula, piece by piece
  5. 05The formula in words
  6. 06Critical Concepts
  7. 07Step-by-step calculation (tiny example)
  8. 08Code examples
A=∫ab∣f(x)∣ dxA = \int_a^b |f(x)|\,dx
(1)

Deep Breakdown

What it tells me (Situation Awareness): When f(x)f(x) crosses zero inside [a,b][a, b], the plain definite integral ∫abf(x) dx\int_a^b f(x)\,dx computes signed area: positive parts add, negative parts subtract, and they can cancel. The absolute area formula ∫ab∣f(x)∣ dx\int_a^b |f(x)|\,dx ignores the sign at every point and always sums non-negative contributions. In DA/DS this distinction matters constantly: Mean Absolute Error (MAE) is the expected value of ∣y^−y∣|\hat{y} - y|, not the expectation of the raw residual (which would be near zero for an unbiased model). Total variation of a signal, the L1 norm of a function over an interval, and Wasserstein-1 distance all involve this absolute area concept. If you use the signed integral when you need absolute area you will systematically undercount error and misread model performance.

Flowchart

Define f(x) andbounds a, bFind all zeros off(x) on the openinterval (a, b)Call zeros c1,c2, ..., ck inorderSplit: [a, c1], [c1,c2], ..., [ck, b]On eachsub-interval,check sign off(x)Compute theintegral on eachsub-intervalTake theabsolute valueof eachsub-intervalresultSum all absolutesub-intervalareasTotal = unsignedarea undercurve

Real-world use

Where it is used

Any time a DA/DS metric computes total deviation without caring about direction: residual analysis (MAE, MAPE), total variation of a KPI time series, signal processing (L1 norm of a waveform), L1 regularization penalty as a functional, Wasserstein-1 distance between two continuous distributions, and testing for mean-reversion by measuring total oscillation.

Problem it solves

The plain definite integral underestimates total error whenever positive and negative residuals cancel. Consider a model that overshoots by 5 and undershoots by 5: the signed integral of residuals is 0 (looks perfect), but the absolute area is 10 (reveals real deviation). The absolute area formula always returns the correct total magnitude.

How it solves the problem

By wrapping ff in absolute value before integrating: ∣f(x)∣|f(x)| flips all negative portions to positive. In practice: (1) find where ff crosses zero, (2) split the integral at those crossings, (3) compute each piece separately, (4) add magnitudes. Numerically, scipy.integrate.quad(lambda x: abs(f(x)), a, b) handles it automatically.

Example in a business

A revenue forecasting model has residuals e(t)=actual(t)−forecast(t)e(t) = \text{actual}(t) - \text{forecast}(t) that oscillate around zero. Total signed error ∫e(t) dt≈0\int e(t)\,dt \approx 0 (bias is low, model is well-calibrated). But total absolute error ∫∣e(t)∣ dt\int |e(t)|\,dt is large — the model has high variance, swinging wildly each day. MAE per day = 1T∫0T∣e(t)∣ dt\frac{1}{T}\int_0^T |e(t)|\,dt. Reporting only signed totals would hide the true inaccuracy of the model.

The formula, piece by piece

A=∫ab∣f(x)∣ dxA = \int_a^b |f(x)|\,dx
(2)

Each symbol:

  • AA: the total unsigned area, always ≥0\geq 0
  • ∫ab\int_a^b: integrate from aa to bb
  • ∣f(x)∣|f(x)|: absolute value of ff at each xx — negative portions are flipped above the axis
  • dxdx: infinitesimal width, xx is the variable Key identity (triangle inequality for integrals):
∫ab∣f(x)∣ dx  ≥  ∣∫abf(x) dx∣\int_a^b |f(x)|\,dx \;\geq\; \left|\int_a^b f(x)\,dx\right|
(3)

Equality holds only when ff does not change sign on [a,b][a, b].

The formula in words

"At every point xx, take the height of the curve but always make it non-negative (flip it if it is below zero). Then integrate those non-negative heights from aa to bb. This gives the true total area swept out by the curve, regardless of whether the curve dips below the axis."

Critical Concepts

  • Must find zeros first: split the interval at each zero crossing; if you skip this and just compute F(b)−F(a)F(b) - F(a), you get the signed area, not the absolute area.
  • Triangle inequality for integrals: ∫∣f∣≥∣∫f∣\int|f| \geq |\int f|. Signed area ≤\leq absolute area always.
  • MAE connection: For a continuous error distribution with density pe(e)p_e(e), MAE=∫−∞∞∣e∣ pe(e) de\text{MAE} = \int_{-\infty}^{\infty} |e|\,p_e(e)\,de.
  • L1 norm of a function: ∥f∥L1[a,b]=∫ab∣f(x)∣ dx\|f\|_{L^1[a,b]} = \int_a^b |f(x)|\,dx. This is the functional analogue of the L1 vector norm.
  • Total variation: A discrete approximation is TV=∑t∣f(t+1)−f(t)∣\text{TV} = \sum_t |f(t+1) - f(t)|; the continuous version is ∫∣f′(x)∣ dx\int |f'(x)|\,dx.
  • Computational note: scipy.integrate.quad handles the absolute value correctly by adaptive subdivision, but it helps to pass the known breakpoints (zeros) explicitly for efficiency.

Step-by-step calculation (tiny example)

Compare ∫−12x dx\int_{-1}^{2} x\,dx (signed) vs. ∫−12∣x∣ dx\int_{-1}^{2} |x|\,dx (absolute).

Step 1: Signed integral (naive) F(x)=x2/2F(x) = x^2/2 ∫−12x dx=F(2)−F(−1)=42−12=32=1.5\int_{-1}^{2} x\,dx = F(2) - F(-1) = \frac{4}{2} - \frac{1}{2} = \frac{3}{2} = 1.5 This combines −0.5-0.5 (area below axis from −1-1 to 00) and +2.0+2.0 (area above axis from 00 to 22), yielding 1.51.5.

Step 2: Find zeros of f(x)=xf(x) = x on (−1,2)(-1, 2) x=0x = 0 is the only zero. Split at x=0x = 0: sub-intervals [−1,0][-1, 0] and [0,2][0, 2].

Step 3: Compute each sub-interval separately On [−1,0][-1, 0]: f(x)=x<0f(x) = x < 0, so ∣f(x)∣=−x|f(x)| = -x. ∫−10(−x) dx=[−x2/2]−10=0−(−1/2)=12\int_{-1}^{0} (-x)\,dx = [-x^2/2]_{-1}^{0} = 0 - (-1/2) = \frac{1}{2} On [0,2][0, 2]: f(x)=x>0f(x) = x > 0, so ∣f(x)∣=x|f(x)| = x. ∫02x dx=[x2/2]02=2−0=2\int_{0}^{2} x\,dx = [x^2/2]_0^2 = 2 - 0 = 2

Step 4: Sum the absolute pieces A=12+2=52=2.5A = \frac{1}{2} + 2 = \frac{5}{2} = 2.5 The absolute area (2.5) is larger than the signed area (1.5) because the below-axis piece was subtracted in the signed version but added here.

Code examples

Beginner example (Python)

python
import numpy as np
from scipy import integrate

def f(x: float) -> float:
    """Simple function that crosses zero: f(x) = x."""
    return float(x)   # Signed area: cancellation occurs
area_signed, _ = integrate.quad(f, -1, 2)   # Absolute area: pass the known breakpoint (zero at x=0) for efficiency
area_absolute, _ = integrate.quad(lambda x: abs(f(x)), -1, 2, points=[0.0])
print(f"Signed area (int x dx from -1 to 2): {area_signed:.4f}")   # 1.5
print(f"Absolute area (int |x| dx from -1 to 2): {area_absolute:.4f}")   # 2.5
print(f"Triangle inequality holds: {area_absolute >= abs(area_signed)}")   # True # Manual split to show the mechanics
piece_left, _ = integrate.quad(lambda x: abs(f(x)), -1, 0)
piece_right, _ = integrate.quad(lambda x: abs(f(x)), 0, 2)
print(f"Left piece ([-1,0]): {piece_left:.4f}")   # 0.5
print(f"Right piece ([0,2]): {piece_right:.4f}")   # 2.0
print(f"Sum: {piece_left + piece_right:.4f}")   # 2.5

Beginner example (R)

r
f <- function(x) x  # f crosses zero at
x = 0  # Signed area
area_signed <- integrate(f, lower = -1, upper = 2)$value
cat("Signed area:", area_signed, "\n")  # 1.5 # Absolute area: pass subdivisions to help the integrator
area_absolute <- integrate(function(x) abs(f(x)), lower = -1, upper = 2, subdivisions = 200L)$value
cat("Absolute area:", area_absolute, "\n")  # 2.5 # Triangle inequality
cat("Triangle inequality holds:", area_absolute >= abs(area_signed), "\n")  # TRUE # Manual split
piece_left <- integrate(function(x) abs(f(x)), lower = -1, upper = 0)$value
piece_right <- integrate(function(x) abs(f(x)), lower = 0, upper = 2)$value
cat("Left piece: ", piece_left, "\n")  # 0.5
cat("Right piece: ", piece_right, "\n")  # 2.0
cat("Sum: ", piece_left + piece_right, "\n")  # 2.5

Professional example (Python)

python
"""
MAE as absolute area under the error density curve. In regression, residuals
e = y_true - y_pred form a distribution.
MAE = E[|e|] = integral_{-inf}^{inf} |e| * p_e(e)
de = int_0^inf e * p_e(e) de + int_{-inf}^0 (-e) * p_e(e)
de = int_0^inf (pos piece) + int_{-inf}^0 (neg piece, flipped) We demonstrate that:
1. sklearn MAE on discrete residuals matches
2. scipy.integrate.quad on fitted KDE of residuals matches
3. Signed integral of residuals is near zero (unbiasedness), NOT MAE.
"""
import numpy as np
from scipy import integrate
from scipy.stats import gaussian_kde
from sklearn.datasets import make_regression
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
RANDOM_SEED = 42
rng = np.random.default_rng(RANDOM_SEED)   # Reproducible regression dataset
x_data, y_data = make_regression( n_samples=1_000, n_features=15, noise=25.0, random_state=RANDOM_SEED )
x_train, x_test, y_train, y_test = train_test_split( x_data, y_data, test_size=0.3, random_state=RANDOM_SEED )
scaler = StandardScaler()
x_train_scaled = scaler.fit_transform(x_train)
x_test_scaled = scaler.transform(x_test)
model = Ridge(alpha=1.0)
model.fit(x_train_scaled, y_train)
y_pred = model.predict(x_test_scaled)
residuals = y_test - y_pred   # 1. Discrete MAE (sklearn)
mae_discrete = mean_absolute_error(y_test, y_pred)   # 2. Signed integral of residuals (should be near zero: unbiased model)
signed_sum = float(np.mean(residuals))   # E[e] ≈ 0 # 3. Continuous MAE via KDE density + absolute area integral
kde = gaussian_kde(residuals, bw_method="scott")
e_min = float(residuals.min()) - 10.0
e_max = float(residuals.max()) + 10.0   # Signed integral of e * p(e): should be ~0 (unbiasedness)
signed_expectation, _ = integrate.quad( lambda e: e * kde(e)[0], e_min, e_max )   # Absolute area: E[|e|] = integral |e| * p(e) de -- TRUE MAE
mae_continuous, _ = integrate.quad( lambda e: abs(e) * kde(e)[0], e_min, e_max, points=[0.0] )
print(f"Signed mean residual (E[e]): {signed_sum:+.4f} <- near 0 (unbiased)")
print(f"Signed integral via KDE (E[e]): {signed_expectation:+.4f} <- near 0")
print(f"MAE (sklearn discrete): {mae_discrete:.4f}")
print(f"MAE (KDE absolute integral): {mae_continuous:.4f}")
print(f"Triangle ineq holds: |E[e]| <= E[|e|]: " f"{abs(signed_expectation) <= mae_continuous + 1e-6}")
# Key lesson: E[e] ≈ 0 does NOT mean MAE ≈ 0. Absolute area captures true error.

Source: domain knowledge

#calculus#integral-calculus#rules-of-integration

Keyboard shortcuts

Single keys, ignored while typing in a field or with Cmd, Ctrl or Alt held.

0
Home
1 2 3 4
Work, Writing, Tools, About
j / k
Next / previous section on this page
n / p
Next / previous project or essay
u
Up one level
l
Deutsch
t
Light or dark theme
?
This list
Esc
Close