|
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 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #ifndef NLP_FULL_TO_REDUCED_H 00043 #define NLP_FULL_TO_REDUCED_H 00044 00045 #include <valarray> 00046 00047 #include "NLPInterfacePack_NLPFirstOrder.hpp" 00048 #include "NLPInterfacePack_NLPVarReductPerm.hpp" 00049 #include "AbstractLinAlgPack_SpVectorClass.hpp" 00050 #include "AbstractLinAlgPack_VectorMutableDense.hpp" 00051 #include "AbstractLinAlgPack_PermutationSerial.hpp" 00052 #include "DenseLinAlgPack_DVectorClass.hpp" 00053 #include "DenseLinAlgPack_IVector.hpp" 00054 00055 namespace NLPInterfacePack { 00056 00221 class NLPSerialPreprocess 00222 : virtual public NLPObjGrad 00223 , virtual public NLPVarReductPerm 00224 { 00225 public: 00226 00229 00231 class InconsistantBounds : public std::logic_error 00232 {public: InconsistantBounds(const std::string& what_arg) : std::logic_error(what_arg) {}}; 00233 00235 00243 NLPSerialPreprocess(); 00244 00248 static value_type fixed_var_mult(); 00249 00252 00254 void force_xinit_in_bounds(bool force_xinit_in_bounds); 00256 bool force_xinit_in_bounds() const; 00258 void initialize(bool test_setup); 00260 bool is_initialized() const; 00262 size_type n() const; 00264 size_type m() const; 00266 vec_space_ptr_t space_x() const; 00268 vec_space_ptr_t space_c() const; 00270 size_type num_bounded_x() const; 00272 const Vector& xl() const; 00274 const Vector& xu() const; 00276 const Vector& xinit() const; 00278 void get_init_lagrange_mult( 00279 VectorMutable* lambda 00280 ,VectorMutable* nu 00281 ) const; 00283 void scale_f( value_type scale_f ); 00285 value_type scale_f() const; 00294 void report_final_solution( 00295 const Vector& x 00296 ,const Vector* lambda 00297 ,const Vector* nu 00298 ,bool is_optimal 00299 ); 00301 virtual size_type ns() const; 00303 vec_space_ptr_t space_c_breve() const; 00305 vec_space_ptr_t space_h_breve() const; 00307 const Vector& hl_breve() const; 00309 const Vector& hu_breve() const; 00311 const Permutation& P_var() const; 00313 const Permutation& P_equ() const; 00314 00316 00319 00321 const perm_fcty_ptr_t factory_P_var() const; 00323 const perm_fcty_ptr_t factory_P_equ() const; 00325 Range1D var_dep() const; 00327 Range1D var_indep() const; 00329 Range1D equ_decomp() const; 00331 Range1D equ_undecomp() const; 00333 bool nlp_selects_basis() const; 00335 bool get_next_basis( 00336 Permutation* P_var, Range1D* var_dep 00337 ,Permutation* P_equ, Range1D* equ_decomp 00338 ); 00340 void set_basis( 00341 const Permutation &P_var, const Range1D &var_dep 00342 ,const Permutation *P_equ, const Range1D *equ_decomp 00343 ); 00345 void get_basis( 00346 Permutation* P_var, Range1D* var_dep 00347 ,Permutation* P_equ, Range1D* equ_decomp 00348 ) const; 00349 00351 00352 protected: 00353 00356 00358 void imp_calc_f( 00359 const Vector &x 00360 ,bool newx 00361 ,const ZeroOrderInfo &zero_order_info 00362 ) const; 00364 void imp_calc_c( 00365 const Vector &x 00366 ,bool newx 00367 ,const ZeroOrderInfo &zero_order_info 00368 ) const; 00370 void imp_calc_c_breve( 00371 const Vector &x 00372 ,bool newx 00373 ,const ZeroOrderInfo &zero_order_info_breve 00374 ) const; 00376 void imp_calc_h_breve( 00377 const Vector &x 00378 ,bool newx 00379 ,const ZeroOrderInfo &zero_order_info_breve 00380 ) const; 00381 00383 00386 00388 void imp_calc_Gf( 00389 const Vector &x 00390 ,bool newx 00391 ,const ObjGradInfo &obj_grad_info 00392 ) const; 00393 00395 00398 00406 struct ZeroOrderInfoSerial { 00407 public: 00409 ZeroOrderInfoSerial() : f(NULL) 00410 {} 00412 ZeroOrderInfoSerial( value_type* f_in, DVector* c_in, DVector* h_in ) 00413 : f(f_in), c(c_in), h(h_in) 00414 {} 00416 value_type* f; 00418 DVector* c; 00420 DVector* h; 00421 }; // end struct ZeroOrderInfoSerial 00422 00431 struct ObjGradInfoSerial { 00432 public: 00434 ObjGradInfoSerial() : f(NULL) 00435 {} 00437 ObjGradInfoSerial( DVector* Gf_in, const ZeroOrderInfoSerial& first_order_info_in ) 00438 : Gf(Gf_in), f(first_order_info_in.f), c(first_order_info_in.c), h(first_order_info_in.h) 00439 {} 00441 DVector* Gf; 00443 value_type* f; 00445 DVector* c; 00447 DVector* h; 00448 }; // end struct ObjGradInfoSerial 00449 00451 00454 00460 virtual bool imp_nlp_has_changed() const { return true; } 00462 virtual size_type imp_n_orig() const = 0; 00464 virtual size_type imp_m_orig() const = 0; 00466 virtual size_type imp_mI_orig() const = 0; 00468 virtual const DVectorSlice imp_xinit_orig() const = 0; 00470 virtual bool imp_has_var_bounds() const = 0; 00480 virtual const DVectorSlice imp_xl_orig() const = 0; 00490 virtual const DVectorSlice imp_xu_orig() const = 0; 00498 virtual const DVectorSlice imp_hl_orig() const = 0; 00506 virtual const DVectorSlice imp_hu_orig() const = 0; 00509 virtual void imp_calc_f_orig( 00510 const DVectorSlice &x_full 00511 ,bool newx 00512 ,const ZeroOrderInfoSerial &zero_order_info 00513 ) const = 0; 00516 virtual void imp_calc_c_orig( 00517 const DVectorSlice &x_full 00518 ,bool newx 00519 ,const ZeroOrderInfoSerial &zero_order_info 00520 ) const = 0; 00523 virtual void imp_calc_h_orig( 00524 const DVectorSlice &x_full 00525 ,bool newx 00526 ,const ZeroOrderInfoSerial &zero_order_info 00527 ) const = 0; 00539 virtual void imp_calc_Gf_orig( 00540 const DVectorSlice &x_full 00541 ,bool newx 00542 ,const ObjGradInfoSerial &obj_grad_info 00543 ) const = 0; 00606 virtual bool imp_get_next_basis( 00607 IVector *var_perm_full 00608 ,IVector *equ_perm_full 00609 ,size_type *rank_full 00610 ,size_type *rank 00611 ); 00623 virtual void imp_report_orig_final_solution( 00624 const DVectorSlice &x_full 00625 ,const DVectorSlice *lambda_orig 00626 ,const DVectorSlice *lambdaI_orig 00627 ,const DVectorSlice *nu_orig 00628 ,bool optimal 00629 ) 00630 {} 00631 00633 00636 00638 void set_not_initialized(); 00639 00641 void assert_initialized() const; 00642 00644 void set_x_full(const DVectorSlice& x, bool newx, DVectorSlice* x_full) const; 00645 00647 DVectorSlice x_full() const; 00648 00650 const ZeroOrderInfoSerial zero_order_orig_info() const; 00651 00653 const ObjGradInfoSerial obj_grad_orig_info() const; 00654 00666 const IVector& var_remove_fixed_to_full() const; 00667 00673 const IVector& var_full_to_remove_fixed() const; 00674 00692 const IVector& var_perm() const; 00693 00705 const IVector& equ_perm() const; 00706 00712 const IVector& inv_equ_perm() const; 00713 00714 // Perform the mapping from a full variable vector to the reduced permuted variable vector 00715 void var_from_full( DVectorSlice::const_iterator vec_full, DVectorSlice::iterator vec ) const; 00716 00717 // Perform the mapping from a reduced permuted variable vector the full variable vector 00718 void var_to_full(DVectorSlice::const_iterator vec, DVectorSlice::iterator vec_full) const; 00719 00720 // Perform the mapping from c_orig, h_orig, s_orig to the permuted constraint vector c 00721 void equ_from_full( 00722 const DVectorSlice &c_orig 00723 ,const DVectorSlice &h_orig 00724 ,const DVectorSlice &s_orig 00725 ,DVectorSlice *c_full 00726 ) const; 00727 00729 00730 private: 00731 00732 // /////////////////////////// 00733 // Private data members 00734 00735 mutable value_type f_orig_; // Computed by subclasses 00736 mutable DVector c_orig_; // ... 00737 mutable DVector h_orig_; // ... 00738 mutable DVector Gf_full_; // ... 00739 00740 bool initialized_; 00741 // Flag for if the NLP has has been properly initialized 00742 00743 bool force_xinit_in_bounds_; 00744 // Determine if the initial point will be adjusted between bounds 00745 00746 value_type scale_f_; 00747 // Set the scaling of the objective function used. 00748 00749 IVector var_full_to_fixed_; 00750 // Holds the indices of variables that are fixed by bounds and those 00751 // that are not (Length = n_full_). These partitions are not 00752 // necessarly sorted in assending order as var_perm and con_perm are. 00753 // 00754 // var_full_to_fixed_ = [ not fixed by bounds | fixed by bounds ] 00755 // [1 .. n_|n_ + 1 .. n_full_] 00756 // 00757 00758 IVector inv_var_full_to_fixed_; 00759 // Inverse of var_full_to_fixed_. If inv_var_full_to_fixed_(i) > n_ then this variable 00760 // is fixed between bounds, else inv_var_full_to_fixed_(i) is the indice of the 00761 // variable in the unsorted x (not permuted to the current basis). 00762 00763 IVector var_perm_; 00764 // Variable permutations (length = n_) from the vector of unstorted variables not fixed 00765 // by bounds as defined by var_full_to_fixed_ 00766 // 00767 // var_perm_ = [ dependent variables | independent variables ] 00768 // [1.. r_|r_+1... n_] 00769 // 00770 00771 IVector equ_perm_; 00772 // Equality Constraint permutations (length = m_) 00773 // 00774 // equ_perm_ = [ decomposed equalities | undecomposed equalities ] 00775 // [1.. r_|r_+1... m_] 00776 // 00777 00778 IVector inv_equ_perm_; 00779 // Inverse of equ_perm 00780 // 00781 00782 mutable DVector x_full_; 00783 DVector xinit_full_; 00784 DVector xl_full_; 00785 DVector xu_full_; 00786 // The full vector (length = n_full_). This vector may include 00787 // slack variables if mI_orig > 0: 00788 // 00789 // [ x_orig; s_orig ] 00790 // 00791 00792 perm_fcty_ptr_t factory_P_var_; 00793 perm_fcty_ptr_t factory_P_equ_; 00794 VectorSpaceSerial space_x_; 00795 VectorSpaceSerial space_c_; 00796 VectorSpaceSerial space_c_breve_; 00797 VectorSpaceSerial space_h_breve_; 00798 size_type num_bounded_x_; 00799 VectorMutableDense xinit_; // Initial point of the shrunken NLP 00800 VectorMutableDense xl_; // Lower bounds of transformed NLP 00801 VectorMutableDense xu_; // Uppers bounds of transformed NLP 00802 VectorMutableDense hl_breve_;// Lower bounds for general inequalities of transformed NLP 00803 VectorMutableDense hu_breve_;// Uppers bounds for general inequalitiess of transformed NLP 00804 PermutationSerial P_var_; 00805 PermutationSerial P_equ_; 00806 size_type n_orig_; // Number of variables in the original NLP 00807 size_type m_orig_; // Number of general equality constraints in the original NLP 00808 size_type mI_orig_; // Number of general inequality constraints in the original NLP 00809 size_type n_full_; // Number of variables in the transformed NLP (before fixed variables are removed) 00810 size_type m_full_; // Number of general equality constraints in the transformed NLP 00811 size_type n_; // Number of variables in the transformed NLP (with slacks and not fixed by bounds) 00812 size_type r_; // Number of independent equations in the transformed NLP 00813 00814 int basis_selection_num_; // Number of the basis to select next 00815 00816 // /////////////////////////// 00817 // Private member functions 00818 00819 // Get the next basis (or first basis) from the NLP subclass and remove the 00820 // fixed variables. Note that this function does not modify var_perm_, equ_perm_ 00821 // or r_. You must do that yourself by calling assert_and_set_basis. 00822 bool get_next_basis_remove_fixed( 00823 IVector* var_perm, IVector* equ_perm, size_type* rank ); 00824 00825 // Assert (throw std::length_error, NLPVarReductPerm::InvalidBasis) and set a basis selection 00826 // If &var_perm == &var_perm_ and/or &equ_perm == &equ_perm_ then the unneeded copy 00827 // is avoided. 00828 void assert_and_set_basis( 00829 const IVector& var_perm, const IVector& equ_perm, size_type rank ); 00830 00831 // Assert that there are bounds on the variables (throw NLP::NoBoundsOnVariables) 00832 void assert_bounds_on_variables() const; 00833 00834 // Adjust initial point this->xinit_ to be within bound 00835 void do_force_xinit_in_bounds(); 00836 00837 }; // end class NLPSerialPreprocess 00838 00839 // ////////////////////////////////////////////////// 00840 // Inline member functions 00841 00842 // protected 00843 00844 inline 00845 void NLPSerialPreprocess::set_not_initialized() 00846 { 00847 initialized_ = false; 00848 } 00849 00850 inline 00851 DVectorSlice NLPSerialPreprocess::x_full() const 00852 { 00853 return x_full_(); 00854 } 00855 00856 inline 00857 const NLPSerialPreprocess::ZeroOrderInfoSerial 00858 NLPSerialPreprocess::zero_order_orig_info() const 00859 { 00860 return ZeroOrderInfoSerial( &f_orig_, &c_orig_, &h_orig_ ); 00861 } 00862 00863 inline 00864 const NLPSerialPreprocess::ObjGradInfoSerial 00865 NLPSerialPreprocess::obj_grad_orig_info() const 00866 { 00867 return ObjGradInfoSerial( &Gf_full_, zero_order_orig_info() ); 00868 } 00869 00870 inline 00871 const IVector& NLPSerialPreprocess::var_remove_fixed_to_full() const 00872 { 00873 return var_full_to_fixed_; 00874 } 00875 00876 inline 00877 const IVector& NLPSerialPreprocess::var_full_to_remove_fixed() const 00878 { 00879 return inv_var_full_to_fixed_; 00880 } 00881 00882 inline 00883 const IVector& NLPSerialPreprocess::var_perm() const 00884 { 00885 return var_perm_; 00886 } 00887 00888 inline 00889 const IVector& NLPSerialPreprocess::equ_perm() const 00890 { 00891 return equ_perm_; 00892 } 00893 00894 inline 00895 const IVector& NLPSerialPreprocess::inv_equ_perm() const 00896 { 00897 return inv_equ_perm_; 00898 } 00899 00900 } // end namespace NLPInterfacePack 00901 00902 #endif // NLP_FULL_TO_REDUCED_H
1.7.6.1