Exercises Notebook
Converted from
exercises.ipynbfor web reading.
Exercises: Manifolds
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: Why curved spaces need local coordinates (*)
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: Manifolds")
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: The manifold hypothesis in ML (*)
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: Manifolds")
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: Local Euclidean behavior vs global curvature (*)
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: Manifolds")
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: Charts atlases and coordinate patches (**)
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: Manifolds")
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: Examples: sphere torus Stiefel Grassmann SPD matrices (**)
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: Manifolds")
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: Topological manifold (**)
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: Manifolds")
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: Smooth atlas and smooth compatibility (***)
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: Manifolds")
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: Smooth manifold (***)
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: Manifolds")
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: Smooth maps between manifolds (***)
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: Manifolds")
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: Embedded and immersed submanifolds (***)
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: Manifolds")
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.")