BRAGA

02 Writing02-02 Notes02-02-189

Orthogonality condition

Published 16 Apr 20266 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
⟨x,y⟩=0  ⟺  x⊥y\langle x, y \rangle = 0 \iff x \perp y
(1)

Deep Breakdown

What it tells me (Situation Awareness): The orthogonality condition ⟨x,y⟩=0⇔x⊥y\langle x, y\rangle = 0 \Leftrightarrow x \perp y states that two vectors are perpendicular (orthogonal) if and only if their inner product is zero. This is one of the most used conditions in linear algebra and ML. It means: no component of xx lies along the direction of yy, and vice versa. Orthogonality appears everywhere in DA/DS: PCA produces orthogonal principal components (each captures variance not explained by the others), OLS residuals are orthogonal to the column space of XX (the projection theorem), and orthonormal bases simplify matrix algebra enormously. The ⇔\Leftrightarrow is critical: zero inner product is both necessary and sufficient for orthogonality.

Flowchart

YesNoTwo vectors: xand yCompute innerproduct: =sum(x_i * y_i)Is == 0?x and y areorthogonal(perpendicular)x and y are NOTorthogonalGeometric: 90degree anglebetween themAlgebraic: noshareddirectionalcomponentConsequence:||x+y||^2 = ||x||^2+ ||y||^2(Pythagoreantheorem)cos(theta) != 0 =shareddirectionalcomponent

Real-world use

Where it is used

Verifying that PCA components are orthogonal (uncorrelated directions), checking that residuals in OLS are orthogonal to the design matrix columns, constructing orthonormal feature bases (Gram-Schmidt), testing independence assumptions in statistical models (uncorrelated Gaussian variables have zero inner product in expectation), and validating that weight updates in different gradient directions do not interfere.

Problem it solves

Orthogonality enables decomposition: if features are orthogonal, the effect of each can be estimated independently without the estimate changing when others are added or removed. Multicollinear (non-orthogonal) features cause instability in regression. Orthogonal principal components in PCA allow dimensionality reduction without redundancy.

How it solves the problem

For ⟨x,y⟩=∑ixiyi=0\langle x, y\rangle = \sum_i x_i y_i = 0: the projection of xx onto yy is ⟨x,y⟩∥y∥2y=0\frac{\langle x,y\rangle}{\|y\|^2}y = 0. There is no component of xx in the direction of yy. Consequently, knowing yy tells you nothing about the component of xx in its direction. This is why orthogonal features in regression have independently estimable coefficients.

Example in a business

A DS checks that two derived features are truly orthogonal before adding both to a regression: $\text{feature}_1 = $ (revenue - mean), $\text{feature}_2 = $ (days active - mean). They compute ⟨f1,f2⟩=∑if1,if2,i\langle f_1, f_2\rangle = \sum_i f_{1,i} f_{2,i}. If this is near zero, the features are orthogonal (uncorrelated when mean-centered) and both can be included without multicollinearity. If it is not zero, they may need to apply Gram-Schmidt orthogonalization.

The formula, piece by piece

  • ⟨x,y⟩\langle x, y\rangle: the inner product of xx and yy; in Rn\mathbb{R}^n: ∑i=1nxiyi\sum_{i=1}^n x_i y_i
  • =0= 0: the inner product equals exactly zero
  •   ⟺  \iff: if and only if (biconditional); zero inner product is both necessary and sufficient
  • x⊥yx \perp y: xx is orthogonal (perpendicular) to yy; angle between them is 90°90°
  • Geometric interpretation: cos⁡θ=⟨x,y⟩∥x∥∥y∥=0⇒θ=90°\cos\theta = \frac{\langle x,y\rangle}{\|x\|\|y\|} = 0 \Rightarrow \theta = 90°

The formula in words

"Two vectors are perpendicular if and only if their dot product is zero. There is no directional overlap between them: one has no component in the direction of the other." Tiny examples:

  • x=(1,0)x = (1, 0), y=(0,1)y = (0, 1): ⟨x,y⟩=0\langle x,y\rangle = 0. These are the standard basis vectors, clearly perpendicular. ✓\checkmark
  • x=(3,4)x = (3, 4), y=(4,−3)y = (4, -3): ⟨x,y⟩=12−12=0\langle x,y\rangle = 12 - 12 = 0. Orthogonal. ✓\checkmark
  • x=(1,1)x = (1, 1), y=(1,2)y = (1, 2): ⟨x,y⟩=1+2=3≠0\langle x,y\rangle = 1+2 = 3 \neq 0. Not orthogonal.

Critical Concepts

  • Pythagorean theorem: if x⊥yx \perp y, then ∥x+y∥2=∥x∥2+∥y∥2\|x+y\|^2 = \|x\|^2 + \|y\|^2. Proof: ∥x+y∥2=⟨x+y,x+y⟩=∥x∥2+2⟨x,y⟩+∥y∥2=∥x∥2+∥y∥2\|x+y\|^2 = \langle x+y, x+y\rangle = \|x\|^2 + 2\langle x,y\rangle + \|y\|^2 = \|x\|^2 + \|y\|^2 when ⟨x,y⟩=0\langle x,y\rangle = 0.
  • Orthonormal: a set of vectors that are mutually orthogonal AND each has unit norm: ⟨xi,xj⟩=δij\langle x_i, x_j\rangle = \delta_{ij} (Kronecker delta: 1 if i=ji=j, 0 otherwise).
  • OLS projection: the residual e^=y−y^=y−Xβ^\hat{e} = y - \hat{y} = y - X\hat{\beta} satisfies ⟨xj,e^⟩=0\langle x_j, \hat{e}\rangle = 0 for every column xjx_j of XX. This is the normal equation XT(y−Xβ^)=0X^T(y - X\hat{\beta}) = 0.
  • PCA components: eigenvectors of a symmetric matrix corresponding to distinct eigenvalues are orthogonal. PCA exploits this to find uncorrelated directions of variance.
  • Near-zero threshold: in floating point, use a tolerance (e.g., abs(np.dot(x, y)) < 1e-10) rather than exact equality.
  • Gram-Schmidt: the algorithm that takes any set of linearly independent vectors and produces an orthonormal basis by successively removing projections.

Step-by-step calculation (tiny example)

Step 1: Pick two vectors and compute the inner product x=(2,−1,0)x = (2, -1, 0), y=(1,2,5)y = (1, 2, 5). ⟨x,y⟩=2⋅1+(−1)⋅2+0⋅5=2−2+0=0\langle x, y\rangle = 2\cdot1 + (-1)\cdot2 + 0\cdot5 = 2 - 2 + 0 = 0.

Step 2: Conclude orthogonality ⟨x,y⟩=0⇒x⊥y\langle x, y\rangle = 0 \Rightarrow x \perp y.

Step 3: Verify via Pythagorean theorem ∥x∥2=4+1+0=5\|x\|^2 = 4+1+0 = 5. ∥y∥2=1+4+25=30\|y\|^2 = 1+4+25 = 30. ∥x+y∥2=∥(3,1,5)∥2=9+1+25=35=5+30\|x+y\|^2 = \|(3,1,5)\|^2 = 9+1+25 = 35 = 5+30. ✓\checkmark (Pythagorean theorem holds.)

Code examples

Beginner example (Python)

python
import numpy as np

# -- Orthogonality check: inner product == 0 ---
# Standard basis vectors
e1 = np.array([1.0, 0.0, 0.0])
e2 = np.array([0.0, 1.0, 0.0])
e3 = np.array([0.0, 0.0, 1.0])
print("Standard basis orthogonality:")
for i, u in enumerate([e1, e2, e3]):
    for j, v in enumerate([e1, e2, e3]):
        if i < j:
            ip = np.dot(u, v)
            print(f" <e{i+1}, e{j+1}> = {ip:.4f} orthogonal: {np.isclose(ip, 0)}")

# Custom vectors
x = np.array([2.0, -1.0, 0.0])
y = np.array([1.0, 2.0, 5.0])
ip = np.dot(x, y)
print(f"\n<x, y> = {ip:.4f} orthogonal: {np.isclose(ip, 0)}")

# Pythagorean theorem verification
print(f"Pythagorean check: ||x||^2 + ||y||^2 = {np.dot(x,x) + np.dot(y,y):.4f}")
print(f" ||x+y||^2 = {np.dot(x+y, x+y):.4f}")

Beginner example (R)

r
# -- Orthogonality check ---
x <- c(2, -1, 0)
y <- c(1, 2, 5)
inner_product <- sum(x * y)
cat(sprintf("<x, y> = %.4f\n", inner_product))
cat(sprintf("Orthogonal: %s\n", isTRUE(all.equal(inner_product, 0))))

# Pythagorean theorem
cat(sprintf("||x||^2 + ||y||^2 = %.4f\n", sum(x^2) + sum(y^2)))
cat(sprintf("||x+y||^2 = %.4f\n", sum((x+y)^2)))

Professional example (Python)

python
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
np.random.seed(42)

# -- Business scenario: verify PCA components are orthogonal ---
# PCA components must be mutually orthogonal by construction.
# This validates the orthogonality condition in a real DS workflow.
N_SAMPLES = 500
N_FEATURES = 5

# Correlated feature data (simulated customer metrics)
raw_data = np.random.randn(N_SAMPLES, N_FEATURES)
raw_data[:, 1] += 0.8 * raw_data[:, 0]   # feature1 correlated with feature0
raw_data[:, 2] += 0.5 * raw_data[:, 0]   # feature2 partially correlated
scaler = StandardScaler()
data_scaled = scaler.fit_transform(raw_data)
pca = PCA(n_components=N_FEATURES)
pca.fit(data_scaled)
components = pca.components_   # shape: (n_components, n_features)

# Verify orthogonality: <component_i, component_j> should be 0 for i != j
print("PCA component orthogonality check:")
violations = 0
for i in range(N_FEATURES):
    for j in range(i + 1, N_FEATURES):
        ip = np.dot(components[i], components[j])
        is_ortho = np.isclose(ip, 0, atol=1e-10)
        if not is_ortho:
            violations += 1
        print(f" <PC{i+1}, PC{j+1}> = {ip:.2e} orthogonal: {is_ortho}")
print(f"\nTotal violations: {violations} (expected: 0)")
print(f"Variance explained per component: {np.round(pca.explained_variance_ratio_, 4)}")
print("\nConclusion: PCA components are mutually orthogonal by construction.")
print("This means each component captures variance not explained by any other.")

Source: MML1 p. 82

#linear-algebra#spatial-distance-norms-and-analytic-geometry#angles-and-orthogonality

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