void
dft_PolyA11_Tpetra_Operator<Scalar,MatrixType>::
Check
(bool verbose) const
{
    RCP<VEC > x = rcp(new VEC(getDomainMap()));
    RCP<VEC > b = rcp(new VEC(getRangeMap()));

    x->randomize(); // Fill x with random numbers
    apply(*x, *b); // Forward operation
    applyInverse(*b, *b); // Reverse operation
    b->update(-STS::one(), *x, STS::one()); // Should be zero

    Scalar absResid = b->norm2();
    Scalar normX = x->norm2();
    Scalar resid = absResid / normX;

    if (verbose)
    {
        std::cout << "A11 self-check residual = " << resid << std::endl;
    }

    TEUCHOS_TEST_FOR_EXCEPTION(resid > 1.0E-12, std::runtime_error, "Bad residual.\n");

} //end Check
void
dft_PolyA22_Tpetra_Operator<Scalar,MatrixType>::
Check
(bool verbose) const
{
  RCP<VEC > x = rcp(new VEC(getDomainMap()));
  RCP<VEC > b = rcp(new VEC(getRangeMap()));
  x->randomize(); // Fill x with random numbers

  apply(*x, *b); // Forward operation

  if (hasDensityOnCms_)
  {
    if (F_location_ == 1) //F in NE
    {
      // Inverse is not exact, so we must modify b2 first:
      RCP<MV> x1 = x->offsetViewNonConst(cmsMap_, 0);
      // Start x1 to view first numCmsElements elements of x
      RCP<MV> b2 = b->offsetViewNonConst(densityMap_, cmsMap_->getNodeNumElements());
      // Start b2 to view last numDensity elements of b
      RCP<MV > DCx1 = rcp(new MV(*b2));
      densityOnCmsMatrixOp_->apply(*x1, *DCx1);
      b2->update(-STS::one(), *DCx1, STS::one()); // b2 = b2 - DC*x1
    }
    else
    {
      // Inverse is not exact, so we must modify b1 first:
      RCP<MV> x2 = x->offsetViewNonConst(cmsMap_, densityMap_->getNodeNumElements());
      //Start x2 to view last numCms elements of x
      RCP<MV> b1 = b->offsetViewNonConst(densityMap_, 0);
      // Start b1 to view first numDensity elements of b
      RCP<MV > DCx2 = rcp(new MV(*b1));
      densityOnCmsMatrixOp_->apply(*x2, *DCx2);
      b1->update(-STS::one(), *DCx2, STS::one()); // b1 = b1 - DC*x2
    }
  }

  // Reverse operation
  applyInverse(*b, *b);

  b->update(-STS::one(), *x, STS::one()); // Should be zero

  Scalar resid = b->norm2();

  if (verbose)
  {
    std::cout << "A22 self-check residual = " << resid << std::endl;
  }

  TEUCHOS_TEST_FOR_EXCEPTION(resid > 1.0E-12, std::runtime_error, "Bad residual.\n");

} //end Check
Пример #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);
}