ordinal_type Stokhos::CGDivisionExpansionStrategy<ordinal_type,value_type,node_type>:: CG(const Teuchos::SerialDenseMatrix<ordinal_type, value_type> & A, Teuchos::SerialDenseMatrix<ordinal_type,value_type> & X, const Teuchos::SerialDenseMatrix<ordinal_type,value_type> & B, ordinal_type max_iter, value_type tolerance, ordinal_type prec_iter, ordinal_type order , ordinal_type m, ordinal_type PrecNum, const Teuchos::SerialDenseMatrix<ordinal_type, value_type> & M, ordinal_type diag) { ordinal_type n = A.numRows(); ordinal_type k=0; value_type resid; Teuchos::SerialDenseMatrix<ordinal_type, value_type> Ax(n,1); Ax.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, X, 0.0); Teuchos::SerialDenseMatrix<ordinal_type, value_type> r(Teuchos::Copy,B); r-=Ax; resid=r.normFrobenius(); Teuchos::SerialDenseMatrix<ordinal_type, value_type> p(r); Teuchos::SerialDenseMatrix<ordinal_type, value_type> rho(1,1); Teuchos::SerialDenseMatrix<ordinal_type, value_type> oldrho(1,1); Teuchos::SerialDenseMatrix<ordinal_type, value_type> pAp(1,1); Teuchos::SerialDenseMatrix<ordinal_type, value_type> Ap(n,1); value_type b; value_type a; while (resid > tolerance && k < max_iter){ Teuchos::SerialDenseMatrix<ordinal_type, value_type> z(r); //Solve Mz=r if (PrecNum != 0){ if (PrecNum == 1){ Stokhos::DiagPreconditioner<ordinal_type, value_type> precond(M); precond.ApplyInverse(r,z,prec_iter); } else if (PrecNum == 2){ Stokhos::JacobiPreconditioner<ordinal_type, value_type> precond(M); precond.ApplyInverse(r,z,2); } else if (PrecNum == 3){ Stokhos::GSPreconditioner<ordinal_type, value_type> precond(M,0); precond.ApplyInverse(r,z,1); } else if (PrecNum == 4){ Stokhos::SchurPreconditioner<ordinal_type, value_type> precond(M, order, m, diag); precond.ApplyInverse(r,z,prec_iter); } } rho.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,1.0, r, z, 0.0); if (k==0){ p.assign(z); rho.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, r, z, 0.0); } else { b=rho(0,0)/oldrho(0,0); p.scale(b); p+=z; } Ap.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, p, 0.0); pAp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,1.0, p, Ap, 0.0); a=rho(0,0)/pAp(0,0); Teuchos::SerialDenseMatrix<ordinal_type, value_type> scalep(p); scalep.scale(a); X+=scalep; Ap.scale(a); r-=Ap; oldrho.assign(rho); resid=r.normFrobenius(); k++; } //std::cout << "iteration count " << k << std::endl; return 0; }
// CG int CG(const Teuchos::SerialDenseMatrix<int, double> & A, Teuchos::SerialDenseMatrix<int,double> X,const Teuchos::SerialDenseMatrix<int,double> & B, int max_iter, double tolerance, Stokhos::DiagPreconditioner<int,double> prec) { int n; int k=0; double resid; n=A.numRows(); std::cout << "A= " << A << std::endl; std::cout << "B= " << B << std::endl; Teuchos::SerialDenseMatrix<int, double> Ax(n,1); Ax.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, X, 0.0); Teuchos::SerialDenseMatrix<int, double> r(B); r-=Ax; resid=r.normFrobenius(); Teuchos::SerialDenseMatrix<int, double> rho(1,1); Teuchos::SerialDenseMatrix<int, double> oldrho(1,1); Teuchos::SerialDenseMatrix<int, double> pAp(1,1); Teuchos::SerialDenseMatrix<int, double> Ap(n,1); double b; double a; Teuchos::SerialDenseMatrix<int, double> p(r); while (resid > tolerance && k < max_iter){ Teuchos::SerialDenseMatrix<int, double> z(r); //z=M-1r // prec.ApplyInverse(r,z); rho.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,1.0, r, z, 0.0); if (k==0){ p.assign(z); rho.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, r, z, 0.0); } else { b=rho(0,0)/oldrho(0,0); p.scale(b); p+=z; } Ap.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, p, 0.0); pAp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,1.0, p, Ap, 0.0); a=rho(0,0)/pAp(0,0); Teuchos::SerialDenseMatrix<int, double> scalep(p); scalep.scale(a); X+=scalep; Ap.scale(a); r-=Ap; oldrho.assign(rho); resid=r.normFrobenius(); k++; } std::cout << "X= " << X << std::endl; return 0; }