Number CompoundVector::MaxImpl() const { DBG_START_METH("CompoundVector::MaxImpl", dbg_verbosity); DBG_ASSERT(vectors_valid_); DBG_ASSERT(NComps() > 0 && Dim() > 0 && "There is no Max of a zero length vector (no reasonable default can be returned)"); Number max = -std::numeric_limits<Number>::max(); for (Index i=0; i<NComps(); i++) { if (ConstComp(i)->Dim() != 0) { max = Ipopt::Max(max, ConstComp(i)->Max()); } } return max; }
Number CompoundVector::DotImpl(const Vector &x) const { DBG_START_METH("CompoundVector::DotImpl", dbg_verbosity); DBG_ASSERT(vectors_valid_); const CompoundVector* comp_x = static_cast<const CompoundVector*>(&x); DBG_ASSERT(dynamic_cast<const CompoundVector*>(&x)); DBG_ASSERT(NComps() == comp_x->NComps()); Number dot = 0.; for (Index i=0; i<NComps(); i++) { DBG_ASSERT(ConstComp(i)); dot += ConstComp(i)->Dot(*comp_x->GetComp(i)); } return dot; }
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); } } } }
/** Method for retrieving one block from the compound matrix. * * Since this only the lower left components are stored, we need * to have jcol<=irow. */ SmartPtr<const Matrix> GetComp( Index irow, Index jcol ) const { return ConstComp(irow, jcol); }
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; }
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 CompoundVector::HasValidNumbersImpl() const { DBG_ASSERT(vectors_valid_); for (Index i=0; i<NComps(); i++) { if (!ConstComp(i)->HasValidNumbers()) { return false; } } return true; }
Number CompoundVector::SumLogsImpl() const { DBG_START_METH("CompoundVector::SumLogsImpl", dbg_verbosity); DBG_ASSERT(vectors_valid_); Number sum=0.; for (Index i=0; i<NComps(); i++) { sum += ConstComp(i)->SumLogs(); } return sum; }
Number CompoundVector::AmaxImpl() const { DBG_START_METH("CompoundVector::AmaxImpl", dbg_verbosity); DBG_ASSERT(vectors_valid_); Number max=0.; for (Index i=0; i<NComps(); i++) { max = Ipopt::Max(max, ConstComp(i)->Amax()); } return max; }
bool CompoundMatrix::HasValidNumbersImpl() const { if (!matrices_valid_) { matrices_valid_ = MatricesValid(); } DBG_ASSERT(matrices_valid_); for ( Index irow = 0; irow < NComps_Rows(); irow++ ) { for ( Index jcol = 0; jcol < NComps_Cols(); jcol++ ) { if ( (owner_space_->Diagonal() && irow == jcol) || (!owner_space_->Diagonal() && ConstComp(irow,jcol)) ) { if (!ConstComp(irow, jcol)->HasValidNumbers()) { return false; } } } } return true; }
void CompoundMatrix::ComputeColAMaxImpl(Vector& cols_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*>(&cols_norms); #ifndef ALLOW_NESTED // A few sanity checks if (comp_vec) { DBG_ASSERT(NComps_Cols()==comp_vec->NComps()); } else { DBG_ASSERT(NComps_Cols() == 1); } #endif if (comp_vec) { if (NComps_Cols()!=comp_vec->NComps()) { comp_vec = NULL; } } for (Index irow = 0; irow < NComps_Rows(); irow++) { for (Index jcol = 0; jcol < NComps_Cols(); jcol++) { if (ConstComp(irow, jcol)) { SmartPtr<Vector> vec_i; if (comp_vec) { vec_i = comp_vec->GetCompNonConst(irow); } else { vec_i = &cols_norms; } DBG_ASSERT(IsValid(vec_i)); ConstComp(irow, jcol)->ComputeColAMax(*vec_i, false); } } } }
Number CompoundVector::Nrm2Impl() const { DBG_START_METH("CompoundVector::Nrm2Impl", dbg_verbosity); DBG_ASSERT(vectors_valid_); Number sum=0.; for (Index i=0; i<NComps(); i++) { Number nrm2 = ConstComp(i)->Nrm2(); sum += nrm2*nrm2; } return sqrt(sum); }
Number CompoundVector::FracToBoundImpl(const Vector& delta, Number tau) const { DBG_ASSERT(vectors_valid_); const CompoundVector* comp_delta = static_cast<const CompoundVector*>(&delta); DBG_ASSERT(dynamic_cast<const CompoundVector*>(&delta)); DBG_ASSERT(NComps() == comp_delta->NComps()); Number alpha = 1.; for (Index i=0; i<NComps(); i++) { alpha = Ipopt::Min(alpha, ConstComp(i)->FracToBound(*comp_delta->GetComp(i), tau)); } return alpha; }
// Specialized method (overloaded from IpMatrix) void CompoundMatrix::SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, const Vector& R, const Vector& Z, const Vector& D, Vector& X) const { // First check if the matrix is indeed such that we can use the // special methods from the component spaces (this only works if // we have exactly one submatrix per column) bool fast_SinvBlrmZMTdBr = false; if (!owner_space_->Diagonal()) { fast_SinvBlrmZMTdBr = true; for (Index jcol=0; jcol < NComps_Cols(); jcol++ ) { Index nblocks = 0; for (Index irow=0; irow < NComps_Rows(); irow++ ) { if (ConstComp(irow, jcol)) { nblocks++; if (nblocks>1) { break; } } } if (nblocks!=1) { fast_SinvBlrmZMTdBr = false; break; } } } if (!owner_space_->Diagonal() && !fast_SinvBlrmZMTdBr) { // Use the standard replacement implementation Matrix::SinvBlrmZMTdBrImpl(alpha, S, R, Z, D, X); DBG_ASSERT(false && "Found a matrix where we can't use the fast SinvBlrmZMTdBr implementation in CompoundMatrix"); } else { // The vectors are assumed to be compound Vectors as well (unless they // are assumed to consist of only one component const CompoundVector* comp_S = dynamic_cast<const CompoundVector*>(&S); const CompoundVector* comp_R = dynamic_cast<const CompoundVector*>(&R); const CompoundVector* comp_Z = dynamic_cast<const CompoundVector*>(&Z); const CompoundVector* comp_D = dynamic_cast<const CompoundVector*>(&D); CompoundVector* comp_X = dynamic_cast<CompoundVector*>(&X); #ifndef ALLOW_NESTED // A few sanity checks for sizes if (comp_S) { DBG_ASSERT(NComps_Cols()==comp_S->NComps()); } else { DBG_ASSERT(NComps_Cols() == 1); } if (comp_Z) { DBG_ASSERT(NComps_Cols()==comp_Z->NComps()); } else { DBG_ASSERT(NComps_Cols() == 1); } if (comp_R) { DBG_ASSERT(NComps_Cols()==comp_R->NComps()); } else { DBG_ASSERT(NComps_Cols() == 1); } if (comp_D) { DBG_ASSERT(NComps_Rows()==comp_D->NComps()); } else { DBG_ASSERT(NComps_Rows() == 1); } if (comp_X) { DBG_ASSERT(NComps_Cols()==comp_X->NComps()); } else { DBG_ASSERT(NComps_Cols() == 1); } #endif if (comp_S) { if (NComps_Cols()!=comp_S->NComps()) { comp_S = NULL; } } if (comp_Z) { if (NComps_Cols()!=comp_Z->NComps()) { comp_Z = NULL; } } if (comp_R) { if (NComps_Cols()!=comp_R->NComps()) { comp_R = NULL; } } if (comp_D) { if (NComps_Rows()!=comp_D->NComps()) { comp_D = NULL; } } if (comp_X) { if (NComps_Cols()!=comp_X->NComps()) { comp_X = NULL; } } for (Index irow=0; irow<NComps_Cols(); irow++) { Index jcol = irow; if (!owner_space_->Diagonal()) { for (Index j=0; j<NComps_Rows(); j++) { if (ConstComp(j, irow)) { jcol = j; break; } } } SmartPtr<const Vector> S_i; if (comp_S) { S_i = comp_S->GetComp(irow); } else { S_i = &S; } DBG_ASSERT(IsValid(S_i)); SmartPtr<const Vector> Z_i; if (comp_Z) { Z_i = comp_Z->GetComp(irow); } else { Z_i = &Z; } DBG_ASSERT(IsValid(Z_i)); SmartPtr<const Vector> R_i; if (comp_R) { R_i = comp_R->GetComp(irow); } else { R_i = &R; } DBG_ASSERT(IsValid(R_i)); SmartPtr<const Vector> D_i; if (comp_D) { D_i = comp_D->GetComp(jcol); } else { D_i = &D; } DBG_ASSERT(IsValid(D_i)); SmartPtr<Vector> X_i; if (comp_X) { X_i = comp_X->GetCompNonConst(irow); } else { X_i = &X; } DBG_ASSERT(IsValid(X_i)); ConstComp(jcol, irow)->SinvBlrmZMTdBr(alpha, *S_i, *R_i, *Z_i, *D_i, *X_i); } } }
/** Return a particular component (const version) */ SmartPtr<const Vector> GetComp(Index i) const { return ConstComp(i); }
void CompoundMatrix::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); #ifndef ALLOW_NESTED // A few sanity checks if (comp_x) { DBG_ASSERT(NComps_Cols()==comp_x->NComps()); } else { DBG_ASSERT(NComps_Cols() == 1); } if (comp_y) { DBG_ASSERT(NComps_Rows()==comp_y->NComps()); } else { DBG_ASSERT(NComps_Rows() == 1); } #endif if (comp_x) { if (NComps_Cols()!=comp_x->NComps()) { comp_x = NULL; } } if (comp_y) { if (NComps_Rows()!=comp_y->NComps()) { comp_y = NULL; } } // 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_Rows(); 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 < NComps_Cols(); jcol++ ) { if ( (owner_space_->Diagonal() && irow == jcol) || (!owner_space_->Diagonal() && ConstComp(irow,jcol)) ) { SmartPtr<const Vector> x_j; if (comp_x) { x_j = comp_x->GetComp(jcol); } else if (NComps_Cols() == 1) { x_j = &x; } DBG_ASSERT(IsValid(x_j)); ConstComp(irow, jcol)->MultVector(alpha, *x_j, 1., *y_i); } } } }
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)); } } } }
// Specialized method (overloaded from IpMatrix) void CompoundMatrix::AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, Vector& X) const { // The vectors are assumed to be compound Vectors as well (unless they // are assumed to consist of only one component const CompoundVector* comp_S = dynamic_cast<const CompoundVector*>(&S); const CompoundVector* comp_Z = dynamic_cast<const CompoundVector*>(&Z); CompoundVector* comp_X = dynamic_cast<CompoundVector*>(&X); #ifndef ALLOW_NESTED // A few sanity checks for sizes if (comp_S) { DBG_ASSERT(NComps_Cols()==comp_S->NComps()); } else { DBG_ASSERT(NComps_Cols() == 1); } if (comp_Z) { DBG_ASSERT(NComps_Cols()==comp_Z->NComps()); } else { DBG_ASSERT(NComps_Cols() == 1); } if (comp_X) { DBG_ASSERT(NComps_Rows()==comp_X->NComps()); } else { DBG_ASSERT(NComps_Rows() == 1); } #endif if (comp_S) { if (NComps_Cols()!=comp_S->NComps()) { comp_S = NULL; } } if (comp_Z) { if (NComps_Cols()!=comp_Z->NComps()) { comp_Z = NULL; } } if (comp_X) { if (NComps_Rows()!=comp_X->NComps()) { comp_X = NULL; } } for ( Index irow = 0; irow < NComps_Rows(); irow++ ) { SmartPtr<Vector> X_i; if (comp_X) { X_i = comp_X->GetCompNonConst(irow); } else { X_i = &X; } DBG_ASSERT(IsValid(X_i)); for ( Index jcol = 0; jcol < NComps_Cols(); jcol++ ) { if ( (owner_space_->Diagonal() && irow == jcol) || (!owner_space_->Diagonal() && ConstComp(irow, jcol)) ) { SmartPtr<const Vector> S_j; if (comp_S) { S_j = comp_S->GetComp(jcol); } else { S_j = &S; } DBG_ASSERT(IsValid(S_j)); SmartPtr<const Vector> Z_j; if (comp_Z) { Z_j = comp_Z->GetComp(jcol); } else { Z_j = &Z; } DBG_ASSERT(IsValid(Z_j)); ConstComp(irow, jcol)->AddMSinvZ(alpha, *S_j, *Z_j, *X_i); } } } }