Gram-Schmidt-eljárás

Innen: testwiki
Ugrás a navigációhoz Ugrás a kereséshez

Sablon:Hunfn

  1. Sablon:Label
      1. **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.

      1. **Célja**

Adott egy {v1,v2,,vn} lineárisan független vektorrendszer, a cél egy olyan {u1,u2,,un} vektorrendszer létrehozása, amely: - **Ortogonális** (uiuj=0,ij). - **Ortonormált** (ui=1).

      1. **Matematikai alapok**
        1. **Ortogonalizálás** Az ortogonális vektorok előállítására a következő képletet használjuk: uk=vkj=1k1projuj(vk) ahol: - projuj(vk) az vk vektornak az uj-re vett vetülete: projuj(vk)=ujvkujujuj
        1. **Normalizálás** Az ortogonális vektorokat egységhosszúra normalizáljuk: ek=ukuk

      1. **Algoritmus lépései**

1. **Kezdeti állapot**: - Adottak az {v1,v2,,vn} vektorok.

2. **Első vektor**: - Állítsuk be az első ortogonális vektort: u1=v1.

3. **Ortogonalizálás**: - A második vektort (v2) úgy állítjuk elő, hogy levonjuk belőle az u1-re vett vetületet: u2=v2proju1(v2)

4. **Ismétlés**: - Az k-adik vektort (vk) a korábbi ortogonális vektorokkal (u1,u2,,uk1) való vetületek levonásával határozzuk meg.

5. **Normalizálás (opcionális)**: - Az ortogonális vektorokat egységhosszúra normalizáljuk: ek=ukuk.

6. **Eredmény**: - Az ortogonális (uk) vagy ortonormált (ek) vektorokat megkapjuk.

      1. **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 “‘

      1. **Példa**
        1. **Adott vektorok**: v1=[110],v2=[101],v3=[011]
        1. **1. Első vektor**: u1=v1=[110]
        1. **2. Második vektor**: u2=v2proju1(v2) proju1(v2)=u1v2u1u1u1=[110][101][110][110][110]=12[110]=[0.50.50] u2=[101][0.50.50]=[0.50.51]
        1. **3. Harmadik vektor**: u3=v3proju1(v3)proju2(v3) Hasonló módon kiszámítva.
        1. **Normalizálás**: e1=u1u1,e2=u2u2,e3=u3u3


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

  1. Általános módszer:
    • Bármilyen dimenzióban alkalmazható.
  2. Egyszerű implementáció:
    • Könnyen érthető és megvalósítható.



Hátrányok

  1. Numerikus instabilitás:
    • Lebegőpontos számok esetén a pontosság romolhat.
  2. 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.

Sablon:Hunl