Gå til indholdet

Tutorial 2: Ortogonale Matricer

Vi har allerede tyvstartet på ortogonale matricer i tidligere sessioner, hvor vi placerede vektorer i matricer for at tjekke, om de var ortogonale. Dette gjorde vi, da det var nemmere end at tjekke alle prikprodukter. I denne tutorial vil vi se på, hvad det betyder for en matrix at være ortogonal.

Ortogonale matricer er en vigtig klasse af matricer, der har en række nyttige egenskaber, især inden for 3D-grafik og lineære transformationer. Denne tutorial vil udforske disse matricer i detaljer, inklusive forskellen mellem ortogonalitet og ortonormalitet, og hvordan man ortogonaliserer en matrix.


Definition af en Ortogonal Matrix

En kvadratisk matrix \( \mathbf{M} \) er ortogonal, hvis og kun hvis produktet af matricen og dens transponerede er lig med identitetsmatricen \( \mathbf{I} \):

\[ \mathbf{M}\mathbf{M}^T = \mathbf{I} \]

Dette er ækvivalent med at sige, at den transponerede af \( \mathbf{M} \) er lig med dens inverse:

\[ \mathbf{M}^T = \mathbf{M}^{-1} \]

Denne egenskab er særlig værdifuld, da den gør det meget nemmere at beregne den inverse af en ortogonal matrix, da man blot kan transponere den.

Gram-matricen og dens betydning

Når vi arbejder med ortogonale matricer, er Gram-matricen et nyttigt værktøj til at analysere relationerne mellem en matrix' søjler eller rækker.

Gram-matricen for en matrix \( \mathbf{M} \) defineres som:

\[ \mathbf{G} = \mathbf{M}^T \mathbf{M} \]

Dette betyder, at Gram-matricen indeholder alle prikprodukter mellem søjlerne i \( \mathbf{M} \).

Egenskaber ved Gram-matricen

  • Hvis \( \mathbf{G} \) er diagonal, betyder det, at søjlerne i \( \mathbf{M} \) er ortogonale.
  • Hvis \( \mathbf{G} \) er identitetsmatricen, er søjlerne i \( \mathbf{M} \) både ortogonale og normaliserede, dvs. \( \mathbf{M} \) er ortonormal.
  • Gram-matricen bruges også i metoder som Gram-Schmidt-ortogonalisering og i mindste kvadraters metode i statistik og machine learning.

💡 Hvis en matrix er ortogonal, vil dens Gram-matrix være diagonal, men ikke nødvendigvis identitetsmatricen. Dette betyder, at ortogonale matricer kan indeholde skalering, mens ortonormale matricer ikke gør.

💻 Beregning af Gram-matricen

import numpy as np

# Definer en matrix
M = np.array([[3, 0],
              [0, 2]])

# Beregn Gram-matricen
G = M.T @ M

print("Gram-matrix:\n", G)

💻 Tjek om en matrix er ortogonal (med tolerance)

import numpy as np

M = np.array([[0, -2, 0],
              [5, 0, 0],
              [0, 0, 3]])

G = M.T @ M  # Gram-matricen

tolerance = 1e-4  # Definer tolerance for numerisk præcision

# Tjek om G er diagonal (alle ikke-diagonale elementer skal være tæt på 0)
is_orthogonal = np.allclose(G - np.diag(np.diagonal(G)), 0, atol=tolerance)

# print
print("Er matricen ortogonal?", is_orthogonal)
🔹 Bemærk: På grund af floating-point afrundingsfejl bruger vi en tolerance på \(10^{-4}\), når vi sammenligner med identitetsmatricen. Du kan ændre tolerancen ved at justere tolerance-variablen.

💻 Tjek om en matrix er ortonormal (med tolerance)

import numpy as np

# Definer en matrix
M = np.array([[0.7071,0.5,0.5],
              [-0.7071,0.5,0.5],
              [0.0,-0.7071,0.7071]])

tolerance = 1e-4  # Definer tolerance for numerisk præcision

# Tjek om M er ortogonal ved at sammenligne med identitetsmatricen
# Bemærk Gram matricen beregnes som M @ M.T
is_orthonormal = np.allclose(M @ M.T, np.eye(3), atol=tolerance)

print("Er matricen ortonormal?", is_orthonormal)

Geometrisk fortolkning

Ortogonale matricer repræsenterer transformationer, der bevarer længder og vinkler. De omfatter:

  • Rotationer: Roterer rummet omkring en akse.
  • Refleksioner: Spejler rummet omkring en akse eller et plan.

💻 En rotationsmatrix om z-aksen

import numpy as np

theta = np.radians(45)  # Rotation på 45 grader
R = np.array([[np.cos(theta), -np.sin(theta), 0],
              [np.sin(theta),  np.cos(theta), 0],
              [0, 0, 1]])

# Tjek om R er ortogonal med tolerance
tolerance = 1e-4
print("Er rotationsmatricen ortogonal?", np.allclose(R @ R.T, np.eye(3), atol=tolerance))

Gram-Schmidt Ortogonalisering

Givet en basis af vektorer \( \mathbf{r}_1, \mathbf{r}_2, ..., \mathbf{r}_n \), konstruerer Gram-Schmidt en ortogonal basis:

💻 Implementering af Gram-Schmidt

def gram_schmidt(X):
    """ Udfører Gram-Schmidt ortogonalisering på søjlerne af X """
    Q = np.zeros_like(X, dtype=float)
    for i in range(X.shape[1]):
        q = X[:, i]
        for j in range(i):
            q -= np.dot(Q[:, j], X[:, i]) * Q[:, j]
        q /= np.linalg.norm(q)
        Q[:, i] = q
    return Q

# Definer en matrix med lineært uafhængige vektorer
A = np.array([[3, 1],
              [2, 2],
              [2, 3]], dtype=float)

Q = gram_schmidt(A)
print("Ortogonaliseret matrix:\n", Q)
print("Er den ortonormal?", np.allclose(Q.T @ Q, np.eye(Q.shape[1]), atol=1e-4))

Konklusion

  • En ortogonal matrix opfylder \( \mathbf{M}^T = \mathbf{M}^{-1} \).
  • Ortonormale matricer har søjler/rækker, der er både ortogonale og normaliserede.
  • Gram-Schmidt er en nyttig metode til at ortogonalisere vektorer.
  • Ortogonale matricer bevarer længder og vinkler og bruges bl.a. til 3D-transformationer.
  • Vi bruger en tolerance på \(10^{-4}\) for at tage højde for floating-point afrundingsfejl. Værdien kan sættes op eller ned efter behov.