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;
}
Esempio n. 2
0
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;
}