void Stokhos::SmolyakPseudoSpectralOperator<ordinal_type,value_type,point_compare_type>:: apply_direct( const Teuchos::SerialDenseMatrix<ordinal_type,value_type>& A, const value_type& alpha, const Teuchos::SerialDenseMatrix<ordinal_type,value_type>& input, Teuchos::SerialDenseMatrix<ordinal_type,value_type>& result, const value_type& beta, bool trans) const { if (trans) { TEUCHOS_ASSERT(input.numCols() <= A.numCols()); TEUCHOS_ASSERT(result.numCols() == A.numRows()); TEUCHOS_ASSERT(result.numRows() == input.numRows()); blas.GEMM(Teuchos::NO_TRANS, Teuchos::TRANS, input.numRows(), A.numRows(), input.numCols(), alpha, input.values(), input.stride(), A.values(), A.stride(), beta, result.values(), result.stride()); } else { TEUCHOS_ASSERT(input.numRows() <= A.numCols()); TEUCHOS_ASSERT(result.numRows() == A.numRows()); TEUCHOS_ASSERT(result.numCols() == input.numCols()); blas.GEMM(Teuchos::NO_TRANS, Teuchos::NO_TRANS, A.numRows(), input.numCols(), input.numRows(), alpha, A.values(), A.stride(), input.values(), input.stride(), beta, result.values(), result.stride()); } }
void assembleIRKState( const int stageIndex, const Teuchos::SerialDenseMatrix<int,Scalar> &A_in, const Scalar dt, const Thyra::VectorBase<Scalar> &x_base, const Thyra::ProductVectorBase<Scalar> &x_stage_bar, Teuchos::Ptr<Thyra::VectorBase<Scalar> > x_out_ptr ) { typedef ScalarTraits<Scalar> ST; const int numStages_in = A_in.numRows(); TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( stageIndex, 0, numStages_in ); TEUCHOS_ASSERT_EQUALITY( A_in.numRows(), numStages_in ); TEUCHOS_ASSERT_EQUALITY( A_in.numCols(), numStages_in ); TEUCHOS_ASSERT_EQUALITY( x_stage_bar.productSpace()->numBlocks(), numStages_in ); Thyra::VectorBase<Scalar>& x_out = *x_out_ptr; V_V( outArg(x_out), x_base ); for ( int j = 0; j < numStages_in; ++j ) { Vp_StV( outArg(x_out), dt * A_in(stageIndex,j), *x_stage_bar.getVectorBlock(j) ); } }
void Stokhos::SmolyakPseudoSpectralOperator<ordinal_type,value_type,point_compare_type>:: transformPCE2QP_smolyak( const value_type& alpha, const Teuchos::SerialDenseMatrix<ordinal_type,value_type>& input, Teuchos::SerialDenseMatrix<ordinal_type,value_type>& result, const value_type& beta, bool trans) const { Teuchos::SerialDenseMatrix<ordinal_type,value_type> op_input, op_result; result.scale(beta); for (ordinal_type i=0; i<operators.size(); i++) { Teuchos::RCP<operator_type> op = operators[i]; if (trans) { op_input.reshape(input.numRows(), op->coeff_size()); op_result.reshape(result.numRows(), op->point_size()); } else { op_input.reshape(op->coeff_size(), input.numCols()); op_result.reshape(op->point_size(), result.numCols()); } gather(scatter_maps[i], input, trans, op_input); op->transformPCE2QP(smolyak_coeffs[i], op_input, op_result, 0.0, trans); scatter(gather_maps[i], op_result, trans, result); } }
virtual ordinal_type ApplyInverse( const Teuchos::SerialDenseMatrix<ordinal_type, value_type>& Input, Teuchos::SerialDenseMatrix<ordinal_type, value_type>& Result, ordinal_type m) const { ordinal_type n=Input.numRows(); Teuchos::SerialDenseMatrix<ordinal_type, value_type> G(A); Teuchos::SerialDenseMatrix<ordinal_type, value_type> z(n,1); for (ordinal_type j=0; j<m; j++){ if (j==0){ // Compute z=D-1r for (ordinal_type i=0; i<n; i++) z(i,0)=Input(i,0)/A(i,i); } else { //Compute G=invD(-L-U)=I-inv(D)A for (ordinal_type i=0; i<n; i++){ for (ordinal_type j=0; j<n; j++){ if (j==i) G(i,j)=0; else G(i,j)=-A(i,j)/A(i,i); } } Result.assign(z); //z=Gz+inv(D)r Result.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, G, z, 1.0); } } return 0; }
/// \brief Verify the result of the "thin" QR factorization \f$A = QR\f$. /// /// This method returns a list of three magnitudes: /// - \f$\| A - QR \|_F\f$ /// - \f$\|I - Q^* Q\|_F\f$ /// - \f$\|A\|_F\f$ /// /// The notation $\f\| X \|\f$ denotes the Frobenius norm /// (square root of sum of squares) of a matrix \f$X\f$. /// Returning the Frobenius norm of \f$A\f$ allows you to scale /// or not scale the residual \f$\|A - QR\|\f$ as you prefer. virtual std::vector< magnitude_type > verify (const multivector_type& A, const multivector_type& Q, const Teuchos::SerialDenseMatrix< local_ordinal_type, scalar_type >& R) { using Teuchos::ArrayRCP; local_ordinal_type nrowsLocal_A, ncols_A, LDA; local_ordinal_type nrowsLocal_Q, ncols_Q, LDQ; fetchDims (A, nrowsLocal_A, ncols_A, LDA); fetchDims (Q, nrowsLocal_Q, ncols_Q, LDQ); if (nrowsLocal_A != nrowsLocal_Q) throw std::runtime_error ("A and Q must have same number of rows"); else if (ncols_A != ncols_Q) throw std::runtime_error ("A and Q must have same number of columns"); else if (ncols_A != R.numCols()) throw std::runtime_error ("A and R must have same number of columns"); else if (R.numRows() < R.numCols()) throw std::runtime_error ("R must have no fewer rows than columns"); // Const views suffice for verification ArrayRCP< const scalar_type > A_ptr = fetchConstView (A); ArrayRCP< const scalar_type > Q_ptr = fetchConstView (Q); return global_verify (nrowsLocal_A, ncols_A, A_ptr.get(), LDA, Q_ptr.get(), LDQ, R.values(), R.stride(), pScalarMessenger_.get()); }
void EpetraOpMultiVec::MvTimesMatAddMv ( double alpha, const MultiVec<double>& A, const Teuchos::SerialDenseMatrix<int,double>& B, double beta ) { Epetra_LocalMap LocalMap(B.numRows(), 0, Epetra_MV->Map().Comm()); Epetra_MultiVector B_Pvec(Epetra_DataAccess::View, LocalMap, B.values(), B.stride(), B.numCols()); EpetraOpMultiVec *A_vec = dynamic_cast<EpetraOpMultiVec *>(&const_cast<MultiVec<double> &>(A)); TEUCHOS_TEST_FOR_EXCEPTION( A_vec==NULL, std::invalid_argument, "Anasazi::EpetraOpMultiVec::SetBlocks() cast of MultiVec<double> to EpetraOpMultiVec failed."); TEUCHOS_TEST_FOR_EXCEPTION( Epetra_MV->Multiply( 'N', 'N', alpha, *(A_vec->GetEpetraMultiVector()), B_Pvec, beta ) != 0, EpetraSpecializedMultiVecFailure, "Anasazi::EpetraOpMultiVec::MvTimesMatAddMv() call to Epetra_MultiVec::Multiply() returned a nonzero value."); }
// Update *this with alpha * A * B + beta * (*this). void MvTimesMatAddMv (ScalarType alpha, const Anasazi::MultiVec<ScalarType> &A, const Teuchos::SerialDenseMatrix<int, ScalarType> &B, ScalarType beta) { assert (Length_ == A.GetVecLength()); assert (B.numRows() == A.GetNumberVecs()); assert (B.numCols() <= NumberVecs_); MyMultiVec* MyA; MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A)); assert(MyA!=NULL); if ((*this)[0] == (*MyA)[0]) { // If this == A, then need additional storage ... // This situation is a bit peculiar but it may be required by // certain algorithms. std::vector<ScalarType> tmp(NumberVecs_); for (int i = 0 ; i < Length_ ; ++i) { for (int v = 0; v < A.GetNumberVecs() ; ++v) { tmp[v] = (*MyA)(i, v); } for (int v = 0 ; v < B.numCols() ; ++v) { (*this)(i, v) *= beta; ScalarType res = Teuchos::ScalarTraits<ScalarType>::zero(); for (int j = 0 ; j < A.GetNumberVecs() ; ++j) { res += tmp[j] * B(j, v); } (*this)(i, v) += alpha * res; } } } else { for (int i = 0 ; i < Length_ ; ++i) { for (int v = 0 ; v < B.numCols() ; ++v) { (*this)(i, v) *= beta; ScalarType res = 0.0; for (int j = 0 ; j < A.GetNumberVecs() ; ++j) { res += (*MyA)(i, j) * B(j, v); } (*this)(i, v) += alpha * res; } } } }
void EpetraMultiVec::MvTransMv ( const double alpha, const MultiVec<double>& A, Teuchos::SerialDenseMatrix<int,double>& B) const { EpetraMultiVec *A_vec = dynamic_cast<EpetraMultiVec *>(&const_cast<MultiVec<double> &>(A)); if (A_vec) { Epetra_LocalMap LocalMap(B.numRows(), 0, Map().Comm()); Epetra_MultiVector B_Pvec(View, LocalMap, B.values(), B.stride(), B.numCols()); int info = B_Pvec.Multiply( 'T', 'N', alpha, *A_vec, *this, 0.0 ); TEST_FOR_EXCEPTION(info!=0, EpetraMultiVecFailure, "Belos::EpetraMultiVec::MvTransMv call to Multiply() returned a nonzero value."); } }
// Generic BLAS level 3 matrix multiplication // \f$\text{this}\leftarrow \alpha A B+\beta\text{this}\f$ void gemm(const Real alpha, const MV& A, const Teuchos::SerialDenseMatrix<int,Real> &B, const Real beta) { // Scale this by beta this->scale(beta); for(int i=0;i<B.numRows();++i) { for(int j=0;j<B.numCols();++j) { mvec_[j]->axpy(alpha*B(i,j),*A.getVector(i)); } } }
void EpetraMultiVec::MvTimesMatAddMv ( const double alpha, const MultiVec<double>& A, const Teuchos::SerialDenseMatrix<int,double>& B, const double beta ) { Epetra_LocalMap LocalMap(B.numRows(), 0, Map().Comm()); Epetra_MultiVector B_Pvec(View, LocalMap, B.values(), B.stride(), B.numCols()); EpetraMultiVec *A_vec = dynamic_cast<EpetraMultiVec *>(&const_cast<MultiVec<double> &>(A)); TEST_FOR_EXCEPTION(A_vec==NULL, EpetraMultiVecFailure, "Belos::EpetraMultiVec::MvTimesMatAddMv cast from Belos::MultiVec<> to Belos::EpetraMultiVec failed."); int info = Multiply( 'N', 'N', alpha, *A_vec, B_Pvec, beta ); TEST_FOR_EXCEPTION(info!=0, EpetraMultiVecFailure, "Belos::EpetraMultiVec::MvTimesMatAddMv call to Multiply() returned a nonzero value."); }
void Stokhos::SmolyakPseudoSpectralOperator<ordinal_type,value_type,point_compare_type>:: scatter( const Teuchos::Array<ordinal_type>& map, const Teuchos::SerialDenseMatrix<ordinal_type,value_type>& input, bool trans, Teuchos::SerialDenseMatrix<ordinal_type,value_type>& result) const { if (trans) { for (ordinal_type j=0; j<map.size(); j++) for (ordinal_type i=0; i<input.numRows(); i++) result(i,map[j]) += input(i,j); } else { for (ordinal_type j=0; j<input.numCols(); j++) for (ordinal_type i=0; i<map.size(); i++) result(map[i],j) += input(i,j); } }
void EpetraMultiVec::MvTransMv ( double alpha, const MultiVec<double>& A, Teuchos::SerialDenseMatrix<int,double>& B #ifdef HAVE_ANASAZI_EXPERIMENTAL , ConjType conj #endif ) const { EpetraMultiVec *A_vec = dynamic_cast<EpetraMultiVec *>(&const_cast<MultiVec<double> &>(A)); if (A_vec) { Epetra_LocalMap LocalMap(B.numRows(), 0, Map().Comm()); Epetra_MultiVector B_Pvec(View, LocalMap, B.values(), B.stride(), B.numCols()); TEUCHOS_TEST_FOR_EXCEPTION( B_Pvec.Multiply( 'T', 'N', alpha, *A_vec, *this, 0.0 ) != 0, EpetraMultiVecFailure, "Anasazi::EpetraMultiVec::MvTransMv() call to Epetra_MultiVec::Multiply() returned a nonzero value."); } }
// Compute a dense matrix B through the matrix-matrix multiply alpha * A^H * (*this). void MvTransMv (ScalarType alpha, const Anasazi::MultiVec<ScalarType>& A, Teuchos::SerialDenseMatrix< int, ScalarType >& B #ifdef HAVE_ANASAZI_EXPERIMENTAL , Anasazi::ConjType conj #endif ) const { MyMultiVec* MyA; MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A)); assert (MyA != 0); assert (A.GetVecLength() == Length_); assert (NumberVecs_ <= B.numCols()); assert (A.GetNumberVecs() <= B.numRows()); #ifdef HAVE_ANASAZI_EXPERIMENTAL if (conj == Anasazi::CONJ) { #endif for (int v = 0 ; v < A.GetNumberVecs() ; ++v) { for (int w = 0 ; w < NumberVecs_ ; ++w) { ScalarType value = 0.0; for (int i = 0 ; i < Length_ ; ++i) { value += Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v)) * (*this)(i, w); } B(v, w) = alpha * value; } } #ifdef HAVE_ANASAZI_EXPERIMENTAL } else { for (int v = 0 ; v < A.GetNumberVecs() ; ++v) { for (int w = 0 ; w < NumberVecs_ ; ++w) { ScalarType value = 0.0; for (int i = 0 ; i < Length_ ; ++i) { value += (*MyA)(i, v) * (*this)(i, w); } B(v, w) = alpha * value; } } } #endif }
// Compute a dense matrix B through the matrix-matrix multiply alpha * A^H * (*this). void MvTransMv (const ScalarType alpha, const Belos::MultiVec<ScalarType>& A, Teuchos::SerialDenseMatrix< int, ScalarType >& B) const { MyMultiVec* MyA; MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A)); TEUCHOS_ASSERT(MyA != NULL); assert (A.GetGlobalLength() == Length_); assert (NumberVecs_ <= B.numCols()); assert (A.GetNumberVecs() <= B.numRows()); for (int v = 0 ; v < A.GetNumberVecs() ; ++v) { for (int w = 0 ; w < NumberVecs_ ; ++w) { ScalarType value = 0.0; for (int i = 0 ; i < Length_ ; ++i) { value += Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v)) * (*this)(i, w); } B(v, w) = alpha * value; } } }
void EpetraOpMultiVec::MvTransMv ( double alpha, const MultiVec<double>& A, Teuchos::SerialDenseMatrix<int,double>& B #ifdef HAVE_ANASAZI_EXPERIMENTAL , ConjType conj #endif ) const { EpetraOpMultiVec *A_vec = dynamic_cast<EpetraOpMultiVec *>(&const_cast<MultiVec<double> &>(A)); if (A_vec) { Epetra_LocalMap LocalMap(B.numRows(), 0, Epetra_MV->Map().Comm()); Epetra_MultiVector B_Pvec(Epetra_DataAccess::View, LocalMap, B.values(), B.stride(), B.numCols()); int info = Epetra_OP->Apply( *Epetra_MV, *Epetra_MV_Temp ); TEUCHOS_TEST_FOR_EXCEPTION( info != 0, EpetraSpecializedMultiVecFailure, "Anasazi::EpetraOpMultiVec::MvTransMv(): Error returned from Epetra_Operator::Apply()" ); TEUCHOS_TEST_FOR_EXCEPTION( B_Pvec.Multiply( 'T', 'N', alpha, *(A_vec->GetEpetraMultiVector()), *Epetra_MV_Temp, 0.0 ) != 0, EpetraSpecializedMultiVecFailure, "Anasazi::EpetraOpMultiVec::MvTransMv() call to Epetra_MultiVector::Multiply() returned a nonzero value."); } }
void factorExplicit (Kokkos::MultiVector<Scalar, NodeType>& A, Kokkos::MultiVector<Scalar, NodeType>& Q, Teuchos::SerialDenseMatrix<LocalOrdinal, Scalar>& R, const bool contiguousCacheBlocks, const bool forceNonnegativeDiagonal=false) { using Teuchos::asSafe; typedef Kokkos::MultiVector<Scalar, NodeType> KMV; // Tsqr currently likes LocalOrdinal ordinals, but // Kokkos::MultiVector has size_t ordinals. Do conversions // here. // // Teuchos::asSafe() can do safe conversion (e.g., checking for // overflow when casting to a narrower integer type), if a // custom specialization is defined for // Teuchos::ValueTypeConversionTraits<size_t, LocalOrdinal>. // Otherwise, this has the same (potentially) unsafe effect as // static_cast<LocalOrdinal>(...) would have. const LocalOrdinal A_numRows = asSafe<LocalOrdinal> (A.getNumRows()); const LocalOrdinal A_numCols = asSafe<LocalOrdinal> (A.getNumCols()); const LocalOrdinal A_stride = asSafe<LocalOrdinal> (A.getStride()); const LocalOrdinal Q_numRows = asSafe<LocalOrdinal> (Q.getNumRows()); const LocalOrdinal Q_numCols = asSafe<LocalOrdinal> (Q.getNumCols()); const LocalOrdinal Q_stride = asSafe<LocalOrdinal> (Q.getStride()); // Sanity checks for matrix dimensions if (A_numRows < A_numCols) { std::ostringstream os; os << "In Tsqr::factorExplicit: input matrix A has " << A_numRows << " local rows, and " << A_numCols << " columns. The input " "matrix must have at least as many rows on each processor as " "there are columns."; throw std::invalid_argument(os.str()); } else if (A_numRows != Q_numRows) { std::ostringstream os; os << "In Tsqr::factorExplicit: input matrix A and output matrix Q " "must have the same number of rows. A has " << A_numRows << " rows" " and Q has " << Q_numRows << " rows."; throw std::invalid_argument(os.str()); } else if (R.numRows() < R.numCols()) { std::ostringstream os; os << "In Tsqr::factorExplicit: output matrix R must have at least " "as many rows as columns. R has " << R.numRows() << " rows and " << R.numCols() << " columns."; throw std::invalid_argument(os.str()); } else if (A_numCols != R.numCols()) { std::ostringstream os; os << "In Tsqr::factorExplicit: input matrix A and output matrix R " "must have the same number of columns. A has " << A_numCols << " columns and R has " << R.numCols() << " columns."; throw std::invalid_argument(os.str()); } // Check for quick exit, based on matrix dimensions if (Q_numCols == 0) return; // Hold on to nonconst views of A and Q. This will make TSQR // correct (if perhaps inefficient) for all possible Kokkos Node // types, even GPU nodes. Teuchos::ArrayRCP<scalar_type> A_ptr = A.getValuesNonConst(); Teuchos::ArrayRCP<scalar_type> Q_ptr = Q.getValuesNonConst(); R.putScalar (STS::zero()); NodeOutput nodeResults = nodeTsqr_->factor (A_numRows, A_numCols, A_ptr.getRawPtr(), A_stride, R.values(), R.stride(), contiguousCacheBlocks); // FIXME (mfh 19 Oct 2010) Replace actions on raw pointer with // actions on the Kokkos::MultiVector or at least the ArrayRCP. nodeTsqr_->fill_with_zeros (Q_numRows, Q_numCols, Q_ptr.getRawPtr(), Q_stride, contiguousCacheBlocks); matview_type Q_rawView (Q_numRows, Q_numCols, Q_ptr.getRawPtr(), Q_stride); matview_type Q_top_block = nodeTsqr_->top_block (Q_rawView, contiguousCacheBlocks); if (Q_top_block.nrows() < R.numCols()) { std::ostringstream os; os << "The top block of Q has too few rows. This means that the " << "the intranode TSQR implementation has a bug in its top_block" << "() method. The top block should have at least " << R.numCols() << " rows, but instead has only " << Q_top_block.ncols() << " rows."; throw std::logic_error (os.str()); } { matview_type Q_top (R.numCols(), Q_numCols, Q_top_block.get(), Q_top_block.lda()); matview_type R_view (R.numRows(), R.numCols(), R.values(), R.stride()); distTsqr_->factorExplicit (R_view, Q_top, forceNonnegativeDiagonal); } nodeTsqr_->apply (ApplyType::NoTranspose, A_numRows, A_numCols, A_ptr.getRawPtr(), A_stride, nodeResults, Q_numCols, Q_ptr.getRawPtr(), Q_stride, contiguousCacheBlocks); // If necessary, force the R factor to have a nonnegative diagonal. if (forceNonnegativeDiagonal && ! QR_produces_R_factor_with_nonnegative_diagonal()) { details::NonnegDiagForcer<LocalOrdinal, Scalar, STS::isComplex> forcer; matview_type Q_mine (Q_numRows, Q_numCols, Q_ptr.getRawPtr(), Q_stride); matview_type R_mine (R.numRows(), R.numCols(), R.values(), R.stride()); forcer.force (Q_mine, R_mine); } // "Commit" the changes to the multivector. A_ptr = Teuchos::null; Q_ptr = Teuchos::null; }
//GMRES int gmres(const Teuchos::SerialDenseMatrix<int, double> & A, Teuchos::SerialDenseMatrix<int,double> X,const Teuchos::SerialDenseMatrix<int,double> & B, int max_iter, double tolerance) { int n; int k; double resid; k=1; 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> r0(B); //r0-=Ax; resid=r0.normFrobenius(); std::cout << "resid= " << resid << std::endl; //define vector v=r/norm(r) where r=b-Ax r0.scale(1/resid); Teuchos::SerialDenseMatrix<int, double> h(1,1); //Matrix of orthog basis vectors V Teuchos::SerialDenseMatrix<int, double> V(n,1); //Set v=r0/norm(r0) to be 1st col of V for (int i=0; i<n; i++){ V(i,0)=r0(i,0); } //right hand side Teuchos::SerialDenseMatrix<int, double> bb(1,1); bb(0,0)=resid; Teuchos::SerialDenseMatrix<int, double> w(n,1); Teuchos::SerialDenseMatrix<int, double> c; Teuchos::SerialDenseMatrix<int, double> s; while (resid > tolerance && k < max_iter){ std::cout << "k = " << k << std::endl; h.reshape(k+1,k); //Arnoldi iteration(Gram-Schmidt ) V.reshape(n,k+1); //set vk to be kth col of V Teuchos::SerialDenseMatrix<int, double> vk(Teuchos::Copy, V, n,1,0,k-1); w.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, A, vk, 0.0); Teuchos::SerialDenseMatrix<int, double> vi(n,1); Teuchos::SerialDenseMatrix<int, double> ip(1,1); for (int i=0; i<k; i++){ //set vi to be ith col of V Teuchos::SerialDenseMatrix<int, double> vi(Teuchos::Copy, V, n,1,0,i); //Calculate inner product ip.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, vi, w, 0.0); h(i,k-1)= ip(0,0); //scale vi by h(i,k-1) vi.scale(ip(0,0)); w-=vi; } h(k,k-1)=w.normFrobenius(); w.scale(1.0/w.normFrobenius()); //add column vk+1=w to V for (int i=0; i<n; i++){ V(i,k)=w(i,0); } //Solve upper hessenberg least squares problem via Givens rotations //Compute previous Givens rotations for (int i=0; i<k-1; i++){ // double hi=h(i,k-1); // double hi1=h(i+1,k-1); // h(i,k-1)=c(i,0)*h(i,k-1)+s(i,0)*h(i+1,k-1); // h(i+1,k-1)=-1*s(i,0)*h(i,k-1)+c(i,0)*h(i+1,k-1); // h(i,k-1)=c(i,0)*hi+s(i,0)*hi1; // h(i+1,k-1)=-1*s(i,0)*hi+c(i,0)*hi1; double q=c(i,0)*h(i,k-1)+s(i,0)*h(i+1,k-1); h(i+1,k-1)=-1*s(i,0)*h(i,k-1)+c(i,0)*h(i+1,k-1); h(i,k-1)=q; } //Compute next Givens rotations c.reshape(k,1); s.reshape(k,1); bb.reshape(k+1,1); double l = sqrt(h(k-1,k-1)*h(k-1,k-1)+h(k,k-1)*h(k,k-1)); c(k-1,0)=h(k-1,k-1)/l; s(k-1,0)=h(k,k-1)/l; std::cout << "c " << c(k-1,0)<<std::endl; std::cout << "s " << s(k-1,0)<<std::endl; // Givens rotation on h and bb // h(k-1,k-1)=l; // h(k,k-1)=0; double hk=h(k,k-1); double hk1=h(k-1,k-1); h(k-1,k-1)=c(k-1,0)*hk1+s(k-1,0)*hk; h(k,k-1)=-1*s(k-1,0)*hk1+c(k-1,0)*hk; std::cout << "l = " << l <<std::endl; std::cout << "h(k-1,k-1) = should be l " << h(k-1,k-1) <<std::endl; std::cout << "h(k,k-1) = should be 0 " << h(k,k-1) <<std::endl; bb(k,0)=-1*s(k-1,0)*bb(k-1,0); bb(k-1,0)=c(k-1,0)*bb(k-1,0); //Determine residual resid =fabs(bb(k,0)); std::cout << "resid = " << resid <<std::endl; k++; } //Extract upper triangular square matrix bb.reshape(h.numRows()-1 ,1); //Solve linear system int info; std::cout << "bb pre solve = " << bb << std::endl; std::cout << "h= " << h << std::endl; Teuchos::LAPACK<int, double> lapack; lapack.TRTRS('U', 'N', 'N', h.numRows()-1, 1, h.values(), h.stride(), bb.values(), bb.stride(),&info); V.reshape(n,k-1); std::cout << "V= " << V << std::endl; std::cout << "y= " << bb << std::endl; X.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, V, bb, 1.0); std::cout << "X= " << X << std::endl; //Check V is orthogoanl // Teuchos::SerialDenseMatrix<int, double> vtv(V); // vtv.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, V, V, 0.0); // std::cout << "Vtv" << vtv << 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; }
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; }
//Mean-Based Preconditioned GMRES int pregmres(const Teuchos::SerialDenseMatrix<int, double> & A, const Teuchos::SerialDenseMatrix<int,double> & X,const Teuchos::SerialDenseMatrix<int,double> & B, int max_iter, double tolerance) { int n; int k; double resid; k=1; n=A.numRows(); std::cout << A << std::endl; Teuchos::SerialDenseMatrix<int, double> D(n,1); //Get diagonal entries of A for (int i=0; i<n; i++){ D(i,0)=A(i,i); } 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> r0(B); r0-=Ax; resid=r0.normFrobenius(); //define vector v=r/norm(r) where r=b-Ax Teuchos::SerialDenseMatrix<int, double> v(n,1); r0.scale(1/resid); Teuchos::SerialDenseMatrix<int, double> h(1,1); //Matrix of orthog basis vectors V Teuchos::SerialDenseMatrix<int, double> V(n,1); //Set v=r0/norm(r0) to be 1st col of V for (int i=0; i<n; i++){ V(i,0)=r0(i,0); } //right hand side Teuchos::SerialDenseMatrix<int, double> bb(1,1); bb(0,0)=resid; Teuchos::SerialDenseMatrix<int, double> w(n,1); Teuchos::SerialDenseMatrix<int, double> c; Teuchos::SerialDenseMatrix<int, double> s; while (resid > tolerance && k < max_iter){ std::cout << "k = " << k << std::endl; h.reshape(k+1,k); //Arnoldi iteration(Gram-Schmidt ) V.reshape(n,k+1); //set vk to be kth col of V Teuchos::SerialDenseMatrix<int, double> vk(Teuchos::Copy, V, n,1,0,k-1); //Preconditioning step w=AMj(-1)vj w.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1/D(k-1,0), A, vk, 0.0); Teuchos::SerialDenseMatrix<int, double> vi(n,1); Teuchos::SerialDenseMatrix<int, double> ip(1,1); for (int i=0; i<k; i++){ //set vi to be ith col of V Teuchos::SerialDenseMatrix<int, double> vi(Teuchos::Copy, V, n,1,0,i); //Calculate inner product ip.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, vi, w, 0.0); h(i,k-1)= ip(0,0); //scale vi by h(i,k-1) vi.scale(ip(0,0)); w-=vi; } h(k,k-1)=w.normFrobenius(); w.scale(1.0/w.normFrobenius()); //add column vk+1=w to V for (int i=0; i<n; i++){ V(i,k)=w(i,0); } //Solve upper hessenberg least squares problem via Givens rotations //Compute previous Givens rotations for (int i=0; i<k-1; i++){ h(i,k-1)=c(i,0)*h(i,k-1)+s(i,0)*h(i+1,k-1); h(i+1,k-1)=-s(i,0)*h(i,k-1)+c(i,0)*h(i+1,k-1); } //Compute next Givens rotations c.reshape(k,1); s.reshape(k,1); bb.reshape(k+1,1); double l = sqrt(h(k-1,k-1)*h(k-1,k-1)+h(k,k-1)*h(k,k-1)); c(k-1,0)=h(k-1,k-1)/l; s(k-1,0)=h(k,k-1)/l; std::cout <<" h(k,k-1)= " << h(k,k-1) << std::endl; // Givens rotation on h and bb h(k-1,k-1)=l; h(k,k-1)=0; bb(k-1,0)=c(k-1,0)*bb(k-1,0); bb(k,0)=-s(k-1,0)*bb(k-1,0); //Determine residual resid = fabs(bb(k,0)); std::cout << "resid = " << resid << std::endl; k=k+1; } //Extract upper triangular square matrix bb.reshape(h.numRows()-1 ,1); //Solve linear system int info; Teuchos::LAPACK<int, double> lapack; lapack.TRTRS('U', 'N', 'N', h.numRows()-1, 1, h.values(), h.stride(), bb.values(), bb.stride(),&info); //Found y=Mx for (int i=0; i<k-1; i++){ bb(i,0)=bb(i,0)/D(i,0); } V.reshape(n,k-1); Teuchos::SerialDenseMatrix<int, double> ans(X); ans.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, V, bb, 1.0); std::cout << "ans= " << ans << std::endl; std::cout << "h= " << h << std::endl; return 0; }
int Stokhos::GMRESDivisionExpansionStrategy<ordinal_type,value_type,node_type>:: GMRES(const Teuchos::SerialDenseMatrix<int, double> & A, Teuchos::SerialDenseMatrix<int,double> & X, const Teuchos::SerialDenseMatrix<int,double> & B, int max_iter, double tolerance, int prec_iter, int order, int dim, int PrecNum, const Teuchos::SerialDenseMatrix<int, double> & M, int diag) { int n = A.numRows(); int k = 1; double resid; Teuchos::SerialDenseMatrix<int, double> P(n,n); 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> r0(B); r0-=Ax; resid=r0.normFrobenius(); //define vector v=r/norm(r) where r=b-Ax Teuchos::SerialDenseMatrix<int, double> v(n,1); r0.scale(1/resid); Teuchos::SerialDenseMatrix<int, double> h(1,1); //Matrix of orthog basis vectors V Teuchos::SerialDenseMatrix<int, double> V(n,1); //Set v=r0/norm(r0) to be 1st col of V for (int i=0; i<n; i++) { V(i,0)=r0(i,0); } //right hand side Teuchos::SerialDenseMatrix<int, double> bb(1,1); bb(0,0)=resid; Teuchos::SerialDenseMatrix<int, double> w(n,1); Teuchos::SerialDenseMatrix<int, double> c; Teuchos::SerialDenseMatrix<int, double> s; while (resid > tolerance && k < max_iter) { h.reshape(k+1,k); //Arnoldi iteration(Gram-Schmidt ) V.reshape(n,k+1); //set vk to be kth col of V Teuchos::SerialDenseMatrix<int, double> vk(Teuchos::Copy, V, n,1,0,k-1); //Preconditioning step: solve Mz=vk Teuchos::SerialDenseMatrix<int, double> z(vk); if (PrecNum == 1) { Stokhos::DiagPreconditioner precond(M); precond.ApplyInverse(vk,z,prec_iter); } else if (PrecNum == 2) { Stokhos::JacobiPreconditioner precond(M); precond.ApplyInverse(vk,z,2); } else if (PrecNum == 3) { Stokhos::GSPreconditioner precond(M,1); precond.ApplyInverse(vk,z,1); } else if (PrecNum == 4) { Stokhos::SchurPreconditioner precond(M, order, dim, diag); precond.ApplyInverse(vk,z,prec_iter); } w.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1, A, z, 0.0); Teuchos::SerialDenseMatrix<int, double> vi(n,1); Teuchos::SerialDenseMatrix<int, double> ip(1,1); for (int i=0; i<k; i++) { //set vi to be ith col of V Teuchos::SerialDenseMatrix<int, double> vi(Teuchos::Copy, V, n,1,0,i); //Calculate inner product ip.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, vi, w, 0.0); h(i,k-1)= ip(0,0); //scale vi by h(i,k-1) vi.scale(ip(0,0)); w-=vi; } h(k,k-1)=w.normFrobenius(); w.scale(1.0/h(k,k-1)); //add column vk+1=w to V for (int i=0; i<n; i++) { V(i,k)=w(i,0); } //Solve upper hessenberg least squares problem via Givens rotations //Compute previous Givens rotations for (int i=0; i<k-1; i++) { double q=c(i,0)*h(i,k-1)+s(i,0)*h(i+1,k-1); h(i+1,k-1)=-1*s(i,0)*h(i,k-1)+c(i,0)*h(i+1,k-1); h(i,k-1)=q; } //Compute next Givens rotations c.reshape(k,1); s.reshape(k,1); bb.reshape(k+1,1); double l = sqrt(h(k-1,k-1)*h(k-1,k-1)+h(k,k-1)*h(k,k-1)); c(k-1,0)=h(k-1,k-1)/l; s(k-1,0)=h(k,k-1)/l; // Givens rotation on h and bb h(k-1,k-1)=l; h(k,k-1)=0; bb(k,0)=-s(k-1,0)*bb(k-1,0); bb(k-1,0)=c(k-1,0)*bb(k-1,0); //Determine residual resid = fabs(bb(k,0)); k++; } //Extract upper triangular square matrix bb.reshape(h.numRows()-1 ,1); //Solve linear system int info; Teuchos::LAPACK<int, double> lapack; lapack.TRTRS('U', 'N', 'N', h.numRows()-1, 1, h.values(), h.stride(), bb.values(), bb.stride(),&info); Teuchos::SerialDenseMatrix<int, double> ans(X); V.reshape(n,k-1); ans.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, V, bb, 0.0); if (PrecNum == 1) { Stokhos::DiagPreconditioner precond(M); precond.ApplyInverse(ans,ans,prec_iter); } else if (PrecNum == 2) { Stokhos::JacobiPreconditioner precond(M); precond.ApplyInverse(ans,ans,2); } else if (PrecNum == 3) { Stokhos::GSPreconditioner precond(M,1); precond.ApplyInverse(ans,ans,1); } else if (PrecNum == 4) { Stokhos::SchurPreconditioner precond(M, order, dim, diag); precond.ApplyInverse(ans,ans,prec_iter); } X+=ans; std::cout << "iteration count= " << k-1 << std::endl; return 0; }