[Lanczos] - Alcuni strani autovalori
Ciao ragazzi. Vi scrivo per una cosa abbastamza urgente.
Ho scritto un algoritmo di Lanczos in MatLab per ridurre una matrice simmetrica $A$ in forma tridiagonale e poi calcolo i suoi autovalori con il comando eig. Poi ho confrontato gli autovalori di $A$ gli autovalori della matrice triadiagonale $T$ e non riesco a spiegarmi perchè compaiano certi valori. Probabilmente mi sfugge qualcosa in Lancozs? O l'ho implementato in maniera sbagliata?
I testi li ho ho fatti su una matrice simmetrica tale che $A_{i,j} = (i+j)/2$ ottenibile con questo codice:
Mentre questo è l'algoritmo di Lanczos:
Con $N=25$ e $Nmax=15$ ottengo:
Perchè ottengo ad esempio quella serie di 3.4833....? I
Ho scritto un algoritmo di Lanczos in MatLab per ridurre una matrice simmetrica $A$ in forma tridiagonale e poi calcolo i suoi autovalori con il comando eig. Poi ho confrontato gli autovalori di $A$ gli autovalori della matrice triadiagonale $T$ e non riesco a spiegarmi perchè compaiano certi valori. Probabilmente mi sfugge qualcosa in Lancozs? O l'ho implementato in maniera sbagliata?
I testi li ho ho fatti su una matrice simmetrica tale che $A_{i,j} = (i+j)/2$ ottenibile con questo codice:
function A = matrice(N) for i=1:N for j=1:N A(i,j)=(i+j)/2; end end end
Mentre questo è l'algoritmo di Lanczos:
function T = lanczos(A,Nmax) [r c]=size(A); v(:,1)=zeros(r,1); v(:,2)=rand(r,1); v(:,2)=v(:,2)./norm(v(:,2)); beta(1)=0; for j=2:Nmax+1 w(:,j-1) = A*v(:,j) - beta(j-1)*v(:,j-1); alpha(j-1) = w(:,j-1)'*v(:,j-1); w(:,j-1) = w(:,j-1) - alpha(j-1)*v(:,j-1); beta(j)=norm(w(:,j-1)); v(:,j+1) = w(:,j-1)/beta(j); end beta=beta(2:end-1); T = diag(alpha) + diag(beta,-1) + diag(beta,1); end
Con $N=25$ e $Nmax=15$ ottengo:
eigA = -2.3326e+001 -4.4082e-014 -8.8909e-015 -7.1030e-015 -5.2336e-015 -4.4061e-015 -3.2682e-015 -2.9234e-015 -2.7111e-015 -1.8849e-015 -1.3176e-015 -7.5872e-016 2.7761e-016 6.0062e-016 1.0938e-015 1.9615e-015 2.3502e-015 2.9748e-015 3.2312e-015 3.9092e-015 4.7404e-015 6.5309e-015 8.7000e-015 4.8025e-014 3.4833e+002 eigT = -3.4833e+002 -3.4833e+002 -3.4833e+002 -2.3326e+001 -2.3326e+001 -2.3326e+001 -3.6715e-014 2.1872e-014 7.8645e-014 2.3326e+001 2.3326e+001 2.3326e+001 3.4833e+002 3.4833e+002 3.4833e+002
Perchè ottengo ad esempio quella serie di 3.4833....? I
Risposte
Penso di aver trovato la risposta che cercavo. Riporto qua quanto letto online. Magari può essere utile ad altri:
Consiglio la lettura dell'esempio numerico a pagine 162:
http://people.inf.ethz.ch/arbenz/ewp/Ln ... apter9.pdf
Consiglio la lettura dell'esempio numerico a pagine 162:
http://people.inf.ethz.ch/arbenz/ewp/Ln ... apter9.pdf
Ragazzi...continuo ad avere problemi con il metodo di Lanczos. Ho seguito il pdf che ho pubblicato in precedenza.
Sto testando il codice su una matrice simmetrica tale che $A_{i,i}=i$ e $A_{i,j}=1/j$ se $i\ne j$.
Il problema è che finché la matrice è $39\times39$ gli autovalori di $A$ e di $T$ sono simili (almeno quelli estremi), poi da $40\times40$ inizia a calcolare bene solo la prima metà degli autovalori, e aumentando sempre di più la dimensione differiscono sempre di più, anche quelli estremi.
Il numero di iterazioni massimo lo calcolo come $\min(100,N)$.
Questo il codice:
Sarei davvero grato se qualcuno riuscisse ad aiutarmi.
Sto testando il codice su una matrice simmetrica tale che $A_{i,i}=i$ e $A_{i,j}=1/j$ se $i\ne j$.
Il problema è che finché la matrice è $39\times39$ gli autovalori di $A$ e di $T$ sono simili (almeno quelli estremi), poi da $40\times40$ inizia a calcolare bene solo la prima metà degli autovalori, e aumentando sempre di più la dimensione differiscono sempre di più, anche quelli estremi.
Il numero di iterazioni massimo lo calcolo come $\min(100,N)$.
Questo il codice:
function [T,alpha,beta,r] = lanczos_ort(A,Nmax) % Lanczos con riortogonalizzazione [nr nc]=size(A); Q(:,1) = ones(nr,1)./norm(ones(nr,1)); r=A*Q(:,1); alpha(1) = Q(:,1)'*r; r = r - alpha(1)*Q(:,1); beta(1)=norm(r); for j=2:Nmax Q(:,j)=r./beta(j-1); r = A*Q(:,j)-beta(j-1)*Q(:,j-1); alpha(j) = Q(:,j)'*r; r = r - Q*(Q'*r); beta(j) = norm(r); if (beta(j)==0) T = diag(alpha)+diag(beta(1:end-1),1)+diag(beta(1:end-1),-1); printf("Happy Breakdown\n"); return; end end T = diag(alpha) + diag(beta(1:end-1),-1) + diag(beta(1:end-1),1); end
Sarei davvero grato se qualcuno riuscisse ad aiutarmi.