// Copyright (C) 2004, 2006 International Business Machines and others. // All Rights Reserved. // This code is published under the Eclipse Public License. // // Authors: Carl Laird, Andreas Waechter IBM 2004-06-06 #ifndef __IPITERATESVECTOR_HPP__ #define __IPITERATESVECTOR_HPP__ #include "IpCompoundVector.hpp" namespace Ipopt { /* forward declarations */ class IteratesVectorSpace; /** Specialized CompoundVector class specifically for the algorithm * iterates. This class inherits from CompoundVector and is a * specialized class for handling the iterates of the Ipopt * Algorithm, that is, x, s, y_c, y_d, z_L, z_U, v_L, and v_U. It * inherits from CompoundVector so it can behave like a CV in most * calculations, but it has fixed dimensions and cannot be * customized */ class IPOPTLIB_EXPORT IteratesVector: public CompoundVector { public: /** Constructors / Destructors */ ///@{ IteratesVector( const IteratesVectorSpace* owner_space, bool create_new ); virtual ~IteratesVector(); ///@} /** Make New methods */ ///@{ /** Use this method to create a new iterates vector. * * The MakeNew method on the Vector class also works, but it does not give * the create_new option. */ SmartPtr MakeNewIteratesVector( bool create_new = true ) const; /** Use this method to create a new iterates vector with a copy of * all the data. */ SmartPtr MakeNewIteratesVectorCopy() const { SmartPtr ret = MakeNewIteratesVector(true); ret->Copy(*this); return ret; } /** Use this method to create a new iterates vector * container. * * This creates a new NonConst container, but the * elements inside the iterates vector may be const. Therefore, * the container can be modified to point to new entries, but the * existing entries may or may not be modifiable. */ SmartPtr MakeNewContainer() const; ///@} /** Iterates Set/Get Methods */ ///@{ /** Get the x iterate (const) */ SmartPtr x() const { return GetIterateFromComp(0); } /** Get the x iterate (non-const) - this can only be called if the * vector was created internally, or the Set_x_NonConst method was * used. */ SmartPtr x_NonConst() { return GetNonConstIterateFromComp(0); } /** Create a new vector in the x entry */ inline SmartPtr create_new_x(); /** Create a new vector in the x entry and copy the current values * into it. */ SmartPtr create_new_x_copy() { SmartPtr curr_x_ = GetComp(0); Set_x_NonConst(*curr_x_->MakeNew()); x_NonConst()->Copy(*curr_x_); return x_NonConst(); } /** Set the x iterate (const). * * Sets the pointer, does NOT copy data. */ void Set_x( const Vector& vec ) { SetComp(0, vec); } /** Set the x iterate (non-const). * * Sets the pointer, does NOT copy data. */ void Set_x_NonConst( Vector& vec ) { SetCompNonConst(0, vec); } /** Get the s iterate (const) */ SmartPtr s() const { return GetIterateFromComp(1); } /** Get the s iterate (non-const) - this can only be called if the * vector was created internally, or the Set_s_NonConst method was * used. */ SmartPtr s_NonConst() { return GetNonConstIterateFromComp(1); } /** Create a new vector in the s entry */ inline SmartPtr create_new_s(); /** Create a new vector in the s entry and copy the current values * into it. */ SmartPtr create_new_s_copy() { SmartPtr curr_s = GetComp(1); Set_s_NonConst(*curr_s->MakeNew()); s_NonConst()->Copy(*curr_s); return s_NonConst(); } /** Set the s iterate (const). * * Sets the pointer, does NOT copy data. */ void Set_s( const Vector& vec ) { SetComp(1, vec); } /** Set the s iterate (non-const). * * Sets the pointer, does NOT copy data. */ void Set_s_NonConst( Vector& vec ) { SetCompNonConst(1, vec); } /** Get the y_c iterate (const) */ SmartPtr y_c() const { return GetIterateFromComp(2); } /** Get the y_c iterate (non-const) - this can only be called if * the vector was created internally, or the Set_y_c_NonConst * method was used. */ SmartPtr y_c_NonConst() { return GetNonConstIterateFromComp(2); } /** Create a new vector in the y_c entry */ inline SmartPtr create_new_y_c(); /** Create a new vector in the y_c entry and copy the current * values into it. */ SmartPtr create_new_y_c_copy() { SmartPtr curr_y_c_ = GetComp(2); Set_y_c_NonConst(*curr_y_c_->MakeNew()); y_c_NonConst()->Copy(*curr_y_c_); return y_c_NonConst(); } /** Set the y_c iterate (const). * * Sets the pointer, does NOT copy data. */ void Set_y_c( const Vector& vec ) { SetComp(2, vec); } /** Set the y_c iterate (non-const). * * Sets the pointer, does NOT copy data. */ void Set_y_c_NonConst( Vector& vec ) { SetCompNonConst(2, vec); } /** Get the y_d iterate (const) */ SmartPtr y_d() const { return GetIterateFromComp(3); } /** Get the y_d iterate (non-const) - this can only be called if * the vector was created internally, or the Set_y_d_NonConst * method was used. */ SmartPtr y_d_NonConst() { return GetNonConstIterateFromComp(3); } /** Create a new vector in the y_d entry */ inline SmartPtr create_new_y_d(); /** Create a new vector in the y_d entry and copy the current * values into it. */ SmartPtr create_new_y_d_copy() { SmartPtr curr_y_d_ = GetComp(3); Set_y_d_NonConst(*curr_y_d_->MakeNew()); y_d_NonConst()->Copy(*curr_y_d_); return y_d_NonConst(); } /** Set the y_d iterate (const). * * Sets the pointer, does NOT copy data. */ void Set_y_d( const Vector& vec ) { SetComp(3, vec); } /** Set the y_d iterate (non-const). * * Sets the pointer, does NOT copy data. */ void Set_y_d_NonConst( Vector& vec ) { SetCompNonConst(3, vec); } /** Get the z_L iterate (const) */ SmartPtr z_L() const { return GetIterateFromComp(4); } /** Get the z_L iterate (non-const) - this can only be called if * the vector was created internally, or the Set_z_L_NonConst * method was used. */ SmartPtr z_L_NonConst() { return GetNonConstIterateFromComp(4); } /** Create a new vector in the z_L entry */ inline SmartPtr create_new_z_L(); /** Create a new vector in the z_L entry and copy the current * values into it. */ SmartPtr create_new_z_L_copy() { SmartPtr curr_z_L_ = GetComp(4); Set_z_L_NonConst(*curr_z_L_->MakeNew()); z_L_NonConst()->Copy(*curr_z_L_); return z_L_NonConst(); } /** Set the z_L iterate (const). * * Sets the pointer, does NOT copy data. */ void Set_z_L( const Vector& vec ) { SetComp(4, vec); } /** Set the z_L iterate (non-const). * * Sets the pointer, does NOT copy data. */ void Set_z_L_NonConst( Vector& vec ) { SetCompNonConst(4, vec); } /** Get the z_U iterate (const) */ SmartPtr z_U() const { return GetIterateFromComp(5); } /** Get the z_U iterate (non-const) - this can only be called if * the vector was created internally, or the Set_z_U_NonConst * method was used. */ SmartPtr z_U_NonConst() { return GetNonConstIterateFromComp(5); } /** Create a new vector in the z_U entry */ inline SmartPtr create_new_z_U(); /** Create a new vector in the z_U entry and copy the current * values into it. */ SmartPtr create_new_z_U_copy() { SmartPtr curr_z_U_ = GetComp(5); Set_z_U_NonConst(*curr_z_U_->MakeNew()); z_U_NonConst()->Copy(*curr_z_U_); return z_U_NonConst(); } /** Set the z_U iterate (const). * * Sets the pointer, does NOT copy data. */ void Set_z_U( const Vector& vec ) { SetComp(5, vec); } /** Set the z_U iterate (non-const). * * Sets the pointer, does NOT copy data. */ void Set_z_U_NonConst( Vector& vec ) { SetCompNonConst(5, vec); } /** Get the v_L iterate (const) */ SmartPtr v_L() const { return GetIterateFromComp(6); } /** Get the v_L iterate (non-const) - this can only be called if * the vector was created internally, or the Set_v_L_NonConst * method was used. */ SmartPtr v_L_NonConst() { return GetNonConstIterateFromComp(6); } /** Create a new vector in the v_L entry */ inline SmartPtr create_new_v_L(); /** Create a new vector in the v_L entry and copy the current * values into it. */ SmartPtr create_new_v_L_copy() { SmartPtr curr_v_L = GetComp(6); Set_v_L_NonConst(*curr_v_L->MakeNew()); v_L_NonConst()->Copy(*curr_v_L); return v_L_NonConst(); } /** Set the v_L iterate (const). * * Sets the pointer, does NOT copy data. */ void Set_v_L( const Vector& vec ) { SetComp(6, vec); } /** Set the v_L iterate (non-const). * Sets the pointer, does NOT copy data. */ void Set_v_L_NonConst( Vector& vec ) { SetCompNonConst(6, vec); } /** Get the v_U iterate (const) */ SmartPtr v_U() const { return GetIterateFromComp(7); } /** Get the v_U iterate (non-const) - this can only be called if * the vector was created intenally, or the Set_v_U_NonConst * method was used. */ SmartPtr v_U_NonConst() { return GetNonConstIterateFromComp(7); } /** Create a new vector in the v_U entry */ inline SmartPtr create_new_v_U(); /** Create a new vector in the v_U entry and copy the current * values into it. */ SmartPtr create_new_v_U_copy() { SmartPtr curr_v_U = GetComp(7); Set_v_U_NonConst(*curr_v_U->MakeNew()); v_U_NonConst()->Copy(*curr_v_U); return v_U_NonConst(); } /** Set the v_U iterate (const). * * Sets the pointer, does NOT copy data. */ void Set_v_U( const Vector& vec ) { SetComp(7, vec); } /** Set the v_U iterate (non-const). * * Sets the pointer, does NOT copy data. */ void Set_v_U_NonConst( Vector& vec ) { SetCompNonConst(7, vec); } /** Set the primal variables all in one shot. * * Sets the pointers, does NOT copy data. */ void Set_primal( const Vector& x, const Vector& s ) { SetComp(0, x); SetComp(1, s); } void Set_primal_NonConst( Vector& x, Vector& s ) { SetCompNonConst(0, x); SetCompNonConst(1, s); } /** Set the eq multipliers all in one shot. * * Sets the pointers, does not copy data. */ void Set_eq_mult( const Vector& y_c, const Vector& y_d ) { SetComp(2, y_c); SetComp(3, y_d); } /** Set the eq multipliers all in one shot. * * Sets the pointers, does not copy data. */ void Set_eq_mult_NonConst( Vector& y_c, Vector& y_d ) { SetCompNonConst(2, y_c); SetCompNonConst(3, y_d); } /** Set the bound multipliers all in one shot. * * Sets the pointers, does not copy data. */ void Set_bound_mult( const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U ) { SetComp(4, z_L); SetComp(5, z_U); SetComp(6, v_L); SetComp(7, v_U); } /** Set the bound multipliers all in one shot. * * Sets the pointers, does not copy data. */ void Set_bound_mult_NonConst( Vector& z_L, Vector& z_U, Vector& v_L, Vector& v_U ) { SetCompNonConst(4, z_L); SetCompNonConst(5, z_U); SetCompNonConst(6, v_L); SetCompNonConst(7, v_U); } /** Get a sum of the tags of the contained items. * * There is no * guarantee that this is unique, but there is a high chance it * is unique and it can be used for debug checks relatively * reliably. */ TaggedObject::Tag GetTagSum() const { TaggedObject::Tag tag = 0; if( IsValid(x()) ) { tag += x()->GetTag(); } if( IsValid(s()) ) { tag += s()->GetTag(); } if( IsValid(y_c()) ) { tag += y_c()->GetTag(); } if( IsValid(y_d()) ) { tag += y_d()->GetTag(); } if( IsValid(z_L()) ) { tag += z_L()->GetTag(); } if( IsValid(z_U()) ) { tag += z_U()->GetTag(); } if( IsValid(v_L()) ) { tag += v_L()->GetTag(); } if( IsValid(v_U()) ) { tag += v_U()->GetTag(); } return tag; } ///@} private: /**@name Default Compiler Generated Methods (Hidden to avoid * implicit creation/calling). * * These methods are not implemented * and we do not want the compiler to implement them for us, so we * declare them private and do not define them. This ensures that * they will not be implicitly created/called. */ ///@{ /** Default Constructor */ IteratesVector(); /** Copy Constructor */ IteratesVector( const IteratesVector& ); /** Default Assignment Operator */ void operator=( const IteratesVector& ); ///@} const IteratesVectorSpace* owner_space_; /** private method to return the const element from the compound vector * * @return NULL, if none is currently set */ SmartPtr GetIterateFromComp( Index i ) const { if( IsCompNull(i) ) { return NULL; } return GetComp(i); } /** private method to return the non-const element from the compound vector * * @return NULL, if none is currently set */ SmartPtr GetNonConstIterateFromComp( Index i ) { if( IsCompNull(i) ) { return NULL; } return GetCompNonConst(i); } }; /** Vector Space for the IteratesVector class. * * This is a specialized vector space for the IteratesVector class. */ class IPOPTLIB_EXPORT IteratesVectorSpace: public CompoundVectorSpace { public: /** @name Constructors / Destructors */ ///@{ /** Constructor that takes the spaces for each of the iterates. * * @attention None of these can be NULL ! */ IteratesVectorSpace( const VectorSpace& x_space, const VectorSpace& s_space, const VectorSpace& y_c_space, const VectorSpace& y_d_space, const VectorSpace& z_L_space, const VectorSpace& z_U_space, const VectorSpace& v_L_space, const VectorSpace& v_U_space ); virtual ~IteratesVectorSpace(); ///@} /** Method for creating vectors . */ ///@{ /** Use this to create a new IteratesVector. * * You can pass-in * create_new = false if you only want a container and do not * want vectors allocated. */ virtual IteratesVector* MakeNewIteratesVector( bool create_new = true ) const { return new IteratesVector(this, create_new); } /** Use this method to create a new const IteratesVector. * * You must pass in valid pointers for all of the entries. */ const SmartPtr MakeNewIteratesVector( const Vector& x, const Vector& s, const Vector& y_c, const Vector& y_d, const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U ) { SmartPtr newvec = MakeNewIteratesVector(false); newvec->Set_x(x); newvec->Set_s(s); newvec->Set_y_c(y_c); newvec->Set_y_d(y_d); newvec->Set_z_L(z_L); newvec->Set_z_U(z_U); newvec->Set_v_L(v_L); newvec->Set_v_U(v_U); return ConstPtr(newvec); } virtual CompoundVector* MakeNewCompoundVector( bool create_new = true ) const { return MakeNewIteratesVector(create_new); } /** This method creates a new vector (and allocates space in all * the contained vectors. * * This is really only used for code that * does not know what type of vector it is dealing with - for * example, this method is called from Vector::MakeNew() */ virtual Vector* MakeNew() const { return MakeNewIteratesVector(); } ///@} /** This method hides the CompoundVectorSpace::SetCompSpace method * since the components of the Iterates are fixed at * construction. */ virtual void SetCompSpace( Index /*icomp*/, const VectorSpace& /*vec_space*/ ) { DBG_ASSERT(false && "This is an IteratesVectorSpace - a special compound vector for Ipopt iterates. The contained spaces should not be modified."); } private: /**@name Default Compiler Generated Methods (Hidden to avoid * implicit creation/calling). * * These methods are not implemented * and we do not want the compiler to implement them for us, so we * declare them private and do not define them. This ensures that * they will not be implicitly created/called. */ ///@{ /** Default constructor */ IteratesVectorSpace(); /** Copy Constructor */ IteratesVectorSpace( const IteratesVectorSpace& ); /** Default Assignment Operator */ IteratesVectorSpace& operator=( const IteratesVectorSpace& ); ///@} /** Contained Spaces */ SmartPtr x_space_; SmartPtr s_space_; SmartPtr y_c_space_; SmartPtr y_d_space_; SmartPtr z_L_space_; SmartPtr z_U_space_; SmartPtr v_L_space_; SmartPtr v_U_space_; }; inline SmartPtr IteratesVector::create_new_x() { Set_x_NonConst(*owner_space_->GetCompSpace(0)->MakeNew()); return x_NonConst(); } inline SmartPtr IteratesVector::create_new_s() { Set_s_NonConst(*owner_space_->GetCompSpace(1)->MakeNew()); return s_NonConst(); } inline SmartPtr IteratesVector::create_new_y_c() { Set_y_c_NonConst(*owner_space_->GetCompSpace(2)->MakeNew()); return y_c_NonConst(); } inline SmartPtr IteratesVector::create_new_y_d() { Set_y_d_NonConst(*owner_space_->GetCompSpace(3)->MakeNew()); return y_d_NonConst(); } inline SmartPtr IteratesVector::create_new_z_L() { Set_z_L_NonConst(*owner_space_->GetCompSpace(4)->MakeNew()); return z_L_NonConst(); } inline SmartPtr IteratesVector::create_new_z_U() { Set_z_U_NonConst(*owner_space_->GetCompSpace(5)->MakeNew()); return z_U_NonConst(); } inline SmartPtr IteratesVector::create_new_v_L() { Set_v_L_NonConst(*owner_space_->GetCompSpace(6)->MakeNew()); return v_L_NonConst(); } inline SmartPtr IteratesVector::create_new_v_U() { Set_v_U_NonConst(*owner_space_->GetCompSpace(7)->MakeNew()); return v_U_NonConst(); } } // namespace Ipopt #endif