NLPInterfacePack: C++ Interfaces and Implementation for Non-Linear Programs Version of the Day
NLPInterfacePack_NLPSerialPreprocess.hpp
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends