求特征值 特征向量1

//此算法两个关键点,1、特征向量矩阵初始化为单位矩阵 2、被求取的是对称矩阵(列向量为特征向量)

//jacobi.h

#pragma once

void jacobi(unsigned int n, double *a, double *d, double *v);

//jacobi.cpp

#include "jacobi.h"
#include <math.h>
#include <stdio.h>


/*! This static function computes the eigenvalues and
eigenvectors of a SYMMETRIC nxn matrix. This method is used
internally by OpenBabel, but may be useful as a general
eigenvalue finder.


The algorithm uses Jacobi transformations. It is described
e.g. in Wilkinson, Reinsch "Handbook for automatic computation,
Volume II: Linear Algebra", part II, contribution II/1. The
implementation is also similar to the implementation in this
book. This method is adequate to solve the eigenproblem for
small matrices, of size perhaps up to 10x10. For bigger
problems, you might want to resort to the sophisticated routines
of LAPACK.


\note If you plan to find the eigenvalues of a symmetric 3x3
matrix, you will probably prefer to use the more convenient
method findEigenvectorsIfSymmetric()


@param n the size of the matrix that should be diagonalized


@param a array of size n^2 which holds the symmetric matrix
whose eigenvectors are to be computed. The convention is that
the entry in row r and column c is addressed as a[n*r+c] where,
of course, 0 <= r < n and 0 <= c < n. There is no check that the
matrix is actually symmetric. If it is not, the behaviour of
this function is undefined. On return, the matrix is
overwritten with junk.


@param d pointer to a field of at least n doubles which will be
overwritten. On return of this function, the entries d[0]..d[n-1]
will contain the eigenvalues of the matrix.


@param v an array of size n^2 where the eigenvectors will be
stored. On return, the columns of this matrix will contain the
eigenvectors. The eigenvectors are normalized and mutually
orthogonal.
*/


#define TOL 1e-3f
#define MAX_SWEEPS 50


void jacobi(unsigned int n, double *a, double *d, double *v)
{
double onorm, dnorm;
double b, dma, q, t, c, s;
double atemp, vtemp, dtemp;
register int i, j, k, l;


// Set v to the identity matrix, set the vector d to contain the
// diagonal elements of the matrix a

d[0] = a[0];
d[1] = a[4];
d[2] = a[8];



for (l = 1; l <= MAX_SWEEPS; l++)
{
// Set dnorm to be the maximum norm of the diagonal elements, set
// onorm to the maximum norm of the off-diagonal elements


dnorm = (double)fabs(d[0]) + (double)fabs(d[1]) + (double)fabs(d[2]);
onorm = (double)fabs(a[1]) + (double)fabs(a[2]) + (double)fabs(a[5]);
// Normal end point of this algorithm.
if((onorm/dnorm) <= TOL)
{
return;
}


for (j = 1; j < static_cast<int>(n); j++)
{
for (i = 0; i <= j - 1; i++)
{


b = a[n*i+j];
if(fabs(b) > 0.0f)
{
dma = d[j] - d[i];
if((fabs(dma) + fabs(b)) <= fabs(dma))
t = b / dma;
else
{
q = 0.5f * dma / b;
t = 1.0f/((double)fabs(q) + (double)sqrt(1.0f+q*q));
if (q < 0.0)
t = -t;
}


c = 1.0f/(double)sqrt(t*t + 1.0f);
s = t * c;
a[n*i+j] = 0.0f;


for (k = 0; k <= i-1; k++)
{
atemp = c * a[n*k+i] - s * a[n*k+j];
a[n*k+j] = s * a[n*k+i] + c * a[n*k+j];
a[n*k+i] = atemp;
}


for (k = i+1; k <= j-1; k++)
{
atemp = c * a[n*i+k] - s * a[n*k+j];
a[n*k+j] = s * a[n*i+k] + c * a[n*k+j];
a[n*i+k] = atemp;
}


for (k = j+1; k < static_cast<int>(n); k++)
{
atemp = c * a[n*i+k] - s * a[n*j+k];
a[n*j+k] = s * a[n*i+k] + c * a[n*j+k];
a[n*i+k] = atemp;
}


for (k = 0; k < static_cast<int>(n); k++)
{
vtemp = c * v[n*k+i] - s * v[n*k+j];
v[n*k+j] = s * v[n*k+i] + c * v[n*k+j];
v[n*k+i] = vtemp;
}


dtemp = c*c*d[i] + s*s*d[j] - 2.0f*c*s*b;
d[j] = s*s*d[i] + c*c*d[j] + 2.0f*c*s*b;
d[i] = dtemp;
} /* end if */
} /* end for i */
} /* end for j */
} /* end for l */
}

//main.cpp

#include <iostream>
#include "jacobi.h"


using namespace std;


int main()
{
double mat[3][3];
double eigenValues[3];
double eigenVectors[3][3];
FILE * fp;
fopen_s(&fp, "./m.txt", "r");
int w, h;
fscanf_s(fp, "%d %d\n", &w, &h);
if(w != h){
printf("martix width != height\n");
return 1;
}
for (int i = 0; i < h; i++){
for(int j = 0; j < w; j++)
{
fscanf_s(fp, "%lf ", &mat[i][j]);
}
}
fclose(fp);
memset(eigenVectors, 0, sizeof(double)*9);
eigenVectors[0][0] = eigenVectors[1][1] = eigenVectors[2][2] = 1.0;
jacobi(3, (double*)mat, (double*)eigenValues, (double*)eigenVectors);


FILE *fpEV = NULL;
fopen_s(&fpEV, "eigenvalue.txt", "w");
for (int i = 0; i < 3; i++){
{
fprintf_s(fp,"%lf ", eigenValues[i]);
}
}
fclose(fpEV);


FILE *fpeigenvetor = NULL;
fopen_s(&fpeigenvetor, "eigenvetor.txt", "w");
for (int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++)
{
fprintf_s(fpeigenvetor,"%lf ", eigenVectors[i][j]);
}
fputc('\n', fpeigenvetor);
}
fclose(fpeigenvetor);


int temp  = 10;
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值