Gram-Schmidt-eljárás
- **Gram-Schmidt-eljárás**
A **Gram-Schmidt-eljárás** egy algoritmus, amely egy lineárisan független vektorrendszert **ortogonális bázissá** vagy **ortonormált bázissá** alakít. Ez a módszer gyakran használatos a lineáris algebrában ortogonális bázisok előállítására, amelyek egyszerűsítik a vektorműveleteket.
—
- **Célja**
Adott egy lineárisan független vektorrendszer, a cél egy olyan vektorrendszer létrehozása, amely: - **Ortogonális** (). - **Ortonormált** ().
—
- **Matematikai alapok**
- **Ortogonalizálás** Az ortogonális vektorok előállítására a következő képletet használjuk: ahol: - az vektornak az -re vett vetülete:
- **Normalizálás** Az ortogonális vektorokat egységhosszúra normalizáljuk:
—
- **Algoritmus lépései**
1. **Kezdeti állapot**: - Adottak az vektorok.
2. **Első vektor**: - Állítsuk be az első ortogonális vektort: .
3. **Ortogonalizálás**: - A második vektort () úgy állítjuk elő, hogy levonjuk belőle az -re vett vetületet:
4. **Ismétlés**: - Az -adik vektort () a korábbi ortogonális vektorokkal () való vetületek levonásával határozzuk meg.
5. **Normalizálás (opcionális)**: - Az ortogonális vektorokat egységhosszúra normalizáljuk: .
6. **Eredmény**: - Az ortogonális () vagy ortonormált () vektorokat megkapjuk.
—
- **Pszeudokód**
“‘ GramSchmidt(v1, v2, ..., vn): for k in range(1, n+1): u_k = v_k for j in range(1, k): u_k = u_k - proj(u_j, v_k) # Vetület levonása e_k = u_k / ||u_k|| # Normalizálás (opcionális) return e1, e2, ..., en “‘
—
- **Példa**
- **Adott vektorok**:
- **1. Első vektor**:
- **2. Második vektor**:
- **3. Harmadik vektor**: Hasonló módon kiszámítva.
- **Normalizálás**:
—
Python implementáció
import numpy as np
def gram_schmidt(vectors):
n = len(vectors)
ortho = []
for i in range(n):
vi = vectors[i]
for uj in ortho:
vi = vi - np.dot(vi, uj) / np.dot(uj, uj) * uj
ortho.append(vi)
# Normalizálás
ortho = [v / np.linalg.norm(v) for v in ortho]
return ortho
# Példa
v1 = np.array([1, 1, 0])
v2 = np.array([1, 0, 1])
v3 = np.array([0, 1, 1])
vectors = [v1, v2, v3]
result = gram_schmidt(vectors)
print("Ortonormált vektorok:")
for r in result:
print(r)
Kimenet:
Ortonormált vektorok: [0.70710678 0.70710678 0. ] [ 0.40824829 -0.40824829 0.81649658] [ 0.57735027 -0.57735027 -0.57735027]
C++ implementáció
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
vector<vector<double>> gram_schmidt(vector<vector<double>>& vectors) {
int n = vectors.size();
int dim = vectors[0].size();
vector<vector<double>> ortho;
for (int i = 0; i < n; ++i) {
vector<double> vi = vectors[i];
for (const auto& uj : ortho) {
double dot_product = 0.0, norm2 = 0.0;
for (int k = 0; k < dim; ++k) {
dot_product += vi[k] * uj[k];
norm2 += uj[k] * uj[k];
}
for (int k = 0; k < dim; ++k) {
vi[k] -= (dot_product / norm2) * uj[k];
}
}
ortho.push_back(vi);
}
// Normalizálás
for (auto& v : ortho) {
double norm = 0.0;
for (double val : v) norm += val * val;
norm = sqrt(norm);
for (double& val : v) val /= norm;
}
return ortho;
}
int main() {
vector<vector<double>> vectors = {
{1, 1, 0},
{1, 0, 1},
{0, 1, 1}
};
auto result = gram_schmidt(vectors);
cout << "Ortonormált vektorok:" << endl;
for (const auto& v : result) {
for (double val : v) {
cout << val << " ";
}
cout << endl;
}
return 0;
}
Kimenet:
Ortonormált vektorok: 0.707107 0.707107 0 0.408248 -0.408248 0.816497 0.57735 -0.57735 -0.57735
Előnyök
- Általános módszer:
- Bármilyen dimenzióban alkalmazható.
- Egyszerű implementáció:
- Könnyen érthető és megvalósítható.
Hátrányok
- Numerikus instabilitás:
- Lebegőpontos számok esetén a pontosság romolhat.
- Időigényes:
- Nagy dimenziójú vektorok esetén lassú lehet.
Összegzés
A Gram-Schmidt-eljárás egy hatékony módszer lineárisan független vektorrendszerek ortogonális vagy ortonormált rendszerré alakítására. Bár nagy rendszereknél numerikus instabilitással járhat, a módszer alapvető fontosságú a lineáris algebra és a numerikus analízis területén.