5  Matrisemultiplikasjon

Matrisemultiplikasjon brukes når vi vil kombinere transformasjoner på vektorer, eller når vi ønsker å transformere matriser.

Gitt to matriser

\[ A \in \mathbb{R}^{m \times n}, \quad B \in \mathbb{R}^{n \times p}, \]

defineres produktet \(C = AB\) som en ny matrise \(C \in \mathbb{R}^{m \times p}\). Hvert element \(c_{ij}\) lages ved å ta rad \(i\) i \(A\) og kolonne \(j\) i \(B\) og summere elementvis:

\[ c_{ij} = \sum_{k=1}^{n} a_{ik} \, b_{kj}. \]

For at dette skal være mulig, må antall kolonner i \(A\) være lik antall rader i \(B\) (\(n\)).


5.0.1 Eksempel — Samme matriser, to rekkefølger

Vi starter med de to matrisene

\[ A = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}, \quad B = \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 1 & 1 \end{bmatrix}. \]

Først \(AB\)
\(A\) er \(2\times 3\) og \(B\) er \(3\times 2\), så produktet blir en \(2\times 2\) matrise:

\[ AB = \begin{bmatrix} 4 & 5 \\ 10 & 11 \end{bmatrix}. \]

\(BA\)
Nå er \(B\) \(3\times 2\) og \(A\) \(2\times 3\), så produktet blir en \(3\times 3\) matrise:

\[ BA = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 5 & 7 & 9 \end{bmatrix}. \]

Dette viser en viktig egenskap:

For matriser gjelder som regel \(AB \ne BA\). Matrisemultiplikasjon er altså ikke-kommutativ, i motsetning til vanlig tallmultiplikasjon.

Kodeeksempel: Python Her ser vi at symbolet @ kan brukes for matrisemultiplikasjon

import numpy as np

A = np.array([[1, 2, 3],
              [4, 5, 6]])
B = np.array([[1, 0],
              [0, 1],
              [1, 1]])

C = A @ B
print(C)

C = B @ A
print(C)

Kodeeksempel: Julia
Her ser vi at symbolet * brukes for matrisemultiplikasjon.

A = [1 2 3;
     4 5 6]

B = [1 0;
     0 1;
     1 1]

C = A * B
println(C)

C = B * A
println(C)

Indreprodukt, ytreprodukt og matrise–vektor-produkt
Som vi har sett tidligere, kan alle vektor-operasjoner betraktes som spesialtilfeller av matrise–matrise-multiplikasjon (kombinert med transponering).

5.1 Formelle Egenskaper

Matrisemultiplikasjon har følgende formelle egenskaper som gjelder for all matriser

  • Assosiativitet:
    For matriser \(A \in \mathbb{R}^{m \times n}\), \(B \in \mathbb{R}^{n \times p}\), og \(C \in \mathbb{R}^{p \times q}\), har vi: \[ A(BC) = (AB)C \] Vi kan derfor skrive slike produkter som \(ABC\) uten parenteser.

  • Distributivitet over addisjon:
    For \(A \in \mathbb{R}^{m \times n}\) og \(B, C \in \mathbb{R}^{n \times p}\): \[ A(B + C) = AB + AC \] Og for \(B, C \in \mathbb{R}^{m \times n}\) og \(D \in \mathbb{R}^{n \times p}\): \[ (B + C)D = BD + CD \]

  • Skalar-assosiativitet:
    Hvis \(c \in \mathbb{R}\) er en skalar, og \(A \in \mathbb{R}^{m \times n}\), \(B \in \mathbb{R}^{n \times p}\), så gjelder: \[ c(AB) = (cA)B = A(cB) \]

  • Eksistens av identitet:
    Identitetsmatrisen \(I_n \in \mathbb{R}^{n \times n}\) er et nøytralt element for multiplikasjon: \[ AI_n = A \quad \text{og} \quad I_mA = A \] for alle \(A \in \mathbb{R}^{m \times n}\).

  • Transponat av produkter:
    Transponatet av et produkt er produktet av transponatene i motsatt rekkefølge: \[ (AB)^\top = B^\top A^\top \]

  • Ikke-kommutativitet:
    Generelt gjelder det at \(AB \ne BA\).

  • Nullelement:
    Hvis \(A \in \mathbb{R}^{m \times n}\) og \(0\) er nullmatrisen med passende dimensjon, så gjelder: \[ A0 = 0 \quad \text{og} \quad 0A = 0 \] > ** Oppgave: Lag selv en matrise \(A \in \mathbb{R}^{m \times n}\) og en matrise \(B \in \mathbb{R}^{n \times p}\), og bruk dem til å verifisere hver av egenskapene over.
    > Gjenta med ulike dimensjoner og verdier. Sjekk spesielt at \(AB\) og \(BA\) generelt ikke er like.
    > For å lage en identitetsmatrise kan du bruke np.eye(n) i Python eller I(n) i Julia.
    > Koden nedenfor genererer tilfeldige matriser som du kan bruke til å sjekke kriteriene.

Python

import numpy as np

m, n, p = 2, 3, 4  # dimensjoner
A = np.random.randint(-5, 6, size=(m, n))  # heltall fra -5 til 5
B = np.random.randint(-5, 6, size=(n, p))

print("A =\n", A)
print("B =\n", B)

Julia:

using LinearAlgebra

m, n, p = 2, 3, 4  # dimensjoner
A = rand(-5:5, m, n)  # heltall fra -5 til 5
B = rand(-5:5, n, p)

println("A =")
println(A)
println("B =")
println(B)

5.2 Ulike representasjoner av matrisemultiplikasjon

Det er ofte nyttig å se på matrisemultiplikasjon fra flere vinkler.
Ulike representasjoner kan gjøre det lettere å koble et praktisk problem til lineær algebra, og gir ofte alternative måter å utføre eller analysere beregninger på.


Matrisemultiplikasjon på kolonneform
Vi kan se produktet \(AB\) som en matrise der hver kolonne er resultatet av \(A\) multiplisert med en kolonne i \(B\).
Om vi representer \(B\) på kollonneform \[ B = [\,b_1 \ \ b_2 \ \dots \ b_p\,], \]
så er
\[ AB = [\,A b_1 \ \ A b_2 \ \dots \ A b_p\,]. \]


Matrisemultiplikasjon på radform
Vi kan se produktet \(AB\) som en matrise der hver rad er resultatet av en rad i \(A\) multiplisert med \(B\).
Skriver vi
\[ A = \begin{bmatrix} a_1^\top \\ a_2^\top \\ \vdots \\ a_m^\top \end{bmatrix}, \]
så er
\[ AB = \begin{bmatrix} a_1^\top B \\ a_2^\top B \\ \vdots \\ a_m^\top B \end{bmatrix}. \]


Matrisemultiplikasjon i blokkform
Hvis \(A\) og \(B\) kan skrives på blokkform, kan vi bruke samme rad–kolonne-regel på blokkene.
Eksempel: hvis \(A\) og \(B\) er delt inn i \(2\times 2\) blokker, \[ A = \begin{bmatrix} A & B \\ C & D \end{bmatrix}, \quad B = \begin{bmatrix} E & F \\ G & H \end{bmatrix}, \] så er \[ AB = \begin{bmatrix} A E + B G & A F + B H \\ C E + D G & C F + D H \end{bmatrix}. \]


Matrisemultiplikasjon som indreprodukter
La \(A \in \mathbb{R}^{m\times n}\) og \(B \in \mathbb{R}^{n\times p}\). Skriv rader og kolonner eksplisitt som \[ A = \begin{bmatrix} a_1^\top \\ a_2^\top \\ \vdots \\ a_m^\top \end{bmatrix}, \qquad B = \begin{bmatrix} \,| & \,| & & \,| \\ b_1 & b_2 & \cdots & b_p \\ \,| & \,| & & \,| \end{bmatrix}. \] Da er hvert element i \(C=AB\) gitt ved indreprodukt: \[ c_{ij} = a_i^\top b_j, \] og hele produktet kan skrives som \[ AB = \begin{bmatrix} a_1^\top b_1 & a_1^\top b_2 & \cdots & a_1^\top b_p \\ a_2^\top b_1 & a_2^\top b_2 & \cdots & a_2^\top b_p \\ \vdots & \vdots & \ddots & \vdots \\ a_m^\top b_1 & a_m^\top b_2 & \cdots & a_m^\top b_p \end{bmatrix}. \]


Matrisemultiplikasjon som ytreprodukter
Skriv \(A\) etter kolonner og \(B\) etter rader: \[ A = \begin{bmatrix} \,| & \,| & & \,| \\ a_1 & a_2 & \cdots & a_n \\ \,| & \,| & & \,| \end{bmatrix}, \qquad B = \begin{bmatrix} b_1^\top \\ b_2^\top \\ \vdots \\ b_n^\top \end{bmatrix}. \] Da kan produktet uttrykkes som en sum av ytreprodukter: \[ AB \;=\; a_1 b_1^\top \;+\; a_2 b_2^\top \;+\; \cdots \;+\; a_n b_n^\top \;=\; \sum_{k=1}^{n} a_k b_k^\top. \]

5.3 Gram-matriser

Et viktig matriseprodukt i lineær algebra er

\[ G = A^\top A. \]
For en matrise \(A \in \mathbb{R}^{m\times n}\) får vi at \(G \in \mathbb{R}^{n\times n}\).
Denne matrisen kalles Gram-matrisen, og er en viktig matrise for lineær algebra, f.eks. i miste-kvadraters metode.

5.3.1 Kolonnetolkning

Skriver vi \(A\) på kolonneform
\[ A = [\,a_1 \ a_2 \ \dots \ a_n\,], \]
så får vi
\[ \quad g_{ij} = a_i^\top a_j \]

  • Diagonalene \(g_{ii} = \|a_i\|^2\) gir lengden til hver kolonnevektor.
  • Utenom-diagonalene \(g_{ij}\) beskriver indreproduktet mellom kolonnene

Generelt har vi for indreprodukt at

\[ g_{ij} = \| a_i \| \| a_j \| \cos \theta \]

Hvis kolonnene er normaliserte så er dette som er cosinus-likheten mellom kolonnevektorene.

5.3.2 Eksempel: en \(3\times 2\) matrise

La oss ta en enkel matrise
\[ A = \begin{bmatrix} 1 & 2 \\ 0 & 1 \\ 1 & 0 \end{bmatrix}. \]

Her har vi to kolonner \[ a_1 = \begin{bmatrix}1 \\ 0 \\ 1\end{bmatrix}, \qquad a_2 = \begin{bmatrix}2 \\ 1 \\ 0\end{bmatrix}. \]

Gram-matrisen er \[ G = A^\top A = \begin{bmatrix} a_1 \cdot a_1 & a_1 \cdot a_2 \\ a_2 \cdot a_1 & a_2 \cdot a_2 \end{bmatrix}. \]

Vi regner ut:
- \(a_1 \cdot a_1 = 1^2 + 0^2 + 1^2 = 2\)
- \(a_2 \cdot a_2 = 2^2 + 1^2 + 0^2 = 5\)
- \(a_1 \cdot a_2 = 1\cdot 2 + 0\cdot 1 + 1\cdot 0 = 2\)

Dermed får vi
\[ G = \begin{bmatrix} 2 & 2 \\ 2 & 5 \end{bmatrix}. \]


Julia-kode

using LinearAlgebra

A = [1 2;
     0 1;
     1 0]

G = A' * A

println("A =")
println(A)
println("Gram-matrisen G = A' * A =")
println(G)

5.3.3 Normalisering av kolonner med matriseprodukt

Eksempelet cosinus-likheter viser at det noen ganger er nyttig å normalisere kollonevektorene i en matrise. Gitt en matrise \(A \in \mathbb{R}^{m\times n}\) med kolonner \(a_1, a_2, \dots, a_n\). Da kan vi definere den diagonale matrisen
\[ D = \operatorname{diag}\!\Big(\tfrac{1}{\|a_1\|}, \tfrac{1}{\|a_2\|}, \dots, \tfrac{1}{\|a_n\|}\Big). \]

Slik at for matrisen \[ \tilde A = A D \]
så er hver kollonnone normalisert til lengde \(\|\tilde{a}_i\|=1\) .

5.3.4 Korrelasjonsmatriser

I kapitlet om vektorer og vektorprodukt så vi at korrelasjonen mellom to datavektorer kan tolkes som cosinus-likheten mellom de tilhørende enhetsvektorene. Har vi mange datasett \(x^{(1)}, x^{(2)}, \dots, x^{(n)}\), kan vi samle alle de parvise korrelasjonene i en korrelasjonsmatrise.

Hvis vi lager matrisen

\[ \tilde X = [\, \hat{\tilde x}^{(1)} \ \hat{\tilde x}^{(2)} \ \dots \ \hat{\tilde x}^{(n)} \,], \]

hvor hver kolonne er en sentrert og normalisert dataserie, så er

\[ R = \tilde X^\top \tilde X \]

korrelasjonsmatrisen.

  • Diagonalene blir \(R_{ii} = 1\) hver dataserie eller datavektor er fullt korrelert med seg selv.
  • Utenom-diagonalene \(R_{ij}\) gir korrelasjonen mellom datavektorern \(i\) og \(j\).

Korrelasjonsmatriser er viktige i statistikk og maskinlæring .

Oppgave: Om vi har en matrise av datavektorer i matrisen \(A\) (som verken er normaliserte eller sentrerte), lag et matematisk uttrykk for korrelasjonsmatrisen..

5.4 Determinanter

En determinant er en funksjon fra en kvadratisk matrise til enkelt tall:

\[ \det: \mathbb{R}^{n\times n} \to \mathbb{R} \]

Geometrisk kan determinanten tolkes som den effektive størrelsen (areal i \(n=2\), volum i \(n=3\), og tilsvarende i høyere dimensjoner) dannet av den geometriske formen kolonnevektorene i matrisen danner (parallelogram i 2 dimensjoner, parellelpiped i 3 dimensjoner). Verdien kan være negativ, noe som betyr at figuren har fått “snudd” orientering sammenlignet med et standard koordinatsystem.

Dette kan forstås med determinanten av diagonalmatrisen. Da er
\[\det(D)= \det\left( \mathrm{diag}(d_1, d_2, \dots, d_n) \right) =\prod_i d_i = d_1d_2\ldots d_n\] hvor \(\prod\) indikerer er produkt av en serie tall på samme måte som \(\sum\) indikerer en sum.

Om alle \(d_i\) er positive, så får vi da en positiv determinant, men om vi bytter retning på en av kolonnevektorene får vi en negativ determinant.

En viktig egenskap med determinanter er at

\[\det(AB) = \det(A)\det(B)\]

Denne egenskaper lar seg lett verifisere for produktet av to diagonale matriser.

area of paralellogram]

For \(2\times 2\)-matriser

\[ A = \begin{bmatrix} a & b \\ c & d \end{bmatrix}, \]

så er

\[ \det(A) = ad - bc, \]

som tilsvarer arealet av parallellogrammet definert av kolonnevektorene \(\begin{bmatrix} a \\ c \end{bmatrix}\) og \(\begin{bmatrix} b \\ d \end{bmatrix}\), med fortegn for orientering.

5.4.1 Areal og volum fra determinanter

Om \(A=[\,u\ v\,]\in\mathbb{R}^{2\times 2}\) med kolonner \(u,v\in\mathbb{R}^2\). Da er \[ \text{areal(parallellogram)} = |\det(A)|. \]

Om \(B=[\,u\ v\ w\,]\in\mathbb{R}^{3\times 3}\) med \(u,v,w\in\mathbb{R}^3\). Da er \[ \text{volum(parallellpiped)} = |\det(B)|. \]

Areal og volum i julia:

using LinearAlgebra

# 2D parallellogram
u = [2.0, 1.0]
v = [1.0, 2.0]
A = [u v]
area = abs(det(A))

# 3D parallellpiped
u3 = [2.0, 1.0, 0.5]
v3 = [1.0, 2.0, 1.0]
w3 = [0.0, 1.0, 2.0]
B = [u3 v3 w3]
volume = abs(det(B))

Areal og volum i python:

import numpy as np

# 2D parallellogram
u = np.array([2.0, 1.0])
v = np.array([1.0, 2.0])
A = np.column_stack([u, v])
area = abs(np.linalg.det(A))

# 3D parallellpiped
u3 = np.array([2.0, 1.0, 0.5])
v3 = np.array([1.0, 2.0, 1.0])
w3 = np.array([0.0, 1.0, 2.0])
B = np.column_stack([u3, v3, w3])
volume = abs(np.linalg.det(B))

Her ser vi at i python må vi bruke column_stack eller en annen metode for å bygge matrisen fra vektorene.

5.4.2 Areal av et flatesegment i rommet

Vi har tidligere sett hvordan determinater kan brukes til å renge ut volum uten å bruke kryssprodukt (og som kan generalisers til hypervolum i mange dimensjoner). Men i mange sammenhenger kan man ønske å vite arealet (eller volum, eller mer generelt hypervolum) til et geometrisk objekt som befinner seg i et større rom.

Et konkret eksempel er et paraellogrammet spent ut av to vektorer \(u,v \in \mathbb{R}^3\) .

Arealet til parallellogrammet kan da beregnes fra Gram-matrisen.

Hvis vi setter opp matrisen
\[ A = [\,u \ v\,] \in \mathbb{R}^{3\times 2}, \]
så er Gram-matrisen
\[ G = A^\top A = \begin{bmatrix} u \cdot u & u \cdot v \\ v \cdot u & v \cdot v \end{bmatrix}. \]

Determinanten av Gram-matriser gir da arealet kvadrert av parellogrammet:
\[ \text{areal}(u,v)^2 = \det(G). \] slik at \[ \text{areal}(u,v) = \sqrt{\det(G)}. \]

Et slikt areal, kan kan f.eks. brukes til å regne ut areaelt til en parellogram-flate i en krystall, utspent av to gittervektorer. I numeriske metoder som finite element analysis (FEM) brukes Gram-determinanter for å regne ut areal og volum til elementer direkte fra hjørnekoordinater.


Julia-kode

using LinearAlgebra

u = [2.0, 1.0, 0.5]
v = [1.0, 2.0, 1.0]

A = [u v]
G = A' * A
area = sqrt(det(G))

println("Gram-matrise G =")
println(G)
println("Areal = ", area)

Merk: Hvis \(\det(G) = 0\), kollapser arealet til null. Dette skjer bare når vektorene \(u\) og \(v\) er lineært avhengige, altså når de peker i samme retning. Gram-determinanten fungerer dermed som en geometrisk test for avhengighet mellom vektorer.

5.4.3 Determinanter i integrasjon

Siden integrasjon summerer mange små volum-/lengdeelementer, har determinanter en viktig rolle i integrasjon.

Én dimensjon (skalering \(y = a x\)).
Ved variabelbytte \(y = a x\) får vi \(dy = a\,dx\), altså \(dx = \tfrac{1}{a}dy\). Dermed får vi for \(a>0\)

\[ \int f(a x)\,dx \;=\; \frac{1}{a}\int f(y)\,dy. \]

5.4.3.1 Eksempel 1: Direkte integrasjon

Om vi har integralet, så kan vi løse det med direkte integrasjon \[ I \;=\; \int_{0}^{10} x\,dx \;=\; \frac{1}{2}x^{2}\Big|_{0}^{10} \;=\; \frac{1}{2}(10^{2}-0) \;=\; 50. \]

Men i mange sammenhenger, enten for å forenkle den analytiske utregningen,
eller for å gjøre numerisk integrasjon lettere og mer systematisk,
ønsker vi å omforme integralet slik at det går mellom \(0\) og \(1\).

5.4.3.2 Eksempel 2: Samme integral med substitusjon \(u = x/10\)

Om vi setter \(u = x/10\). Da er \(x = 10u\) og \(dx = 10\,du\).

Når \(x=0 \Rightarrow u=0\), og når \(x=10 \Rightarrow u=1\).

\[ I = \int_{0}^{10} x\,dx = (10)(10)\int_{0}^{10} \frac{x}{10}\,\frac{dx}{10} = 100 \int_{0}^{1} u\,\,du = 100 \cdot \tfrac{1}{2} = 50. \] Her ser vi at intervallet \([0,10]\) blir skalert ned til \([0,1]\), men både \(x\) og \(dx\) får en faktor \(10\). Resultatet blir selvsagt det samme som direkte utregning.


Flere dimensjoner (lineært bytte \(y = A x\)).

I høyere dimensjoner skjer det samme prinsippet: volumelementet skaleres når vi gjør et variabelbytte.

Setter vi \(y = A x\) for en invertibel matrise \(A \in \mathbb{R}^{n\times n}\), får vi at differensialelementene henger sammen som

\[ dy = |\det A|\,dx, \]

der \(dx\) og \(dy\) står for de \(n\)-dimensjonale volum-elementene.

Dermed får vi

\[ \int_{\Omega_x} f(Ax)\,dx \;=\; \int_{\Omega_y} f(y)\,\frac{1}{|\det A|}\,dy. \]

Her er \(|\det A|\) volumfaktoren (Jacobianen) som beskriver hvordan en lineær transformasjon strekker eller komprimerer volumet.
- Hvis \(|\det A| > 1\), blåses volumet opp.
- Hvis \(|\det A| < 1\), presses volumet sammen.
- Hvis \(\det A < 0\), skjer det i tillegg en speiling.

Ikke-lineært koordinatbytte

For en mer generell funksjon \(y=g(x)\) i én dimensjon, blir faktoren gitt av absoluttverdien av den deriverte \(g'(x)\), som tilsvarer det lokale stigningstallet (og spiller samme rolle som \(a\) i det lineære tilfellet):

\[ \int f(g(x))\,dx = \int f(y)\,\frac{dy}{|g'(x)|}. \]

I flere dimensjoner, med en funksjon

\[y=g(x)\]

der \(g:\mathbb{R}^n \to \mathbb{R}^n\), spiller den Jacobianske matrisen den samme rollen som \(A\) for det lineære tilfellet:

\[ J(x) = \begin{bmatrix} \frac{\partial y_1}{\partial x_1} & \cdots & \frac{\partial y_1}{\partial x_n} \\ \vdots & \ddots & \vdots \\ \frac{\partial y_n}{\partial x_1} & \cdots & \frac{\partial y_n}{\partial x_n} \end{bmatrix}. \]

Dette gir den generelle regelen

\[ \int f(g(x))\,dx = \int f(y)\,\frac{dy}{|\det J(x)|}. \]

5.4.4 Store matriser

Som vi har sett, kan determinanter brukes til å regne ut areal og volum, og de kan også brukes til å avgjøre om et ligningssystem har en unik løsning. De har også viktige teoretiske egenskaper og dukker ofte opp i teoretiske utledninger.

I praktisk analyse av svært store matriser (som i mange områder av maskinlæring) regnes man ofte ikke ut determinanter. De kan være sensitive for avrunnignsfeil og kostbare å regne ut. Man finner ofte ut det man trenger ved hjelp av andre metoder for eksempel når man skal avgjøre om et ligningssystem kan løses.

5.5 Rotasjonsmatriser

En rotasjonsmatrise beskriver en rotasjon av vektorer. I to dimensjoner kan en rotasjon med vinkel \(\theta\) mot klokken skrives som \[ R(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}. \]

I tre dimensjoner kan vi for eksempel rotere rundt \(z\)-aksen: \[ R_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}. \]

5.5.1 Eksempel: rotasjon av flere punkter

La oss starte med et sett punkter i planer.
Ved å multiplisere hver av disse vektorene med \(R(\theta)\), får vi en rotasjon av hele figuren eller figursegementet uten at avstander eller vinkler endres.

Koden nedenfor viser hvordan vi kan rotere et sett med punkter

Julia:

using LinearAlgebra
using Plots

# --- Rotation matrix (input in degrees) ---
R_deg(angle_deg) = [cosd(angle_deg) -sind(angle_deg);
                    sind(angle_deg)  cosd(angle_deg)]

# --- Define a simple figure ("house") as polylines ---
square = [0 0; 1 0; 1 1; 0 1; 0 0]
roof   = [0 1; 0.5 1.5; 1 1]
door   = [0.35 0; 0.35 0.55; 0.65 0.55; 0.65 0; 0.35 0]

# --- Rotate directly with R * P' ---
angle_deg = 10.0
R = R_deg(angle_deg)

sq_rot   = (R * square')'
roof_rot = (R * roof')'
door_rot = (R * door')'

# --- Plot ---
plt = plot(size=(600,600), aspect_ratio=1, grid=true, legend=:topleft,
           xlabel="x", ylabel="y", title="Rotate 2D points by $(Int(round(angle_deg)))°")

# original (black)
plot!(square[:,1], square[:,2], label="Original", color=:black)
plot!(roof[:,1],   roof[:,2],   label="", color=:black)
plot!(door[:,1],   door[:,2],   label="", color=:black)

# rotated (red)
plot!(sq_rot[:,1],   sq_rot[:,2],   label="Rotated", color=:red)
plot!(roof_rot[:,1], roof_rot[:,2], label="", color=:red)
plot!(door_rot[:,1], door_rot[:,2], label="", color=:red)

xlims!(-1, 2); ylims!(-1, 2)
display(plt)

Kommentar: Her ser vi at Julia har funksjon sind og cosd som svarer til sinus og cosinus men som tar grader som input istedenfor radianer.

I eksempel over definerte vi en funksjon (fra et tall til en matrise) med å bare skrive

R_deg(angle_deg) = [cosd(angle_deg) -sind(angle_deg);
                    sind(angle_deg)  cosd(angle_deg)]

Dette er en meget enkel måte å skrive en funksjon på.

I Python måtte vi derimot brukt mer omstendelig syntaks, for eksempel:

import numpy as np
def R_deg(a):
    c, s = np.cos(np.deg2rad(a)), np.sin(np.deg2rad(a))
    return np.array([[c,-s],[s,c]])

P = np.array([[0,0],[1,0],[1,1],[0,1],[0,0]])  # square
P_rot = (R_deg(10) @ P.T).T

eller en lambda-definisjon.

5.5.2 Gjentatte rotasjoner

Om vi har en rotasjon, så er er produktet av to rotasjoner også en rotasjon \[R'' = R' R\] Som vist i eksempelet under:

using LinearAlgebra
using Plots

# --- Rotation matrix (input in degrees) ---
R_deg(angle_deg) = [cosd(angle_deg) -sind(angle_deg);
                    sind(angle_deg)  cosd(angle_deg)]

# --- Define a simple figure ("house") as polylines ---
square = [0 0; 1 0; 1 1; 0 1; 0 0]
roof   = [0 1; 0.5 1.5; 1 1]
door   = [0.35 0; 0.35 0.55; 0.65 0.55; 0.65 0; 0.35 0]

# --- Two rotation angles ---
angle1 = 10.0
angle2 = 10.0

R1 = R_deg(angle1)
R2 = R_deg(angle2)

# Combined rotation
R_combined = R2 * R1   # equivalent to rotation by (angle1 + angle2)

# --- Apply rotations ---
sq_rot1   = (R1 * square')'
roof_rot1 = (R1 * roof')'
door_rot1 = (R1 * door')'

sq_rot2   = (R_combined * square')'
roof_rot2 = (R_combined * roof')'
door_rot2 = (R_combined * door')'

# --- Plot ---
plt = plot(size=(600,600), aspect_ratio=1, grid=true, legend=:topleft,
           xlabel="x", ylabel="y",
           title="Composition of Rotations: $(Int(angle1))° + $(Int(angle2))°")

# original (black)
plot!(square[:,1], square[:,2], label="Original", color=:black)
plot!(roof[:,1],   roof[:,2],   label="", color=:black)
plot!(door[:,1],   door[:,2],   label="", color=:black)

# first rotation (red)
plot!(sq_rot1[:,1],   sq_rot1[:,2],   label="After $(Int(angle1))°", color=:red)
plot!(roof_rot1[:,1], roof_rot1[:,2], label="", color=:red)
plot!(door_rot1[:,1], door_rot1[:,2], label="", color=:red)

# combined rotation (blue)
plot!(sq_rot2[:,1],   sq_rot2[:,2],   label="After $(Int(angle1+angle2))°", color=:blue)
plot!(roof_rot2[:,1], roof_rot2[:,2], label="", color=:blue)
plot!(door_rot2[:,1], door_rot2[:,2], label="", color=:blue)

xlims!(-1, 2); ylims!(-1, 2)
display(plt)


5.5.3 Egenskaper til rotasjonsmatriser

Fra geometrien vet vi at at en rotasjonsmatrise må ha følgende egenskaper:

  1. Bevaring av lengder
    For alle vektorer \(x\): \(\|Rx\| = \|x\|\).

  2. Bevaring av vinkler
    Med cosinuslikhet \(\cos\phi = \dfrac{a\cdot b}{\|a\|\|b\|}\) følger at
    \((Ra)\cdot(Rb) = a\cdot b\) for alle \(a,b\).

Satt i matriseform: \[ (Ra)^\top(Rb) = a^\top b \ \Rightarrow\ a^\top(R^\top R)b = a^\top b\ \forall a,b \ \Rightarrow\ R^\top R = I. \]

  1. Bevaring av orientering
    Når vi roterer en hel figur (et sett punkter), skal geometrien bevares uten å bli “vrengt” som ved et speilbilde (eller inversjon). Dette skiller rotasjoner fra refleksjoner, og uttrykkes matematisk som \[ \det(R) = +1. \] Hvis \(\det(R) = -1\), blir orienteringen snudd selv om avstander og vinkler er uendret.

    For å skille rotasjon fra inversjon+rotasjon krever vi at \[ \det(R) = +1. \] Hvis dette ikke holder, blir orienteringen invertert (“vrengt”) og det er ikke en rotasjonsmatrise.


5.5.4 Sjekk 2d- rotasjonsmatrise

For \[ R(\theta)=\begin{bmatrix} \cos\theta & -\sin\theta\\ \sin\theta & \ \cos\theta \end{bmatrix} \] får vi:

  1. \(R^\top R = I\): \[ R^\top = \begin{bmatrix} \cos\theta & \sin\theta\\ -\sin\theta & \cos\theta \end{bmatrix},\quad R^\top R = \begin{bmatrix} \cos^2\theta+\sin^2\theta & 0\\ 0 & \cos^2\theta+\sin^2\theta \end{bmatrix} = I. \]

  2. \(\det(R) = \cos^2\theta+\sin^2\theta = 1\).

Dermed oppfyller \(R(\theta)\) kravene til en rotasjonsmatrise.


5.5.5 \(R^\top R = I\)

En rotasjonsmatrise bevarer lengden til alle vektorer: \[ \|R(\theta) x\|^2 = x^\top R(\theta)^\top R(\theta) x = \|x\|^2 \] Dette leder til kravet \(R^\top R = I\)

5.6 Ortogonale matriser

En ortogonal matrise er definert ved \[ Q^\top Q = I, \]

Alle slike matriser har \(\det(Q) = \pm 1\).
- \(\det(Q) = +1\): rotasjon
- \(\det(Q) = -1\): refleksjon eller rotasjon kombinert med refleksjon eller inversjon.

5.6.1 Ortogonale matriser på kolonneform

Om \[ Q = [\,q_1\ q_2\ \dots\ q_n\,] \] er en ortogonal matrise.

Betingelsen \(Q^\top Q = I\) betyr at \[ q_i^\top q_j = 0 \quad\text{for}\ i\ne j, \] og \[ \|q_i\| = 1 \quad\text{for alle}\ i. \] Med andre ord: i en ortogonal matrise, må kolonnevektorene være ortonormale.

I 3d er en viktig matrise en inversjonsmatrise (ikke det samme som en invers-matrise)

\[ O_\mathrm{inv} = \begin{bmatrix} -1 & 0 & 0 \\ 0 & -1 & 0 \\ 0 & 0 & -1 \end{bmatrix}. \]

5.7 Matrisepotenser

Potensen av en matrise \(A^n\) svarer till gjentatte matrisemultiplikasjoner, for eksempel, så er

\[ A^3 = AAA=(AA)A = A(AA) \]

Eksempel: la oss ta matrisen

\[ A = \begin{bmatrix} 0.9 & 0.1 \\ 0.2 & 0.8 \end{bmatrix}. \]

I Julia:

A = [0.9 0.1; 0.2 0.8]  
A^4                         
#output: 2×2 Matrix{Float64}:
#        0.7467  0.2533
#        0.5066  0.4934

I Python:

import numpy as np  
A = np.array([[0.9, 0.1],  
              [0.2, 0.8]])  
np.linalg.matrix_power(A, 4)

Mer at du kan ikke bruke ** for pyton for det blir tolket som elementvis. Om du faktisk ønsker elementvise potenser i Julia, så må du skriver A.^4

5.7.1 Oppgave: Hva skjer når vi tar store potenser?

For hver av de tre matrisene under, beregn \(A^n\) for ulike \(n\) (for eksempel \(n=1,2,5,10,20,50\)).
Bruk gjerne Frobenius-normen

\[ \|A^n\|_F = \sqrt{\sum_{i,j} (a^{(n)}_{ij})^2 } \]

som et mål på størrelsen til matrisen.

Undersøk:
- Går matrisen (eller normen) mot null?
- Vokser den?
- Stabiliserer den seg mot en bestemt form?

Matrisene er:

\[ A_1 = \begin{bmatrix} 0.5 & 0.2 \\ 0.1 & 0.4 \end{bmatrix} \]

\[ A_2 = \begin{bmatrix} 1.1 & 0.2 \\ 0.0 & 0.9 \end{bmatrix} \]

\[ A_3 = \begin{bmatrix} 0.9 & 0.1 \\ 0.2 & 0.8 \end{bmatrix} \]

Beskriv med egne ord hva som skjer når \(n\) blir stor i hvert tilfelle.

5.7.2 Matrisespor (trace)

En annen viktig funksjon fra kvadratiske matriser til tall er sporet:

\[ \operatorname{tr}(A) = \sum_{i=1}^n a_{ii}, \]
altså summen av diagonal-elementene.

Egenskaper : - Linearitet: \(\operatorname{tr}(A+B)=\operatorname{tr}(A)+\operatorname{tr}(B)\) og \(\operatorname{tr}(\alpha A)=\alpha\,\operatorname{tr}(A)\).
- Transponat: \(\operatorname{tr}(A^\top)=\operatorname{tr}(A)\).
- Rotasjonsregel For matriser av passende størrelse gjelder
\[ \operatorname{tr}(AB)=\operatorname{tr}(BA), \] og mer generelt \(\operatorname{tr}(ABC)=\operatorname{tr}(BCA)=\operatorname{tr}(CAB)\).


Matrisespor av Gram-matriser.
Hvis \(G = A^\top A\) er Gram-matrisen til kolonnene i \(A=[\,a_1 \ \cdots \ a_n\,]\), så får vi

\[ \operatorname{tr}(G)=\sum_{j=1}^n \|a_j\|^2. \]

Sporet summerer altså opp lengdene (i kvadrat) av alle kolonnene i \(A\).
Mens Gram-matrisen samler alle indreprodukt, gir sporet av Gram matrisen summen av alle normene.


Eksempel.
For matrisen
\[ A=\begin{bmatrix} 1 & 2\\ 0 & 1\\ 1 & 0 \end{bmatrix}, \qquad G=A^\top A=\begin{bmatrix}2&2\\2&5\end{bmatrix}, \] har vi \[ \operatorname{tr}(G)=2+5=7, \] og dette stemmer med summen av kvadrerte elementer i \(A\): +

\(1^2+0^2+1^2+2^2+1^2+0^2=7\).


Oppgaver 1. Regn ut sporet av et par små matriser og sjekk at \(\operatorname{tr}(A^\top A)=\sum_{i,j} a_{ij}^2\).
2. La \(A\) være en \(m\times n\) matrise. Bruk definisjonen av Gram-matrise til å vise at \(\operatorname{tr}(A^\top A)\) er summen av lengdene i kvadrat av kolonnene.


5.8 Inversmatrisen

For matriser hvor \(\mathrm{det} (A) \neq 0\), så finnes en inversmatrise. Den defineres av matrisen som oppfyller

\[ A A^{-1} = A^{-1} A = I, \]

der \(I\) er identitetsmatrisen. En matrise hvor det finnes en invers, kalles inverterbar.


For enhetsmatrisen gjelder det at \(I^{-1}=I\) , ettersom \(II=I\)


Hvis ingen av diagonalelementene er null, så er den inverterbar, og inversen er gitt ved:

\[ D^{-1} = \begin{bmatrix} 1/d_1 & 0 & 0 & \cdots & 0 \\ 0 & 1/d_2 & 0 & \cdots & 0 \\ 0 & 0 & 1/d_3 & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & 1/d_n \end{bmatrix}. \]


For ortogonale matriser gjelder det at \[ Q^T Q = Q Q^T = I. \]

Inversmatrisen er derfor gitt ved:

\[ Q^{-1} = Q^T. \]

Eksempel:

\[ Q = \begin{bmatrix} 0 & 1 \\ -1 & 0 \end{bmatrix}, \qquad Q^{-1} = Q^T = \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}. \]


For en \(2 \times 2\)-matrise

\[ A = \begin{bmatrix} a & b \\ c & d \end{bmatrix}, \]

er inversen gitt ved

\[ A^{-1} = \frac{1}{ad-bc}\begin{bmatrix} d & -b \\ -c & a \end{bmatrix}, \]

så lenge \(ad - bc \neq 0\).


For den følgende \(3 \times 3\)-matrisen:

\[ A = \begin{bmatrix} 1 & 2 & 0 \\ 0 & 1 & 1 \\ 1 & 0 & 1 \end{bmatrix}. \]

så er inversen gitt ved

\[ A^{-1} = \begin{bmatrix} 1 & -2 & 2 \\ 1 & -1 & 1 \\ -1 & 2 & -1 \end{bmatrix}. \]

Vi kan sjekke dette ved å multiplisere \(A A^{-1} = I\).


Julia eksempler:

using LinearAlgebra

# Eksempel: ortogonal matrise
Q = [0 1; -1 0]
Q' == inv(Q)   # true

# Eksempel: 3x3 matrise
A = [1 2 0;
     0 1 1;
     1 0 1]
A_inv = inv(A)
isapprox(A * A_inv, I)    # approximate equality

5.9

5.10 Komplekse matriser: Unitære matriser

Vi har tidligere diskutert adjugering, av komplekse materiser, det vil si kombinasjonen av transponering og kompleks konjugering av alle tallene i matrisen

\[ A^{\dagger} \equiv {(A^*)}^{\top} = {(A^\top)}^* \]

Hva er determinant av en adjungert matrise? Vi vet fra tidligere at \(\det (A^\top) = \det A\) . Av dette følger det at

\[\det (A^\dagger) = \det(A)^* \]

Determinanten er altså et komplekst tall, og determinanten av den adjugerte er kompleks konjugerte av dette tallet.


Generaliseringen av ortogonale matriser, altså matriser hvor \(O^\top O = I\), er unitære matriser.
En kvadratisk matrise \(U \in \mathbb{C}^{n\times n}\) er unitær dersom \[ U^{\dagger} U = I \quad\text{(ekvivalent med } UU^{\dagger}=I\text{)}. \] Av dette følger det at

\[(\det U)^* (\det U) = |\det U|² = 1 \]

Dette er oppfylt generelt med en kompleks fasefaktor:

\[\det U = e^{i \phi}\]

Om unitære matriser er generaliseringen av orthgonale matriser. Hva er generaliseringen av rotasjoner? Dette er unitære matriser hvor \(|\det U| = 1\). Slike matriser kalles spesielle unitære matriser. Studiet av slike matriser var sentralt i arbeidet til den norske matematikeren [Sophus Lie](https://no.wikipedia.org/wiki/Sophus_Lie. Han er mindre kjent enn Niels Henrik Abel, men regnes av mange som like viktig.

Når vi er inne på Abel, så kan det nevnes at kommuterende matriser \(AB = BA\), kan representere såkalte Abelske grupper. Norge har hatt altså hatt flere internasjonalt ledende matematikere innen algebra. I nyere tid kan Idun Reiten, tidligere professor ved NTNU neves. >Jeg hadde selv Idun Reiten som foreleser i abstrakt algebra på NTNU. Som studenter flest skjønte vi lite av hvor internasjonalt anerkjent hun faktisk var.


På samme måte som ortogonale matriser kan unitære matriser sees som «lengde- og vinkelbevarende» transformasjoner, men i komplekst rom. De endrer representasjon, men ikke geometri. Alle normer og indreprodukter bevares.

  • Normbevaring: for alle vektorer \(x\) (antar 2-norm) \[ \|Ux\| = \|x\| \]
  • Indreprodukt bevares: for alle \(x,y\) \[ (Ux)^{\dagger}(Uy) = x^{\dagger}y. \]

Dette betyr at både lengder og vinkler bevares, på samme måte som for rotasjoner i det reelle planet.

Kolonnene i en unitær matrise er ortonormale : \[ U = [\,u_1\ u_2\ \dots\ u_n\,], \qquad \langle u_i, u_j \rangle = u_i^{\dagger} u_j = \delta_{ij}. \]


5.10.1 Eksempler

1) Reell rotasjon (2D)
Rotasjonsmatrisen \[ R(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \ \cos\theta \end{bmatrix} \] oppfyller \(R^{\dagger}R = I\), siden \(R^{\dagger}=R^{\top}\). Rotasjoner er derfor unitære (ortogonale i det reelle tilfellet).


2) Ren fasefaktor
En ren kompleks fase \[ U = e^{i\phi} I \] er unitær, siden \(U^{\dagger}U = e^{-i\phi} e^{i\phi} I = I\).
Dette multipliserer alle komponenter med samme fase uten å endre lengden.


3) Diskret Fourier-transform (DFT)

Diskret Fourier-transformasjoner dukker opp i signalbehandling, bildeanalyse, analyse av mekaniske vibrasjoner og mange numeriske algoritmer.

Indeksert definisjon: For \(j,k=1,\dots,n\) er \[ f_{jk} \;=\; \frac{1}{\sqrt{n}}\;\exp\!\Bigl(-2\,i\,\pi\,\frac{(j-1)(k-1)}{n}\Bigr) \;=\; \frac{1}{\sqrt{n}}\;\omega^{(j-1)(k-1)}, \qquad \omega = e^{-2\pi i/n}. \]

Dette kan skriver i potentser av \(\omega\) som følger: \[ F = \frac{1}{\sqrt{n}} \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 \\ 1 & \omega & \omega^2 & \cdots & \omega^{\,n-1} \\ 1 & \omega^2 & \omega^4 & \cdots & \omega^{\,2(n-1)} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & \omega^{\,n-1} & \omega^{\,2(n-1)} & \cdots & \omega^{\,(n-1)(n-1)} \end{bmatrix}. \]

Eksempel \(n=4\): \[ F = \frac{1}{2} \begin{bmatrix} 1 & 1 & 1 & 1 \\ 1 & \omega & \omega^2 & \omega^3 \\ 1 & \omega^2 & \omega^4 & \omega^6 \\ 1 & \omega^3 & \omega^6 & \omega^9 \end{bmatrix}, \qquad \omega = e^{-2\pi i/4} = -i. \]

Setter vi inn verdiene for \(\omega\): \[ F = \tfrac{1}{2} \begin{bmatrix} 1 & 1 & 1 & 1 \\ 1 & -i & -1 & i \\ 1 & -1 & 1 & -1 \\ 1 & i & -1 & -i \end{bmatrix}. \]

Med denne normaliseringen gjelder

\[ F^{\dagger}F = I, \] Det vil også si at \(F^{\dagger} = F^{\text{inv}}\) Mer at i noen bøker er DFT skalert med respektivt \(1\) og \(1/n\) i den inverse transformasjonene. Her bruker vi \(1/\sqrt n\) slik at \(F\) er unitær.”


5.10.2 Julia: sjekk av unitaritet

Her gjør vi sjekk av unitaritet for rotasjon, fasefaktor og DFT.

using LinearAlgebra

# Test for unitarity: U†U ≈ I and UU† ≈ I
is_unitary(U; atol=1e-12, rtol=1e-12) =
    isapprox(U' * U, I, atol=atol, rtol=rtol) &&
    isapprox(U * U', I, atol=atol, rtol=rtol)

# 1) 2D rotation (real ⇒ orthogonal ⇒ unitary)
theta = 0.3
R = [cos(theta) -sin(theta); sin(theta) cos(theta)]
println("R unitær? ", is_unitary(R))

# 2) Pure phase (multiple of identity)
phi = 0.7
Uphase = exp(im*phi) * I(3)
println("exp(i*phi) * I unitær? ", is_unitary(Uphase))

# 3) DFT (n=4), normalized by 1/sqrt(n)
function dft_matrix(n)
    w = exp(-2im*pi/n)
    [w^((j-1)*(k-1)) for j in 1:n, k in 1:n] / sqrt(n)
end

n = 4
F = dft_matrix(n)

println("F unitær? ", is_unitary(F))
# Optional: print residual norms (spectral norm of the difference)
println("‖F'F - I‖₂ = ", opnorm(F' * F - I))
println("‖FF' - I‖₂ = ", opnorm(F * F' - I))

5.10.3 Mini-oppgaver

  1. Vis at kolonnene i en unitær matrise er ortonormale.
  2. Bruk matrisen \(F\) for \(n=4\) til å sjekke at \(\|Fx\|_2=\|x\|_2\) for en vilkårlig vektor \(x \in \mathbb{C}^4\).
  3. Forklar hvorfor \(e^{i\phi}\) ikke endrer lengden til en kompleks skalar.

5.10.4 Fast Fourier transform implementasjon av F

DFT kan uttrykkes som en matriseoperasjon \(y = Fx\), men for store \(n\) koster dette \(O(n^2)\) multiplikasjoner. I praksis bruker man i stedet Fast Fourier Transform (FFT) som reduserer kompleksiteten til \(O(n \log n)\). Resultatet er det samme, men beregningen går svært mye raskere.

I Julia leveres FFT gjennom FFTW-biblioteket.

Merk om konvensjoner:
- DFT-matrisen vår er normalisert med \(1/\sqrt{n}\) slik at \(F\) er unitær.
- fft(x) i Julia/FFTW er ikke normalisert: den tilsvarer \(Fx \cdot \sqrt{n}\).
- ifft(x) er normalisert med \(1/n\): den tilsvarer \(F^{\dagger}x / \sqrt{n}\).

Med andre ord: \[ \texttt{fft}(x) \;\approx\; \sqrt{n}\, (F x), \qquad \texttt{ifft}(x) \;\approx\; \frac{1}{\sqrt{n}}\,(F^{\dagger}x). \] Sammenligning av de:

using LinearAlgebra, FFTW, Random
Random.seed!(0)

# DFT-matrise
function dft_matrix(n)
    w = exp(-2im*pi/n)
    [w^((j-1)*(k-1)) for j in 1:n, k in 1:n] / sqrt(n)
end

n = 4
F = dft_matrix(n)
x = randn(n)

y_matrix = F * x
y_fft    = fft(x) / sqrt(n)   # FFTW uses unnormalized convention

println("DFT via matrise: ", y_matrix)
println("DFT via FFTW:    ", y_fft)
println("Forskjellnorm:   ", norm(y_matrix - y_fft))

FFT kan brukes til å fjerne støy. Man kan f.eks. kaste alt utenom de laveste frekvensene. Merk at de største potensene av \(\omega\) svarer egentlig til lave potenser (fordi \(\omega^n=1\) )

using LinearAlgebra, Random, FFTW, Plots

# Samme funksjon og støy som før
n = 200
xs = range(0, 5, length=n)
f_true = xs .* exp.(-xs)
Random.seed!(1)
f_noisy = f_true .+ 0.02*randn(n)

# Enkel FFT-lavpass
function fft_lowpass(x; k::Int=20)
    F = fft(x)
    G = zeros(ComplexF64, length(x))
    G[1:k] .= F[1:k]                    # behold de første k
    G[end-k+1:end] .= F[end-k+1:end]    # behold de siste k
    return real(ifft(G))
end

# Bruk funksjonen
f_lp10 = fft_lowpass(f_noisy; k=10)
f_lp15 = fft_lowpass(f_noisy; k=15)

# Plot sammenligning
plot(xs, f_noisy, alpha=0.4, lw=1, label="Støyete data")
plot!(xs, f_true, lw=2, color=:black, label="f(x) = x e^{-x}")
plot!(xs, f_lp10, lw=2, color=:blue, label="FFT lavpass (k=10)")
plot!(xs, f_lp15, lw=2, color=:green, label="FFT lavpass (k=15)")
xlabel!("x"); ylabel!("f(x)")
title!("FFT-basert filtrering med justerbar parameter k")

Her ser vi at denne typen filter må må balansere støyfjerning mot å bevare de ekte detaljene i signalet, for hardt filter kan gi kunstige oscillasjoner (ringing). Man kan få bedre resultater med å introdusere mykere cutoff.

Noen ganger ønsker man i stedet å fjerne mykt bakgrunnsspekter fordi det er de finere detlajene i spekteret som er de viktige, og da fjerner man i stedet de lavere frekvensene. Dette kalles et høypassfilter, og lages på samme måte ved å beholde de høye i stedet for de lave frekvensene (til forskjell fra et lavpassfilter). Her ser vi at denne typen filter må balansere støyfjerning mot å bevare de ekte detaljene i signalet.
For hard cutoff kan gi kunstige oscillasjoner (ringing). Man kan få bedre resultater med en mykere cutoff.

Generelt viser FFT-basert støyfjerning at i mange tilfeller trenger man ikke alle dataene for å representere informasjonen. Selv om \(k=20\) ikke kunne fjerne støyet (bare endre dets karakter), så tar det vare på all informasjonen i signalet.
Dette prinsippet – at mye av dataene er overflødig mens informasjonen kan ligge i en lavdimensjonal representasjon – er sentralt i datavitenskap.