void test01 ( void ) /******************************************************************************/ /* Purpose: TEST01 uses POWER_METHOD on the Fibonacci2 matrix. Discussion: This matrix, despite having a single dominant eigenvalue, will generally converge only very slowly under the power method. This has to do with the fact that the matrix has only 3 eigenvectors. Licensing: This code is distributed under the GNU LGPL license. Modified: 20 July 2008 Author: John Burkardt */ { double *a; double cos_x1x2; double ctime; double ctime1; double ctime2; int i; int it_max; int it_num; double lambda; int n = 50; double norm; double phi; int seed; double sin_x1x2; double tol; double *x; double *x2; a = fibonacci2 ( n ); seed = 123456789; x = r8vec_uniform_01 ( n, &seed ); it_max = 300; tol = 0.000001; phi = ( 1.0 + sqrt ( 5.0 ) ) / 2.0; printf ( "\n" ); printf ( "TEST01\n" ); printf ( " Use the power method on the Fibonacci2 matrix.\n" ); printf ( "\n" ); printf ( " Matrix order N = %d\n", n ); printf ( " Maximum iterations = %d\n", it_max ); printf ( " Error tolerance = %e\n", tol ); ctime1 = cpu_time ( ); power_method ( n, a, x, it_max, tol, &lambda, &it_num ); ctime2 = cpu_time ( ); ctime = ctime2 - ctime1; printf ( "\n" ); printf ( " Number of iterations = %d\n", it_num ); printf ( " CPU time = %f\n", ctime ); printf ( " Estimated eigenvalue = %24.16f\n", lambda ); printf ( " Correct value = %24.16f\n", phi ); printf ( " Error = %e\n", r8_abs ( lambda - phi ) ); /* X2 is the exact eigenvector. */ x2 = ( double * ) malloc ( n * sizeof ( double ) ); x2[0] = 1.0; for ( i = 1; i < n; i++ ) { x2[i] = phi * x2[i-1]; } norm = r8vec_norm_l2 ( n, x2 ); for ( i = 0; i < n; i++ ) { x2[i] = x2[i] / norm; } /* The sine of the angle between X and X2 is a measure of error. */ cos_x1x2 = r8vec_dot ( n, x, x2 ); sin_x1x2 = sqrt ( ( 1.0 - cos_x1x2 ) * ( 1.0 + cos_x1x2 ) ); printf ( "\n" ); printf ( " Sine of angle between true and estimated vectors = %e\n", sin_x1x2 ); free ( a ); free ( x ); free ( x2 ); return; }
double *r8vec_house_column ( int n, double a[], int k ) /******************************************************************************/ /* Purpose: R8VEC_HOUSE_COLUMN defines a Householder premultiplier that "packs" a column. Discussion: An R8VEC is a vector of R8's. The routine returns a vector V that defines a Householder premultiplier matrix H(V) that zeros out the subdiagonal entries of column K of the matrix A. H(V) = I - 2 * v * v' Licensing: This code is distributed under the GNU LGPL license. Modified: 21 August 2010 Author: John Burkardt Parameters: Input, int N, the order of the matrix A. Input, double A[N], column K of the matrix A. Input, int K, the column of the matrix to be modified. Output, double R8VEC_HOUSE_COLUMN[N], a vector of unit L2 norm which defines an orthogonal Householder premultiplier matrix H with the property that the K-th column of H*A is zero below the diagonal. */ { int i; double s; double *v; v = r8vec_zero_new ( n ); if ( k < 1 || n <= k ) { return v; } s = r8vec_norm_l2 ( n+1-k, a+k-1 ); if ( s == 0.0 ) { return v; } v[k-1] = a[k-1] + r8_abs ( s ) * r8_sign ( a[k-1] ); r8vec_copy ( n-k, a+k, v+k ); s = r8vec_norm_l2 ( n-k+1, v+k-1 ); for ( i = k-1; i < n; i++ ) { v[i] = v[i] / s; } return v; }