|
NLPInterfacePack: C++ Interfaces and Implementation for Non-Linear Programs Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization 00005 // Copyright (2003) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #ifndef NLP_FULL_TO_REDUCED_H 00030 #define NLP_FULL_TO_REDUCED_H 00031 00032 #include <valarray> 00033 00034 #include "NLPInterfacePack_NLPFirstOrder.hpp" 00035 #include "NLPInterfacePack_NLPVarReductPerm.hpp" 00036 #include "AbstractLinAlgPack_SpVectorClass.hpp" 00037 #include "AbstractLinAlgPack_VectorMutableDense.hpp" 00038 #include "AbstractLinAlgPack_PermutationSerial.hpp" 00039 #include "DenseLinAlgPack_DVectorClass.hpp" 00040 #include "DenseLinAlgPack_IVector.hpp" 00041 00042 namespace NLPInterfacePack { 00043 00208 class NLPSerialPreprocess 00209 : virtual public NLPObjGrad 00210 , virtual public NLPVarReductPerm 00211 { 00212 public: 00213 00216 00218 class InconsistantBounds : public std::logic_error 00219 {public: InconsistantBounds(const std::string& what_arg) : std::logic_error(what_arg) {}}; 00220 00222 00230 NLPSerialPreprocess(); 00231 00235 static value_type fixed_var_mult(); 00236 00239 00241 void force_xinit_in_bounds(bool force_xinit_in_bounds); 00243 bool force_xinit_in_bounds() const; 00245 void initialize(bool test_setup); 00247 bool is_initialized() const; 00249 size_type n() const; 00251 size_type m() const; 00253 vec_space_ptr_t space_x() const; 00255 vec_space_ptr_t space_c() const; 00257 size_type num_bounded_x() const; 00259 const Vector& xl() const; 00261 const Vector& xu() const; 00263 const Vector& xinit() const; 00265 void get_init_lagrange_mult( 00266 VectorMutable* lambda 00267 ,VectorMutable* nu 00268 ) const; 00270 void scale_f( value_type scale_f ); 00272 value_type scale_f() const; 00281 void report_final_solution( 00282 const Vector& x 00283 ,const Vector* lambda 00284 ,const Vector* nu 00285 ,bool is_optimal 00286 ); 00288 virtual size_type ns() const; 00290 vec_space_ptr_t space_c_breve() const; 00292 vec_space_ptr_t space_h_breve() const; 00294 const Vector& hl_breve() const; 00296 const Vector& hu_breve() const; 00298 const Permutation& P_var() const; 00300 const Permutation& P_equ() const; 00301 00303 00306 00308 const perm_fcty_ptr_t factory_P_var() const; 00310 const perm_fcty_ptr_t factory_P_equ() const; 00312 Range1D var_dep() const; 00314 Range1D var_indep() const; 00316 Range1D equ_decomp() const; 00318 Range1D equ_undecomp() const; 00320 bool nlp_selects_basis() const; 00322 bool get_next_basis( 00323 Permutation* P_var, Range1D* var_dep 00324 ,Permutation* P_equ, Range1D* equ_decomp 00325 ); 00327 void set_basis( 00328 const Permutation &P_var, const Range1D &var_dep 00329 ,const Permutation *P_equ, const Range1D *equ_decomp 00330 ); 00332 void get_basis( 00333 Permutation* P_var, Range1D* var_dep 00334 ,Permutation* P_equ, Range1D* equ_decomp 00335 ) const; 00336 00338 00339 protected: 00340 00343 00345 void imp_calc_f( 00346 const Vector &x 00347 ,bool newx 00348 ,const ZeroOrderInfo &zero_order_info 00349 ) const; 00351 void imp_calc_c( 00352 const Vector &x 00353 ,bool newx 00354 ,const ZeroOrderInfo &zero_order_info 00355 ) const; 00357 void imp_calc_c_breve( 00358 const Vector &x 00359 ,bool newx 00360 ,const ZeroOrderInfo &zero_order_info_breve 00361 ) const; 00363 void imp_calc_h_breve( 00364 const Vector &x 00365 ,bool newx 00366 ,const ZeroOrderInfo &zero_order_info_breve 00367 ) const; 00368 00370 00373 00375 void imp_calc_Gf( 00376 const Vector &x 00377 ,bool newx 00378 ,const ObjGradInfo &obj_grad_info 00379 ) const; 00380 00382 00385 00393 struct ZeroOrderInfoSerial { 00394 public: 00396 ZeroOrderInfoSerial() : f(NULL) 00397 {} 00399 ZeroOrderInfoSerial( value_type* f_in, DVector* c_in, DVector* h_in ) 00400 : f(f_in), c(c_in), h(h_in) 00401 {} 00403 value_type* f; 00405 DVector* c; 00407 DVector* h; 00408 }; // end struct ZeroOrderInfoSerial 00409 00418 struct ObjGradInfoSerial { 00419 public: 00421 ObjGradInfoSerial() : f(NULL) 00422 {} 00424 ObjGradInfoSerial( DVector* Gf_in, const ZeroOrderInfoSerial& first_order_info_in ) 00425 : Gf(Gf_in), f(first_order_info_in.f), c(first_order_info_in.c), h(first_order_info_in.h) 00426 {} 00428 DVector* Gf; 00430 value_type* f; 00432 DVector* c; 00434 DVector* h; 00435 }; // end struct ObjGradInfoSerial 00436 00438 00441 00447 virtual bool imp_nlp_has_changed() const { return true; } 00449 virtual size_type imp_n_orig() const = 0; 00451 virtual size_type imp_m_orig() const = 0; 00453 virtual size_type imp_mI_orig() const = 0; 00455 virtual const DVectorSlice imp_xinit_orig() const = 0; 00457 virtual bool imp_has_var_bounds() const = 0; 00467 virtual const DVectorSlice imp_xl_orig() const = 0; 00477 virtual const DVectorSlice imp_xu_orig() const = 0; 00485 virtual const DVectorSlice imp_hl_orig() const = 0; 00493 virtual const DVectorSlice imp_hu_orig() const = 0; 00496 virtual void imp_calc_f_orig( 00497 const DVectorSlice &x_full 00498 ,bool newx 00499 ,const ZeroOrderInfoSerial &zero_order_info 00500 ) const = 0; 00503 virtual void imp_calc_c_orig( 00504 const DVectorSlice &x_full 00505 ,bool newx 00506 ,const ZeroOrderInfoSerial &zero_order_info 00507 ) const = 0; 00510 virtual void imp_calc_h_orig( 00511 const DVectorSlice &x_full 00512 ,bool newx 00513 ,const ZeroOrderInfoSerial &zero_order_info 00514 ) const = 0; 00526 virtual void imp_calc_Gf_orig( 00527 const DVectorSlice &x_full 00528 ,bool newx 00529 ,const ObjGradInfoSerial &obj_grad_info 00530 ) const = 0; 00593 virtual bool imp_get_next_basis( 00594 IVector *var_perm_full 00595 ,IVector *equ_perm_full 00596 ,size_type *rank_full 00597 ,size_type *rank 00598 ); 00610 virtual void imp_report_orig_final_solution( 00611 const DVectorSlice &x_full 00612 ,const DVectorSlice *lambda_orig 00613 ,const DVectorSlice *lambdaI_orig 00614 ,const DVectorSlice *nu_orig 00615 ,bool optimal 00616 ) 00617 {} 00618 00620 00623 00625 void set_not_initialized(); 00626 00628 void assert_initialized() const; 00629 00631 void set_x_full(const DVectorSlice& x, bool newx, DVectorSlice* x_full) const; 00632 00634 DVectorSlice x_full() const; 00635 00637 const ZeroOrderInfoSerial zero_order_orig_info() const; 00638 00640 const ObjGradInfoSerial obj_grad_orig_info() const; 00641 00653 const IVector& var_remove_fixed_to_full() const; 00654 00660 const IVector& var_full_to_remove_fixed() const; 00661 00679 const IVector& var_perm() const; 00680 00692 const IVector& equ_perm() const; 00693 00699 const IVector& inv_equ_perm() const; 00700 00701 // Perform the mapping from a full variable vector to the reduced permuted variable vector 00702 void var_from_full( DVectorSlice::const_iterator vec_full, DVectorSlice::iterator vec ) const; 00703 00704 // Perform the mapping from a reduced permuted variable vector the full variable vector 00705 void var_to_full(DVectorSlice::const_iterator vec, DVectorSlice::iterator vec_full) const; 00706 00707 // Perform the mapping from c_orig, h_orig, s_orig to the permuted constraint vector c 00708 void equ_from_full( 00709 const DVectorSlice &c_orig 00710 ,const DVectorSlice &h_orig 00711 ,const DVectorSlice &s_orig 00712 ,DVectorSlice *c_full 00713 ) const; 00714 00716 00717 private: 00718 00719 // /////////////////////////// 00720 // Private data members 00721 00722 mutable value_type f_orig_; // Computed by subclasses 00723 mutable DVector c_orig_; // ... 00724 mutable DVector h_orig_; // ... 00725 mutable DVector Gf_full_; // ... 00726 00727 bool initialized_; 00728 // Flag for if the NLP has has been properly initialized 00729 00730 bool force_xinit_in_bounds_; 00731 // Determine if the initial point will be adjusted between bounds 00732 00733 value_type scale_f_; 00734 // Set the scaling of the objective function used. 00735 00736 IVector var_full_to_fixed_; 00737 // Holds the indices of variables that are fixed by bounds and those 00738 // that are not (Length = n_full_). These partitions are not 00739 // necessarly sorted in assending order as var_perm and con_perm are. 00740 // 00741 // var_full_to_fixed_ = [ not fixed by bounds | fixed by bounds ] 00742 // [1 .. n_|n_ + 1 .. n_full_] 00743 // 00744 00745 IVector inv_var_full_to_fixed_; 00746 // Inverse of var_full_to_fixed_. If inv_var_full_to_fixed_(i) > n_ then this variable 00747 // is fixed between bounds, else inv_var_full_to_fixed_(i) is the indice of the 00748 // variable in the unsorted x (not permuted to the current basis). 00749 00750 IVector var_perm_; 00751 // Variable permutations (length = n_) from the vector of unstorted variables not fixed 00752 // by bounds as defined by var_full_to_fixed_ 00753 // 00754 // var_perm_ = [ dependent variables | independent variables ] 00755 // [1.. r_|r_+1... n_] 00756 // 00757 00758 IVector equ_perm_; 00759 // Equality Constraint permutations (length = m_) 00760 // 00761 // equ_perm_ = [ decomposed equalities | undecomposed equalities ] 00762 // [1.. r_|r_+1... m_] 00763 // 00764 00765 IVector inv_equ_perm_; 00766 // Inverse of equ_perm 00767 // 00768 00769 mutable DVector x_full_; 00770 DVector xinit_full_; 00771 DVector xl_full_; 00772 DVector xu_full_; 00773 // The full vector (length = n_full_). This vector may include 00774 // slack variables if mI_orig > 0: 00775 // 00776 // [ x_orig; s_orig ] 00777 // 00778 00779 perm_fcty_ptr_t factory_P_var_; 00780 perm_fcty_ptr_t factory_P_equ_; 00781 VectorSpaceSerial space_x_; 00782 VectorSpaceSerial space_c_; 00783 VectorSpaceSerial space_c_breve_; 00784 VectorSpaceSerial space_h_breve_; 00785 size_type num_bounded_x_; 00786 VectorMutableDense xinit_; // Initial point of the shrunken NLP 00787 VectorMutableDense xl_; // Lower bounds of transformed NLP 00788 VectorMutableDense xu_; // Uppers bounds of transformed NLP 00789 VectorMutableDense hl_breve_;// Lower bounds for general inequalities of transformed NLP 00790 VectorMutableDense hu_breve_;// Uppers bounds for general inequalitiess of transformed NLP 00791 PermutationSerial P_var_; 00792 PermutationSerial P_equ_; 00793 size_type n_orig_; // Number of variables in the original NLP 00794 size_type m_orig_; // Number of general equality constraints in the original NLP 00795 size_type mI_orig_; // Number of general inequality constraints in the original NLP 00796 size_type n_full_; // Number of variables in the transformed NLP (before fixed variables are removed) 00797 size_type m_full_; // Number of general equality constraints in the transformed NLP 00798 size_type n_; // Number of variables in the transformed NLP (with slacks and not fixed by bounds) 00799 size_type r_; // Number of independent equations in the transformed NLP 00800 00801 int basis_selection_num_; // Number of the basis to select next 00802 00803 // /////////////////////////// 00804 // Private member functions 00805 00806 // Get the next basis (or first basis) from the NLP subclass and remove the 00807 // fixed variables. Note that this function does not modify var_perm_, equ_perm_ 00808 // or r_. You must do that yourself by calling assert_and_set_basis. 00809 bool get_next_basis_remove_fixed( 00810 IVector* var_perm, IVector* equ_perm, size_type* rank ); 00811 00812 // Assert (throw std::length_error, NLPVarReductPerm::InvalidBasis) and set a basis selection 00813 // If &var_perm == &var_perm_ and/or &equ_perm == &equ_perm_ then the unneeded copy 00814 // is avoided. 00815 void assert_and_set_basis( 00816 const IVector& var_perm, const IVector& equ_perm, size_type rank ); 00817 00818 // Assert that there are bounds on the variables (throw NLP::NoBoundsOnVariables) 00819 void assert_bounds_on_variables() const; 00820 00821 // Adjust initial point this->xinit_ to be within bound 00822 void do_force_xinit_in_bounds(); 00823 00824 }; // end class NLPSerialPreprocess 00825 00826 // ////////////////////////////////////////////////// 00827 // Inline member functions 00828 00829 // protected 00830 00831 inline 00832 void NLPSerialPreprocess::set_not_initialized() 00833 { 00834 initialized_ = false; 00835 } 00836 00837 inline 00838 DVectorSlice NLPSerialPreprocess::x_full() const 00839 { 00840 return x_full_(); 00841 } 00842 00843 inline 00844 const NLPSerialPreprocess::ZeroOrderInfoSerial 00845 NLPSerialPreprocess::zero_order_orig_info() const 00846 { 00847 return ZeroOrderInfoSerial( &f_orig_, &c_orig_, &h_orig_ ); 00848 } 00849 00850 inline 00851 const NLPSerialPreprocess::ObjGradInfoSerial 00852 NLPSerialPreprocess::obj_grad_orig_info() const 00853 { 00854 return ObjGradInfoSerial( &Gf_full_, zero_order_orig_info() ); 00855 } 00856 00857 inline 00858 const IVector& NLPSerialPreprocess::var_remove_fixed_to_full() const 00859 { 00860 return var_full_to_fixed_; 00861 } 00862 00863 inline 00864 const IVector& NLPSerialPreprocess::var_full_to_remove_fixed() const 00865 { 00866 return inv_var_full_to_fixed_; 00867 } 00868 00869 inline 00870 const IVector& NLPSerialPreprocess::var_perm() const 00871 { 00872 return var_perm_; 00873 } 00874 00875 inline 00876 const IVector& NLPSerialPreprocess::equ_perm() const 00877 { 00878 return equ_perm_; 00879 } 00880 00881 inline 00882 const IVector& NLPSerialPreprocess::inv_equ_perm() const 00883 { 00884 return inv_equ_perm_; 00885 } 00886 00887 } // end namespace NLPInterfacePack 00888 00889 #endif // NLP_FULL_TO_REDUCED_H
1.7.4