int
powerMethod (double & lambda, 
             Epetra_CrsMatrix& A, 
             const int niters, 
             const double tolerance,
             const bool verbose)
{
  // In the power iteration, z = A*q.  Thus, q must be in the domain
  // of A, and z must be in the range of A.  The residual vector is of
  // course in the range of A.
  Epetra_Vector q (A.OperatorDomainMap ());
  Epetra_Vector z (A.OperatorRangeMap ());
  Epetra_Vector resid (A.OperatorRangeMap ());

  Epetra_Flops* counter = A.GetFlopCounter();
  if (counter != 0) {
    q.SetFlopCounter(A);
    z.SetFlopCounter(A);
    resid.SetFlopCounter(A);
  }

  // Initialize the starting vector z with random data.
  z.Random();

  double normz, residual;
  int ierr = 1;
  for (int iter = 0; iter < niters; ++iter)
    {
      z.Norm2 (&normz);        // normz  := ||z||_2
      q.Scale (1.0/normz, z);  // q      := z / normz
      A.Multiply(false, q, z); // z      := A * q
      q.Dot(z, &lambda);       // lambda := dot (q, z)

      // Compute the residual vector and display status output every
      // 100 iterations, or if we have reached the maximum number of
      // iterations.
      if (iter % 100 == 0 || iter + 1 == niters)
        {
          resid.Update (1.0, z, -lambda, q, 0.0); // resid := A*q - lambda*q
          resid.Norm2 (&residual);                // residual := ||resid||_2
          if (verbose) 
            cout << "Iter = " << iter << "  Lambda = " << lambda 
                 << "  Residual of A*q - lambda*q = " << residual << endl;
        } 
      if (residual < tolerance) { // We've converged!
        ierr = 0;
        break;
      }
    }
  return ierr;
}
Beispiel #2
0
int power_method(Epetra_CrsMatrix& A, double &lambda, int niters, 
		 double tolerance, bool verbose) {  

  Epetra_Vector q(A.RowMap());
  Epetra_Vector z(A.RowMap());
  Epetra_Vector resid(A.RowMap());

  Epetra_Flops * counter = A.GetFlopCounter();
  if (counter!=0) {
    q.SetFlopCounter(A);
    z.SetFlopCounter(A);
    resid.SetFlopCounter(A);
  }

  // Fill z with random Numbers
  z.Random();

  // variable needed for iteration
  double normz, residual;

  int ierr = 1;

  for (int iter = 0; iter < niters; iter++)
    {
      z.Norm2(&normz); // Compute 2-norm of z
      q.Scale(1.0/normz, z);
      A.Multiply(false, q, z); // Compute z = A*q
      q.Dot(z, &lambda); // Approximate maximum eigenvalue
      if (iter%100==0 || iter+1==niters)
	{
	  resid.Update(1.0, z, -lambda, q, 0.0); // Compute A*q - lambda*q
	  resid.Norm2(&residual);
	  if (verbose) cout << "Iter = " << iter << "  Lambda = " << lambda 
			    << "  Residual of A*q - lambda*q = " 
			    << residual << endl;
	} 
      if (residual < tolerance) {
	ierr = 0;
	break;
      }
    }
  return(ierr);
}
Beispiel #3
0
int invIteration(Epetra_CrsMatrix& A, double &lambda, bool verbose) {

  Ifpack_CrsRiluk * M;
  applyInverseSetup(A, M);
  Epetra_Vector q(A.RowMap());
  Epetra_Vector z(A.RowMap());
  Epetra_Vector resid(A.RowMap());

  Epetra_Flops * counter = A.GetFlopCounter();
  if (counter!=0) {
    q.SetFlopCounter(A);
    z.SetFlopCounter(A);
    resid.SetFlopCounter(A);
  }

  // Fill z with random Numbers
  z.Random();

  // variable needed for iteration
  double normz, residual;

  int niters = 100;
  double tolerance = 1.0E-6;
  int ierr = 1;

  for (int iter = 0; iter < niters; iter++)
    {
      if (verbose)
	cout << endl
	     << " ***** Performing step " << iter << " of inverse iteration ***** " << endl;

      z.Norm2(&normz); // Compute 2-norm of z
      q.Scale(1.0/normz, z);
      applyInverse(A, z, q, M, verbose); // Compute z such that Az = q
      q.Dot(z, &lambda); // Approximate maximum eigenvalue
      if (iter%10==0 || iter+1==niters)
	{
	  resid.Update(1.0, z, -lambda, q, 0.0); // Compute A(inv)*q - lambda*q
	  resid.Norm2(&residual);
	  cout << endl
	       << "***** Inverse Iteration Step " << iter+1 << endl
	       << "  Lambda = " << 1.0/lambda << endl
	       << "  Residual of A(inv)*q - lambda*q = "
	       << residual << endl;
	}
      if (residual < tolerance) {
	ierr = 0;
	break;
      }
    }
  // lambda is the largest eigenvalue of A(inv).  1/lambda is smallest eigenvalue of A.
  lambda = 1.0/lambda;

  // Compute A*q - lambda*q explicitly
  A.Multiply(false, q, z);
  resid.Update(1.0, z, -lambda, q, 0.0); // Compute A*q - lambda*q
  resid.Norm2(&residual);
  cout << "  Explicitly computed residual of A*q - lambda*q = " << residual << endl;
  applyInverseDestroy(M);
  return(ierr);
}