//! initialize a newly created preconditioner object
void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > & ASrc,
                                                const RCP<const Thyra::MultiVectorBase<double> > & solnVec,
                                                PreconditionerBase<double> * prec,
                                                const ESupportSolveUse supportSolveUse) const
{
   Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
   blkPrec->setSourceVector(Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(solnVec));

   initializePrec(ASrc,prec,supportSolveUse);
}
Example #2
0
double CMT::MLR::evaluate(
	const pair<ArrayXXd, ArrayXXd>& data,
	const Preconditioner& preconditioner) const
{
	return -logLikelihood(preconditioner(data.first, data.second)).mean() / log(2.)
		- preconditioner.logJacobian(data).mean() / log(2.);
}
Example #3
0
void DefaultIterativeSolver<BasisFunctionType, ResultType>::initializeSolver(
        const Teuchos::RCP<Teuchos::ParameterList>& paramList,
        const Preconditioner<ResultType>& preconditioner)
{
    m_impl->solverWrapper->setPreconditioner(preconditioner.get());
    m_impl->solverWrapper->initializeSolver(paramList);
}
Example #4
0
double CMT::MLR::evaluate(
	const MatrixXd& input,
	const MatrixXd& output,
	const Preconditioner& preconditioner) const
{
	return -logLikelihood(preconditioner(input, output)).mean() / log(2.)
		- preconditioner.logJacobian(input, output).mean() / log(2.);
}
Example #5
0
bool IterativeSolvers::pcg(const IRCMatrix &A,
                           Vector &x,
                           const Vector &b,
                           const Preconditioner &M) {
    /*!
      Solves Ax=b using the preconditioned conjugate gradient method.
      */
    const idx N = x.getLength();
    real resid(100.0);
    Vector p(N), z(N), q(N);
    real alpha;
    real normr(0);
    real normb = norm(b);
    real rho(0), rho_1(0), beta(0);
    Vector r = b - A * x;
    if (normb == 0.0)
        normb = 1;
    resid = norm(r) / normb;
    if (resid <= IterativeSolvers::toler) {
        IterativeSolvers::toler = resid;
        IterativeSolvers::maxIter = 0;
        return true;
    }
    // MAIN LOOP
    idx i = 1;
    for (; i <= IterativeSolvers::maxIter; i++) {
        M.solveMxb(z, r);
        rho = dot(r, z);
        if (i == 1)
            p = z;
        else {
            beta = rho / rho_1;
            aypx(beta, p, z); // p = beta*p + z;
        }
        // CALCULATES q = A*p AND dp = dot(q,p)
        real dp = multiply_dot(A, p, q);
        alpha = rho / dp;
        normr = 0;
#ifdef USES_OPENMP
        #pragma omp parallel for reduction(+:normr)
#endif
        for (idx j = 0 ; j < N ; ++j) {
            x[j] += alpha * p[j]; // x + alpha(0) * p;
            r[j] -= alpha * q[j]; // r - alpha(0) * q;
            normr += r[j] * r[j];
        }
        normr = sqrt(normr);
        resid = normr / normb;
        if (resid <= IterativeSolvers::toler) {
            IterativeSolvers::toler = resid;
            IterativeSolvers::maxIter = i;
            return true;
        }
        rho_1 = rho;
    }
    IterativeSolvers::toler = resid;
    return false;
}
Example #6
0
  SolverState<double> PCGSolver::solve(const LinearOperator<double>& A,
				       const Vector<double>& b,
				       Vector<double>& x) const
  {
    if (precFactory_.ptr().get() == 0)
      {
	return solveUnprec(A, b, x);
      }
    else
      {
	SolverState<double> rtn;
	Preconditioner<double> prec = precFactory_.createPreconditioner(A);
	if (prec.isIdentity())
	  {
	    rtn = solveUnprec(A, b, x);
	  }
	else if (prec.isTwoSided())
	  {
	    LinearOperator<double> P = prec.left();
	    LinearOperator<double> Q = prec.right();
	    LinearOperator<double> PAQ = P*A*Q;
	    Vector<double> Pb = P*b;
	    Vector<double> y;
	    rtn = solveUnprec(PAQ, Pb, y);
	    x = Q*y;
	  }
	else if (prec.hasRight())
	  {
	    LinearOperator<double> Q = prec.right();
	    LinearOperator<double> AQ = A*Q;
	    Vector<double> y;
	    rtn = solveUnprec(AQ, b, y);
	    x = Q*y;
	  }
	else if (prec.hasLeft())
	  {
	    LinearOperator<double> P = prec.left();
	    LinearOperator<double> PA = P*A;
	    Vector<double> Pb = P*b;
	    rtn = solveUnprec(PA, Pb, x);
	  }
	else
	  {
	    TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
				       "Inconsistent preconditioner state "
				       "in PGCSolver::solve()");
	  }
	return rtn;
      }
  }
Example #7
0
	int CG(const MMatrix &A, MVector &x, const MVector &b, const Preconditioner &M, int &max_iter, Real &tol)
	{
		Real resid;
		MVector p, z, q;
		MVector alpha(1), beta(1), rho(1), rho_1(1);

		MVector r = b - A*x;

		Real normb = norm(b);

		if (normb == 0.0) normb = 1;

		if ((resid = norm(r) / normb) <= tol){
			tol = resid;
			max_iter = 0;
			return 0;
		}

		for (int i = 1; i <= max_iter; i++) 
		{
			// Assign Z
			z = M.solve(r);

			rho.p_[0] = dot(r, z);

			// Assign P
			if (i == 1)
				p = z;
			else {
				beta.p_[0] = rho.p_[0] / rho_1.p_[0];
				p = z + beta.p_[0] * p;
			}

			// Assign Q
			q = A*p;

			alpha.p_[0] = rho.p_[0] / dot(p, q);

			// Change X and R
			x += alpha.p_[0] * p;
			r -= alpha.p_[0] * q;

			// Check tol
			if ((resid = norm(r) / normb) <= tol)
			{
				tol = resid;
				max_iter = i;
				return 0;     
			}

			rho_1.p_[0] = rho.p_[0];
		}

		tol = resid;
		return 1;
	}
//! initialize a newly created preconditioner object
void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > & ASrc,
                    PreconditionerBase<double> * prec,
                    const ESupportSolveUse supportSolveUse) const
{
   // get the blocked linear operator
   LinearOp A = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(ASrc->getOp());

   Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
   TEUCHOS_ASSERT(blkPrec!=0);
 
   // grab the state object
   RCP<PreconditionerState> state = blkPrec->getStateObject();
   state->setInitialized(false);

   // build the preconditioner
   const RCP<const LinearOpBase<double> > M = buildPreconditionerOperator(A,*state);

   // set the request handler for the 
   setOpRequestHandler(*this,M);

   // must first cast that to be initialized
   DefaultPreconditioner<double> & dPrec = Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
   dPrec.initializeUnspecified(Teuchos::rcp_const_cast<LinearOpBase<double> >(M));
}
SolverState<double> BelosSolver::solve(const LinearOperator<double>& A, 
  const Vector<double>& rhs, 
  Vector<double>& soln) const
{
  typedef Anasazi::SimpleMV                      MV;
  typedef LinearOperator<double>                 OP;
  typedef Belos::LinearProblem<double, MV, OP>   LP;

  TEUCHOS_TEST_FOR_EXCEPT(!A.ptr().get());
  TEUCHOS_TEST_FOR_EXCEPT(!rhs.ptr().get());

  if (!soln.ptr().get()) 
  {
    soln = rhs.copy();
    /* KRL 8 Jun 2012: set x0 to zero to workaround bug in Belos */
    soln.zero();
  }

  if (rhs.norm2()==0.0)
  {
    soln.zero();
    SolverStatusCode code = SolveConverged;
    SolverState<double> state(code, "Detected trivial solution", 0, 0.0);
    
    return state;
  }


  RCP<OP> APtr = rcp(new LinearOperator<double>(A));
  RCP<MV> bPtr = rcp(new MV(1));
  (*bPtr)[0] = rhs;
  RCP<MV> ansPtr = rcp(new MV(1));
  (*ansPtr)[0] = soln;
  
  
  RCP<LP> prob = rcp(new LP(APtr, ansPtr, bPtr));

  TEUCHOS_TEST_FOR_EXCEPT(!prob->setProblem());

  
  if (pf_.ptr().get())
  {
    Preconditioner<double> P = pf_.createPreconditioner(A);
    if (P.hasLeft())
    {
      prob->setLeftPrec(rcp(new OP(P.left())));
    }
  
    if (P.hasRight())
    {
      prob->setRightPrec(rcp(new OP(P.right())));
    }
  }

  if (!hasSolver_)
  {

    ParameterList plist = parameters();

    RCP<ParameterList> belosList = rcp(&plist, false);

    std::string solverType = parameters().get<string>("Method");
      
    if (solverType=="GMRES")
    {
      solver_=rcp(new Belos::BlockGmresSolMgr<double, MV, OP>(prob, belosList));
    }
    else if (solverType=="CG")
    {
      solver_=rcp(new Belos::BlockCGSolMgr<double, MV, OP>(prob, belosList));
    }
    else if (solverType=="TFQMR")
    {
      solver_=rcp(new Belos::TFQMRSolMgr<double, MV, OP>(prob, belosList));
    }
    else if (solverType=="GCRODR")
    {
      solver_=rcp(new Belos::GCRODRSolMgr<double, MV, OP>(prob, belosList));
      hasSolver_ = true; // only cache recycling solvers
    }
    else if (solverType=="RCG")
    {
      solver_=rcp(new Belos::RCGSolMgr<double, MV, OP>(prob, belosList));
      hasSolver_ = true; // only cache recycling solvers
    }
    else
    {
      TEUCHOS_TEST_FOR_EXCEPT(!(solverType=="GMRES" || solverType=="CG"));
    }
  }
  else // reset problem
  {
    solver_->setProblem( prob );
  }
  
  Belos::ReturnType rtn = solver_->solve();

  int numIters = solver_->getNumIters();
  double resid = solver_->achievedTol();
  
  SolverStatusCode code = SolveFailedToConverge;
  if (rtn==Belos::Converged) code = SolveConverged;
  SolverState<double> state(code, "Belos solver completed", numIters, resid);
  
  return state;
}
Example #10
0
SolverState<double> BelosSolver::solve(const LinearOperator<double>& A, 
  const Vector<double>& rhs, 
  Vector<double>& soln) const
{
  typedef Thyra::MultiVectorBase<double>         MV;
  typedef Thyra::LinearOpBase<double>            OP;
  typedef Belos::LinearProblem<double, MV, OP>   LP;

  TEST_FOR_EXCEPT(!A.ptr().get());
  TEST_FOR_EXCEPT(!rhs.ptr().get());

  /* get Thyra objects */
  RCP<OP> APtr = A.ptr();
  RCP<MV> bPtr = rhs.ptr(); 

  if (!soln.ptr().get()) soln = rhs.copy();

  RCP<MV> ansPtr = soln.ptr();

  
  
  RCP<LP> prob = rcp(new LP(APtr, ansPtr, bPtr));

  TEST_FOR_EXCEPT(!prob->setProblem());

  
  if (pf_.ptr().get())
  {
    Preconditioner<double> P = pf_.createPreconditioner(A);
    if (P.hasLeft())
    {
      prob->setLeftPrec(P.left().ptr());
    }
  
    if (P.hasRight())
    {
      prob->setRightPrec(P.right().ptr());
    }
  }

  ParameterList plist = parameters();

  RCP<ParameterList> belosList = rcp(&plist, false);
  RCP<Belos::SolverManager<double, MV, OP> > solver ;
  std::string solverType = parameters().get<string>("Method");
  
  if (solverType=="GMRES")
  {
    solver=rcp(new Belos::BlockGmresSolMgr<double, MV, OP>(prob, belosList));
  }
  else if (solverType=="CG")
  {
    solver=rcp(new Belos::BlockCGSolMgr<double, MV, OP>(prob, belosList));
  }
  else
  {
    TEST_FOR_EXCEPT(!(solverType=="GMRES" || solverType=="CG"));
  }

  Belos::ReturnType rtn = solver->solve();

  int numIters = solver->getNumIters();
  double resid = -1.0;
  
  SolverStatusCode code = SolveFailedToConverge;
  if (rtn==Belos::Converged) code = SolveConverged;
  SolverState<double> state(code, "Belos solver completed", numIters, resid);
  
  return state;
}
Example #11
0
bool IterativeSolvers::gmres(const IRCMatrix &A,
                             Vector &x,
                             const Vector &b,
                             const Preconditioner &M) {
    const idx N = x.getLength();
    idx i, j = 1, k;
    Vector s(maxInnerIter + 1);
    Vector cs(maxInnerIter + 1);
    Vector sn(maxInnerIter + 1);
    Vector w(N);
    real normb = norm(M.solve(b));
    Vector r = M.solve(b - A * x);
    real beta = norm(r);
    if (normb == 0.0)
        normb = 1;
    real res(norm(r) / normb);
    if (res <= toler) {
        toler = res;
        maxIter = 0;
        return true;
    }
    Vector *v = new Vector[maxInnerIter + 1];
    for (idx id = 0; id < maxInnerIter + 1; ++id)
        v[id] = Vector(N);
    // CREATE HESSENBERG MATRIX NEEDED TO STORE INTERMEDIATES
    DenseMatrix H(maxInnerIter + 1, maxInnerIter);
    Vector temp(N);
    Vector temp2(maxInnerIter + 1);
    // MAIN LOOP
    while (j <= maxIter) {
        v[0] = r * (1.0 / beta);
        s = 0.0;
        s(0) = beta;
        // INNER ITERATIONS
        for (i = 0; i < maxInnerIter && j <= maxIter; i++, j++) {
            // CALCULATE w = M^{-1}(A*v[i])
            multiply(A, v[i], temp);
            M.solveMxb(w, temp);
            // PRE-CALCULATE DOT PRODUCTS IN PARALLEL
            // H(k,i) = dot( v[k], w)
#ifdef USES_OPENMP
            #pragma omp parallel for
#endif
            for (k = 0; k <= i ; ++k) {
                register real dp(0);
                for (idx id = 0 ; id < N ; ++id)
                    dp += w[id] * v[k][id];
                H(k, i) = dp; //dot(w,v[k]);
            }
            for (k = 0; k <= i; ++k) {
                // w -= v[k]*H(k,i) without temporaries
                register real tempr = H(k, i);
#ifdef USES_OPENMP
                #pragma omp parallel for // why is this loop so critical??
#endif
                for (idx id = 0 ; id < N ; ++id)
                    w[id] -= v[k][id] * tempr;
            }
            // BELOW PARALLEL REGION CALCULATES:
            // H(i+1,i) = norm(w);
            // v[i+1] = w * (1.0 / H(i+1, i));
            H(i + 1, i) = 0;
            real tempr(0);
#ifdef USES_OPENMP
            #pragma omp parallel shared(tempr)
#endif
            {
#ifdef USES_OPENMP
                #pragma omp for reduction(+:tempr)
#endif
                for (idx id = 0 ; id < N ; ++id)
                    tempr += w[id] * w[id]; //norm(w);
#ifdef USES_OPENMP
                #pragma omp single
#endif
                {
                    H(i + 1, i) = sqrt(tempr);
                    tempr = (1.0 / H(i + 1, i));
                }
#ifdef USES_OPENMP
                #pragma omp for
#endif
                for (idx id = 0 ; id < N ; ++id)
                    v[i + 1][id] = w[id] * tempr;
            }// end for omp parallel
            for (k = 0; k < i; k++)
                ApplyPlaneRotation(H(k, i), H(k + 1, i), cs(k), sn(k));
            GeneratePlaneRotation(H(i, i), H(i + 1, i), cs(i), sn(i));
            ApplyPlaneRotation(H(i, i), H(i + 1, i), cs(i), sn(i));
            ApplyPlaneRotation(s(i), s(i + 1), cs(i), sn(i));
            res = fabs(s(i + 1)) / normb;
            if (res < toler) {
                // COPY S INTO temp WITHOUT RESIZING
                for (idx id = 0 ; id < maxInnerIter + 1 ; ++id)
                    temp2[id] = s[id];
                Update(x, i, H, temp2, v);
                toler = res;
                maxIter = j;
                delete [] v;
                return true;
            }
        }// end for i IINNER ITERATIONS
        // COPY S INTO temp WITHOUT RESIZING
        for (idx id = 0 ; id < maxInnerIter + 1 ; ++id)
            temp2[id] = s[id];
        Update(x, maxInnerIter - 1, H, temp2, v);
        //multiply(A, x, temp);     //r = M.solve(b - A * x);
        M.solveMxb(r, b - A * x);
        beta = norm(r);
        res = beta / normb;
        if (res < toler) {
            toler = res;
            maxIter = j;
            delete [] v;
            return true;
        }
    }
    toler = res;
    delete [] v;
    return false;
}
Example #12
0
File: Solver.cpp Project: 93i/godot
// Conjugate gradient with preconditioner.
/*static*/ bool ConjugateGradientSolver(const Preconditioner & preconditioner, const SparseMatrix & A, const FullVector & b, FullVector & x, float epsilon)
{
    nvDebugCheck( A.isSquare() );
    nvDebugCheck( A.width() == b.dimension() );
    nvDebugCheck( A.width() == x.dimension() );

    int i = 0;
    const int D = A.width();
    const int i_max = 4 * D;   // Convergence should be linear, but in some cases, it's not.

    FullVector r(D);    // residual
    FullVector p(D);    // search direction
    FullVector q(D);    // 
    FullVector s(D);    // preconditioned
    float delta_0;
    float delta_old;
    float delta_new;
    float alpha;
    float beta;

    // r = b - A·x
    copy(b, r);
    sgemv(-1, A, x, 1, r);


    // p = M^-1 · r
    preconditioner.apply(r, p);
    //copy(r, p);


    delta_new = dot(r, p);
    delta_0 = delta_new;

    while (i < i_max && delta_new > epsilon*epsilon*delta_0)
    {
        i++;

        // q = A·p
        mult(A, p, q);

        // alpha = delta_new / p·q
        alpha = delta_new / dot(p, q);

        // x = alfa·p + x
        saxpy(alpha, p, x);

        if ((i & 31) == 0)  // recompute r after 32 steps
        {			
            // r = b - A·x
            copy(b, r);
            sgemv(-1, A, x, 1, r);
        }
        else
        {
            // r = r - alfa·q
            saxpy(-alpha, q, r);
        }

        // s = M^-1 · r
        preconditioner.apply(r, s);
        //copy(r, s);

        delta_old = delta_new;
        delta_new = dot( r, s );

        beta = delta_new / delta_old;

        // p = s + beta·p
        scal(beta, p);
        saxpy(1, s, p);
    }

    return delta_new <= epsilon*epsilon*delta_0;
}
Example #13
0
void DefaultIterativeSolver<BasisFunctionType, ResultType>::setPreconditioner(
        const Preconditioner<ResultType>& preconditioner)
{
    m_impl->solverWrapper->setPreconditioner(preconditioner.get());
}