void CompoundSymMatrix::PrintImpl( const Journalist& jnlst, EJournalLevel level, EJournalCategory category, const std::string& name, Index indent, const std::string& prefix ) const { jnlst.Printf(level, category, "\n"); jnlst.PrintfIndented(level, category, indent, "%sCompoundSymMatrix \"%s\" with %d rows and columns components:\n", prefix.c_str(), name.c_str(), NComps_Dim()); for( Index irow = 0; irow < NComps_Dim(); irow++ ) { for( Index jcol = 0; jcol <= irow; jcol++ ) { jnlst.PrintfIndented(level, category, indent, "%sComponent for row %d and column %d:\n", prefix.c_str(), irow, jcol); if( ConstComp(irow, jcol) ) { DBG_ASSERT(name.size() < 200); char buffer[256]; Snprintf(buffer, 255, "%s[%d][%d]", name.c_str(), irow, jcol); std::string term_name = buffer; ConstComp(irow, jcol)->Print(&jnlst, level, category, term_name, indent + 1, prefix); } else { jnlst.PrintfIndented(level, category, indent, "%sThis component has not been set.\n", prefix.c_str()); } } } }
void CompoundSymMatrix::ComputeRowAMaxImpl( Vector& rows_norms, bool init ) const { if( !matrices_valid_ ) { matrices_valid_ = MatricesValid(); } DBG_ASSERT(matrices_valid_); // The vector is assumed to be compound Vectors as well except if // there is only one component CompoundVector* comp_vec = dynamic_cast<CompoundVector*>(&rows_norms); // A few sanity checks if( comp_vec ) { DBG_ASSERT(NComps_Dim() == comp_vec->NComps()); } else { DBG_ASSERT(NComps_Dim() == 1); } for( Index jcol = 0; jcol < NComps_Dim(); jcol++ ) { for( Index irow = 0; irow < NComps_Dim(); irow++ ) { SmartPtr<Vector> vec_i; if( comp_vec ) { vec_i = comp_vec->GetCompNonConst(irow); } else { vec_i = &rows_norms; } DBG_ASSERT(IsValid(vec_i)); if( jcol <= irow && ConstComp(irow, jcol) ) { ConstComp(irow, jcol)->ComputeRowAMax(*vec_i, false); } else if( jcol > irow && ConstComp(jcol, irow) ) { ConstComp(jcol, irow)->ComputeRowAMax(*vec_i, false); } } } }
CompoundSymMatrix::CompoundSymMatrix(const CompoundSymMatrixSpace* owner_space) : SymMatrix(owner_space), owner_space_(owner_space), matrices_valid_(false) { for (Index irow=0; irow<NComps_Dim(); irow++) { std::vector< SmartPtr<Matrix> > row(irow+1); std::vector< SmartPtr<const Matrix> > const_row(irow+1); comps_.push_back(row); const_comps_.push_back(const_row); } }
/** Internal method to return a non-const pointer to one of the comps */ Matrix* Comp(Index irow, Index jcol) { DBG_ASSERT(irow < NComps_Dim()); DBG_ASSERT(jcol <= irow); // We shouldn't be asking for a non-const if this entry holds a // const one... DBG_ASSERT(IsNull(const_comps_[irow][jcol])); if (IsValid(comps_[irow][jcol])) { return GetRawPtr(comps_[irow][jcol]); } return NULL; }
/** Internal method to return a const pointer to one of the comps */ const Matrix* ConstComp(Index irow, Index jcol) const { DBG_ASSERT(irow < NComps_Dim()); DBG_ASSERT(jcol <= irow); if (IsValid(comps_[irow][jcol])) { return GetRawPtr(comps_[irow][jcol]); } else if (IsValid(const_comps_[irow][jcol])) { return GetRawPtr(const_comps_[irow][jcol]); } return NULL; }
void CompoundSymMatrix::SetCompNonConst(Index irow, Index jcol, Matrix& matrix) { DBG_ASSERT(!matrices_valid_); DBG_ASSERT(irow < NComps_Dim()); DBG_ASSERT(jcol <= irow); // Matrices on the diagonal must be symmetric DBG_ASSERT( irow != jcol || dynamic_cast<SymMatrix*>(&matrix)); DBG_ASSERT(owner_space_->GetCompSpace(irow, jcol)->IsMatrixFromSpace(matrix)); const_comps_[irow][jcol] = NULL; comps_[irow][jcol] = &matrix; ObjectChanged(); }
CompoundSymMatrix* CompoundSymMatrixSpace::MakeNewCompoundSymMatrix() const { if (!dimensions_set_) { dimensions_set_ = DimensionsSet(); } DBG_ASSERT(dimensions_set_); CompoundSymMatrix* mat = new CompoundSymMatrix(this); for(Index i=0; i<NComps_Dim(); i++) { for (Index j=0; j<=i; j++) { if (allocate_block_[i][j]) { mat->SetCompNonConst(i, j, *GetCompSpace(i, j)->MakeNew()); } } } return mat; }
bool CompoundSymMatrix::MatricesValid() const { // Check to make sure we have matrices everywhere the space has matrices // We already check that the matrix agrees with the block space // in the SetComp methods bool retValue = true; for (Index i=0; i<NComps_Dim(); i++) { for (Index j=0; j<=i; j++) { if ( (!ConstComp(i, j) && IsValid(owner_space_->GetCompSpace(i,j))) || (ConstComp(i, j) && IsNull(owner_space_->GetCompSpace(i,j))) ) { retValue = false; break; } } } return retValue; }
bool CompoundSymMatrix::HasValidNumbersImpl() const { if (!matrices_valid_) { matrices_valid_ = MatricesValid(); } DBG_ASSERT(matrices_valid_); for (Index irow=0; irow<NComps_Dim(); irow++) { for (Index jcol=0; jcol<=irow; jcol++) { if (ConstComp(irow,jcol)) { if (!ConstComp(irow,jcol)->HasValidNumbers()) { return false; } } } } return true; }
void CompoundSymMatrix::MultVectorImpl(Number alpha, const Vector &x, Number beta, Vector &y) const { if (!matrices_valid_) { matrices_valid_ = MatricesValid(); } DBG_ASSERT(matrices_valid_); // The vectors are assumed to be compound Vectors as well const CompoundVector* comp_x = dynamic_cast<const CompoundVector*>(&x); CompoundVector* comp_y = dynamic_cast<CompoundVector*>(&y); // A few sanity checks if (comp_x) { DBG_ASSERT(NComps_Dim()==comp_x->NComps()); } else { DBG_ASSERT(NComps_Dim() == 1); } if (comp_y) { DBG_ASSERT(NComps_Dim()==comp_y->NComps()); } else { DBG_ASSERT(NComps_Dim() == 1); } // Take care of the y part of the addition if( beta!=0.0 ) { y.Scal(beta); } else { y.Set(0.0); // In case y hasn't been initialized yet } for (Index irow=0; irow<NComps_Dim(); irow++) { SmartPtr<Vector> y_i; if (comp_y) { y_i = comp_y->GetCompNonConst(irow); } else { y_i = &y; } DBG_ASSERT(IsValid(y_i)); for (Index jcol=0; jcol<=irow; jcol++) { SmartPtr<const Vector> x_j; if (comp_x) { x_j = comp_x->GetComp(irow); } else { x_j = &x; } DBG_ASSERT(IsValid(x_j)); if (ConstComp(irow,jcol)) { ConstComp(irow,jcol)->MultVector(alpha, *comp_x->GetComp(jcol), 1., *comp_y->GetCompNonConst(irow)); } } for (Index jcol = irow+1; jcol < NComps_Dim(); jcol++) { if (ConstComp(jcol,irow)) { ConstComp(jcol,irow)->TransMultVector(alpha, *comp_x->GetComp(jcol), 1., *comp_y->GetCompNonConst(irow)); } } } }