现在有个矩阵计算的需求,需要求出一实数范围上的n阶方阵的特征向量,其中n为常数(即每次输入的方阵阶数都相同),希望下面几个问题可以得到回答:
1. 是否有与此矩阵计算相关的php内部函数?
2. 是否有已经知道的前人写过的相关的函数?
3. 如果上面两个都没有,那么是否可以通过其他语言的程序(比如一个C++程序)来计算,如果是,用php怎么粘接?
4. 如果有人愿意写一个,再感激不过了(额外加100分)
1. 是否有与此矩阵计算相关的php内部函数?
2. 是否有已经知道的前人写过的相关的函数?
3. 如果上面两个都没有,那么是否可以通过其他语言的程序(比如一个C++程序)来计算,如果是,用php怎么粘接?
4. 如果有人愿意写一个,再感激不过了(额外加100分)
http://baike.baidu.com/view/475996.html我也是昨天才翻出线性代数书复习了概念,上面只介绍了一种解法,需要求解齐次线性方程组定义:设A是数域F上的一个n阶方阵,如果存在 λ∈F,使 AX=λX 有非零解:X=(ξ1,ξ2,...,ξn)'∈Fn,则称λ为矩阵A的一个特征值,而称X为属于特征值的一个特征向量。
矩阵v为特征向量矩阵, pArray为为特征值
------------------------------------------------
void Matrix :: Jacobbi ( Matrix& v , double* pArray )
{
int p , q , j , ind ,n;
double dsqr , d1 , d2 , thr , dv1 , dv2 , dv3 , dmu , dga , st , ct ;
double eps = 0.00000001;
int* iZ; //add 2002.8.27 Matrix CA ( *this ) ;
n = Rownum ; //add 2002.8.27
try {
iZ = new int[n] ;
}
catch (std::bad_alloc) { // ENTER THIS BLOCK ONLY IF bad_alloc IS THROWN.
// YOU COULD REQUEST OTHER ACTIONS BEFORE TERMINATING
Application -> MessageBox("不能在堆中分配内存,再见...","异常", MB_OK);
exit(-1);
}
//add 2002.8.27 for ( p = 0 ; p < n ; p ++ )
for ( q = 0 ; q < n ; q ++ )
v.dmat[p][q] = ( p == q ) ? 1.0 : 0 ; dsqr = 0 ;
for ( p = 1 ; p < n ; p ++ )
for ( q = 0 ; q < p ; q ++ )
dsqr += 2 * CA.dmat[p][q]* CA.dmat[p][q] ;
d1 = sqrt ( dsqr ) ;
d2 = eps / n * d1 ;
thr = d1 ;
ind = 0 ;
do {
thr = thr / n ;
while ( !ind ) {
for ( q = 1 ; q < n ; q ++ )
for ( p = 0 ; p < q ; p ++ )
if ( fabs ( CA.dmat[p][q] ) >= thr ) {
ind = 1 ;
dv1 = CA.dmat[p][p] ;
dv2 = CA.dmat[p][q] ;
dv3 = CA.dmat[q][q] ;
dmu = 0.5 * ( dv1 - dv3 ) ;
double dls = sqrt ( dv2 * dv2 + dmu * dmu ) ;
if ( fabs ( dmu ) < 0.00000000001 ) dga = -1 ;
//if ( dmu == 0.0 ) dga = -1.0 ;
else dga = ( dmu < 0 ) ? ( dv2 / dls ): ( - dv2 / dls );
st = dga / sqrt ( 2 * ( 1 + sqrt ( 1 - dga * dga ) ) ) ;
ct = sqrt ( 1 - st * st ) ;
for ( register int l = 0 ; l < n ; l ++ ) {
dsqr = CA.dmat[l][p] * ct - CA.dmat [l][q] * st ;
CA.dmat [l][q] = CA.dmat[l][p] * st + CA.dmat[l][q] * ct ;
CA.dmat [l][p] = dsqr ;
dsqr = v.dmat[l][p] * ct - v.dmat[l][q]*st ;
v.dmat[l][q] = v.dmat[l][p] * st + v.dmat[l][q] * ct ;
v.dmat[l][p] = dsqr ;
}
for ( register int l = 0 ; l < n ; l ++ ) {
CA.dmat[p][l] = CA.dmat[l][p] ;
CA.dmat[q][l] = CA.dmat[l][q] ;
}
CA.dmat [p][p] = dv1 * ct * ct + dv3 * st * st - 2 * dv2 * st * ct;
CA.dmat [q][q] = dv1 * st * st + dv3 * ct * ct + 2 * dv2 * st * ct;
CA.dmat [p][q] = CA.dmat[q][p] = 0.0 ;
}
if ( ind ) ind = 0 ;
else break ;
}
} while ( thr > d2 ) ;
for ( register int l = 0 ; l < n ; l ++ ) {
pArray[l] = CA.dmat[l][l];
iZ [l] = l;
}
//2002.8.27 add
double dTemp ;
int i , k; for ( i = 0 ; i < n ; i++ ){
//dmax = pArray[i];
for ( j = i + 1 ; j < n ; j++ ){
if ( pArray[i] < pArray[j]){
dTemp = pArray[i];
pArray[i] = pArray[j];
pArray[j] = dTemp;
k = iZ[i] ;
iZ[i] = iZ[j];
iZ[j] = k;
}
}
}
CA = v; for ( j = 0 ; j < n ; j++ )
for ( i = 0 ; i < n ; i++ )
v.dmat [i][j] = CA.dmat[i][iZ[j]]; delete[] iZ;
//2002.8.27 end add
}