Matrix &Matrix::eigenSystem()
{
    Matrix *values;

    assertDefined("eigenSystem");
    assertSquare("eigenSystem");
    
    values = new Matrix(1, maxc);   // allocates space for eigen values

    {
        double *d, *e;

        tridiagonalize(d, e);         // allocates space for 2 double arrays
        eigen(d, e, maxc, m);         // returns eigen values in d

        delete values->m[0];           // save the eigen values from above routines
        values->m[0] = d;

        delete e;
    }

    transposeSelf();               // result was returned in columns so put it in rows
    isort(values->m[0], m, maxc);  // sort rows so vector with max eigenvalue is first
    values->defined = true;        // mark eigen value matrix as defined

    return *values;
}
示例#2
0
int main()
{
	int i, j, k, n;
	static matrix a, p;
	static vector d, e, temp;
	double s, t;

	printf("n = ");  scanf("%d", &n);
	printf("乱数の種 (正の整数) = ");
	scanf("%ul", &seed);  seed |= 1;
	a = new_matrix(n, n);
	p = new_matrix(n, n);
	d = new_vector(n);
	e = new_vector(n);
	temp = new_vector(n);
	for (i = 0; i < n; i++)
		for (j = 0; j <= i; j++)
			a[i][j] = a[j][i] = p[i][j] = p[j][i]
				= rnd() - rnd();
	printf("A:\n");
	matprint(a, n, 7, "%10.6f");
	tridiagonalize(n, p, d, e);
	printf("d:\n");
	vecprint(d, n, 5, "% -14g");
	printf("e:\n");
	vecprint(e, n - 1, 5, "% -14g");
	for (i = 0; i < n; i++) {
		for (k = 0; k < n; k++)
			temp[k] = a[i][k];
		for (j = 0; j < n; j++) {
			s = 0;
			for (k = 0; k < n; k++)
				s += temp[k] * p[j][k];
			a[i][j] = s;
		}
	}
	for (j = 0; j < n; j++) {
		for (k = 0; k < n; k++)
			temp[k] = a[k][j];
		for (i = 0; i < n; i++) {
			s = 0;
			for (k = 0; k < n; k++)
				s += p[i][k] * temp[k];
			a[i][j] = s;
		}
	}
	s = 0;
	for (i = 0; i < n; i++)
		for (j = 0; j < n; j++)
			if (i == j) {
				t = a[i][j] - d[i];  s += t * t;
			} else if (i + 1 == j) {
				t = a[i][j] - e[i];  s += t * t;
			} else if (i == j + 1) {
				t = a[i][j] - e[j];  s += t * t;
			} else {
				t = a[i][j];  s += t * t;
			}
	printf("二乗平均誤差: %g\n", sqrt(s) / n);
	return EXIT_SUCCESS;
}
double * symmetricQR(matrix A){
	/*
	Symmetric QR for computation of eigenvalues.

	Source: Golub and Van Loan, Matrix Computations p. 421.

	Input:
	matrix A   Square, symmetric matrix of which to compute eigenvalues

	Output:
	double *eigs (returned)   Eigenvalues of the matrix
	*/

	double *eigs = (double *) malloc(A.n * sizeof(double)) ;
	A = tridiagonalize(A) ;

	int i, k;
	int start;

	int n = A.n ;
	int maxIt = 10000;
	int p,q = 0 ;

	double tol = 1e-14 ;
	int iteration = 0 ;

	while(q < n-1){
	    for (i = 0; i<n-1; i++){
	       if ( fabs( A.values[i+1][i] ) <= tol * (fabs( A.values[i][i] ) + fabs( A.values[i+1][i+1] )) ) {
	           A.values[i+1][i] = 0.0;
	           A.values[i][i+1] = 0.0;
	       }
	    }

	    // find largest diagonal block in lower right of matrix
	    start = n-q; //loop index starts with previously found diagonal block
	    for( k = start - 1; k >= 0; k--){
	        //check off-diagonal entries
	        //only above diagonal is checked because of symmetry
	    	if(k != 0){
				if(A.values[k][k-1] == 0.0)
					q++;
				else
					break ;
	    	}
	    }

	    p = n - q - 1;
		for (k = start - 1; k > 0; k--) {
			if (A.values[k][k - 1] != 0)
				p--;
			else
				break;
		}


	    if (q < n - 1 ){
	        A = symmetricQRStep(A, p, n-q)  ;
	    }

	    iteration++ ;
	    if (iteration > maxIt){
	        fprintf(stderr, "Max it reached. Returning.\n");
	        break ;
	    }
	}


	for(i=0; i<n; i++)
		eigs[i] = A.values[i][i] ;


	qsort(eigs, n, sizeof(double), compareDoubles) ;
	return eigs ;
}