Ejemplo n.º 1
0
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() );
}
Ejemplo n.º 5
0
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
}
Ejemplo n.º 6
0
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!
}
Ejemplo n.º 8
0
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 << "]" );
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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() )
      ) );
}
Ejemplo n.º 16
0
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())
      )
    );
}
Ejemplo n.º 26
0
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);
}
Ejemplo n.º 27
0
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);
}
Ejemplo n.º 28
0
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;
}