void SpmdMultiVectorBase<Scalar>::acquireNonconstDetachedMultiVectorViewImpl( const Range1D &rowRng_in, const Range1D &colRng_in, RTOpPack::SubMultiVectorView<Scalar> *sub_mv ) { using Teuchos::outArg; const Range1D rowRng = validateRowRange(rowRng_in); const Range1D colRng = validateColRange(colRng_in); if( rowRng.lbound() < localOffset_ || localOffset_+localSubDim_-1 < rowRng.ubound() ) { // rng consists of off-processor elements so use the default implementation! MultiVectorDefaultBase<Scalar>::acquireNonconstDetachedMultiVectorViewImpl( rowRng_in, colRng_in, sub_mv ); return; } ArrayRCP<Scalar> localValues; Ordinal leadingDim = 0; this->getNonconstLocalData(outArg(localValues), outArg(leadingDim)); sub_mv->initialize( rowRng.lbound() // globalOffset ,rowRng.size() // subDim ,colRng.lbound() // colOffset ,colRng.size() // numSubCols ,localValues +(rowRng.lbound()-localOffset_) +colRng.lbound()*leadingDim // values ,leadingDim // leadingDim ); }
std::ostream& MatrixIdentConcat::output(std::ostream& out_arg) const { Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::getFancyOStream(Teuchos::rcp(&out_arg,false)); Teuchos::OSTab tab(out); const Range1D D_rng = this->D_rng(); const BLAS_Cpp::Transp D_trans = this->D_trans(); *out << "Converted to dense =\n"; MatrixOp::output(*out); *out << "This is a " << this->rows() << " x " << this->cols() << " general matrix / identity matrix concatenated matrix object "; if( D_rng.lbound() == 1 ) { if( D_trans == BLAS_Cpp::no_trans ) *out << "[ alpha*D; I ]"; else *out << "[ alpha*D'; I ]"; } else { if( D_trans == BLAS_Cpp::no_trans ) *out << "[ I; alpha*D ]"; else *out << "[ I; alpha*D' ]"; } *out << " where alpha and D are:"; tab.incrTab(); *out << "\nalpha = " << this->alpha(); *out << "\nD =\n" << D(); return out_arg; }
void DefaultProductVector<Scalar>::acquireNonconstDetachedVectorViewImpl( const Range1D& rng_in, RTOpPack::SubVectorView<Scalar>* sub_vec ) { const Range1D rng = rng_in.full_range() ? Range1D(0,productSpace_->dim()-1) : rng_in; int kth_vector_space = -1; Ordinal kth_global_offset = 0; productSpace_->getVecSpcPoss(rng.lbound(),&kth_vector_space,&kth_global_offset); #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) ); #endif if( rng.lbound() + rng.size() <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim() ) { // This involves only one sub-vector so just return it. vecs_[kth_vector_space].getConstObj()->acquireDetachedView( rng - kth_global_offset, sub_vec ); sub_vec->setGlobalOffset( sub_vec->globalOffset() + kth_global_offset ); } else { // Just let the default implementation handle this. ToDo: In the future // we could manually construct an explicit sub-vector that spanned // two or more constituent vectors but this would be a lot of work. // However, this would require the use of temporary memory but // so what. VectorDefaultBase<Scalar>::acquireNonconstDetachedVectorViewImpl(rng_in,sub_vec); } }
inline const DMatrixSlice DMatrix::operator()(const Range1D& I, const Range1D& J) const { Range1D Ix = RangePack::full_range(I,1,rows()), Jx = RangePack::full_range(J,1,cols()); return DMatrixSlice( const_cast<value_type*>(col_ptr(1)) + (Ix.lbound() - 1) + (Jx.lbound() - 1) * rows() , max_rows() * cols(), max_rows(), Ix.size(), Jx.size() ); }
inline void VectorDefaultBase<Scalar>::validateColRng( const Range1D &col_rng ) const { #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPT( !( col_rng.full_range() || ( col_rng.lbound() == 0 && col_rng.ubound() == 0) ) ); #endif }
bool DefaultSpmdVectorSpace<Scalar>::hasInCoreView( const Range1D& rng_in, const EViewType viewType, const EStrideType strideType ) const { const Range1D rng = full_range(rng_in,0,this->dim()-1); const Ordinal l_localOffset = this->localOffset(); return ( l_localOffset<=rng.lbound() && rng.ubound()<l_localOffset+localSubDim_ ); }
RCP<const MultiVectorBase<Scalar> > MultiVectorDefaultBase<Scalar>::contigSubViewImpl( const Range1D& colRng_in ) const { using Teuchos::Workspace; using Teuchos::as; Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get(); const VectorSpaceBase<Scalar> &l_domain = *this->domain(); const VectorSpaceBase<Scalar> &l_range = *this->range(); const Ordinal dimDomain = l_domain.dim(); const Range1D colRng = Teuchos::full_range(colRng_in,0,dimDomain-1); if( colRng.lbound() == 0 && as<Ordinal>(colRng.ubound()) == dimDomain-1 ) return Teuchos::rcp(this,false); // Takes all of the columns! if( colRng.size() ) { // We have to create a view of a subset of the columns Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,colRng.size()); for( Ordinal j = colRng.lbound(); j <= colRng.ubound(); ++j ) col_vecs[j-colRng.lbound()] = Teuchos::rcp_const_cast<VectorBase<Scalar> >(this->col(j)); return Teuchos::rcp( new DefaultColumnwiseMultiVector<Scalar>( this->range(),l_range.smallVecSpcFcty()->createVecSpc(colRng.size()),col_vecs ) ); } return Teuchos::null; // There was an empty set in colRng_in! }
Teuchos::Range1D EpetraVector::validateRange(const Teuchos::Range1D& rng_in) const { const Range1D rng = Teuchos::full_range(rng_in,0,globalDim_-1); TEST_FOR_EXCEPTION( !( 0 <= rng.lbound() && rng.ubound() < globalDim_ ), std::invalid_argument ,"EpetraVector::validateRange(rowRng): Error, the range rng = [" <<rng.lbound()<<","<<rng.ubound()<<"] is not " "in the range [0,"<<(globalDim_-1)<<"]!" ); return rng; }
bool SetDBoundsStd_AddedStep::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); EJournalOutputLevel ns_olevel = algo.algo_cntr().null_space_journal_output_level(); std::ostream &out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } const Range1D var_dep = s.var_dep(), var_indep = s.var_indep(); const Vector &x_k = s.x().get_k(0), &xl = algo.nlp().xl(), &xu = algo.nlp().xu(); VectorMutable &dl = dl_iq_(s).set_k(0), &du = du_iq_(s).set_k(0); // dl = xl - x_k LinAlgOpPack::V_VmV( &dl, xl, x_k ); // du = xu - x_k LinAlgOpPack::V_VmV( &du, xu, x_k ); if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { if(var_indep.size()) { out << "\ndl(var_indep)_k = \n" << *dl.sub_view(var_indep); out << "\ndu(var_indep)_k = \n" << *du.sub_view(var_indep); } } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { if(var_dep.size()) { out << "\ndl(var_dep)_k = \n" << *dl.sub_view(var_dep); out << "\ndu(var_dep)_k = \n" << *du.sub_view(var_dep); } out << "\ndl_k = \n" << dl; out << "\ndu_k = \n" << du; } return true; }
MultiVectorMutable::multi_vec_mut_ptr_t MultiVectorMutableThyra::mv_sub_view(const Range1D& row_rng_in, const Range1D& col_rng_in) { const index_type this_rows = this->rows(); const Range1D row_rng = RangePack::full_range(row_rng_in,1,this->rows()); TEUCHOS_TEST_FOR_EXCEPTION( !(row_rng.lbound()==1 && row_rng.ubound()==this_rows), std::invalid_argument ,"MultiVectorMutableThyra::mv_sub_view(thyra_multi_vec): Error, can not handle subviews of the" " elements in a row yet!" ); return Teuchos::rcp(new MultiVectorMutableThyra(cast_thyra_multi_vec()->subView(convert(col_rng_in)))); }
void VectorSpaceSubSpace::validate_range(const Range1D& rng) const { const index_type n = this->dim(); TEST_FOR_EXCEPTION( full_space_.get() == NULL, std::logic_error ,"VectorSpaceSubSpace::validate_range(rng): Error, Uninitialized" ); TEST_FOR_EXCEPTION( full_space_.get() && !rng.full_range() && rng.ubound() > n, std::logic_error ,"VectorSpaceSubSpace::validate_range(rng): Error, " "rng = [" << rng.lbound() << "," << rng.ubound() << "] is not in the range " "[1,this->dim] = [1," << n << "]" ); }
Range1D SpmdMultiVectorBase<Scalar>::validateRowRange( const Range1D &rowRng_in ) const { const Range1D rowRng = Teuchos::full_range(rowRng_in,0,globalDim_-1); #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( !( 0 <= rowRng.lbound() && rowRng.ubound() < globalDim_ ), std::invalid_argument ,"SpmdMultiVectorBase<Scalar>::validateRowRange(rowRng): Error, the range rowRng = [" <<rowRng.lbound()<<","<<rowRng.ubound()<<"] is not " "in the range [0,"<<(globalDim_-1)<<"]!" ); #endif return rowRng; }
Range1D SpmdMultiVectorBase<Scalar>::validateColRange( const Range1D &colRng_in ) const { const Range1D colRng = Teuchos::full_range(colRng_in,0,numCols_-1); #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( !(0 <= colRng.lbound() && colRng.ubound() < numCols_), std::invalid_argument ,"SpmdMultiVectorBase<Scalar>::validateColRange(colRng): Error, the range colRng = [" <<colRng.lbound()<<","<<colRng.ubound()<<"] is not " "in the range [0,"<<(numCols_-1)<<"]!" ); #endif return colRng; }
MultiVectorMutable::multi_vec_mut_ptr_t MultiVectorMutableCols::mv_sub_view(const Range1D& row_rng, const Range1D& col_rng) { #ifdef TEUCHOS_DEBUG const size_type rows = this->rows(); TEST_FOR_EXCEPTION( !( row_rng.full_range() || (row_rng.lbound() == 1 && row_rng.ubound() == rows) ) ,std::logic_error, "Error, can't handle subrange on vectors yet!" ); #endif return Teuchos::rcp( new MultiVectorMutableCols( space_cols_,space_rows_->sub_space(col_rng),&col_vecs_[col_rng.lbound()-1] ) ); }
Vector::vec_ptr_t VectorSubView::sub_view( const Range1D& rng_in ) const { namespace rcp = MemMngPack; const index_type this_dim = this->dim(); const Range1D rng = RangePack::full_range(rng_in,1,this_dim); space_.validate_range(rng); const index_type this_offset = space_.rng().lbound() - 1; return Teuchos::rcp( new VectorSubView( full_vec_ ,Range1D( this_offset + rng.lbound() ,this_offset + rng.ubound() ) ) ); }
void EpetraVector::acquireNonconstDetachedVectorViewImpl( const Teuchos::Range1D& rng_in, RTOpPack::SubVectorView<double>* sub_vec) { if( rng_in == Range1D::Invalid ) { // Just return an null view sub_vec->initialize(rng_in.lbound(), 0, Teuchos::ArrayRCP<double>(), 1); return; } const Range1D rng = validateRange(rng_in); if( rng.lbound() < localOffset_ || localOffset_+localSubDim_-1 < rng.ubound() ) { /* rng consists of off-processor elements so use the * default implementation! */ VectorDefaultBase<double>::acquireNonconstDetachedVectorViewImpl(rng_in, sub_vec); return; } /* All requested elements are on-processor. */ double* localValues = &(epetraVec_->operator[](0)); Teuchos::ArrayRCP<double> locVals(localValues, rng.lbound()-localOffset_, // rng.ubound()-localOffset_, false); rng.size(), false); OrdType stride = 1; sub_vec->initialize(rng.lbound(), rng.size(), locVals, stride); // localValues+(rng.lbound()-localOffset_),stride); }
void VectorSpaceSubSpace::initialize( const space_ptr_t& full_space, const Range1D& rng ) { #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPTION( full_space.get() == NULL, std::invalid_argument ,"VectorSpaceSubSpace::initialize(...): Error!" ); #endif const index_type n = full_space->dim(); #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPTION( !rng.full_range() && rng.ubound() > n, std::out_of_range ,"VectorSpaceSubSpace::initialize(...): Error, " "rng = [" << rng.lbound() << "," << rng.ubound() << "] is not in the range " "[1,vec->dim()] = [1," << n << "]" ); #endif full_space_ = full_space; rng_ = rng.full_range() ? Range1D(1,n) : rng; }
RTOpPack::SparseSubVector AbstractLinAlgPack::sub_vec_view( const SpVectorSlice& sv_in ,const Range1D& rng_in ) { using Teuchos::null; const Range1D rng = RangePack::full_range(rng_in,1,sv_in.dim()); const SpVectorSlice sv = sv_in(rng); RTOpPack::SparseSubVector sub_vec; if(!sv.nz()) { sub_vec.initialize( rng.lbound()-1 // global_offset ,rng.size() // sub_dim ,0 // nz ,null // vlaues ,1 // values_stride ,null // indices ,1 // indices_stride ,0 // local_offset ,1 // is_sorted ); } else { SpVectorSlice::const_iterator itr = sv.begin(); TEUCHOS_TEST_FOR_EXCEPT( !( itr != sv.end() ) ); if( sv.dim() && sv.nz() == sv.dim() && sv.is_sorted() ) { const Teuchos::ArrayRCP<const value_type> values = Teuchos::arcp(&itr->value(), 0, values_stride*rng.size(), false) ; sub_vec.initialize( rng.lbound()-1 // global_offset ,rng.size() // sub_dim ,values // values ,values_stride // values_stride ); } else { const Teuchos::ArrayRCP<const value_type> values = Teuchos::arcp(&itr->value(), 0, values_stride*sv.nz(), false) ; const Teuchos::ArrayRCP<const index_type> indexes = Teuchos::arcp(&itr->index(), 0, indices_stride*sv.nz(), false); sub_vec.initialize( rng.lbound()-1 // global_offset ,sv.dim() // sub_dim ,sv.nz() // sub_nz ,values // values ,values_stride // values_stride ,indexes // indices ,indices_stride // indices_stride ,sv.offset() // local_offset ,sv.is_sorted() // is_sorted ); } } return sub_vec; }
void MultiVectorDefaultBase<Scalar>::commitNonconstDetachedMultiVectorViewImpl( RTOpPack::SubMultiVectorView<Scalar>* sub_mv ) { #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( sub_mv==NULL, std::logic_error, "MultiVectorDefaultBase<Scalar>::commitNonconstDetachedMultiVectorViewImpl(...): Error!" ); #endif // Set back the multi-vector values column by column const Range1D rowRng(sub_mv->globalOffset(),sub_mv->globalOffset()+sub_mv->subDim()-1); RTOpPack::SubVectorView<Scalar> msv; // uninitialized by default for( int k = sub_mv->colOffset(); k < sub_mv->numSubCols(); ++k ) { RCP<VectorBase<Scalar> > col_k = this->col(k); col_k->acquireDetachedView( rowRng, &msv ); for( int i = 0; i < rowRng.size(); ++i ) msv[i] = sub_mv->values()[ i + k*rowRng.size() ]; col_k->commitDetachedView( &msv ); } // Zero out the view sub_mv->uninitialize(); }
void MatrixOpSubView::initialize( const mat_ptr_t& M_full ,const Range1D& rng_rows_in ,const Range1D& rng_cols_in ,BLAS_Cpp::Transp M_trans ) { namespace rcp = MemMngPack; if( M_full.get() ) { const index_type M_rows = M_full->rows(), M_cols = M_full->cols(); const Range1D rng_rows = RangePack::full_range(rng_rows_in,1,M_rows), rng_cols = RangePack::full_range(rng_cols_in,1,M_cols); TEUCHOS_TEST_FOR_EXCEPTION( rng_rows.ubound() > M_rows, std::invalid_argument ,"MatrixOpSubView::initialize(...): Error, " "rng_rows = ["<<rng_rows.lbound()<<","<<rng_rows.ubound()<<"] is of range of " "[1,M_full->rows()] = [1,"<<M_rows<<"]" ); TEUCHOS_TEST_FOR_EXCEPTION( rng_cols.ubound() > M_cols, std::invalid_argument ,"MatrixOpSubView::initialize(...): Error, " "rng_cols = ["<<rng_cols.lbound()<<","<<rng_cols.ubound()<<"] is of range of " "[1,M_full->cols()] = [1,"<<M_cols<<"]" ); M_full_ = M_full; rng_rows_ = rng_rows; rng_cols_ = rng_cols; M_trans_ = M_trans; space_cols_ = ( M_trans == BLAS_Cpp::no_trans ? M_full->space_cols().sub_space(rng_rows)->clone() : M_full->space_rows().sub_space(rng_cols)->clone() ); space_rows_ = ( M_trans == BLAS_Cpp::no_trans ? M_full->space_rows().sub_space(rng_cols)->clone() : M_full->space_cols().sub_space(rng_rows)->clone() ); } else { M_full_ = Teuchos::null; rng_rows_ = Range1D::Invalid; rng_cols_ = Range1D::Invalid; M_trans_ = BLAS_Cpp::no_trans; space_cols_ = Teuchos::null; space_rows_ = Teuchos::null; } }
void MatrixConvertToSparseEncap::initialize( const mese_ptr_t &mese ,const i_vector_ptr_t &inv_row_perm ,const Range1D &row_rng_in ,const i_vector_ptr_t &inv_col_perm ,const Range1D &col_rng_in ,const BLAS_Cpp::Transp mese_trans ,const value_type alpha ) { const size_type mese_rows = mese->rows(), mese_cols = mese->cols(); const Range1D row_rng = RangePack::full_range(row_rng_in,1,mese_rows); const Range1D col_rng = RangePack::full_range(col_rng_in,1,mese_cols); #ifdef TEUCHOS_DEBUG const char msg_head[] = "MatrixConvertToSparseEncap::initialize(...): Error!"; TEUCHOS_TEST_FOR_EXCEPTION( mese.get() == NULL, std::logic_error, msg_head ); TEUCHOS_TEST_FOR_EXCEPTION( inv_row_perm.get() != NULL && inv_row_perm->size() != mese_rows, std::logic_error, msg_head ); TEUCHOS_TEST_FOR_EXCEPTION( row_rng.ubound() > mese_rows, std::logic_error, msg_head ); TEUCHOS_TEST_FOR_EXCEPTION( inv_col_perm.get() != NULL && inv_col_perm->size() != mese_cols, std::logic_error, msg_head ); TEUCHOS_TEST_FOR_EXCEPTION( col_rng.ubound() > mese->cols(), std::logic_error, msg_head ); #endif mese_ = mese; mese_trans_ = mese_trans; alpha_ = alpha; inv_row_perm_ = inv_row_perm; inv_col_perm_ = inv_col_perm; row_rng_ = row_rng; col_rng_ = col_rng; nz_full_ = this->num_nonzeros(EXTRACT_FULL_MATRIX,ELEMENTS_ALLOW_DUPLICATES_SUM); space_cols_ = ( mese_trans_ == BLAS_Cpp::no_trans ? mese_->space_cols().sub_space(row_rng_) : mese_->space_rows().sub_space(col_rng_) ); space_rows_ = ( mese_trans_ == BLAS_Cpp::no_trans ? mese_->space_rows().sub_space(col_rng_) : mese_->space_cols().sub_space(row_rng_) ); }
inline DMatrixSlice::DMatrixSlice( DMatrixSlice& gms, const Range1D& I , const Range1D& J) : ptr_( gms.col_ptr(1) + (I.lbound() - 1) + (J.lbound() - 1) * gms.max_rows() ) , max_rows_(gms.max_rows()) , rows_(I.size()) , cols_(J.size()) { gms.validate_row_subscript(I.ubound()); gms.validate_col_subscript(J.ubound()); }
VectorMutable::vec_mut_ptr_t VectorMutable::sub_view( const Range1D& rng_in ) { namespace rcp = MemMngPack; const index_type dim = this->dim(); const Range1D rng = rng_in.full_range() ? Range1D(1,dim) : rng_in; #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPTION( rng.ubound() > dim, std::out_of_range ,"VectorMutable::sub_view(rng): Error, rng = ["<<rng.lbound()<<","<<rng.ubound()<<"] " "is not in the range [1,this->dim()] = [1,"<<dim<<"]" ); #endif if( rng.lbound() == 1 && rng.ubound() == dim ) return Teuchos::rcp( this, false ); // We are returning a view that could change this vector so we had better // wipe out the cache //this->has_changed(); // I don't think this line is needed! return Teuchos::rcp( new VectorMutableSubView( Teuchos::rcp( this, false ) ,rng ) ); }
VectorSpace::space_ptr_t VectorSpaceSubSpace::sub_space(const Range1D& rng_in) const { namespace rcp = MemMngPack; if( full_space_.get() == NULL && rng_in == Range1D::Invalid ) return Teuchos::rcp(this,false); validate_range(rng_in); const index_type dim = this->dim(); const Range1D rng = rng_in.full_range() ? Range1D(1,dim) : rng_in; if( rng.lbound() == 1 && rng.ubound() == dim ) return space_ptr_t( this, false ); const index_type this_offset = rng_.lbound() - 1; return Teuchos::rcp( new VectorSpaceSubSpace( full_space_ ,Range1D( this_offset + rng.lbound() ,this_offset + rng.ubound() ) ) ); }
RCP<MultiVectorBase<Scalar> > DefaultColumnwiseMultiVector<Scalar>::nonconstContigSubViewImpl( const Range1D& col_rng_in ) { const Ordinal numCols = domain_->dim(); const Range1D col_rng = Teuchos::full_range(col_rng_in,0,numCols-1); #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( !( col_rng.ubound() < numCols ), std::logic_error ,"DefaultColumnwiseMultiVector<Scalar>::subView(col_rng):" "Error, the input range col_rng = ["<<col_rng.lbound() <<","<<col_rng.ubound()<<"] " "is not in the range [0,"<<(numCols-1)<<"]!" ); #endif return Teuchos::rcp( new DefaultColumnwiseMultiVector<Scalar>( range_, domain_->smallVecSpcFcty()->createVecSpc(col_rng.size()), col_vecs_(col_rng.lbound(),col_rng.size()) ) ); }
void EpetraVector::acquireDetachedVectorViewImpl( const Teuchos::Range1D& rng_in, RTOpPack::ConstSubVectorView<double>* sub_vec) const { /* if range is empty, return a null view */ if (rng_in == Range1D::Invalid) { sub_vec->initialize(rng_in.lbound(), 0, Teuchos::ArrayRCP<double>(), 1); return ; } /* */ const Range1D rng = validateRange(rng_in); /* If any requested elements are off-processor, fall back to slow * VDB implementation */ if ( rng.lbound() < localOffset_ || localOffset_ + localSubDim_ - 1 < rng.ubound()) { VectorDefaultBase<double>::acquireDetachedVectorViewImpl(rng_in,sub_vec); return ; } /* All requested elements are on-processor. */ const double* localValues = &(epetraVec_->operator[](0)); Teuchos::ArrayRCP<const double> locVals(localValues, rng.lbound()-localOffset_, rng.size(), false); // rng.ubound()-localOffset_, false); OrdType stride = 1; sub_vec->initialize(rng.lbound(), rng.size(), locVals, stride); // localValues+(rng.lbound()-localOffset_), stride); }
void VectorDefaultBase<Scalar>::acquireDetachedVectorViewImpl( const Range1D& rng_in, RTOpPack::ConstSubVectorView<Scalar>* sub_vec_inout ) const { using Teuchos::dyn_cast; const Range1D rng = rng_in.full_range() ? Range1D(0,this->space()->dim()-1) : rng_in; #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( !(rng.ubound() < this->space()->dim()), std::out_of_range ,"VectorDefaultBase<Scalar>::acquireDetachedVectorViewImpl(rng,...):" " Error, rng = ["<<rng.lbound()<<","<<rng.ubound() <<"] is not in range = [0,"<<(this->space()->dim()-1)<<"]" ); #endif // Initialize the operator RTOpPack::ROpGetSubVector<Scalar> get_sub_vector_op(rng.lbound(),rng.ubound()); // Create the reduction object (another sub_vec) RCP<RTOpPack::ReductTarget> reduct_obj = get_sub_vector_op.reduct_obj_create(); // This is really of type RTOpPack::ConstSubVectorView<Scalar>! // Perform the reduction (get the sub-vector requested) ::Thyra::applyOp<Scalar>(get_sub_vector_op, tuple(Teuchos::ptr<const VectorBase<Scalar> >(this))(), Teuchos::null, reduct_obj.ptr()); // Get the sub-vector. *sub_vec_inout = get_sub_vector_op(*reduct_obj); }
void EpetraVector::applyOp( const RTOpPack::RTOpT<double> &op, const int num_vecs, const VectorBase<double>*const vecs[], const int num_targ_vecs, VectorBase<double>*const targ_vecs[], RTOpPack::ReductTarget *reduct_obj, const OrdType first_ele_offset_in, const OrdType sub_dim_in, const OrdType global_offset_in ) const { #ifdef THYRA_SPMD_VECTOR_BASE_DUMP Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream(); Teuchos::OSTab tab(out); if(show_dump) { *out << "\nEntering SpmdVectorBase<double>::applyOp(...) ...\n"; *out << "\nop = " << typeName(op) << "\nnum_vecs = " << num_vecs << "\nnum_targ_vecs = " << num_targ_vecs << "\nreduct_obj = " << reduct_obj << "\nfirst_ele_offset_in = " << first_ele_offset_in << "\nsub_dim_in = " << sub_dim_in << "\nglobal_offset_in = " << global_offset_in << "\n" ; } #endif // THYRA_SPMD_VECTOR_BASE_DUMP using Teuchos::dyn_cast; using Teuchos::Workspace; Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get(); #ifdef TEUCHOS_DEBUG // ToDo: Validate input! TEST_FOR_EXCEPTION( in_applyOpImpl_, std::invalid_argument ,"SpmdVectorBase<>::applyOp(...): Error, this method is being entered recursively which is a " "clear sign that one of the methods acquireDetachedView(...), releaseDetachedView(...) or commitDetachedView(...) " "was not implemented properly!" ); Thyra::apply_op_validate_input( "SpmdVectorBase<>::applyOp(...)",*space() ,op,num_vecs,vecs,num_targ_vecs,targ_vecs,reduct_obj,first_ele_offset_in,sub_dim_in,global_offset_in ); #endif const Teuchos::RCP<const Teuchos::Comm<OrdType> >& comm = epetraVecSpace_->getComm(); const SerialComm<OrdType>* serialComm = dynamic_cast<const SerialComm<OrdType>* >(comm.get()); // Flag that we are in applyOp() in_applyOpImpl_ = true; // First see if this is a locally replicated vector in which case // we treat this as a local operation only. const bool locallyReplicated = ( serialComm != 0 && localSubDim_ == globalDim_ ); // Get the overlap in the current process with the input logical sub-vector // from (first_ele_offset_in,sub_dim_in,global_offset_in) OrdType overlap_first_local_ele_off = 0; OrdType overlap_local_sub_dim = 0; OrdType overlap_global_off = 0; if(localSubDim_) { RTOp_parallel_calc_overlap( globalDim_, localSubDim_, localOffset_, first_ele_offset_in, sub_dim_in, global_offset_in ,&overlap_first_local_ele_off, &overlap_local_sub_dim, &overlap_global_off ); } const Range1D local_rng = ( overlap_first_local_ele_off>=0 ? Range1D( localOffset_ + overlap_first_local_ele_off, localOffset_ + overlap_first_local_ele_off + overlap_local_sub_dim - 1 ) : Range1D::Invalid ); #ifdef THYRA_SPMD_VECTOR_BASE_DUMP if(show_dump) { *out << "\noverlap_first_local_ele_off = " << overlap_first_local_ele_off << "\noverlap_local_sub_dim = " << overlap_local_sub_dim << "\noverlap_global_off = " << overlap_global_off << "\nlocal_rng = ["<<local_rng.lbound()<<","<<local_rng.ubound()<<"]" << "\n" ; } #endif // THYRA_SPMD_VECTOR_BASE_DUMP // Create sub-vector views of all of the *participating* local data Workspace<RTOpPack::ConstSubVectorView<double> > sub_vecs(wss,num_vecs); Workspace<RTOpPack::SubVectorView<double> > sub_targ_vecs(wss,num_targ_vecs); if( overlap_first_local_ele_off >= 0 ) { {for(int k = 0; k < num_vecs; ++k ) { vecs[k]->acquireDetachedView( local_rng, &sub_vecs[k] ); sub_vecs[k].setGlobalOffset( overlap_global_off ); }} {for(int k = 0; k < num_targ_vecs; ++k ) { targ_vecs[k]->acquireDetachedView( local_rng, &sub_targ_vecs[k] ); sub_targ_vecs[k].setGlobalOffset( overlap_global_off ); }} } // Apply the RTOp operator object (all processors must participate) const bool validSubVecs = ( localSubDim_ > 0 && overlap_first_local_ele_off >= 0 ); RTOpPack::SPMD_apply_op( locallyReplicated ? NULL : comm.get() // comm ,op // op ,num_vecs // num_vecs ,num_vecs && validSubVecs ? &sub_vecs[0] : NULL // sub_vecs ,num_targ_vecs // num_targ_vecs ,num_targ_vecs && validSubVecs ? &sub_targ_vecs[0] : NULL // targ_sub_vecs ,reduct_obj // reduct_obj ); // Free and commit the local data if( overlap_first_local_ele_off >= 0 ) { {for(int k = 0; k < num_vecs; ++k ) { sub_vecs[k].setGlobalOffset(local_rng.lbound()); vecs[k]->releaseDetachedView( &sub_vecs[k] ); }} {for(int k = 0; k < num_targ_vecs; ++k ) { sub_targ_vecs[k].setGlobalOffset(local_rng.lbound()); targ_vecs[k]->commitDetachedView( &sub_targ_vecs[k] ); }} } // Flag that we are leaving applyOp() in_applyOpImpl_ = false; #ifdef THYRA_SPMD_VECTOR_BASE_DUMP if(show_dump) { *out << "\nLeaving SpmdVectorBase<double>::applyOp(...) ...\n"; } #endif // THYRA_SPMD_VECTOR_BASE_DUMP }
bool TangentialStepWithInequStd_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { using Teuchos::RCP; using Teuchos::dyn_cast; using ::fabs; using LinAlgOpPack::Vt_S; using LinAlgOpPack::V_VpV; using LinAlgOpPack::V_VmV; using LinAlgOpPack::Vp_StV; using LinAlgOpPack::Vp_V; using LinAlgOpPack::V_StV; using LinAlgOpPack::V_MtV; // using ConstrainedOptPack::min_abs; using AbstractLinAlgPack::max_near_feas_step; typedef VectorMutable::vec_mut_ptr_t vec_mut_ptr_t; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); EJournalOutputLevel ns_olevel = algo.algo_cntr().null_space_journal_output_level(); std::ostream &out = algo.track().journal_out(); //const bool check_results = algo.algo_cntr().check_results(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } // problem dimensions const size_type //n = algo.nlp().n(), m = algo.nlp().m(), r = s.equ_decomp().size(); // Get the iteration quantity container objects IterQuantityAccess<value_type> &alpha_iq = s.alpha(), &zeta_iq = s.zeta(), &eta_iq = s.eta(); IterQuantityAccess<VectorMutable> &dl_iq = dl_iq_(s), &du_iq = du_iq_(s), &nu_iq = s.nu(), *c_iq = m > 0 ? &s.c() : NULL, *lambda_iq = m > 0 ? &s.lambda() : NULL, &rGf_iq = s.rGf(), &w_iq = s.w(), &qp_grad_iq = s.qp_grad(), &py_iq = s.py(), &pz_iq = s.pz(), &Ypy_iq = s.Ypy(), &Zpz_iq = s.Zpz(); IterQuantityAccess<MatrixOp> &Z_iq = s.Z(), //*Uz_iq = (m > r) ? &s.Uz() : NULL, *Uy_iq = (m > r) ? &s.Uy() : NULL; IterQuantityAccess<MatrixSymOp> &rHL_iq = s.rHL(); IterQuantityAccess<ActSetStats> &act_set_stats_iq = act_set_stats_(s); // Accessed/modified/updated (just some) VectorMutable *Ypy_k = (m ? &Ypy_iq.get_k(0) : NULL); const MatrixOp &Z_k = Z_iq.get_k(0); VectorMutable &pz_k = pz_iq.set_k(0); VectorMutable &Zpz_k = Zpz_iq.set_k(0); // Comupte qp_grad which is an approximation to rGf + Z'*HL*Y*py // qp_grad = rGf VectorMutable &qp_grad_k = ( qp_grad_iq.set_k(0) = rGf_iq.get_k(0) ); // qp_grad += zeta * w if( w_iq.updated_k(0) ) { if(zeta_iq.updated_k(0)) Vp_StV( &qp_grad_k, zeta_iq.get_k(0), w_iq.get_k(0) ); else Vp_V( &qp_grad_k, w_iq.get_k(0) ); } // // Set the bounds for: // // dl <= Z*pz + Y*py <= du -> dl - Ypy <= Z*pz <= du - Ypz vec_mut_ptr_t bl = s.space_x().create_member(), bu = s.space_x().create_member(); if(m) { // bl = dl_k - Ypy_k V_VmV( bl.get(), dl_iq.get_k(0), *Ypy_k ); // bu = du_k - Ypy_k V_VmV( bu.get(), du_iq.get_k(0), *Ypy_k ); } else { *bl = dl_iq.get_k(0); *bu = du_iq.get_k(0); } // Print out the QP bounds for the constraints if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nqp_grad_k = \n" << qp_grad_k; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nbl = \n" << *bl; out << "\nbu = \n" << *bu; } // // Determine if we should perform a warm start or not. // bool do_warm_start = false; if( act_set_stats_iq.updated_k(-1) ) { if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nDetermining if the QP should use a warm start ...\n"; } // We need to see if we should preform a warm start for the next iteration ActSetStats &stats = act_set_stats_iq.get_k(-1); const size_type num_active = stats.num_active(), num_adds = stats.num_adds(), num_drops = stats.num_drops(); const value_type frac_same = ( num_adds == ActSetStats::NOT_KNOWN || num_active == 0 ? 0.0 : my_max(((double)(num_active)-num_adds-num_drops) / num_active, 0.0 ) ); do_warm_start = ( num_active > 0 && frac_same >= warm_start_frac() ); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nnum_active = " << num_active; if( num_active ) { out << "\nmax(num_active-num_adds-num_drops,0)/(num_active) = " << "max("<<num_active<<"-"<<num_adds<<"-"<<num_drops<<",0)/("<<num_active<<") = " << frac_same; if( do_warm_start ) out << " >= "; else out << " < "; out << "warm_start_frac = " << warm_start_frac(); } if( do_warm_start ) out << "\nUse a warm start this time!\n"; else out << "\nDon't use a warm start this time!\n"; } } // Use active set from last iteration as an estimate for current active set // if we are to use a warm start. // // ToDo: If the selection of dependent and independent variables changes // then you will have to adjust this or not perform a warm start at all! if( do_warm_start ) { nu_iq.set_k(0,-1); } else { nu_iq.set_k(0) = 0.0; // No guess of the active set } VectorMutable &nu_k = nu_iq.get_k(0); // // Setup the reduced QP subproblem // // The call to the QP is setup for the more flexible call to the QPSolverRelaxed // interface to deal with the three independent variabilities: using simple // bounds for pz or not, general inequalities included or not, and extra equality // constraints included or not. // If this method of calling the QP solver were not used then 4 separate // calls to solve_qp(...) would have to be included to handle the four possible // QP formulations. // // The numeric arguments for the QP solver (in the nomenclatrue of QPSolverRelaxed) const value_type qp_bnd_inf = NLP::infinite_bound(); const Vector &qp_g = qp_grad_k; const MatrixSymOp &qp_G = rHL_iq.get_k(0); const value_type qp_etaL = 0.0; vec_mut_ptr_t qp_dL = Teuchos::null; vec_mut_ptr_t qp_dU = Teuchos::null; Teuchos::RCP<const MatrixOp> qp_E = Teuchos::null; BLAS_Cpp::Transp qp_trans_E = BLAS_Cpp::no_trans; vec_mut_ptr_t qp_b = Teuchos::null; vec_mut_ptr_t qp_eL = Teuchos::null; vec_mut_ptr_t qp_eU = Teuchos::null; Teuchos::RCP<const MatrixOp> qp_F = Teuchos::null; BLAS_Cpp::Transp qp_trans_F = BLAS_Cpp::no_trans; vec_mut_ptr_t qp_f = Teuchos::null; value_type qp_eta = 0.0; VectorMutable &qp_d = pz_k; // pz_k will be updated directly! vec_mut_ptr_t qp_nu = Teuchos::null; vec_mut_ptr_t qp_mu = Teuchos::null; vec_mut_ptr_t qp_Ed = Teuchos::null; vec_mut_ptr_t qp_lambda = Teuchos::null; // // Determine if we can use simple bounds on pz. // // If we have a variable-reduction null-space matrix // (with any choice for Y) then: // // d = Z*pz + (1-eta) * Y*py // // [ d(var_dep) ] = [ D ] * pz + (1-eta) * [ Ypy(var_dep) ] // [ d(var_indep) ] [ I ] [ Ypy(var_indep) ] // // For a cooridinate decomposition (Y = [ I ; 0 ]) then Ypy(var_indep) == // 0.0 and in this case the bounds on d(var_indep) become simple bounds on // pz even with the relaxation. Also, if dl(var_dep) and du(var_dep) are // unbounded, then we can also use simple bounds since we don't need the // relaxation and we can set eta=0. In this case we just have to subtract // from the upper and lower bounds on pz! // // Otherwise, we can not use simple variable bounds and implement the // relaxation properly. // const MatrixIdentConcat *Zvr = dynamic_cast<const MatrixIdentConcat*>( &Z_k ); const Range1D var_dep = Zvr ? Zvr->D_rng() : Range1D::Invalid, var_indep = Zvr ? Zvr->I_rng() : Range1D(); RCP<Vector> Ypy_indep; const value_type Ypy_indep_norm_inf = ( m ? (Ypy_indep=Ypy_k->sub_view(var_indep))->norm_inf() : 0.0); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) out << "\nDetermine if we can use simple bounds on pz ...\n" << " m = " << m << std::endl << " dynamic_cast<const MatrixIdentConcat*>(&Z_k) = " << Zvr << std::endl << " ||Ypy_k(var_indep)||inf = " << Ypy_indep_norm_inf << std::endl; const bool bounded_var_dep = ( m > 0 && num_bounded( *bl->sub_view(var_dep), *bu->sub_view(var_dep), qp_bnd_inf ) ); const bool use_simple_pz_bounds = ( m == 0 || ( Zvr != NULL && ( Ypy_indep_norm_inf == 0.0 || bounded_var_dep == 0 ) ) ); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) out << (use_simple_pz_bounds ? "\nUsing simple bounds on pz ...\n" : "\nUsing bounds on full Z*pz ...\n") << (bounded_var_dep ? "\nThere are finite bounds on dependent variables. Adding extra inequality constrints for D*pz ...\n" : "\nThere are no finite bounds on dependent variables. There will be no extra inequality constraints added on D*pz ...\n" ) ; if( use_simple_pz_bounds ) { // Set simple bound constraints on pz qp_dL = bl->sub_view(var_indep); qp_dU = bu->sub_view(var_indep); qp_nu = nu_k.sub_view(var_indep); // nu_k(var_indep) will be updated directly! if( m && bounded_var_dep ) { // Set general inequality constraints for D*pz qp_E = Teuchos::rcp(&Zvr->D(),false); qp_b = Ypy_k->sub_view(var_dep); qp_eL = bl->sub_view(var_dep); qp_eU = bu->sub_view(var_dep); qp_mu = nu_k.sub_view(var_dep); // nu_k(var_dep) will be updated directly! qp_Ed = Zpz_k.sub_view(var_dep); // Zpz_k(var_dep) will be updated directly! } else { // Leave these as NULL since there is no extra general inequality constraints } } else if( !use_simple_pz_bounds ) { // ToDo: Leave out parts for unbounded dependent variables! // There are no simple bounds! (leave qp_dL, qp_dU and qp_nu as null) // Set general inequality constraints for Z*pz qp_E = Teuchos::rcp(&Z_k,false); qp_b = Teuchos::rcp(Ypy_k,false); qp_eL = bl; qp_eU = bu; qp_mu = Teuchos::rcp(&nu_k,false); qp_Ed = Teuchos::rcp(&Zpz_k,false); // Zpz_k will be updated directly! } else { TEST_FOR_EXCEPT(true); } // Set the general equality constriants (if they exist) Range1D equ_undecomp = s.equ_undecomp(); if( m > r && m > 0 ) { // qp_f = Uy_k * py_k + c_k(equ_undecomp) qp_f = s.space_c().sub_space(equ_undecomp)->create_member(); V_MtV( qp_f.get(), Uy_iq->get_k(0), BLAS_Cpp::no_trans, py_iq.get_k(0) ); Vp_V( qp_f.get(), *c_iq->get_k(0).sub_view(equ_undecomp) ); // Must resize for the undecomposed constriants if it has not already been qp_F = Teuchos::rcp(&Uy_iq->get_k(0),false); qp_lambda = lambda_iq->set_k(0).sub_view(equ_undecomp); // lambda_k(equ_undecomp), will be updated directly! } // Setup the rest of the arguments QPSolverRelaxed::EOutputLevel qp_olevel; switch( olevel ) { case PRINT_NOTHING: qp_olevel = QPSolverRelaxed::PRINT_NONE; break; case PRINT_BASIC_ALGORITHM_INFO: qp_olevel = QPSolverRelaxed::PRINT_NONE; break; case PRINT_ALGORITHM_STEPS: qp_olevel = QPSolverRelaxed::PRINT_BASIC_INFO; break; case PRINT_ACTIVE_SET: qp_olevel = QPSolverRelaxed::PRINT_ITER_SUMMARY; break; case PRINT_VECTORS: qp_olevel = QPSolverRelaxed::PRINT_ITER_VECTORS; break; case PRINT_ITERATION_QUANTITIES: qp_olevel = QPSolverRelaxed::PRINT_EVERY_THING; break; default: TEST_FOR_EXCEPT(true); } // ToDo: Set print options so that only vectors matrices etc // are only printed in the null space // // Solve the QP // qp_solver().infinite_bound(qp_bnd_inf); const QPSolverStats::ESolutionType solution_type = qp_solver().solve_qp( int(olevel) == int(PRINT_NOTHING) ? NULL : &out ,qp_olevel ,( algo.algo_cntr().check_results() ? QPSolverRelaxed::RUN_TESTS : QPSolverRelaxed::NO_TESTS ) ,qp_g, qp_G, qp_etaL, qp_dL.get(), qp_dU.get() ,qp_E.get(), qp_trans_E, qp_E.get() ? qp_b.get() : NULL ,qp_E.get() ? qp_eL.get() : NULL, qp_E.get() ? qp_eU.get() : NULL ,qp_F.get(), qp_trans_F, qp_F.get() ? qp_f.get() : NULL ,NULL // obj_d ,&qp_eta, &qp_d ,qp_nu.get() ,qp_mu.get(), qp_E.get() ? qp_Ed.get() : NULL ,qp_F.get() ? qp_lambda.get() : NULL ,NULL // qp_Fd ); // // Check the optimality conditions for the QP // std::ostringstream omsg; bool throw_qp_failure = false; if( qp_testing() == QP_TEST || ( qp_testing() == QP_TEST_DEFAULT && algo.algo_cntr().check_results() ) ) { if( int(olevel) >= int(PRINT_ALGORITHM_STEPS) ) { out << "\nChecking the optimality conditions of the reduced QP subproblem ...\n"; } if(!qp_tester().check_optimality_conditions( solution_type,qp_solver().infinite_bound() ,int(olevel) == int(PRINT_NOTHING) ? NULL : &out ,int(olevel) >= int(PRINT_VECTORS) ? true : false ,int(olevel) >= int(PRINT_ITERATION_QUANTITIES) ? true : false ,qp_g, qp_G, qp_etaL, qp_dL.get(), qp_dU.get() ,qp_E.get(), qp_trans_E, qp_E.get() ? qp_b.get() : NULL ,qp_E.get() ? qp_eL.get() : NULL, qp_E.get() ? qp_eU.get() : NULL ,qp_F.get(), qp_trans_F, qp_F.get() ? qp_f.get() : NULL ,NULL // obj_d ,&qp_eta, &qp_d ,qp_nu.get() ,qp_mu.get(), qp_E.get() ? qp_Ed.get() : NULL ,qp_F.get() ? qp_lambda.get() : NULL ,NULL // qp_Fd )) { omsg << "\n*** Alert! at least one of the QP optimality conditions did not check out.\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } throw_qp_failure = true; } } // // Set the solution // if( !use_simple_pz_bounds ) { // Everything is already updated! } else if( use_simple_pz_bounds ) { // Just have to set Zpz_k(var_indep) = pz_k *Zpz_k.sub_view(var_indep) = pz_k; if( m && !bounded_var_dep ) { // Must compute Zpz_k(var_dep) = D*pz LinAlgOpPack::V_MtV( &*Zpz_k.sub_view(var_dep), Zvr->D(), BLAS_Cpp::no_trans, pz_k ); // ToDo: Remove the compuation of Zpz here unless you must } } else { TEST_FOR_EXCEPT(true); } // Set the solution statistics qp_solver_stats_(s).set_k(0) = qp_solver().get_qp_stats(); // Cut back Ypy_k = (1-eta) * Ypy_k const value_type eps = std::numeric_limits<value_type>::epsilon(); if( fabs(qp_eta - 0.0) > eps ) { if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\n*** Alert! the QP was infeasible (eta = "<<qp_eta<<"). Cutting back Ypy_k = (1.0 - eta)*Ypy_k ...\n"; } Vt_S( Ypy_k, 1.0 - qp_eta ); } // eta_k eta_iq.set_k(0) = qp_eta; // // Modify the solution if we have to! // switch(solution_type) { case QPSolverStats::OPTIMAL_SOLUTION: break; // we are good! case QPSolverStats::PRIMAL_FEASIBLE_POINT: { omsg << "\n*** Alert! the returned QP solution is PRIMAL_FEASIBLE_POINT but not optimal!\n"; if( primal_feasible_point_error() ) omsg << "\n*** primal_feasible_point_error == true, this is an error!\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } throw_qp_failure = primal_feasible_point_error(); break; } case QPSolverStats::DUAL_FEASIBLE_POINT: { omsg << "\n*** Alert! the returned QP solution is DUAL_FEASIBLE_POINT" << "\n*** but not optimal so we cut back the step ...\n"; if( dual_feasible_point_error() ) omsg << "\n*** dual_feasible_point_error == true, this is an error!\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } // Cut back the step to fit in the bounds // // dl <= u*(Ypy_k+Zpz_k) <= du // vec_mut_ptr_t zero = s.space_x().create_member(0.0), d_tmp = s.space_x().create_member(); V_VpV( d_tmp.get(), *Ypy_k, Zpz_k ); const std::pair<value_type,value_type> u_steps = max_near_feas_step( *zero, *d_tmp, dl_iq.get_k(0), du_iq.get_k(0), 0.0 ); const value_type u = my_min( u_steps.first, 1.0 ); // largest positive step size alpha_iq.set_k(0) = u; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nFinding u s.t. dl <= u*(Ypy_k+Zpz_k) <= du\n" << "max step length u = " << u << std::endl << "alpha_k = u = " << alpha_iq.get_k(0) << std::endl; } throw_qp_failure = dual_feasible_point_error(); break; } case QPSolverStats::SUBOPTIMAL_POINT: { omsg << "\n*** Alert!, the returned QP solution is SUBOPTIMAL_POINT!\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } throw_qp_failure = true; break; } default: TEST_FOR_EXCEPT(true); // should not happen! } // // Output the final solution! // if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\n||pz_k||inf = " << s.pz().get_k(0).norm_inf() << "\nnu_k.nz() = " << s.nu().get_k(0).nz() << "\nmax(|nu_k(i)|) = " << s.nu().get_k(0).norm_inf() // << "\nmin(|nu_k(i)|) = " << min_abs( s.nu().get_k(0)() ) ; if( m > r ) out << "\n||lambda_k(undecomp)||inf = " << s.lambda().get_k(0).norm_inf(); out << "\n||Zpz_k||2 = " << s.Zpz().get_k(0).norm_2() ; if(qp_eta > 0.0) out << "\n||Ypy||2 = " << s.Ypy().get_k(0).norm_2(); out << std::endl; } if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\npz_k = \n" << s.pz().get_k(0); if(var_indep.size()) out << "\nnu_k(var_indep) = \n" << *s.nu().get_k(0).sub_view(var_indep); } if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { if(var_indep.size()) out << "\nZpz(var_indep)_k = \n" << *s.Zpz().get_k(0).sub_view(var_indep); out << std::endl; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { if(var_dep.size()) out << "\nZpz(var_dep)_k = \n" << *s.Zpz().get_k(0).sub_view(var_dep); out << "\nZpz_k = \n" << s.Zpz().get_k(0); out << std::endl; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nnu_k = \n" << s.nu().get_k(0); if(var_dep.size()) out << "\nnu_k(var_dep) = \n" << *s.nu().get_k(0).sub_view(var_dep); if( m > r ) out << "\nlambda_k(equ_undecomp) = \n" << *s.lambda().get_k(0).sub_view(equ_undecomp); if(qp_eta > 0.0) out << "\nYpy = \n" << s.Ypy().get_k(0); } if( qp_eta == 1.0 ) { omsg << "TangentialStepWithInequStd_Step::do_step(...) : Error, a QP relaxation parameter\n" << "of eta = " << qp_eta << " was calculated and therefore it must be assumed\n" << "that the NLP's constraints are infeasible\n" << "Throwing an InfeasibleConstraints exception!\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } throw InfeasibleConstraints(omsg.str()); } if( throw_qp_failure ) throw QPFailure( omsg.str(), qp_solver().get_qp_stats() ); return true; }
bool NLPInterfacePack::test_nlp_direct( NLPDirect *nlp ,OptionsFromStreamPack::OptionsFromStream *options ,std::ostream *out ) { using TestingHelperPack::update_success; bool result; bool success = true; Teuchos::VerboseObjectTempState<NLP> nlpOutputTempState(Teuchos::rcp(nlp,false),Teuchos::getFancyOStream(Teuchos::rcp(out,false)),Teuchos::VERB_LOW); if(out) *out << "\n****************************" << "\n*** test_nlp_direct(...) ***" << "\n*****************************\n"; nlp->initialize(true); // Test the DVector spaces if(out) *out << "\nTesting the vector spaces ...\n"; VectorSpaceTester vec_space_tester; if(options) { VectorSpaceTesterSetOptions opt_setter(&vec_space_tester); opt_setter.set_options(*options); } if(out) *out << "\nTesting nlp->space_x() ...\n"; result = vec_space_tester.check_vector_space(*nlp->space_x(),out); if(out) { if(result) *out << "nlp->space_x() checks out!\n"; else *out << "nlp->space_x() check failed!\n"; } update_success( result, &success ); if(out) *out << "\nTesting nlp->space_x()->sub_space(nlp->var_dep()) ...\n"; result = vec_space_tester.check_vector_space( *nlp->space_x()->sub_space(nlp->var_dep()),out); if(out) { if(result) *out << "nlp->space_x()->sub_space(nlp->var_dep()) checks out!\n"; else *out << "nlp->space_x()->sub_space(nlp->var_dep()) check failed!\n"; } update_success( result, &success ); if(out) *out << "\nTesting nlp->space_x()->sub_space(nlp->var_indep()) ...\n"; result = vec_space_tester.check_vector_space( *nlp->space_x()->sub_space(nlp->var_indep()),out); if(out) { if(result) *out << "nlp->space_x()->sub_space(nlp->var_indep()) checks out!\n"; else *out << "nlp->space_x()->sub_space(nlp->var_indep()) check failed!\n"; } update_success( result, &success ); if(out) *out << "\nTesting nlp->space_c() ...\n"; result = vec_space_tester.check_vector_space(*nlp->space_c(),out); if(out) { if(result) *out << "nlp->space_c() checks out!\n"; else *out << "nlp->space_c() check failed!\n"; } update_success( result, &success ); if(out) *out << "\nTesting nlp->space_c()->sub_space(nlp->con_decomp()) ...\n"; result = vec_space_tester.check_vector_space( *nlp->space_c()->sub_space(nlp->con_decomp()),out); if(out) { if(result) *out << "nlp->space_c()->sub_space(nlp->con_decomp()) checks out!\n"; else *out << "nlp->space_c()->sub_space(nlp->con_decomp()) check failed!\n"; } update_success( result, &success ); if( nlp->con_decomp().size() < nlp->m() ) { if(out) *out << "\nTesting nlp->space_c()->sub_space(nlp->con_undecomp()) ...\n"; result = vec_space_tester.check_vector_space( *nlp->space_c()->sub_space(nlp->con_undecomp()),out); if(out) { if(result) *out << "nlp->space_c()->sub_space(nlp->con_undecomp()) checks out!\n"; else *out << "nlp->space_c()->sub_space(nlp->con_undecomp()) check failed!\n"; } update_success( result, &success ); } // Test the NLP interface first! NLPTester nlp_tester; if(options) { NLPTesterSetOptions nlp_tester_opt_setter(&nlp_tester); nlp_tester_opt_setter.set_options(*options); } const bool print_all_warnings = nlp_tester.print_all(); result = nlp_tester.test_interface( nlp, nlp->xinit(), print_all_warnings, out ); update_success( result, &success ); // Test the NLPDirect interface now! const bool supports_Gf = nlp->supports_Gf(); if(out) *out << "\nCalling nlp->calc_point(...) at nlp->xinit() ...\n"; const size_type n = nlp->n(), m = nlp->m(); const Range1D var_dep = nlp->var_dep(), var_indep = nlp->var_indep(), con_decomp = nlp->con_decomp(), con_undecomp = nlp->con_undecomp(); VectorSpace::vec_mut_ptr_t c = nlp->space_c()->create_member(), Gf = nlp->space_x()->create_member(), py = nlp->space_x()->sub_space(var_dep)->create_member(), rGf = nlp->space_x()->sub_space(var_indep)->create_member(); NLPDirect::mat_fcty_ptr_t::element_type::obj_ptr_t GcU = con_decomp.size() < m ? nlp->factory_GcU()->create() : Teuchos::null, D = nlp->factory_D()->create(), Uz = con_decomp.size() < m ? nlp->factory_Uz()->create() : Teuchos::null; nlp->calc_point( nlp->xinit(), NULL, c.get(), true, supports_Gf?Gf.get():NULL, py.get(), rGf.get() ,GcU.get(), D.get(), Uz.get() ); if(out) { if(supports_Gf) { *out << "\n||Gf||inf = " << Gf->norm_inf(); if(nlp_tester.print_all()) *out << "\nGf =\n" << *Gf; } *out << "\n||py||inf = " << py->norm_inf(); if(nlp_tester.print_all()) *out << "\npy =\n" << *py; *out << "\n||rGf||inf = " << rGf->norm_inf(); if(nlp_tester.print_all()) *out << "\nrGf =\n" << *rGf; if(nlp_tester.print_all()) *out << "\nD =\n" << *D; if( con_decomp.size() < m ) { TEST_FOR_EXCEPT(true); // ToDo: Print GcU and Uz } *out << "\n"; } CalcFiniteDiffProd calc_fd_prod; if(options) { CalcFiniteDiffProdSetOptions options_setter( &calc_fd_prod ); options_setter.set_options(*options); } NLPDirectTester nlp_first_order_direct_tester(Teuchos::rcp(&calc_fd_prod,false)); if(options) { NLPDirectTesterSetOptions nlp_tester_opt_setter(&nlp_first_order_direct_tester); nlp_tester_opt_setter.set_options(*options); } result = nlp_first_order_direct_tester.finite_diff_check( nlp, nlp->xinit() ,nlp->num_bounded_x() ? &nlp->xl() : NULL ,nlp->num_bounded_x() ? &nlp->xu() : NULL ,c.get() ,supports_Gf?Gf.get():NULL,py.get(),rGf.get(),GcU.get(),D.get(),Uz.get() ,print_all_warnings, out ); update_success( result, &success ); return success; }