45 #include "DenseLinAlgPack_PermOut.hpp"
53 #include "NLPInterfacePack_NLPSerialPreprocess.hpp"
54 #include "AbstractLinAlgPack_SpVectorOp.hpp"
55 #include "AbstractLinAlgPack_PermutationSerial.hpp"
56 #include "AbstractLinAlgPack_VectorDenseEncap.hpp"
57 #include "AbstractLinAlgPack_VectorStdOps.hpp"
58 #include "AbstractLinAlgPack_VectorAuxiliaryOps.hpp"
59 #include "DenseLinAlgPack_DVectorOp.hpp"
60 #include "DenseLinAlgPack_IVector.hpp"
61 #include "DenseLinAlgPack_PermVecMat.hpp"
62 #include "DenseLinAlgPack_LinAlgOpPack.hpp"
63 #include "Teuchos_Assert.hpp"
64 #include "Teuchos_AbstractFactoryStd.hpp"
65 #include "Teuchos_dyn_cast.hpp"
67 namespace LinAlgOpPack {
71 namespace NLPInterfacePack {
80 return std::numeric_limits<DenseLinAlgPack::DVector::value_type>::max()-100;
88 ,force_xinit_in_bounds_(true)
90 ,basis_selection_num_(0)
103 return force_xinit_in_bounds_;
108 namespace mmp = MemMngPack;
112 basis_selection_num_ = 0;
129 n_full_ = n_orig_ + mI_orig_;
130 m_full_ = m_orig_ + mI_orig_;
134 xinit_full_.resize(n_full_);
135 xl_full_.resize(n_full_);
136 xu_full_.resize(n_full_);
137 x_full_.resize(n_full_);
138 c_orig_.resize(m_orig_);
139 h_orig_.resize(mI_orig_);
140 Gf_full_.resize(n_full_);
141 var_full_to_fixed_.resize(n_full_);
142 equ_perm_.resize(m_full_);
143 inv_equ_perm_.resize(m_full_);
144 space_c_.initialize(m_full_);
145 space_c_breve_.initialize(m_orig_);
146 space_h_breve_.initialize(mI_orig_);
155 if( n_full_ > n_orig_ ) {
156 xinit_full_(n_orig_+1,n_full_) = 0.0;
166 VectorMutableDense( xl_full_(), Teuchos::null )
167 ,VectorMutableDense( xu_full_(), Teuchos::null )
168 ,&VectorMutableDense( x_full_(), Teuchos::null )
177 if( has_var_bounds ) {
181 xl_full = xl_full_.begin(),
182 xu_full = xu_full_.begin();
185 for(
int i = 1; i <= n_full_; ++i, ++xl_full, ++xu_full) {
188 ,
"NLPSerialPreprocess::initialize() : Error, Inconsistant bounds: xl_full("
189 << i <<
") > xu_full(" << i <<
")" );
190 if(*xl_full == *xu_full) {
194 var_full_to_fixed_(n_full_ - num_fixed) = i;
202 *xl_full = *xl_full < -inf_bnd ? -inf_bnd : *xl_full;
203 *xu_full = *xu_full > +inf_bnd ? +inf_bnd : *xu_full;
206 var_full_to_fixed_(n_) = i;
208 if( *xl_full != -inf_bnd )
211 if( *xu_full != inf_bnd )
213 if( *xl_full != -inf_bnd || *xu_full != inf_bnd )
221 DenseLinAlgPack::identity_perm( &var_full_to_fixed_ );
227 num_bounded_x_ = num_bnd_x;
232 ,
"NLPSerialPreprocess::initialize() : Error, after removing fixed "
233 <<
"variables, n = " << n_ <<
" < m = " << m_full_
234 <<
", and the NLP is over determined and can not be solved!" );
237 DenseLinAlgPack::inv_perm( var_full_to_fixed_, &inv_var_full_to_fixed_ );
241 var_perm_.resize(n_);
242 space_x_.initialize(n_);
245 xinit_.initialize(n_);
249 hl_breve_.initialize(mI_orig_);
250 hu_breve_.initialize(mI_orig_);
258 DenseLinAlgPack::identity_perm(&var_perm_);
260 DenseLinAlgPack::identity_perm(&equ_perm_);
262 DenseLinAlgPack::identity_perm(&inv_equ_perm_);
265 var_from_full( xinit_full_().begin(), xinit_.set_vec().begin() );
267 var_from_full( xl_full_().begin(), xl_.set_vec().begin() );
268 var_from_full( xu_full_().begin(), xu_.set_vec().begin() );
269 do_force_xinit_in_bounds();
286 get_next_basis_return = get_next_basis_remove_fixed( &var_perm_, &equ_perm_, &rank );
288 !get_next_basis_return, std::logic_error
289 ,
"NLPSerialPreprocess::initialize(): "
290 " If nlp_selects_basis() is true then imp_get_next_basis() "
291 " must return true for the first call" );
292 assert_and_set_basis( var_perm_, equ_perm_, rank );
299 initialized_ =
false;
303 initialized_ =
false;
307 DenseLinAlgPack::identity_perm(&var_perm_);
309 var_from_full( xinit_full_().begin(), xinit_.set_vec().begin() );
311 var_from_full( xl_full_().begin(), xl_.set_vec().begin() );
312 var_from_full( xu_full_().begin(), xu_.set_vec().begin() );
313 do_force_xinit_in_bounds();
352 namespace mmp = MemMngPack;
358 namespace mmp = MemMngPack;
359 return ( m_full_ ?
Teuchos::rcp(&space_c_,
false) : Teuchos::null );
364 return num_bounded_x_;
419 VectorDenseEncap x_d(x);
422 var_to_full( x_d().begin(),
x_full().begin() );
426 VectorDenseEncap lambda_d(*lambda);
427 DVectorSlice lambda = lambda_d();
428 lambda_full.resize(m_full_);
430 lambda_full(equ_perm_(j)) = lambda(j);
433 DVector nu_full(n_full_);
437 VectorDenseEncap nu_d(*nu);
438 var_to_full( nu_d().begin(), nu_full().begin() );
442 lambda_orig = lambda && m_orig_ ? lambda_full(1,m_orig_) : DVectorSlice(),
443 lambdaI_orig = ( lambda && m_full_ > m_orig_
444 ? lambda_full(m_orig_+1,m_full_)
446 nu_orig = nu ? nu_full(1,n_orig_) : DVectorSlice();
449 ,lambda_orig.dim() ? &lambda_orig : NULL
450 ,lambdaI_orig.dim() ? &lambdaI_orig : NULL
451 ,nu_orig.dim() ? &nu_orig : NULL
465 namespace mmp = MemMngPack;
467 return ( m_orig_ ?
Teuchos::rcp(&space_c_breve_,
false) : Teuchos::null );
472 namespace mmp = MemMngPack;
474 return ( mI_orig_ ?
Teuchos::rcp(&space_h_breve_,
false) : Teuchos::null );
506 return factory_P_var_;
512 return factory_P_equ_;
518 return r_ ? Range1D(1,r_) : Range1D::Invalid;
524 return Range1D(r_+1,n_);
530 return r_ ? Range1D(1,r_) : Range1D::Invalid;
536 return r_ < m_full_ ? Range1D(r_+1,m_full_) : Range1D::Invalid;
543 sprintf(ind,
"%d", basis_selection_num_);
544 std::string fname =
"basis_";
548 std::ifstream basis_file(fname.c_str());
558 Permutation* P_var, Range1D* var_dep
559 ,Permutation* P_equ, Range1D* equ_decomp
565 get_next_basis_return = get_next_basis_remove_fixed( &var_perm_, &equ_perm_, &rank );
566 if(get_next_basis_return)
567 assert_and_set_basis( var_perm_, equ_perm_, rank );
570 this->
get_basis(P_var,var_dep,P_equ,equ_decomp);
575 const Permutation &P_var,
const Range1D &var_dep
576 ,
const Permutation *P_equ,
const Range1D *equ_decomp
579 namespace mmp = MemMngPack;
582 (m_full_ > 0 && (P_equ == NULL || equ_decomp == NULL))
583 ,std::invalid_argument
584 ,
"NLPSerialPreprocess::set_basis(...) : Error!" );
586 m_full_ > 0 && var_dep.size() != equ_decomp->size()
588 ,
"NLPSerialPreprocess::set_basis(...) : Error!" );
590 const PermutationSerial
592 *P_equ_s = m_full_ ? &dyn_cast<const PermutationSerial>(*P_equ) : NULL;
595 var_perm = Teuchos::rcp_const_cast<IVector>(P_var_s.perm()),
597 ? Teuchos::rcp_const_cast<IVector>(P_equ_s->perm())
600 (m_full_ > 0 &&
equ_perm.get() == NULL)
601 ,std::invalid_argument
602 ,
"NLPSerialPreprocess::set_basis(...) : Error, P_equ is not initialized properly!" );
604 assert_and_set_basis( *var_perm, *
equ_perm, var_dep.size() );
608 Permutation* P_var, Range1D* var_dep
609 ,Permutation* P_equ, Range1D* equ_decomp
612 namespace mmp = MemMngPack;
616 P_var == NULL || var_dep == NULL
617 || (m_full_ > 0 && (P_equ == NULL || equ_decomp == NULL))
618 ,std::invalid_argument
619 ,
"NLPSerialPreprocess::get_basis(...) : Error!" );
622 &P_var_s =
dyn_cast<PermutationSerial>(*P_var),
623 *P_equ_s = m_full_ ? &
dyn_cast<PermutationSerial>(*P_equ) : NULL;
626 var_perm = Teuchos::rcp_const_cast<IVector>(P_var_s.perm()),
628 ? Teuchos::rcp_const_cast<IVector>(P_equ_s->perm())
636 (*var_perm) = var_perm_;
637 (*var_dep) = Range1D(1,r_);
639 (*equ_perm) = equ_perm_;
640 (*equ_decomp) = Range1D(1,r_);
643 P_var_s.initialize( var_perm, Teuchos::null,
true );
645 P_equ_s->initialize(
equ_perm, Teuchos::null,
true );
657 VectorDenseEncap x_d(x);
660 *zero_order_info.
f = scale_f_ * f_orig_;
670 VectorDenseEncap x_d(x);
676 VectorDenseMutableEncap c_d(*zero_order_info.
c);
678 m_orig_ ? c_orig_() : DVectorSlice()
679 ,mI_orig_ ? h_orig_() : DVectorSlice()
680 ,mI_orig_ ?
x_full()(n_orig_+1,n_full_) : DVectorSlice()
692 VectorDenseEncap x_d(x);
698 VectorDenseMutableEncap c_breve_d(*zero_order_info_breve.
c);
699 c_breve_d() = c_orig_();
711 VectorDenseEncap x_d(x);
714 VectorDenseMutableEncap h_breve_d(*zero_order_info_breve.
h);
715 h_breve_d() = h_orig_();
728 VectorDenseEncap x_d(x);
730 if( n_full_ > n_orig_ ) Gf_full_(n_orig_+1,n_full_) = 0.0;
732 VectorDenseMutableEncap Gf_d(*obj_grad_info.
Gf);
733 var_from_full( Gf_full_.begin(), Gf_d().begin() );
734 Vt_S( &Gf_d(), scale_f_ );
740 IVector *var_perm_full
741 ,IVector *equ_perm_full
753 ,
"NLPSerialPreprocess : The nlp has not been initialized yet" );
757 const DVectorSlice& x,
bool newx
758 ,DVectorSlice* x_full
761 DenseLinAlgPack::assert_vs_sizes(x.dim(),n_);
763 var_to_full(x.begin(), x_full->begin());
766 void NLPSerialPreprocess::var_from_full(
767 DVectorSlice::const_iterator vec_full
768 ,DVectorSlice::iterator vec
773 *vec++ = vec_full[var_full_to_fixed_(var_perm_(i)) - 1];
783 void NLPSerialPreprocess::var_to_full( DVectorSlice::const_iterator vec, DVectorSlice::iterator vec_full )
const
786 vec_full[var_full_to_fixed_(var_perm_(i)) - 1] = *vec++;
789 void NLPSerialPreprocess::equ_from_full(
790 const DVectorSlice &c_orig
791 ,
const DVectorSlice &h_orig
792 ,
const DVectorSlice &s_orig
793 ,DVectorSlice *c_full
798 for(i = 1; i <= m_orig_; ++i)
799 (*c_full)(inv_equ_perm_(i)) = c_orig(i);
800 for(i = 1; i <= mI_orig_; ++i)
801 (*c_full)(inv_equ_perm_(m_orig_+i)) = h_orig(i) - s_orig(i);
806 bool NLPSerialPreprocess::get_next_basis_remove_fixed(
807 IVector* var_perm, IVector* equ_perm,
size_type* rank
810 IVector var_perm_full(n_full_);
811 equ_perm->resize(m_full_);
813 if(
imp_get_next_basis( &var_perm_full, equ_perm, &rank_full, &rank_fixed_removed ) ) {
832 IVector::const_iterator fixed_itr = var_full_to_fixed_.begin() + n_;
833 IVector::const_iterator fixed_end = var_full_to_fixed_.end();
836 IVector::iterator basic_itr = var_perm_full.begin();
837 IVector::iterator basic_end = basic_itr + rank_full;
840 IVector::iterator nonbasic_itr = basic_end;
841 IVector::iterator nonbasic_end = var_perm_full.end();
846 count_basic_fixed = 0,
847 count_nonbasic_fixed = 0;
850 for( ; fixed_itr != fixed_end; ++fixed_itr ) {
852 next_fixed = ( fixed_itr +1 != fixed_end ? *(fixed_itr+1) : n_full_+1);
854 for( ; *basic_itr < *fixed_itr; ++basic_itr )
855 *(basic_itr - count_basic_fixed) = *basic_itr - count_fixed;
856 for( ; *nonbasic_itr < *fixed_itr; ++nonbasic_itr )
857 *(nonbasic_itr - count_nonbasic_fixed) = *nonbasic_itr - count_fixed;
859 if( *basic_itr == *fixed_itr ) {
865 ++count_nonbasic_fixed;
871 for( ; *basic_itr < next_fixed; ++basic_itr )
872 *(basic_itr - count_basic_fixed) = *basic_itr - count_fixed;
873 for( ; *nonbasic_itr < next_fixed; ++nonbasic_itr )
874 *(nonbasic_itr - count_nonbasic_fixed) = *nonbasic_itr - count_fixed;
878 var_perm->resize(n_);
880 var_perm_full.begin()
881 ,var_perm_full.begin() + rank_fixed_removed
885 var_perm_full.begin() + rank_full
886 ,var_perm_full.begin() + rank_full + (n_-rank_fixed_removed)
887 ,var_perm->begin() + rank_fixed_removed
889 *rank = rank_fixed_removed;
896 sprintf(ind,
"%d", basis_selection_num_);
897 std::string fname =
"basis_";
900 basis_selection_num_++;
902 std::ifstream basis_file(fname.c_str());
911 tags !=
"n", std::logic_error
912 ,
"Incorrect basis file format - \"n\" expected, \"" << tags <<
"\" found.");
915 n <= 0, std::logic_error
916 ,
"Incorrect basis file format - n > 0 \"" << n <<
"\" found.");
921 tags !=
"m", std::logic_error
922 ,
"Incorrect basis file format - \"m\" expected, \"" << tags <<
"\" found.");
925 m > n , std::logic_error
926 ,
"Incorrect basis file format - 0 < m <= n expected, \"" << m <<
"\" found.");
931 tags !=
"rank", std::logic_error
932 ,
"Incorrect basis file format - \"rank\" expected, \"" << tags <<
"\" found.");
935 r > m, std::logic_error
936 ,
"Incorrect basis file format - 0 < rank <= m expected, \"" << r <<
"\" found.");
943 tags !=
"var_perm", std::logic_error
944 ,
"Incorrect basis file format -\"var_perm\" expected, \"" << tags <<
"\" found.");
946 {
for (
int i=0; i <
n; i++)
949 basis_file >> var_index;
951 var_index < 1 || var_index > n, std::logic_error
952 ,
"Incorrect basis file format for var_perm: 1 <= indice <= n expected, \"" << n <<
"\" found.");
953 (*var_perm)[i] = var_index;
959 tags !=
"equ_perm", std::logic_error
960 ,
"Incorrect basis file format -\"equ_perm\" expected, \"" << tags <<
"\" found.");
962 {
for (
int i=0; i < r; i++)
965 basis_file >> equ_index;
967 equ_index < 1 || equ_index > m, std::logic_error
968 ,
"Incorrect basis file format for equ_perm: 1 <= indice <= m expected, \"" << m <<
"\" found.");
969 (*equ_perm)[i] = equ_index;
979 void NLPSerialPreprocess::assert_and_set_basis(
980 const IVector& var_perm,
const IVector& equ_perm,
size_type rank
983 namespace mmp = MemMngPack;
992 var_perm.size() != n_ || equ_perm.size() != m_full_, std::length_error
993 ,
"NLPSerialPreprocess::set_basis(): The sizes "
994 "of the permutation vectors does not match the size of the NLP" );
996 rank > m_full_, InvalidBasis
997 ,
"NLPSerialPreprocess::set_basis(): The rank "
998 "of the basis can not be greater that the number of constraints" );
1002 if( &var_perm_ != &var_perm )
1004 if( &equ_perm_ != &equ_perm )
1006 DenseLinAlgPack::inv_perm( equ_perm_, &inv_equ_perm_ );
1008 var_from_full( xinit_full_().begin(), xinit_.set_vec().begin() );
1009 if(num_bounded_x_) {
1010 var_from_full( xl_full_().begin(), xl_.set_vec().begin() );
1011 var_from_full( xu_full_().begin(), xu_.set_vec().begin() );
1012 do_force_xinit_in_bounds();
1018 P_var_.initialize(
Teuchos::rcp(
new IVector(var_perm)),Teuchos::null);
1019 P_equ_.initialize(
Teuchos::rcp(
new IVector(equ_perm)),Teuchos::null);
1022 void NLPSerialPreprocess::assert_bounds_on_variables()
const
1026 ,
"There are no bounds on the variables for this NLP" );
1029 void NLPSerialPreprocess::do_force_xinit_in_bounds()
void initialize(bool test_setup)
Initialize the NLP for its first use.
Thrown if an invalid basis selection is made.
size_type num_bounded_x() const
void set_basis(const Permutation &P_var, const Range1D &var_dep, const Permutation *P_equ, const Range1D *equ_decomp)
virtual bool imp_nlp_has_changed() const
Return if the definition of the NLP has changed since the last call to initialize() ...
VectorMutable * c
Pointer to constraints residual c (Will be NULL if not set)
Struct for gradient (objective), objective and constriants (pointers)
void imp_calc_h_breve(const Vector &x, bool newx, const ZeroOrderInfo &zero_order_info_breve) const
virtual size_type imp_m_orig() const =0
Return the number of general equality constraints in the original problem.
bool is_initialized() const
const Permutation & P_var() const
value_type scale_f() const
const IVector & equ_perm() const
Permutes from the original constriant ordering to the current basis selection.
const Vector & xl() const
virtual size_type ns() const
Range1D equ_decomp() const
const Permutation & P_equ() const
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
const perm_fcty_ptr_t factory_P_equ() const
NLPSerialPreprocess()
Default Constructor.
VectorMutable * Gf
Pointer to gradient of objective function Gf (may be NULL if not set)
vec_space_ptr_t space_x() const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void Vp_StV(VectorMutable *v_lhs, const value_type &alpha, const Vector &v_rhs)
T_To & dyn_cast(T_From &from)
virtual size_type imp_n_orig() const =0
Return the number of variables in the original problem (including those fixed by bounds) ...
vec_space_ptr_t space_c() const
vec_space_ptr_t space_h_breve() const
virtual void imp_calc_c_orig(const DVectorSlice &x_full, bool newx, const ZeroOrderInfoSerial &zero_order_info) const =0
Calculate the vector for all of the general equality constaints in the original NLP.
const IVector & var_perm() const
Permutes from the compated variable vector (removing fixed variables) to the current basis selection...
DVectorSlice x_full() const
Give reference to current x_full.
const ObjGradInfoSerial obj_grad_orig_info() const
virtual void imp_calc_Gf_orig(const DVectorSlice &x_full, bool newx, const ObjGradInfoSerial &obj_grad_info) const =0
Calculate the vector for the gradient of the objective in the original NLP.
virtual void imp_calc_h_orig(const DVectorSlice &x_full, bool newx, const ZeroOrderInfoSerial &zero_order_info) const =0
Calculate the vector for all of the general inequality constaints in the original NLP...
void report_final_solution(const Vector &x, const Vector *lambda, const Vector *nu, bool is_optimal)
Overridden to permute the variables back into an order that is natural to the subclass.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void get_basis(Permutation *P_var, Range1D *var_dep, Permutation *P_equ, Range1D *equ_decomp) const
bool force_xinit_in_bounds() const
virtual const DVectorSlice imp_xinit_orig() const =0
Return the original initial point (size imp_n_orig()).
void imp_calc_f(const Vector &x, bool newx, const ZeroOrderInfo &zero_order_info) const
virtual const DVectorSlice imp_xu_orig() const =0
Return the original upper variable bounds (size imp_n_orig()).
bool nlp_selects_basis() const
const Vector & xu() const
void initialize(bool test_setup)
void imp_calc_c(const Vector &x, bool newx, const ZeroOrderInfo &zero_order_info) const
const Vector & xinit() const
virtual bool imp_has_var_bounds() const =0
Return if the NLP has bounds.
void assert_initialized() const
Assert if we have been initizlized (throws UnInitialized)
Struct for objective and constriants (pointer).
virtual void imp_report_orig_final_solution(const DVectorSlice &x_full, const DVectorSlice *lambda_orig, const DVectorSlice *lambdaI_orig, const DVectorSlice *nu_orig, bool optimal)
To be overridden by subclasses to report the final solution in the original ordering natural to the s...
virtual const DVectorSlice imp_hu_orig() const =0
Return the original upper general inequality bounds (size imp_mI_orig()).
const Vector & hu_breve() const
virtual void imp_calc_f_orig(const DVectorSlice &x_full, bool newx, const ZeroOrderInfoSerial &zero_order_info) const =0
Calculate the objective function for the original NLP.
Thrown if any member functions are called before initialize() has been called.
Range1D equ_undecomp() const
virtual size_type imp_mI_orig() const =0
Return the number of general inequality constraints in the original problem.
void imp_calc_c_breve(const Vector &x, bool newx, const ZeroOrderInfo &zero_order_info_breve) const
const perm_fcty_ptr_t factory_P_var() const
value_type * f
Pointer to objective function f (Will be NULL if not set)
void force_in_bounds(const Vector &xl, const Vector &xu, VectorMutable *x)
virtual bool imp_get_next_basis(IVector *var_perm_full, IVector *equ_perm_full, size_type *rank_full, size_type *rank)
Return the next basis selection (default returns false).
const ZeroOrderInfoSerial zero_order_orig_info() const
const Vector & hl_breve() const
void get_init_lagrange_mult(VectorMutable *lambda, VectorMutable *nu) const
virtual const DVectorSlice imp_xl_orig() const =0
Return the original lower variable bounds (size imp_n_orig()).
Thrown from initialize() if some logical error occured.
Range1D var_indep() const
void set_x_full(const DVectorSlice &x, bool newx, DVectorSlice *x_full) const
Set the full x vector if newx == true
static value_type fixed_var_mult()
Gives the value of a Lagrange multipler for a fixed variable bound .that has been preprocessed out of...
static value_type infinite_bound()
Value for an infinite bound.
VectorMutable * h
Pointer to inequality constraints h (Will be NULL if not set)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
virtual const DVectorSlice imp_hl_orig() const =0
Return the original lower general inequality bounds (size imp_mI_orig()).
vec_space_ptr_t space_c_breve() const
void imp_calc_Gf(const Vector &x, bool newx, const ObjGradInfo &obj_grad_info) const
bool get_next_basis(Permutation *P_var, Range1D *var_dep, Permutation *P_equ, Range1D *equ_decomp)