Exercises NotebookMath for LLMs

Riemannian Geometry

Differential Geometry / Riemannian Geometry

Run notebook
Exercises Notebook

Exercises Notebook

Converted from exercises.ipynb for web reading.

Exercises: Riemannian Geometry

There are 10 exercises. Exercises 1-3 are mechanics, 4-6 are theory, and 7-10 connect differential geometry to AI systems.

Code cell 2

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

try:
    import seaborn as sns
    sns.set_theme(style="whitegrid", palette="colorblind")
    HAS_SNS = True
except ImportError:
    plt.style.use("seaborn-v0_8-whitegrid")
    HAS_SNS = False

mpl.rcParams.update({
    "figure.figsize":    (10, 6),
    "figure.dpi":         120,
    "font.size":           13,
    "axes.titlesize":      15,
    "axes.labelsize":      13,
    "xtick.labelsize":     11,
    "ytick.labelsize":     11,
    "legend.fontsize":     11,
    "legend.framealpha":   0.85,
    "lines.linewidth":      2.0,
    "axes.spines.top":     False,
    "axes.spines.right":   False,
    "savefig.bbox":       "tight",
    "savefig.dpi":         150,
})
np.random.seed(42)
print("Plot setup complete.")

Code cell 3


COLORS = {
    "primary":   "#0077BB",
    "secondary": "#EE7733",
    "tertiary":  "#009988",
    "error":     "#CC3311",
    "neutral":   "#555555",
    "highlight": "#EE3377",
}

def header(title):
    print("\n" + "=" * 72)
    print(title)
    print("=" * 72)

def check_true(condition, name):
    ok = bool(condition)
    print(f"{'PASS' if ok else 'FAIL'} - {name}")
    assert ok, name

def check_close(value, target, tol=1e-8, name="value"):
    ok = abs(float(value) - float(target)) <= tol
    print(f"{'PASS' if ok else 'FAIL'} - {name}: got {float(value):.6f}, expected {float(target):.6f}")
    assert ok, name

def normalize(x):
    x = np.asarray(x, dtype=float)
    n = np.linalg.norm(x)
    if n == 0:
        raise ValueError("cannot normalize zero vector")
    return x / n

def tangent_projection_sphere(x, v):
    x = normalize(x)
    v = np.asarray(v, dtype=float)
    return v - np.dot(x, v) * x

def exp_sphere(x, v):
    x = normalize(x)
    v = tangent_projection_sphere(x, v)
    n = np.linalg.norm(v)
    if n < 1e-12:
        return x.copy()
    return np.cos(n) * x + np.sin(n) * v / n

def retract_sphere(x, v):
    return normalize(np.asarray(x, dtype=float) + np.asarray(v, dtype=float))

def slerp(x, y, t):
    x = normalize(x)
    y = normalize(y)
    dot = np.clip(np.dot(x, y), -1.0, 1.0)
    theta = np.arccos(dot)
    if theta < 1e-12:
        return x.copy()
    return (np.sin((1 - t) * theta) * x + np.sin(t * theta) * y) / np.sin(theta)

def riemannian_gradient_sphere(x, euclidean_grad):
    return tangent_projection_sphere(x, euclidean_grad)

def sphere_descent(target, steps=20, eta=0.3):
    target = normalize(target)
    x = normalize(np.array([1.0, 0.2, 0.1]))
    values = []
    for _ in range(steps):
        values.append(float(-np.dot(target, x)))
        egrad = -target
        rgrad = riemannian_gradient_sphere(x, egrad)
        x = retract_sphere(x, -eta * rgrad)
    values.append(float(-np.dot(target, x)))
    return x, np.array(values)

def stiefel_tangent_projection(Q, Z):
    Q = np.asarray(Q, dtype=float)
    Z = np.asarray(Z, dtype=float)
    sym = 0.5 * (Q.T @ Z + Z.T @ Q)
    return Z - Q @ sym

def qr_retraction(Y):
    Q, R = np.linalg.qr(Y)
    signs = np.sign(np.diag(R))
    signs[signs == 0] = 1.0
    return Q @ np.diag(signs)

def spd_from_eigs(eigs):
    Q = np.array([[np.cos(0.4), -np.sin(0.4)], [np.sin(0.4), np.cos(0.4)]])
    return Q @ np.diag(eigs) @ Q.T

def mat_log_spd(A):
    vals, vecs = np.linalg.eigh(A)
    return vecs @ np.diag(np.log(vals)) @ vecs.T

def mat_invsqrt_spd(A):
    vals, vecs = np.linalg.eigh(A)
    return vecs @ np.diag(1.0 / np.sqrt(vals)) @ vecs.T

def spd_distance(A, B):
    C = mat_invsqrt_spd(A) @ B @ mat_invsqrt_spd(A)
    return float(np.linalg.norm(mat_log_spd(C), ord="fro"))

print("Differential-geometry helpers ready.")

Exercise 1: Adding inner products to tangent spaces (*)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 5

# Your Solution - Exercise 1
answer = None
print("Your answer placeholder:", answer)

Code cell 6

# Solution - Exercise 1
header("Exercise 1: Riemannian Geometry")
x = normalize(np.array([1.0, 2.0, 2.0]))
v = tangent_projection_sphere(x, np.array([3.0, -1.0, 0.5]))
check_close(np.dot(x, v), 0.0, tol=1e-10, name="sphere tangent condition")
print("Tangent vector:", np.round(v, 4).tolist())
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")

Exercise 2: Length angle and distance on curved spaces (*)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 8

# Your Solution - Exercise 2
answer = None
print("Your answer placeholder:", answer)

Code cell 9

# Solution - Exercise 2
header("Exercise 2: Riemannian Geometry")
x = normalize(np.array([1.0, 0.0, 0.0]))
y = normalize(np.array([0.0, 1.0, 0.0]))
mid = slerp(x, y, 0.5)
check_true(abs(np.linalg.norm(mid) - 1.0) < 1e-10, "geodesic midpoint stays on sphere")
print("Midpoint:", np.round(mid, 4).tolist())
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")

Exercise 3: Why Euclidean gradients are coordinate-dependent (*)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 11

# Your Solution - Exercise 3
answer = None
print("Your answer placeholder:", answer)

Code cell 12

# Solution - Exercise 3
header("Exercise 3: Riemannian Geometry")
x = normalize(np.array([0.5, 0.5, 1.0]))
egrad = np.array([1.0, -2.0, 0.5])
rgrad = riemannian_gradient_sphere(x, egrad)
check_close(np.dot(x, rgrad), 0.0, tol=1e-10, name="projected gradient tangent")
print("Projected gradient:", np.round(rgrad, 4).tolist())
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")

Exercise 4: Curvature as changing geometry (**)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 14

# Your Solution - Exercise 4
answer = None
print("Your answer placeholder:", answer)

Code cell 15

# Solution - Exercise 4
header("Exercise 4: Riemannian Geometry")
Q = np.eye(3, 2)
Z = np.array([[1.0, 0.5], [0.2, -0.4], [0.3, 0.7]])
Xi = stiefel_tangent_projection(Q, Z)
check_true(np.linalg.norm(Q.T @ Xi + Xi.T @ Q) < 1e-10, "Stiefel tangent projection")
print("Projected direction norm:", round(float(np.linalg.norm(Xi)), 4))
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")

Exercise 5: Information geometry and natural gradients (**)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 17

# Your Solution - Exercise 5
answer = None
print("Your answer placeholder:", answer)

Code cell 18

# Solution - Exercise 5
header("Exercise 5: Riemannian Geometry")
A = spd_from_eigs([1.0, 2.0])
B = spd_from_eigs([3.0, 4.0])
d = spd_distance(A, B)
check_true(d > 0, "SPD distance is positive for distinct matrices")
print("SPD distance:", round(d, 6))
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")

Exercise 6: Riemannian metric gp(,)g_p(\cdot,\cdot) (**)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 20

# Your Solution - Exercise 6
answer = None
print("Your answer placeholder:", answer)

Code cell 21

# Solution - Exercise 6
header("Exercise 6: Riemannian Geometry")
x = normalize(np.array([1.0, 2.0, 2.0]))
v = tangent_projection_sphere(x, np.array([3.0, -1.0, 0.5]))
check_close(np.dot(x, v), 0.0, tol=1e-10, name="sphere tangent condition")
print("Tangent vector:", np.round(v, 4).tolist())
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")

Exercise 7: Riemannian manifold (M,g)(M,g) (***)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 23

# Your Solution - Exercise 7
answer = None
print("Your answer placeholder:", answer)

Code cell 24

# Solution - Exercise 7
header("Exercise 7: Riemannian Geometry")
x = normalize(np.array([1.0, 0.0, 0.0]))
y = normalize(np.array([0.0, 1.0, 0.0]))
mid = slerp(x, y, 0.5)
check_true(abs(np.linalg.norm(mid) - 1.0) < 1e-10, "geodesic midpoint stays on sphere")
print("Midpoint:", np.round(mid, 4).tolist())
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")

Exercise 8: Length of curves and induced distance (***)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 26

# Your Solution - Exercise 8
answer = None
print("Your answer placeholder:", answer)

Code cell 27

# Solution - Exercise 8
header("Exercise 8: Riemannian Geometry")
x = normalize(np.array([0.5, 0.5, 1.0]))
egrad = np.array([1.0, -2.0, 0.5])
rgrad = riemannian_gradient_sphere(x, egrad)
check_close(np.dot(x, rgrad), 0.0, tol=1e-10, name="projected gradient tangent")
print("Projected gradient:", np.round(rgrad, 4).tolist())
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")

Exercise 9: Riemannian gradient gradf\operatorname{grad} f (***)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 29

# Your Solution - Exercise 9
answer = None
print("Your answer placeholder:", answer)

Code cell 30

# Solution - Exercise 9
header("Exercise 9: Riemannian Geometry")
Q = np.eye(3, 2)
Z = np.array([[1.0, 0.5], [0.2, -0.4], [0.3, 0.7]])
Xi = stiefel_tangent_projection(Q, Z)
check_true(np.linalg.norm(Q.T @ Xi + Xi.T @ Q) < 1e-10, "Stiefel tangent projection")
print("Projected direction norm:", round(float(np.linalg.norm(Xi)), 4))
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")

Exercise 10: Volume forms and integration preview (***)

State the geometric object, compute the low-dimensional example, and interpret the ML relevance.

Code cell 32

# Your Solution - Exercise 10
answer = None
print("Your answer placeholder:", answer)

Code cell 33

# Solution - Exercise 10
header("Exercise 10: Riemannian Geometry")
A = spd_from_eigs([1.0, 2.0])
B = spd_from_eigs([3.0, 4.0])
d = spd_distance(A, B)
check_true(d > 0, "SPD distance is positive for distinct matrices")
print("SPD distance:", round(d, 6))
print("\nTakeaway: curved spaces require tangent, metric, geodesic, or retraction-aware calculations.")