NLPInterfacePack: C++ Interfaces and Implementation for Non-Linear Programs  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
NLPInterfacePack_NLPSerialPreprocess.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef NLP_FULL_TO_REDUCED_H
43 #define NLP_FULL_TO_REDUCED_H
44 
45 #include <valarray>
46 
47 #include "NLPInterfacePack_NLPFirstOrder.hpp"
48 #include "NLPInterfacePack_NLPVarReductPerm.hpp"
49 #include "AbstractLinAlgPack_SpVectorClass.hpp"
50 #include "AbstractLinAlgPack_VectorMutableDense.hpp"
51 #include "AbstractLinAlgPack_PermutationSerial.hpp"
52 #include "DenseLinAlgPack_DVectorClass.hpp"
53 #include "DenseLinAlgPack_IVector.hpp"
54 
55 namespace NLPInterfacePack {
56 
222  : virtual public NLPObjGrad
223  , virtual public NLPVarReductPerm
224 {
225 public:
226 
229 
231  class InconsistantBounds : public std::logic_error
232  {public: InconsistantBounds(const std::string& what_arg) : std::logic_error(what_arg) {}};
233 
235 
244 
248  static value_type fixed_var_mult();
249 
252 
256  bool force_xinit_in_bounds() const;
258  void initialize(bool test_setup);
260  bool is_initialized() const;
262  size_type n() const;
264  size_type m() const;
266  vec_space_ptr_t space_x() const;
268  vec_space_ptr_t space_c() const;
270  size_type num_bounded_x() const;
272  const Vector& xl() const;
274  const Vector& xu() const;
276  const Vector& xinit() const;
279  VectorMutable* lambda
280  ,VectorMutable* nu
281  ) const;
283  void scale_f( value_type scale_f );
285  value_type scale_f() const;
295  const Vector& x
296  ,const Vector* lambda
297  ,const Vector* nu
298  ,bool is_optimal
299  );
301  virtual size_type ns() const;
307  const Vector& hl_breve() const;
309  const Vector& hu_breve() const;
311  const Permutation& P_var() const;
313  const Permutation& P_equ() const;
314 
316 
319 
321  const perm_fcty_ptr_t factory_P_var() const;
323  const perm_fcty_ptr_t factory_P_equ() const;
325  Range1D var_dep() const;
327  Range1D var_indep() const;
329  Range1D equ_decomp() const;
331  Range1D equ_undecomp() const;
333  bool nlp_selects_basis() const;
335  bool get_next_basis(
336  Permutation* P_var, Range1D* var_dep
337  ,Permutation* P_equ, Range1D* equ_decomp
338  );
340  void set_basis(
341  const Permutation &P_var, const Range1D &var_dep
342  ,const Permutation *P_equ, const Range1D *equ_decomp
343  );
345  void get_basis(
346  Permutation* P_var, Range1D* var_dep
347  ,Permutation* P_equ, Range1D* equ_decomp
348  ) const;
349 
351 
352 protected:
353 
356 
358  void imp_calc_f(
359  const Vector &x
360  ,bool newx
362  ) const;
364  void imp_calc_c(
365  const Vector &x
366  ,bool newx
368  ) const;
370  void imp_calc_c_breve(
371  const Vector &x
372  ,bool newx
374  ) const;
376  void imp_calc_h_breve(
377  const Vector &x
378  ,bool newx
380  ) const;
381 
383 
386 
388  void imp_calc_Gf(
389  const Vector &x
390  ,bool newx
391  ,const ObjGradInfo &obj_grad_info
392  ) const;
393 
395 
398 
407  public:
410  {}
412  ZeroOrderInfoSerial( value_type* f_in, DVector* c_in, DVector* h_in )
413  : f(f_in), c(c_in), h(h_in)
414  {}
416  value_type* f;
418  DVector* c;
420  DVector* h;
421  }; // end struct ZeroOrderInfoSerial
422 
432  public:
435  {}
437  ObjGradInfoSerial( DVector* Gf_in, const ZeroOrderInfoSerial& first_order_info_in )
438  : Gf(Gf_in), f(first_order_info_in.f), c(first_order_info_in.c), h(first_order_info_in.h)
439  {}
441  DVector* Gf;
443  value_type* f;
445  DVector* c;
447  DVector* h;
448  }; // end struct ObjGradInfoSerial
449 
451 
454 
460  virtual bool imp_nlp_has_changed() const { return true; }
462  virtual size_type imp_n_orig() const = 0;
464  virtual size_type imp_m_orig() const = 0;
466  virtual size_type imp_mI_orig() const = 0;
468  virtual const DVectorSlice imp_xinit_orig() const = 0;
470  virtual bool imp_has_var_bounds() const = 0;
480  virtual const DVectorSlice imp_xl_orig() const = 0;
490  virtual const DVectorSlice imp_xu_orig() const = 0;
498  virtual const DVectorSlice imp_hl_orig() const = 0;
506  virtual const DVectorSlice imp_hu_orig() const = 0;
509  virtual void imp_calc_f_orig(
510  const DVectorSlice &x_full
511  ,bool newx
512  ,const ZeroOrderInfoSerial &zero_order_info
513  ) const = 0;
516  virtual void imp_calc_c_orig(
517  const DVectorSlice &x_full
518  ,bool newx
519  ,const ZeroOrderInfoSerial &zero_order_info
520  ) const = 0;
523  virtual void imp_calc_h_orig(
524  const DVectorSlice &x_full
525  ,bool newx
526  ,const ZeroOrderInfoSerial &zero_order_info
527  ) const = 0;
539  virtual void imp_calc_Gf_orig(
540  const DVectorSlice &x_full
541  ,bool newx
542  ,const ObjGradInfoSerial &obj_grad_info
543  ) const = 0;
606  virtual bool imp_get_next_basis(
607  IVector *var_perm_full
608  ,IVector *equ_perm_full
609  ,size_type *rank_full
610  ,size_type *rank
611  );
624  const DVectorSlice &x_full
625  ,const DVectorSlice *lambda_orig
626  ,const DVectorSlice *lambdaI_orig
627  ,const DVectorSlice *nu_orig
628  ,bool optimal
629  )
630  {}
631 
633 
636 
638  void set_not_initialized();
639 
641  void assert_initialized() const;
642 
644  void set_x_full(const DVectorSlice& x, bool newx, DVectorSlice* x_full) const;
645 
647  DVectorSlice x_full() const;
648 
650  const ZeroOrderInfoSerial zero_order_orig_info() const;
651 
653  const ObjGradInfoSerial obj_grad_orig_info() const;
654 
666  const IVector& var_remove_fixed_to_full() const;
667 
673  const IVector& var_full_to_remove_fixed() const;
674 
692  const IVector& var_perm() const;
693 
705  const IVector& equ_perm() const;
706 
712  const IVector& inv_equ_perm() const;
713 
714  // Perform the mapping from a full variable vector to the reduced permuted variable vector
715  void var_from_full( DVectorSlice::const_iterator vec_full, DVectorSlice::iterator vec ) const;
716 
717  // Perform the mapping from a reduced permuted variable vector the full variable vector
718  void var_to_full(DVectorSlice::const_iterator vec, DVectorSlice::iterator vec_full) const;
719 
720  // Perform the mapping from c_orig, h_orig, s_orig to the permuted constraint vector c
721  void equ_from_full(
722  const DVectorSlice &c_orig
723  ,const DVectorSlice &h_orig
724  ,const DVectorSlice &s_orig
725  ,DVectorSlice *c_full
726  ) const;
727 
729 
730 private:
731 
732  // ///////////////////////////
733  // Private data members
734 
735  mutable value_type f_orig_; // Computed by subclasses
736  mutable DVector c_orig_; // ...
737  mutable DVector h_orig_; // ...
738  mutable DVector Gf_full_; // ...
739 
740  bool initialized_;
741  // Flag for if the NLP has has been properly initialized
742 
743  bool force_xinit_in_bounds_;
744  // Determine if the initial point will be adjusted between bounds
745 
746  value_type scale_f_;
747  // Set the scaling of the objective function used.
748 
749  IVector var_full_to_fixed_;
750  // Holds the indices of variables that are fixed by bounds and those
751  // that are not (Length = n_full_). These partitions are not
752  // necessarly sorted in assending order as var_perm and con_perm are.
753  //
754  // var_full_to_fixed_ = [ not fixed by bounds | fixed by bounds ]
755  // [1 .. n_|n_ + 1 .. n_full_]
756  //
757 
758  IVector inv_var_full_to_fixed_;
759  // Inverse of var_full_to_fixed_. If inv_var_full_to_fixed_(i) > n_ then this variable
760  // is fixed between bounds, else inv_var_full_to_fixed_(i) is the indice of the
761  // variable in the unsorted x (not permuted to the current basis).
762 
763  IVector var_perm_;
764  // Variable permutations (length = n_) from the vector of unstorted variables not fixed
765  // by bounds as defined by var_full_to_fixed_
766  //
767  // var_perm_ = [ dependent variables | independent variables ]
768  // [1.. r_|r_+1... n_]
769  //
770 
771  IVector equ_perm_;
772  // Equality Constraint permutations (length = m_)
773  //
774  // equ_perm_ = [ decomposed equalities | undecomposed equalities ]
775  // [1.. r_|r_+1... m_]
776  //
777 
778  IVector inv_equ_perm_;
779  // Inverse of equ_perm
780  //
781 
782  mutable DVector x_full_;
783  DVector xinit_full_;
784  DVector xl_full_;
785  DVector xu_full_;
786  // The full vector (length = n_full_). This vector may include
787  // slack variables if mI_orig > 0:
788  //
789  // [ x_orig; s_orig ]
790  //
791 
792  perm_fcty_ptr_t factory_P_var_;
793  perm_fcty_ptr_t factory_P_equ_;
794  VectorSpaceSerial space_x_;
795  VectorSpaceSerial space_c_;
796  VectorSpaceSerial space_c_breve_;
797  VectorSpaceSerial space_h_breve_;
798  size_type num_bounded_x_;
799  VectorMutableDense xinit_; // Initial point of the shrunken NLP
800  VectorMutableDense xl_; // Lower bounds of transformed NLP
801  VectorMutableDense xu_; // Uppers bounds of transformed NLP
802  VectorMutableDense hl_breve_;// Lower bounds for general inequalities of transformed NLP
803  VectorMutableDense hu_breve_;// Uppers bounds for general inequalitiess of transformed NLP
804  PermutationSerial P_var_;
805  PermutationSerial P_equ_;
806  size_type n_orig_; // Number of variables in the original NLP
807  size_type m_orig_; // Number of general equality constraints in the original NLP
808  size_type mI_orig_; // Number of general inequality constraints in the original NLP
809  size_type n_full_; // Number of variables in the transformed NLP (before fixed variables are removed)
810  size_type m_full_; // Number of general equality constraints in the transformed NLP
811  size_type n_; // Number of variables in the transformed NLP (with slacks and not fixed by bounds)
812  size_type r_; // Number of independent equations in the transformed NLP
813 
814  int basis_selection_num_; // Number of the basis to select next
815 
816  // ///////////////////////////
817  // Private member functions
818 
819  // Get the next basis (or first basis) from the NLP subclass and remove the
820  // fixed variables. Note that this function does not modify var_perm_, equ_perm_
821  // or r_. You must do that yourself by calling assert_and_set_basis.
822  bool get_next_basis_remove_fixed(
823  IVector* var_perm, IVector* equ_perm, size_type* rank );
824 
825  // Assert (throw std::length_error, NLPVarReductPerm::InvalidBasis) and set a basis selection
826  // If &var_perm == &var_perm_ and/or &equ_perm == &equ_perm_ then the unneeded copy
827  // is avoided.
828  void assert_and_set_basis(
829  const IVector& var_perm, const IVector& equ_perm, size_type rank );
830 
831  // Assert that there are bounds on the variables (throw NLP::NoBoundsOnVariables)
832  void assert_bounds_on_variables() const;
833 
834  // Adjust initial point this->xinit_ to be within bound
835  void do_force_xinit_in_bounds();
836 
837 }; // end class NLPSerialPreprocess
838 
839 // //////////////////////////////////////////////////
840 // Inline member functions
841 
842 // protected
843 
844 inline
846 {
847  initialized_ = false;
848 }
849 
850 inline
851 DVectorSlice NLPSerialPreprocess::x_full() const
852 {
853  return x_full_();
854 }
855 
856 inline
859 {
860  return ZeroOrderInfoSerial( &f_orig_, &c_orig_, &h_orig_ );
861 }
862 
863 inline
866 {
867  return ObjGradInfoSerial( &Gf_full_, zero_order_orig_info() );
868 }
869 
870 inline
872 {
873  return var_full_to_fixed_;
874 }
875 
876 inline
878 {
879  return inv_var_full_to_fixed_;
880 }
881 
882 inline
883 const IVector& NLPSerialPreprocess::var_perm() const
884 {
885  return var_perm_;
886 }
887 
888 inline
889 const IVector& NLPSerialPreprocess::equ_perm() const
890 {
891  return equ_perm_;
892 }
893 
894 inline
895 const IVector& NLPSerialPreprocess::inv_equ_perm() const
896 {
897  return inv_equ_perm_;
898 }
899 
900 } // end namespace NLPInterfacePack
901 
902 #endif // NLP_FULL_TO_REDUCED_H
NLP interface class that adds gradient information for the objective function {abstract}.
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() ...
value_type * f
Pointer to objective function f (may be NULL if not set)
Struct for gradient (objective), objective and constriants (pointers)
const IVector & var_full_to_remove_fixed() const
Inverse permutation vector of var_remove_fixed_to_full().
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.
const IVector & equ_perm() const
Permutes from the original constriant ordering to the current basis selection.
const IVector & var_remove_fixed_to_full() const
Permutation vector for partitioning free and fixed variables.
DVector * h
Pointer to constraints residual h (may be NULL if not set)
virtual size_type imp_n_orig() const =0
Return the number of variables in the original problem (including those fixed by bounds) ...
DVector * c
Pointer to constraints residual c (may be NULL if not set)
void set_not_initialized()
Used by subclasses to set the state of the NLP to not initialized.
const ZeroOrderInfo zero_order_info() const
Return pointer to set quantities.
const ObjGradInfo obj_grad_info() const
Return objective gradient and zero order information.
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.
NLP interface class that adds variable and constriant permutations for variable reduction basis selec...
const IVector & var_perm() const
Permutes from the compated variable vector (removing fixed variables) to the current basis selection...
NLP node implementation subclass for preprocessing and basis manipulation.
DVectorSlice x_full() const
Give reference to current x_full.
value_type * f
Pointer to objective function f (may be NULL if not set)
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.
void get_basis(Permutation *P_var, Range1D *var_dep, Permutation *P_equ, Range1D *equ_decomp) 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()).
size_t size_type
const ZeroOrderInfo zero_order_info_breve() const
Return pointer to set hat quantities.
Struct for objective and constriants (pointer) as serial vectors.
void imp_calc_c(const Vector &x, bool newx, const ZeroOrderInfo &zero_order_info) const
DVector * Gf
Gradient of objective function Gf (may be NULL if not set)
Teuchos::RCP< const Teuchos::AbstractFactory< Permutation > > perm_fcty_ptr_t
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...
DVector * c
Pointer to constraints residual c (may be NULL if not set)
virtual const DVectorSlice imp_hu_orig() const =0
Return the original upper general inequality bounds (size imp_mI_orig()).
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.
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 IVector & inv_equ_perm() const
Inverse of equ_perm()
Struct for serial gradient (objective), objective and constriants (pointers)
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).
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()).
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...
ObjGradInfoSerial(DVector *Gf_in, const ZeroOrderInfoSerial &first_order_info_in)
DVector * h
Pointer to constraints residual h (may be NULL if not set)
virtual const DVectorSlice imp_hl_orig() const =0
Return the original lower general inequality bounds (size imp_mI_orig()).
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)