lapack tridiag - 特征向量错误符号
lapack tridiag - eigenvectors wrong sign
我正在使用 lapack 函数 tridiag 在无限方井的模拟中找到汉密尔顿的特征向量,我似乎随机得到一个错误的符号(在这种情况下 p=4 和 6):
红色是理论,绿色是模拟
(他们也没有归一化,但我认为这是正常的?)
这是代码:
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
extern "C"
void dsteqr_( char * , int *, double [], double [], double [], int *, double [],
int * ) ;
void tridiag( int n, double d[], double e[], double z[] )
/* Appel du sous-programme dsteqr de Lapack : calcul des valeurs et vecteurs
propres d'une matrice tridiagonale symmetrique */
{
int info ; // diagnostic
double work[2*n-2] ; // espace de travail
char compz='v' ; // mettre 'n' pour n'avoir que les valeurs propres
dsteqr_( &compz, &n, d, e, z, &n, work, &info ) ; // scalaires pointeurs
if ( info == 0 ) cout << "La diagonalisation s'est bien passée" << endl ;
else cout << "Attention ! SSTEQR : info =" << info << endl ;
}
double V(double x){
return 0;
}
int main() {
int n=100;
double d[n], e[n-1], z[n*n], x[n], v[n], L = 5, delta_x = L/n;
ofstream of1("eigenvalues.dat"), of2("eigenvectors.dat");
for(int i=0; i<n; i++){
for (int j=0; j<n; j++){
if (i == j) z[i+n*j] = 1;
else z[i+n*j] = 0;
}
x[i] = (i+0.5)*delta_x - 0.5*L;
v[i] = V(x[i]);
d[i] = 2/pow(delta_x, 2) + v[i];
if (i<n-2){
e[i] = -1/pow(delta_x, 2);
}
}
tridiag(n,d,e,z);
for (int i=0; i<n; i++){
of1 << d[i] << endl;
for (int j=0; j<n; j++){
of2 << z[i+n*j] << " ";
}
of2 << x[i] << endl;
}
of1.close();
of2.close();
return 0;
}
所以有人知道发生了什么事吗?
您的数值结果的幅度大于参考结果的幅度是由于L=5
。 LAPACK 的归一化将对应于 L=1
。要获得正确的向量,请将所有值除以 L
!
关于符号...如果您在正交基中更改向量的符号,结果仍然是正交基。此外,如果 A
是 Hermitian 矩阵并且如果 x
是向量使得 A.x=l.x
其中 l
是标量,则 A.(-x)=l.(-x)
。所以你得到的向量的符号不是很重要......此外,如果矩阵具有多次相同的特征值,则结果可以包含与该特征值相关联的子空间的任何标准正交基。例如,如果矩阵 A
是恒等式,则任何标准正交基都是 dsteqr()
.
的可接受结果
我正在使用 lapack 函数 tridiag 在无限方井的模拟中找到汉密尔顿的特征向量,我似乎随机得到一个错误的符号(在这种情况下 p=4 和 6):
红色是理论,绿色是模拟
(他们也没有归一化,但我认为这是正常的?)
这是代码:
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
extern "C"
void dsteqr_( char * , int *, double [], double [], double [], int *, double [],
int * ) ;
void tridiag( int n, double d[], double e[], double z[] )
/* Appel du sous-programme dsteqr de Lapack : calcul des valeurs et vecteurs
propres d'une matrice tridiagonale symmetrique */
{
int info ; // diagnostic
double work[2*n-2] ; // espace de travail
char compz='v' ; // mettre 'n' pour n'avoir que les valeurs propres
dsteqr_( &compz, &n, d, e, z, &n, work, &info ) ; // scalaires pointeurs
if ( info == 0 ) cout << "La diagonalisation s'est bien passée" << endl ;
else cout << "Attention ! SSTEQR : info =" << info << endl ;
}
double V(double x){
return 0;
}
int main() {
int n=100;
double d[n], e[n-1], z[n*n], x[n], v[n], L = 5, delta_x = L/n;
ofstream of1("eigenvalues.dat"), of2("eigenvectors.dat");
for(int i=0; i<n; i++){
for (int j=0; j<n; j++){
if (i == j) z[i+n*j] = 1;
else z[i+n*j] = 0;
}
x[i] = (i+0.5)*delta_x - 0.5*L;
v[i] = V(x[i]);
d[i] = 2/pow(delta_x, 2) + v[i];
if (i<n-2){
e[i] = -1/pow(delta_x, 2);
}
}
tridiag(n,d,e,z);
for (int i=0; i<n; i++){
of1 << d[i] << endl;
for (int j=0; j<n; j++){
of2 << z[i+n*j] << " ";
}
of2 << x[i] << endl;
}
of1.close();
of2.close();
return 0;
}
所以有人知道发生了什么事吗?
您的数值结果的幅度大于参考结果的幅度是由于L=5
。 LAPACK 的归一化将对应于 L=1
。要获得正确的向量,请将所有值除以 L
!
关于符号...如果您在正交基中更改向量的符号,结果仍然是正交基。此外,如果 A
是 Hermitian 矩阵并且如果 x
是向量使得 A.x=l.x
其中 l
是标量,则 A.(-x)=l.(-x)
。所以你得到的向量的符号不是很重要......此外,如果矩阵具有多次相同的特征值,则结果可以包含与该特征值相关联的子空间的任何标准正交基。例如,如果矩阵 A
是恒等式,则任何标准正交基都是 dsteqr()
.