De kolommen van een reële $$N \times N$$-matrix $$A$$ kunnen geïnterpreteerd worden als vectoren in een $$N$$-dimensionale ruimte. Deze vectoren zijn niet noodzakelijk orthonormaal (d.w.z. onderling loodrecht en met lengte 1). Het Gram-Schmidt algoritme construeert uitgaande van de kolommen van $$A$$ een reeks van $$N$$ vectoren, allen lineaire combinaties van de kolommen van $$A$$ die wel orthonormaal zijn.
Noem $$\vec{x_i}$$ de vector die geassocieerd is met de $$i$$-de kolom van $$A$$. In een eerste stap zoeken we $$N$$ vectoren $$\vec{y_i}$$
die onderling loodrecht zijn, namelijk:
$$
\vec{y_0} = \vec{x_0}
$$
en voor $$0 < i < N$$:
$$
\vec{y_i} = \vec{x_i} - \sum_{j=0}^{i-1} \frac{\vec{x_i}\cdot\vec{y_j}}{\vec{y_j}\cdot\vec{y_j}} \vec{y_j}
$$
In deze uitdrukking staat $$\vec{a} \cdot \vec{b}$$ voor het scalair product van de vectoren $$\vec{a}$$ en
$$\vec{b}$$.
In een laatste stap, normeren we de vectoren $$\vec{y_i}$$, namelijk
$$
\vec{z_i} = \frac{\vec{y_i}}{||\vec{y_i}||}
$$
met $$||\vec{a}||$$ de klassieke norm van de vector $$\vec{a}$$, gedefinieerd als de vierkantswortel uit de som van de kwadraten
van de componenten van $$\vec{a}$$.
Schrijf de functie orthonormaal()
met als enig argument een NumPy-tabel, met $$N$$ rijen en $$N$$ kolommen, en $$N > 0$$.
Het resultaat van de functie is een NumPy-tabel, eveneens bestaande uit $$N$$ rijen en $$N$$ kolommen, waarvan de kolommen de vectoren $$\vec{z_i}$$
voorstellen, verkregen via de hierboven beschreven aanpak. Je mag aannemen dat de originele tabel niet-singulier is.
a = [[1.0, 2.0, 3.0],[4.0, 5.0, 6.0], [9.0, 8.0, 4.0]] orthonormaal(np.array(a)) = [[ 0.10101525 0.61796622 -0.77968819] [ 0.40406102 0.69066813 0.59976014] [ 0.90913729 -0.37562653 -0.17992804]]