BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/QP_solver/QP_solver.h
Go to the documentation of this file.
00001 // Copyright (c) 1997-2007  ETH Zurich (Switzerland).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00005 // the terms of the Q Public License version 1.0.
00006 // See the file LICENSE.QPL distributed with CGAL.
00007 //
00008 // Licenseges holding a valid commercial license may use this file in
00009 // accordance with the commercial license agreement provided with the software.
00010 //
00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 //
00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/QP_solver/include/CGAL/QP_solver/QP_solver.h $
00015 // $Id: QP_solver.h 46451 2008-10-23 14:31:10Z gaertner $
00016 // 
00017 //
00018 // Author(s)     : Kaspar Fischer
00019 //               : Bernd Gaertner <gaertner@inf.ethz.ch>
00020 //               : Sven Schoenherr 
00021 //               : Franz Wessendorp 
00022 
00023 #ifndef CGAL_QP_SOLVER_H
00024 #define CGAL_QP_SOLVER_H
00025 
00026 #include <CGAL/iterator.h>
00027 #include <CGAL/QP_solver/basic.h>
00028 #include <CGAL/QP_solver/functors.h>
00029 #include <CGAL/QP_options.h>
00030 #include <CGAL/QP_solution.h>
00031 #include <CGAL/QP_solver/QP_basis_inverse.h>
00032 #include <CGAL/QP_solver/QP_pricing_strategy.h>
00033 #include <CGAL/QP_solver/QP_full_exact_pricing.h>
00034 #include <CGAL/QP_solver/QP_partial_exact_pricing.h>
00035 #include <CGAL/QP_solver/QP_full_filtered_pricing.h>
00036 #include <CGAL/QP_solver/QP_partial_filtered_pricing.h>
00037 #include <CGAL/QP_solver/QP_exact_bland_pricing.h>
00038 
00039 #include <CGAL/algorithm.h>
00040 
00041 #include <CGAL/IO/Verbose_ostream.h>
00042 
00043 #include <boost/bind.hpp>
00044 #include <boost/function.hpp>
00045 #include <boost/iterator/transform_iterator.hpp>
00046 
00047 #include <vector>
00048 #include <numeric>
00049 #include <algorithm>
00050 
00051 CGAL_BEGIN_NAMESPACE
00052 
00053 // ==================
00054 // class declarations
00055 // ==================
00056 template < typename Q, typename ET, typename Tags  >
00057 class QP_solver;
00058 
00059 template <class ET>
00060 class QP_solution; 
00061 
00062 namespace QP_solver_impl {   // namespace for implemenation details
00063   // --------------
00064   // Tags generator
00065   // --------------
00066   template < typename Linear, 
00067              typename Nonnegative >
00068   struct QP_tags {
00069     typedef Linear                Is_linear;
00070     typedef Nonnegative           Is_nonnegative;
00071   };
00072 
00073   template < class Q, class Is_linear >
00074   struct D_selector {};
00075 
00076   template <class Q>
00077   struct D_selector<Q, Tag_false> // quadratic
00078   {
00079     typedef typename Q::D_iterator D_iterator;
00080   };
00081 
00082   template <class Q>
00083   struct D_selector<Q, Tag_true> // linear
00084   {
00085     // dummy type, not used
00086     typedef int** D_iterator;
00087   };
00088 
00089   template < class Q, class Is_nonnegative >
00090   struct Bd_selector {};
00091 
00092   template < class Q >
00093   struct Bd_selector<Q, Tag_false> // nonstandard form
00094   {
00095     typedef typename Q::FL_iterator FL_iterator;
00096     typedef typename Q::L_iterator L_iterator;
00097     typedef typename Q::FU_iterator FU_iterator;
00098     typedef typename Q::U_iterator U_iterator;
00099   };
00100 
00101   template < class Q >
00102   struct Bd_selector<Q, Tag_true> // standard form
00103   {
00104     // dummy types, not used
00105     typedef int* FL_iterator;
00106     typedef int* L_iterator;
00107     typedef int* FU_iterator;
00108     typedef int* U_iterator;
00109   };
00110 
00111   // only allow filtered pricing if NT = double
00112   template <typename Q, typename ET, typename Tags, typename NT>
00113   struct Filtered_pricing_strategy_selector
00114   {
00115     typedef QP_full_exact_pricing<Q, ET, Tags> FF;
00116     typedef QP_partial_exact_pricing<Q, ET, Tags> PF;
00117   };
00118 
00119   template <typename Q, typename ET, typename Tags>
00120   struct Filtered_pricing_strategy_selector<Q, ET, Tags, double> 
00121   {
00122     typedef QP_full_filtered_pricing<Q, ET, Tags> FF;
00123     typedef QP_partial_filtered_pricing<Q, ET, Tags> PF;
00124   };
00125 
00126 } // end of namespace for implementation details
00127 
00128 // ================
00129 // class interfaces
00130 // ================
00131 
00132 
00133 template < typename Q, typename ET, typename Tags >
00134 class QP_solver : public QP_solver_base<ET> {
00135 
00136 public: // public types
00137   typedef  QP_solver<Q, ET, Tags> Self;
00138   typedef  QP_solver_base<ET> Base;
00139   
00140   // types from the QP
00141   typedef  typename Q::A_iterator   A_iterator;
00142   typedef  typename Q::B_iterator   B_iterator;
00143   typedef  typename Q::C_iterator   C_iterator;
00144   typedef  CGAL::Comparison_result Row_type;
00145   typedef  typename Q::R_iterator Row_type_iterator;
00146   
00147   // the remaining types might not be present in the qp, so the
00148   // following selectors generate dummy types for them 
00149   typedef  typename QP_solver_impl::
00150   D_selector<Q, typename Tags::Is_linear>::
00151   D_iterator D_iterator;
00152   typedef typename QP_solver_impl::
00153   Bd_selector<Q, typename Tags::Is_nonnegative>::
00154   L_iterator L_iterator;
00155   typedef typename QP_solver_impl::
00156   Bd_selector<Q, typename Tags::Is_nonnegative>::
00157   U_iterator U_iterator;
00158   typedef typename QP_solver_impl::
00159   Bd_selector<Q, typename Tags::Is_nonnegative>::
00160   FL_iterator FL_iterator;
00161   typedef typename QP_solver_impl::
00162   Bd_selector<Q, typename Tags::Is_nonnegative>::
00163   FU_iterator FU_iterator;
00164 
00165   // types from the Tags
00166   typedef  typename Tags::Is_linear    Is_linear;
00167   typedef  typename Tags::Is_nonnegative Is_nonnegative;
00168 
00169   // friends
00170   template <class Q_, class ET_>
00171   friend bool has_linearly_independent_equations 
00172   (const Q_& qp, const ET_& dummy);
00173 
00174 private: // private types
00175 
00176   // types of original problem:
00177   typedef  typename std::iterator_traits<A_iterator>::value_type  A_column;
00178   typedef  typename std::iterator_traits<D_iterator>::value_type  D_row;
00179   
00180   typedef  typename std::iterator_traits<A_column  >::value_type  A_entry;
00181   typedef  typename std::iterator_traits<B_iterator>::value_type  B_entry;
00182   typedef  typename std::iterator_traits<C_iterator>::value_type  C_entry;
00183   typedef  typename std::iterator_traits<D_row     >::value_type  D_entry;
00184   typedef  typename std::iterator_traits<L_iterator>::value_type  L_entry;
00185   typedef  typename std::iterator_traits<U_iterator>::value_type  U_entry;
00186   
00187   // slack columns:
00188   //
00189   // The following two types are used to (conceptually) add to the matrix A
00190   // additional columns that model the constraints "x_s>=0" for the slack
00191   // variables x_s.  Of course, we do not store the column (which is just
00192   // plus/minus a unit vector), but maintain a pair (int,bool): the first
00193   // entry says in which column the +-1 is and the second entry of the pair
00194   // says whether it is +1 (false) or -1 (true).
00195   typedef  std::pair<int,bool>        Slack_column;
00196   typedef  std::vector<Slack_column>  A_slack;
00197 
00198   // artificial columns
00199   //
00200   // Artificial columns that are (conceptually) added to the matrix A are
00201   // handled exactly like slack columns (see above).
00202   typedef  std::pair<int,bool>        Art_column;
00203   typedef  std::vector<Art_column>    A_art;
00204 
00205   // special artificial column:
00206   //
00207   // Also for the special artificial variable we (conceptually) add a column
00208   // to A. This column contains only +-1's (but it may contain several nonzero
00209   // entries).
00210   typedef  std::vector<A_entry>       S_art;
00211   
00212   // auxiliary objective vector (i.e., the objective vector for phase I):
00213   typedef  std::vector<C_entry>       C_aux;
00214 
00215 public: // export some additional types:
00216   
00217   typedef  typename Base::Indices     Indices; 
00218   typedef  typename Base::Index_mutable_iterator   Index_iterator;
00219   typedef  typename Base::Index_const_iterator     Index_const_iterator;
00220  
00221   // For problems in nonstandard form we also export the following type, which
00222   // for an original variable will say whether it sits at is lower, upper, at
00223   // its lower and upper (fixed) bound, or at zero, or whether the variable is
00224   // basic:
00225   enum  Bound_index  { LOWER, ZERO, UPPER, FIXED, BASIC };
00226 
00227 private:
00228   typedef  std::vector<Bound_index>    Bound_index_values;
00229   typedef  typename Bound_index_values::iterator
00230   Bound_index_value_iterator;
00231   typedef  typename Bound_index_values::const_iterator
00232   Bound_index_value_const_iterator;
00233   
00234   // values (variables' numerators):
00235   typedef  std::vector<ET>            Values;
00236   typedef  typename Values::iterator  Value_iterator;
00237   typedef  typename Values::const_iterator
00238   Value_const_iterator;
00239     
00240   // access values by basic index functor:
00241   typedef  CGAL::Value_by_basic_index<Value_const_iterator>
00242   Value_by_basic_index;
00243 
00244   // access to original problem by basic variable/constraint index:
00245   typedef  QP_vector_accessor<A_column, false, false >  A_by_index_accessor;
00246   typedef  boost::transform_iterator
00247   < A_by_index_accessor,Index_const_iterator >
00248   A_by_index_iterator;
00249 
00250   // todo kf: following can be removed once we have all these (outdated)
00251   // accessors removed:
00252   typedef  QP_vector_accessor< B_iterator, false, false >
00253   B_by_index_accessor;
00254   typedef  boost::transform_iterator
00255   < B_by_index_accessor, Index_const_iterator >
00256   B_by_index_iterator;
00257 
00258   typedef  QP_vector_accessor< C_iterator, false, false >
00259   C_by_index_accessor;
00260   typedef  boost::transform_iterator
00261   <C_by_index_accessor, Index_const_iterator >
00262   C_by_index_iterator;
00263 
00264   typedef  QP_matrix_accessor< A_iterator, false, true, false, false>
00265   A_accessor;
00266   typedef  boost::function1<typename A_accessor::result_type, int>
00267   A_row_by_index_accessor;
00268   typedef  boost::transform_iterator 
00269   < A_row_by_index_accessor, Index_iterator >
00270   A_row_by_index_iterator;
00271 
00272   // Access to the matrix D sometimes converts to ET, and 
00273   // sometimes retruns the original input type
00274   typedef  QP_matrix_pairwise_accessor< D_iterator, ET >
00275   D_pairwise_accessor;
00276   typedef boost::transform_iterator 
00277   < D_pairwise_accessor, Index_const_iterator>
00278   D_pairwise_iterator;
00279   typedef  QP_matrix_pairwise_accessor< D_iterator, D_entry >
00280   D_pairwise_accessor_input_type;
00281   typedef  boost::transform_iterator
00282   < D_pairwise_accessor_input_type, Index_const_iterator >
00283   D_pairwise_iterator_input_type;
00284 
00285   // access to special artificial column by basic constraint index:
00286   typedef  QP_vector_accessor< typename S_art::const_iterator, false, false>
00287   S_by_index_accessor;
00288   typedef  boost::transform_iterator
00289   < S_by_index_accessor, Index_iterator >
00290   S_by_index_iterator;
00291   
00292 public:
00293     
00294   typedef  typename A_slack::const_iterator
00295   A_slack_iterator;
00296 
00297   typedef  typename A_art::const_iterator
00298   A_artificial_iterator;
00299     
00300   typedef  typename C_aux::const_iterator
00301   C_auxiliary_iterator;
00302 
00303   typedef typename Base::Variable_numerator_iterator
00304   Variable_numerator_iterator;
00305 
00306   typedef  Index_const_iterator       Basic_variable_index_iterator;
00307   typedef  Value_const_iterator       Basic_variable_numerator_iterator;
00308   typedef  Index_const_iterator       Basic_constraint_index_iterator;
00309         
00310   typedef  QP_pricing_strategy<Q, ET, Tags>  Pricing_strategy;
00311 
00312 private:
00313   // compile time tag for symbolic perturbation, should be moved into traits
00314   // class when symbolic perturbation is to be implemented
00315   Tag_false                is_perturbed;
00316     
00317   // some constants
00318   const ET                 et0, et1, et2;
00319 
00320   // verbose output streams
00321   mutable Verbose_ostream  vout;      // used for any  diagnostic output
00322   mutable Verbose_ostream  vout1;     // used for some diagnostic output
00323   mutable Verbose_ostream  vout2;     // used for more diagnostic output
00324   mutable Verbose_ostream  vout3;     // used for full diagnostic output
00325   mutable Verbose_ostream  vout4;     // used for output of basis inverse
00326   mutable Verbose_ostream  vout5;     // used for output of validity tests
00327     
00328   // pricing strategy
00329   Pricing_strategy*        strategyP;
00330 
00331   // given QP
00332   int                      qp_n;      // number of variables
00333   int                      qp_m;      // number of constraints
00334     
00335   // min x^T D x + c^T x + c0
00336   A_iterator               qp_A;      // constraint matrix
00337   B_iterator               qp_b;      // right-hand-side vector
00338   C_iterator               qp_c;      // objective vector
00339   C_entry                  qp_c0;     // constant term in objective function
00340   // attention: qp_D represents *twice* the matrix D
00341   D_iterator               qp_D;      // objective matrix
00342   Row_type_iterator        qp_r;      // row-types of constraints
00343   FL_iterator              qp_fl;     // lower bound finiteness vector
00344   L_iterator               qp_l;      // lower bound vector
00345   FU_iterator              qp_fu;     // upper bound finiteness vector
00346   U_iterator               qp_u;      // upper bound vector
00347 
00348   A_slack                  slack_A;   // slack part of constraint matrix
00349 
00350   // auxiliary problem    
00351   A_art                    art_A;     // artificial part of constraint matrix
00352   // Note: in phase I there is an
00353   // additional "fake" column attached
00354   // to this "matrix", see init_basis()
00355 
00356   S_art                    art_s;     // special artificial column for slacks
00357   int                      art_s_i;   // art_s_i>=0  -> index of special
00358   //                artificial column
00359   // art_s_i==-1 -> no sp. art. col
00360   // art_s_i==-2 -> sp. art. col removed
00361   //                after it left basis 
00362   int                      art_basic; // number of basic artificial variables
00363   C_aux                    aux_c;     // objective function for phase I
00364   // initially has the same size as A_art
00365 
00366   Indices                  B_O;       // basis (original variables)
00367   // Note: the size of B_O is always
00368   // correct, i.e., equals the number of
00369   // basic original variables, plus (in
00370   // phase I) the number of basic
00371   // artificial variables.
00372 
00373   Indices                  B_S;       // basis (   slack variables)
00374     
00375   Indices                  C;         // basic constraints ( C = E+S_N )
00376   // Note: the size of C is always
00377   // correct, i.e., corresponds to the
00378   // size of the (conceptual) set
00379   // $E\cup S_N$.
00380 
00381   Indices                  S_B;       // nonbasic constraints ( S_B '=' B_S)
00382     
00383   QP_basis_inverse<ET,Is_linear>
00384   inv_M_B;   // inverse of basis matrix
00385 
00386   const ET&                d;         // reference to `inv_M_B.denominator()'
00387     
00388   Values                   x_B_O;     // basic variables (original)
00389   // Note: x_B_O is only enlarged,
00390   // so its size need not be |B|.
00391 
00392   Values                   x_B_S;     // basic variables (slack)
00393   Values                   lambda;    // lambda (from KKT conditions)
00394   Bound_index_values       x_O_v_i;   // bounds value index vector
00395   // the following vectors are updated
00396   // with each update in order to avoid
00397   // evaluating a matrix vector
00398   // multiplication
00399   Values                   r_C;       // r_C = A_{C,N_O}x_{N_O}
00400   // Note: r_C.size() == C.size().
00401 
00402   Values                   r_S_B;     // r_S_B = A_{S_B,N_O}x_{N_O}
00403 
00404   // The following to variables are initialized (if used at all) in
00405   // transition().  They are not used in case Is_linear or
00406   // Is_nonnegative is set to Tag_true.
00407   Values                   r_B_O;     // r_B_O = 2D_{B_O,N_O}x_{N_O}
00408   Values                   w;         // w = 2D_{O, N_O}x_{N_O}
00409     
00410   int                      m_phase;   // phase of the Simplex method
00411   Quadratic_program_status                   m_status;  // status of last pivot step
00412   int                      m_pivots;  // number of pivot steps
00413     
00414   bool                     is_phaseI; // flag indicating phase I
00415   bool                     is_phaseII;// flag indicating phase II
00416   bool                     is_RTS_transition; // flag indicating transition
00417   // from Ratio Test Step1 to Ratio
00418   // Test Step2                                           
00419   const bool               is_LP;     // flag indicating a linear program
00420   const bool               is_QP;     // flag indicating a quadratic program
00421 
00422   // the following flag indicates whether the program is in equational form
00423   // AND still has all its equations; this is given in phase I for any
00424   // program in equational form, but it may change if redundant constraints
00425   // get removed from the basis. If no_ineq == true, the program is treated
00426   // in a more efficient manner, since in that case we need no bookkeeping 
00427   // for basic constraints
00428   bool                     no_ineq;   
00429   bool                     has_ineq;  // !no_ineq
00430 
00431   const bool               is_nonnegative; // standard form, from Tag
00432 
00433   // additional variables
00434   int                      l;         // minimum of 'qp_n+e+1' and 'qp_m'
00435   // Note: this is an upper bound for
00436   // the size of the reduced basis in
00437   // phase I (in phase II, the reduced
00438   // basis size can be arbitrarily
00439   // large)
00440     
00441   int                e;         // number of equality constraints
00442     
00443   // Given a variable number i, in_B[i] is -1 iff x_i is not in the current
00444   // basis.  If the number in_B[i] is >=0, it is the basis heading of x_i.
00445   Indices                  in_B;      // variable   in basis, -1 if non-basic
00446 
00447   // Given a number i in {0,...,qp_m-1} of a constraint, 
00448   Indices                  in_C;      // constraint in basis, -1 if non-basic
00449   // Note: in_C is only maintained if
00450   // there are inequality constraints.
00451 
00452   Values                   b_C;       // exact version of `qp_b'
00453   // restricted to basic constraints C
00454   Values                   minus_c_B; // exact version of `-qp_c'
00455   // restricted to basic variables B_O
00456   // Note: minus_c_B is only enlarged,
00457   // so its size need not be |B|.
00458 
00459   Values                   A_Cj;      // exact version of j-th column of A
00460   // restricted to basic constraints C
00461   Values                   two_D_Bj;  // exact version of twice the j-th
00462   // column of D restricted to B_O
00463   // Note: tmp_x_2 is only enlarged,
00464   // so its size need not be |B|.
00465     
00466   int                      j;         // index of entering variable `x_j'
00467     
00468   int                      i;         // index of leaving variable `x_i'
00469   ET                       x_i;       // numerator of leaving variable `x_i'
00470   ET                       q_i;       // corresponding `q_i'
00471   int                      direction; // indicates whether the current
00472   // entering variable x_j is increased
00473   // or decreased
00474   Bound_index              ratio_test_bound_index;  // indicates for leaving
00475   // original variables which bound
00476   // was hit with upper bounding
00477 
00478   ET                       mu;        //   numerator of `t_j'
00479   ET                       nu;        // denominator of `t_j'
00480     
00481   Values                   q_lambda;  // length dependent on C
00482   Values                   q_x_O;     // used in the ratio test & update
00483   // Note: q_x_O is only enlarged,
00484   // so its size need not be |B|.
00485 
00486   Values                   q_x_S;     // 
00487 
00488   Values                   tmp_l;     // temporary vector of size l
00489   Values                   tmp_x;     // temporary vector of s. >= B_O.size()
00490   // Note: tmp_x is only enlarged,
00491   // so its size need not be |B|.
00492 
00493   Values                   tmp_l_2;   // temporary vector of size l
00494   Values                   tmp_x_2;   // temporary vector of s. >= B_O.size()
00495   // Note: tmp_x_2 is only enlarged,
00496   // so its size need not be |B|.
00497   // Diagnostics
00498   struct Diagnostics {
00499     bool redundant_equations;
00500   };
00501     
00502   Diagnostics              diagnostics;
00503 
00504 public:
00505 
00506   /*
00507    * Note: Some member functions below are suffixed with '_'.
00508    * They are member templates and their declaration is "hidden",
00509    * because they are also implemented in the class interface.
00510    * This is a workaround for M$-VC++, which otherwise fails to
00511    * instantiate them correctly.
00512    */
00513 
00514   // creation & initialization
00515   // -------------------------
00516   // creation
00517   QP_solver(const Q& qp, 
00518             const Quadratic_program_options& options = 
00519             Quadratic_program_options());
00520 
00521   virtual ~QP_solver()
00522   {
00523     if (strategyP != static_cast<Pricing_strategy*>(0))
00524       delete strategyP;
00525   }
00526 
00527               
00528 private:
00529   // set-up of QP
00530   void set( const Q& qp); 
00531   void set_D (const Q& qp, Tag_true is_linear);
00532   void set_D (const Q& qp, Tag_false is_linear);
00533                  
00534   // set-up of explicit bounds
00535   void set_explicit_bounds(const Q& qp); 
00536   void set_explicit_bounds(const Q& qp, Tag_true /*is_nonnegative*/); 
00537   void set_explicit_bounds(const Q& qp, Tag_false /*is_nonnegative*/);
00538 
00539   // initialization (of phase I)
00540   void  init( );
00541     
00542   // initialization (of phase II)
00543   /*
00544     template < class InputIterator >
00545     void  init( InputIterator  basic_variables_first,
00546     InputIterator  basic_variables_beyond);
00547   */
00548     
00549   // operations
00550   // ----------
00551   // pivot step
00552   Quadratic_program_status  pivot( )
00553   { CGAL_qpe_assertion( phase() > 0);
00554   CGAL_qpe_assertion( phase() < 3);
00555   pivot_step();
00556   return status(); }
00557 
00558   // solve QP
00559   Quadratic_program_status  solve( )
00560   { CGAL_qpe_assertion( phase() > 0);
00561   while ( phase() < 3) { pivot_step(); }
00562   return status(); }
00563 
00564 public:
00565 
00566   // access
00567   // ------
00568   // access to QP
00569   int  number_of_variables  ( ) const { return qp_n; }
00570   int  number_of_constraints( ) const { return qp_m; }
00571     
00572   A_iterator  a_begin( ) const { return qp_A;      }
00573   A_iterator  a_end  ( ) const { return qp_A+qp_n; }
00574     
00575   B_iterator  b_begin( ) const { return qp_b;      }
00576   B_iterator  b_end  ( ) const { return qp_b+qp_m; }
00577     
00578   C_iterator  c_begin( ) const { return qp_c;      }
00579   C_iterator  c_end  ( ) const { return qp_c+qp_n; }
00580 
00581   C_entry     c_0    ( ) const { return qp_c0;}
00582     
00583   D_iterator  d_begin( ) const { return qp_D;      }
00584   D_iterator  d_end  ( ) const { return qp_D+qp_n; }
00585     
00586   Row_type_iterator  row_type_begin( ) const { return qp_r;      }
00587   Row_type_iterator  row_type_end  ( ) const { return qp_r+qp_m; }
00588 
00589   // access to current status
00590   int     phase     ( ) const { return m_phase;  }
00591   Quadratic_program_status  status    ( ) const { return m_status; }
00592   int     iterations( ) const { return m_pivots; }
00593     
00594   // access to common denominator
00595   const ET& variables_common_denominator( ) const 
00596   { 
00597     CGAL_qpe_assertion (d > 0);
00598     return d; 
00599   }
00600 
00601   // access to current solution
00602   ET  solution_numerator( ) const;
00603 
00604   // access to current solution
00605   ET  solution_denominator( ) const { return et2*d*d; }
00606     
00607   // access to original variables
00608   int  number_of_original_variables( ) const { return qp_n; }
00609     
00610   // access to slack variables
00611   int  number_of_slack_variables( ) const { return slack_A.size(); }
00612 
00613   // access to artificial variables
00614   int  number_of_artificial_variables( ) const { return art_A.size(); }
00615     
00616   C_auxiliary_iterator
00617   c_auxiliary_value_iterator_begin( ) const { return aux_c.begin(); }
00618   C_auxiliary_iterator
00619   c_auxiliary_value_iterator_end( ) const {return aux_c.end(); }
00620 
00621   // access to basic variables
00622   int  number_of_basic_variables( ) const { return B_O.size()+B_S.size(); }
00623   int  number_of_basic_original_variables( ) const { return B_O.size(); }
00624   int  number_of_basic_slack_variables( ) const { return B_S.size(); }
00625 
00626   Basic_variable_index_iterator
00627   basic_original_variable_indices_begin( ) const { return B_O.begin(); }
00628   Basic_variable_index_iterator
00629   basic_original_variable_indices_end  ( ) const { return B_O.end(); }
00630     
00631   Basic_variable_numerator_iterator
00632   basic_original_variables_numerator_begin( ) const { return x_B_O.begin(); }
00633   Basic_variable_numerator_iterator
00634   basic_original_variables_numerator_end  ( ) const { return x_B_O.begin()
00635                                                         + B_O.size(); }
00636 
00637 public: // only the pricing strategies (including user-defined ones
00638         // need access to this) -- make them friends?
00639 
00640   // access to working variables
00641   int  number_of_working_variables( ) const { return in_B.size(); }
00642   
00643   bool is_basic( int j) const
00644   { 
00645     CGAL_qpe_assertion(j >= 0);
00646     CGAL_qpe_assertion(j < number_of_working_variables());
00647     return (in_B[ j] >= 0);
00648   }
00649   
00650   bool is_original(int j) const
00651   {
00652     CGAL_qpe_assertion(j >= 0);
00653     CGAL_qpe_assertion(j < number_of_working_variables());
00654     return (j < qp_n);    
00655   }
00656     
00657   bool phaseI( ) const {return is_phaseI;}
00658   
00659   bool is_artificial(int k) const;
00660 
00661   int get_l() const;
00662 
00663   // Returns w[j] for an original variable x_j.
00664   ET w_j_numerator(int j) const
00665   { 
00666     CGAL_qpe_assertion((0 <= j) && (j < qp_n) && is_phaseII);
00667     return w[j];
00668   }
00669   
00670   Bound_index nonbasic_original_variable_bound_index(int i) const
00671     // Returns on which bound the nonbasic variable x_i is currently
00672     // sitting:
00673     //
00674     // - LOWER: the variable is sitting on its lower bound.
00675     // - UPPER: the variable is sitting on its upper bound.
00676     // - FIXED: the variable is sitting on its lower and upper bound.
00677     // - ZERO: the variable has value zero and is sitting on its lower
00678     //   bound, its upper bound, or betweeen the two bounds.
00679     //
00680     // Note: in the latter case you can call state_of_zero_nonbasic_variable()
00681     // to find out which bound is active, if any.
00682   {
00683     CGAL_assertion(!check_tag(Is_nonnegative()) &&
00684                    !is_basic(i) && i < qp_n);
00685     if (x_O_v_i[i] == BASIC) {
00686       CGAL_qpe_assertion(false);
00687     }
00688     return x_O_v_i[i];  
00689   };
00690   
00691   int state_of_zero_nonbasic_variable(int i) const
00692     // Returns -1 if the original variable x_i equals its lower bound,
00693     // 0 if it lies strictly between its lower and upper bound, and 1 if
00694     // it coincides with its upper bound.
00695     // 
00696     // See also the documentation of nonbasic_original_variable_bound_index()
00697     // above.
00698   {
00699     CGAL_assertion(!check_tag(Is_nonnegative()) &&
00700                    !is_basic(i) && i < qp_n && x_O_v_i[i] == ZERO);
00701     if (*(qp_fl+i) && CGAL::is_zero(*(qp_l+i)))
00702       return -1;
00703     if (*(qp_fu+i) && CGAL::is_zero(*(qp_u+i)))
00704       return 1;
00705     return 0;
00706   }
00707   
00708 private:
00709   // miscellaneous
00710   // -------------
00711   // setting the pricing strategy:
00712   void  set_pricing_strategy ( Quadratic_program_pricing_strategy strategy);
00713 
00714   // diagnostic output
00715   void  set_verbosity( int verbose = 0, std::ostream& stream = std::cout);
00716 
00717 
00718 public:
00719   // access to indices of basic constraints
00720   int  number_of_basic_constraints( ) const { return C.size(); }
00721 
00722   Basic_constraint_index_iterator
00723   basic_constraint_indices_begin( ) const { return C.begin(); }
00724   Basic_constraint_index_iterator
00725   basic_constraint_indices_end  ( ) const { return C.end(); }
00726 
00727   // helper functions
00728   template < class RndAccIt1, class RndAccIt2, class NT >  
00729   NT  mu_j_( int j, RndAccIt1 lambda_it, RndAccIt2 x_it, const NT& dd) const;
00730 
00731   ET  dual_variable( int i)
00732   {
00733     for ( int j = 0; j < qp_m; ++j) {
00734       tmp_x[ j] = inv_M_B.entry( j, i);
00735     }
00736     return std::inner_product( tmp_x.begin(), tmp_x.begin()+qp_m,
00737                                minus_c_B.begin(), et0);
00738   }
00739 
00740 public:
00741   // public access to compressed lambda (used in filtered base)
00742   Value_const_iterator get_lambda_begin() const
00743   {
00744     return lambda.begin();
00745   }
00746   Value_const_iterator get_lambda_end() const
00747   {
00748     return lambda.begin() + C.size();
00749   }
00750   
00751 
00752 private:    
00753 
00754   // private member functions
00755   // ------------------------
00756   // initialization
00757   void  init_basis( );
00758   void  init_basis__slack_variables( int s_i, Tag_true  has_no_inequalities);
00759   void  init_basis__slack_variables( int s_i, Tag_false has_no_inequalities);
00760   void  init_basis__slack_variables( int s_i, bool has_no_inequalities) {
00761     if (has_no_inequalities)
00762       init_basis__slack_variables (s_i, Tag_true());
00763     else 
00764       init_basis__slack_variables (s_i, Tag_false());
00765   }
00766 
00767   void  init_basis__constraints    ( int s_i, Tag_true  has_no_inequalities);
00768   void  init_basis__constraints    ( int s_i, Tag_false has_no_inequalities);
00769   void  init_basis__constraints    ( int s_i, bool has_no_inequalities) {
00770     if (has_no_inequalities)
00771       init_basis__constraints (s_i, Tag_true());
00772     else 
00773       init_basis__constraints (s_i, Tag_false());
00774   }
00775 
00776   void  init_x_O_v_i();
00777   void  init_r_C(Tag_true  /*is_nonnegative*/);
00778   void  init_r_C(Tag_false /*is_nonnegative*/);
00779   void  init_r_S_B(Tag_true  /*is_nonnegative*/);
00780   void  init_r_S_B(Tag_false /*is_nonnegative*/);
00781 
00782   void  init_r_B_O();
00783   void  init_w();
00784 
00785 
00786   void  init_solution( );
00787   void  init_solution__b_C( Tag_true  has_no_inequalities);
00788   void  init_solution__b_C( Tag_false has_no_inequalities); 
00789   void  init_solution__b_C( bool has_no_inequalities) {
00790     if (has_no_inequalities)
00791       init_solution__b_C (Tag_true());
00792     else
00793       init_solution__b_C (Tag_false());
00794   }
00795 
00796   void  init_additional_data_members( );
00797     
00798   // function needed for set up of auxiliary problem for symbolic perturbation
00799   int  signed_leading_exponent( int row);
00800   // This is a variant of set_up_auxiliary_problem for symbolic perturbation
00801   // for the perturbed case
00802   void  set_up_auxiliary_problemI( Tag_true is_perturbed);
00803 
00804   void  set_up_auxiliary_problem();
00805 
00806   // transition (to phase II)
00807   void  transition( );
00808   void  transition( Tag_true  is_linear);
00809   void  transition( Tag_false is_linear);
00810     
00811   // pivot step
00812   void  pivot_step( );
00813 
00814   // pricing
00815   void  pricing( );
00816 
00817   template < class NT, class It >
00818   void  mu_j__linear_part_( NT& mu_j, int j, It lambda_it,
00819                             Tag_true  has_no_inequalities) const;
00820   template < class NT, class It >
00821   void  mu_j__linear_part_( NT& mu_j, int j, It lambda_it,
00822                             Tag_false has_no_inequalities) const;
00823   template < class NT, class It >
00824   void  mu_j__linear_part_( NT& mu_j, int j, It lambda_it,
00825                             bool has_no_inequalities) const {
00826     if (has_no_inequalities)
00827       mu_j__linear_part_ (mu_j, j, lambda_it, Tag_true());
00828     else
00829       mu_j__linear_part_ (mu_j, j, lambda_it, Tag_false());
00830   }
00831 
00832 
00833 //   template < class NT, class It >
00834 //   void  mu_j__quadratic_part_( NT& mu_j, int j, It x_it,
00835 //                             Tag_true  is_linear) const;
00836 //   template < class NT, class It >
00837 //   void  mu_j__quadratic_part_( NT& mu_j, int j, It x_it,
00838 //                             Tag_false is_linear) const;
00839 //   template < class NT, class It >
00840 //   void  mu_j__quadratic_part_( NT& mu_j, int j, It x_it,
00841 //                             Tag_false is_linear,
00842 //                             Tag_true  is_symmetric) const;
00843 //   template < class NT, class It >
00844 //   void  mu_j__quadratic_part_( NT& mu_j, int j, It x_it,
00845 //                             Tag_false is_linear,
00846 //                             Tag_false is_symmetric) const;
00847 
00848   template < class NT, class It >
00849   void  mu_j__slack_or_artificial_( NT& mu_j, int j, It lambda_it, 
00850                                     const NT& dd,
00851                                     Tag_true  has_no_inequalities) const;
00852   template < class NT, class It >
00853   void  mu_j__slack_or_artificial_( NT& mu_j, int j, It lambda_it, 
00854                                     const NT& dd,
00855                                     Tag_false has_no_inequalities) const;
00856 
00857   template < class NT, class It >
00858   void  mu_j__slack_or_artificial_( NT& mu_j, int j, It lambda_it,
00859                                     const NT& dd,
00860                                     bool has_no_inequalities) const {
00861     if (has_no_inequalities)
00862       mu_j__slack_or_artificial_ (mu_j, j, lambda_it, dd, Tag_true());
00863     else
00864       mu_j__slack_or_artificial_ (mu_j, j, lambda_it, dd, Tag_false());
00865   }
00866 
00867   // ratio test
00868   void  ratio_test_init( );
00869   void  ratio_test_init__A_Cj( Value_iterator A_Cj_it, int j,
00870                                Tag_true  has_no_inequalities);
00871   void  ratio_test_init__A_Cj( Value_iterator A_Cj_it, int j,
00872                                Tag_false has_no_inequalities);
00873   void  ratio_test_init__A_Cj( Value_iterator A_Cj_it, int j,
00874                                bool has_no_inequalities) {
00875     if (has_no_inequalities) 
00876       ratio_test_init__A_Cj (A_Cj_it, j, Tag_true());
00877     else
00878       ratio_test_init__A_Cj (A_Cj_it, j, Tag_false());
00879   }
00880 
00881   void  ratio_test_init__2_D_Bj( Value_iterator two_D_Bj_it, int j,
00882                                  Tag_true  is_linear);
00883   void  ratio_test_init__2_D_Bj( Value_iterator two_D_Bj_it, int j,
00884                                  Tag_false is_linear);
00885   void  ratio_test_init__2_D_Bj( Value_iterator two_D_Bj_it, int j,
00886                                  Tag_false is_linear,
00887                                  Tag_true  has_no_inequalities);
00888   void  ratio_test_init__2_D_Bj( Value_iterator two_D_Bj_it, int j,
00889                                  Tag_false is_linear,
00890                                  Tag_false has_no_inequalities);
00891   void  ratio_test_init__2_D_Bj( Value_iterator two_D_Bj_it, int j,
00892                                  Tag_false is_linear,
00893                                  bool has_no_inequalities) {
00894     if (has_no_inequalities)
00895       ratio_test_init__2_D_Bj( two_D_Bj_it, j, is_linear, Tag_true());
00896     else
00897       ratio_test_init__2_D_Bj( two_D_Bj_it, j, is_linear, Tag_false());
00898   }
00899 
00900 
00901   void  ratio_test_1( );
00902   void  ratio_test_1__q_x_O( Tag_true  is_linear);
00903   void  ratio_test_1__q_x_O( Tag_false is_linear);
00904   void  ratio_test_1__q_x_S( Tag_true  has_no_inequalities);
00905   void  ratio_test_1__q_x_S( Tag_false has_no_inequalities);
00906   void  ratio_test_1__q_x_S( bool has_no_inequalities) {
00907     if (has_no_inequalities)
00908       ratio_test_1__q_x_S (Tag_true());
00909     else
00910       ratio_test_1__q_x_S (Tag_false());
00911   }
00912 
00913   void  ratio_test_1__t_min_j(Tag_true  /*is_nonnegative*/);  
00914   void  ratio_test_1__t_min_j(Tag_false /*is_nonnegative*/);
00915     
00916   void  ratio_test_1__t_i( Index_iterator i_it, Index_iterator end_it,
00917                            Value_iterator x_it, Value_iterator   q_it,
00918                            Tag_true  no_check);
00919   void  ratio_test_1__t_i( Index_iterator i_it, Index_iterator end_it,
00920                            Value_iterator x_it, Value_iterator   q_it,
00921                            Tag_false  no_check);
00922     
00923   // replaces the above two functions
00924   void  ratio_test_1__t_min_B(Tag_true has_no_inequalities );
00925   void  ratio_test_1__t_min_B(Tag_false has_no_inequalities ); 
00926   void  ratio_test_1__t_min_B(bool has_no_inequalities ) {
00927     if (has_no_inequalities)
00928       ratio_test_1__t_min_B (Tag_true());
00929     else
00930       ratio_test_1__t_min_B (Tag_false());
00931   }
00932    
00933   void  ratio_test_1_B_O__t_i(Index_iterator i_it, Index_iterator end_it,
00934                               Value_iterator x_it, Value_iterator q_it,
00935                               Tag_true  /*is_nonnegative*/);
00936   void  ratio_test_1_B_O__t_i(Index_iterator i_it, Index_iterator end_it,
00937                               Value_iterator x_it, Value_iterator q_it,
00938                               Tag_false /*is_nonnegative*/);
00939   void  ratio_test_1_B_S__t_i(Index_iterator i_it, Index_iterator end_it,
00940                               Value_iterator x_it, Value_iterator q_it,
00941                               Tag_true  /*is_nonnegative*/);
00942   void  ratio_test_1_B_S__t_i(Index_iterator i_it, Index_iterator end_it,
00943                               Value_iterator x_it, Value_iterator q_it,
00944                               Tag_false /*is_nonnegative*/);
00945                              
00946   void  test_implicit_bounds_dir_pos(int k, const ET& x_k, const ET& q_k, 
00947                                      int& i_min, ET& d_min, ET& q_min);
00948   void  test_implicit_bounds_dir_neg(int k, const ET& x_k, const ET& q_k, 
00949                                      int& i_min, ET& d_min, ET& q_min);
00950   void  test_explicit_bounds_dir_pos(int k, const ET& x_k, const ET& q_k, 
00951                                      int& i_min, ET& d_min, ET& q_min);
00952   void  test_explicit_bounds_dir_neg(int k, const ET& x_k, const ET& q_k, 
00953                                      int& i_min, ET& d_min, ET& q_min);
00954   void  test_mixed_bounds_dir_pos(int k, const ET& x_k, const ET& q_k, 
00955                                   int& i_min, ET& d_min, ET& q_min);
00956   void  test_mixed_bounds_dir_neg(int k, const ET& x_k, const ET& q_k, 
00957                                   int& i_min, ET& d_min, ET& q_min);    
00958                                     
00959   void  ratio_test_1__t_j( Tag_true  is_linear);
00960   void  ratio_test_1__t_j( Tag_false is_linear);
00961 
00962   void  ratio_test_2( Tag_true  is_linear);
00963   void  ratio_test_2( Tag_false is_linear);
00964   void  ratio_test_2__p( Tag_true  has_no_inequalities);
00965   void  ratio_test_2__p( Tag_false has_no_inequalities);   
00966   void  ratio_test_2__p( bool has_no_inequalities) {
00967     if (has_no_inequalities)
00968       ratio_test_2__p (Tag_true());
00969     else
00970       ratio_test_2__p (Tag_false());
00971   }
00972 
00973   // update
00974   void  update_1( );
00975   void  update_1( Tag_true  is_linear);
00976   void  update_1( Tag_false is_linear);
00977 
00978   void  update_2( Tag_true  is_linear);
00979   void  update_2( Tag_false is_linear);
00980 
00981   void  replace_variable( );
00982   void  replace_variable( Tag_true  has_no_inequalities);
00983   void  replace_variable( Tag_false has_no_inequalities);
00984   void  replace_variable( bool has_no_inequalities) {
00985     if (has_no_inequalities)
00986       replace_variable (Tag_true());
00987     else
00988       replace_variable (Tag_false());
00989   }
00990 
00991   void  replace_variable_original_original( );
00992   // update of the vector r
00993   void  replace_variable_original_original_upd_r(Tag_true
00994                                                  /*is_nonnegative*/);
00995   void  replace_variable_original_original_upd_r(Tag_false
00996                                                  /*is_nonnegative*/);
00997 
00998   void  replace_variable_original_slack( );
00999   // update of the vector r
01000   void  replace_variable_original_slack_upd_r(Tag_true /*is_nonnegative*/);
01001   void  replace_variable_original_slack_upd_r(Tag_false /*is_nonnegative*/);
01002 
01003   void  replace_variable_slack_original( );
01004   // update of the vector r
01005   void  replace_variable_slack_original_upd_r(Tag_true /*is_nonnegative*/);
01006   void  replace_variable_slack_original_upd_r(Tag_false /*is_nonnegative*/);
01007     
01008   void  replace_variable_slack_slack( );
01009   // update of the vector r
01010   void  replace_variable_slack_slack_upd_r(Tag_true /*is_nonnegative*/);
01011   void  replace_variable_slack_slack_upd_r(Tag_false /*is_nonnegative*/);
01012     
01013   void  remove_artificial_variable_and_constraint( );
01014   // update of the vector r
01015   void  remove_artificial_variable_and_constraint_upd_r(Tag_true
01016                                                         /*is_nonnegative*/);
01017   void  remove_artificial_variable_and_constraint_upd_r(Tag_false
01018                                                         /*is_nonnegative*/);    
01019     
01020   void  expel_artificial_variables_from_basis( );
01021     
01022   // update that occurs only with upper bounding in ratio test step 1
01023   void  enter_and_leave_variable( );
01024 
01025   void  enter_variable( );
01026   // update of the vectors w and r
01027   void  enter_variable_original_upd_w_r(Tag_true /*is_nonnegative*/);
01028   void  enter_variable_original_upd_w_r(Tag_false /*is_nonnegative*/);
01029   void  enter_variable_slack_upd_w_r(Tag_true /*is_nonnegative*/);
01030   void  enter_variable_slack_upd_w_r(Tag_false /*is_nonnegative*/);
01031     
01032   void  leave_variable( );
01033   // update of the vectors w and r
01034   void  leave_variable_original_upd_w_r(Tag_true /*is_nonnegative*/);    
01035   void  leave_variable_original_upd_w_r(Tag_false /*is_nonnegative*/);
01036   void  leave_variable_slack_upd_w_r(Tag_true /*is_nonnegative*/);
01037   void  leave_variable_slack_upd_w_r(Tag_false /*is_nonnegative*/);
01038     
01039   void  z_replace_variable( );
01040   void  z_replace_variable( Tag_true has_no_inequalities);
01041   void  z_replace_variable( Tag_false has_no_inequalities);
01042   void  z_replace_variable( bool has_no_inequalities) {
01043     if (has_no_inequalities) 
01044       z_replace_variable (Tag_true());
01045     else
01046       z_replace_variable (Tag_false());
01047   }
01048     
01049   void  z_replace_variable_original_by_original( );
01050   // update of the vectors w and r
01051   void  z_replace_variable_original_by_original_upd_w_r(Tag_true 
01052                                                         /*is_nonnegative*/);
01053   void  z_replace_variable_original_by_original_upd_w_r(Tag_false 
01054                                                         /*is_nonnegative*/);
01055     
01056   void  z_replace_variable_original_by_slack( );
01057   // update of the vectors w and r    
01058   void  z_replace_variable_original_by_slack_upd_w_r(Tag_true 
01059                                                      /*is_nonnegative*/);
01060   void  z_replace_variable_original_by_slack_upd_w_r(Tag_false
01061                                                      /*is_nonnegative*/);
01062     
01063   void  z_replace_variable_slack_by_original( );
01064   // update of the vectors w and r
01065   void  z_replace_variable_slack_by_original_upd_w_r(Tag_true
01066                                                      /*is_nonnegative*/);
01067   void  z_replace_variable_slack_by_original_upd_w_r(Tag_false
01068                                                      /*is_nonnegative*/);
01069     
01070   void  z_replace_variable_slack_by_slack( );
01071   // update of the vectors w and r
01072   void  z_replace_variable_slack_by_slack_upd_w_r(Tag_true
01073                                                   /*is_nonnegative*/);
01074   void  z_replace_variable_slack_by_slack_upd_w_r(Tag_false
01075                                                   /*is_nonnegative*/);
01076     
01077   // update of the parts r_C and r_S_B
01078   void  update_r_C_r_S_B__j(ET& x_j);
01079   void  update_r_C_r_S_B__j_i(ET& x_j, ET& x_i);
01080   void  update_r_C_r_S_B__i(ET& x_i);
01081     
01082   // update of w and r_B_O 
01083   void  update_w_r_B_O__j(ET& x_j);
01084   void  update_w_r_B_O__j_i(ET& x_j, ET& x_i);
01085   void  update_w_r_B_O__i(ET& x_i);
01086     
01087     
01088   bool  basis_matrix_stays_regular( );
01089 
01090   // current solution
01091   void  compute_solution(Tag_true  /*is_nonnegative*/);
01092   void  compute_solution(Tag_false /*is_nonnegative*/);
01093 
01094   void  compute__x_B_S( Tag_false  has_no_inequalities,
01095                         Tag_false /*is_nonnegative*/);
01096   void  compute__x_B_S( Tag_false  has_no_inequalities,
01097                         Tag_true  /*is_nonnegative*/);
01098   void  compute__x_B_S( Tag_true  has_no_inequalities,
01099                         Tag_false /*is_nonnegative*/);
01100   void  compute__x_B_S( Tag_true  has_no_inequalities,
01101                         Tag_true  /*is_nonnegative*/);
01102   void  compute__x_B_S( bool  has_no_inequalities,
01103                         Tag_true  is_nonnegative) {
01104     if (has_no_inequalities)
01105       compute__x_B_S (Tag_true(), is_nonnegative);
01106     else
01107       compute__x_B_S (Tag_false(), is_nonnegative);
01108   }
01109     
01110   void  compute__x_B_S( bool  has_no_inequalities,
01111                         Tag_false  is_nonnegative) {
01112     if (has_no_inequalities)
01113       compute__x_B_S (Tag_true(), is_nonnegative);
01114     else
01115       compute__x_B_S (Tag_false(), is_nonnegative);
01116   }  
01117 
01118   void  multiply__A_S_BxB_O( Value_iterator in, Value_iterator out) const;
01119     
01120   ET    multiply__A_ixO(int row) const;
01121   void  multiply__A_CxN_O(Value_iterator out) const;
01122   bool  check_r_C(Tag_true  /*is_nonnegative*/) const;
01123   bool  check_r_C(Tag_false /*is_nonnegative*/) const;
01124     
01125   void  multiply__A_S_BxN_O(Value_iterator out) const;
01126   bool  check_r_S_B(Tag_true  /*is_nonnegative*/) const;
01127   bool  check_r_S_B(Tag_false /*is_nonnegative*/) const;
01128     
01129   void  multiply__2D_B_OxN_O(Value_iterator out) const;
01130   bool  check_r_B_O(Tag_true  /*is_nonnegative*/) const;
01131   bool  check_r_B_O(Tag_false /*is_nonnegative*/) const;
01132         
01133   void  multiply__2D_OxN_O(Value_iterator out) const;
01134   bool  check_w(Tag_true  /*is_nonnegative*/) const;
01135   bool  check_w(Tag_false /*is_nonnegative*/) const;
01136     
01137   // utility routines for QP's in nonstandard form:
01138   ET original_variable_value_under_bounds(int i) const;
01139   ET nonbasic_original_variable_value (int i) const;
01140 
01141 public: 
01142   // for original variables
01143   ET variable_numerator_value(int i) const;
01144   ET unbounded_direction_value(int i) const;
01145   ET lambda_numerator(int i) const
01146   {
01147     // we use the vector lambda which conforms to C (basic constraints)
01148     CGAL_qpe_assertion (i >= 0);
01149     CGAL_qpe_assertion (i <= qp_m);
01150     if (no_ineq)
01151       return lambda[i];
01152     else {
01153       int k = in_C[i];     // position of i in C
01154       if (k != -1) 
01155         return lambda[k];
01156       else 
01157         return et0;
01158     }   
01159 }
01160 
01161 private:
01162   // check basis inverse
01163   bool  check_basis_inverse( );
01164   bool  check_basis_inverse( Tag_true  is_linear);
01165   bool  check_basis_inverse( Tag_false is_linear);
01166 
01167   // diagnostic output
01168   void  print_program ( ) const;
01169   void  print_basis   ( ) const;
01170   void  print_solution( ) const;
01171   void  print_ratio_1_original(int k, const ET& x_k, const ET& q_k);
01172   void  print_ratio_1_slack(int k, const ET& x_k, const ET& q_k);
01173 
01174   const char*  variable_type( int k) const;
01175     
01176   // ensure container size
01177   template <class Container>
01178   void ensure_size(Container& c, typename Container::size_type desired_size) {
01179     typedef typename Container::value_type Value_type;
01180     for (typename Container::size_type i=c.size(); i < desired_size; ++i) {
01181       c.push_back(Value_type());
01182     }
01183   }
01184     
01185 private:
01186 
01187 private:  // (inefficient) access to bounds of variables:
01188   // Given an index of an original or slack variable, returns whether
01189   // or not the variable has a finite lower bound.
01190   bool has_finite_lower_bound(int i) const;
01191 
01192   // Given an index of an original or slack variable, returns whether
01193   // or not the variable has a finite upper bound.
01194   bool has_finite_upper_bound(int i) const;
01195 
01196   // Given an index of an original or slack variable, returns its
01197   // lower bound.
01198   ET lower_bound(int i) const;
01199 
01200   // Given an index of an original variable, returns its upper bound.
01201   ET upper_bound(int i) const;
01202 
01203   struct Bnd { // (inefficient) utility class representing a possibly
01204     // infinite bound
01205     enum Kind { MINUS_INF=-1, FINITE=0, PLUS_INF=1 };
01206     const Kind kind;      // whether the bound is finite or not
01207     const ET value;       // bound's value in case it is finite
01208 
01209     Bnd(bool is_upper, bool is_finite, const ET& value) 
01210       : kind(is_upper? (is_finite? FINITE : PLUS_INF) :
01211              (is_finite? FINITE : MINUS_INF)),
01212         value(value) {}
01213     Bnd(Kind kind, const ET& value) : kind(kind), value(value) {}
01214     
01215     bool operator==(const ET& v) const { return kind == FINITE && value == v; }
01216     bool operator==(const Bnd& b) const {
01217       return kind == b.kind && (kind != FINITE || value == b.value);
01218     }
01219     bool operator!=(const Bnd& b) const { return !(*this == b); }
01220     bool operator<(const ET& v) const { return kind == FINITE && value < v; }
01221     bool operator<(const Bnd& b) const {
01222       return kind < b.kind ||
01223         (kind == b.kind && kind == FINITE && value < b.value);
01224     }
01225     bool operator<=(const Bnd& b) const { return *this < b || *this == b; }
01226     bool operator>(const ET& v) const { return kind == FINITE && value > v; }
01227     bool operator>(const Bnd& b)  const { return !(*this <= b); }
01228     bool operator>=(const Bnd& b) const { return !(*this < b); }
01229     
01230     Bnd operator*(const ET& f) const { return Bnd(kind, value*f); }
01231   };
01232 
01233   // Given an index of an original, slack, or artificial variable,
01234   // return its lower bound.
01235   Bnd lower_bnd(int i) const;
01236 
01237   // Given an index of an original, slack, or artificial variable,
01238   // return its upper bound.
01239   Bnd upper_bnd(int i) const;
01240 
01241 private:
01242   bool is_value_correct() const;
01243   // ----------------------------------------------------------------------------
01244 
01245   // ===============================
01246   // class implementation (template)
01247   // ===============================
01248 
01249 public:
01250 
01251   // pricing
01252   // -------
01253   // The solver provides three methods to compute mu_j; the first
01254   // two below take additional information (which the pricing
01255   // strategy either provides in exact- or NT-form), and the third
01256   // simply does the exact computation. (Note: internally, we use
01257   // the third version, too, see ratio_test_1__t_j().)
01258 
01259   // computation of mu_j with standard form
01260   template < class RndAccIt1, class RndAccIt2, class NT >  
01261   NT
01262   mu_j( int j, RndAccIt1 lambda_it, RndAccIt2 x_it, const NT& dd) const
01263   {
01264     NT  mu_j;
01265 
01266     if ( j < qp_n) {                                // original variable
01267 
01268       // [c_j +] A_Cj^T * lambda_C
01269       mu_j = ( is_phaseI ? NT( 0) : dd * NT(*(qp_c+ j)));
01270       mu_j__linear_part( mu_j, j, lambda_it, no_ineq);
01271 
01272       // ... + 2 D_Bj^T * x_B
01273       mu_j__quadratic_part( mu_j, j, x_it, Is_linear());
01274 
01275     } else {                                        // slack or artificial
01276 
01277       mu_j__slack_or_artificial( mu_j, j, lambda_it, dd,
01278                                  no_ineq);
01279 
01280     }
01281 
01282     return mu_j;
01283   }
01284     
01285   // computation of mu_j with upper bounding
01286   template < class RndAccIt1, class RndAccIt2, class NT >  
01287   NT
01288   mu_j( int j, RndAccIt1 lambda_it, RndAccIt2 x_it, const NT& w_j,
01289         const NT& dd) const
01290   {
01291     NT  mu_j;
01292 
01293     if ( j < qp_n) {                                // original variable
01294 
01295       // [c_j +] A_Cj^T * lambda_C
01296       mu_j = ( is_phaseI ? NT( 0) : dd * NT(*(qp_c+ j)));
01297       mu_j__linear_part( mu_j, j, lambda_it, no_ineq);
01298 
01299       // ... + 2 D_Bj^T * x_B + 2 D_Nj x_N
01300       mu_j__quadratic_part( mu_j, j, x_it, w_j, dd, Is_linear());
01301 
01302     } else {                                        // slack or artificial
01303 
01304       mu_j__slack_or_artificial( mu_j, j, lambda_it, dd,
01305                                  no_ineq);
01306 
01307     }
01308 
01309     return mu_j;
01310   }
01311 
01312   // computation of mu_j (exact, both for upper bounding and standard form)
01313   ET
01314   mu_j( int j) const
01315   {
01316     CGAL_qpe_assertion(!is_basic(j));
01317     
01318     if (!check_tag(Is_nonnegative()) &&
01319         !check_tag(Is_linear()) &&
01320         !is_phaseI && is_original(j)) {
01321       return mu_j(j,
01322                   lambda.begin(),
01323                   basic_original_variables_numerator_begin(),
01324                   w_j_numerator(j),
01325                   variables_common_denominator());
01326     } else {
01327       return mu_j(j,
01328                   lambda.begin(),
01329                   basic_original_variables_numerator_begin(),
01330                   variables_common_denominator());
01331     }
01332   }
01333 
01334 private:
01335 
01336   // pricing (private helper functions)
01337   // ----------------------------------
01338   template < class NT, class It > inline                      // no ineq.
01339   void
01340   mu_j__linear_part( NT& mu_j, int j, It lambda_it, Tag_true) const
01341   {
01342     mu_j += inv_M_B.inner_product_l( lambda_it, *(qp_A+ j));
01343   }
01344 
01345   template < class NT, class It > inline                      // has ineq.
01346   void
01347   mu_j__linear_part( NT& mu_j, int j, It lambda_it, Tag_false) const
01348   {
01349     mu_j += inv_M_B.inner_product_l
01350       ( lambda_it,
01351         A_by_index_iterator( C.begin(),
01352                              A_by_index_accessor( *(qp_A + j))));
01353   }
01354 
01355   template < class NT, class It > inline                     
01356   void
01357   mu_j__linear_part( NT& mu_j, int j, It lambda_it, 
01358                      bool has_no_inequalities) const {
01359     if (has_no_inequalities) 
01360       mu_j__linear_part (mu_j, j, lambda_it, Tag_true());
01361     else
01362       mu_j__linear_part (mu_j, j, lambda_it, Tag_false());     
01363   }
01364 
01365   template < class NT, class It > inline          // LP case, standard form
01366   void
01367   mu_j__quadratic_part( NT&, int, It, Tag_true) const
01368   {
01369     // nop
01370   }
01371     
01372   template < class NT, class It > inline          // LP case, upper bounded
01373   void
01374   mu_j__quadratic_part( NT&, int, It, const NT& /*w_j*/, const NT& /*dd*/,
01375                         Tag_true) const
01376   {
01377     // nop
01378   }    
01379 
01380   template < class NT, class It > inline          // QP case, standard form
01381   void
01382   mu_j__quadratic_part( NT& mu_j, int j, It x_it, Tag_false) const
01383   {
01384     if ( is_phaseII) {
01385       // 2 D_Bj^T * x_B
01386       mu_j += inv_M_B.inner_product_x
01387         ( x_it,
01388           D_pairwise_iterator_input_type( B_O.begin(),
01389                                D_pairwise_accessor_input_type(qp_D, j)));
01390     }
01391   }
01392 
01393   template < class NT, class It > inline          // QP case, upper bounded
01394   void
01395   mu_j__quadratic_part( NT& mu_j, int j, It x_it, const NT& w_j,
01396                         const NT& dd, Tag_false) const
01397   {
01398     if ( is_phaseII) {
01399       mu_j += dd * w_j;
01400       // 2 D_Bj^T * x_B
01401       mu_j += inv_M_B.inner_product_x
01402         ( x_it,
01403           D_pairwise_iterator_input_type( B_O.begin(),
01404                                D_pairwise_accessor_input_type(qp_D, j)));
01405     }
01406   }
01407 
01408 
01409   template < class NT, class It >  inline                     // no ineq.
01410   void
01411   mu_j__slack_or_artificial( NT& mu_j, int j, It lambda_it, const NT& dd, Tag_true) const
01412   {
01413     j -= qp_n;
01414     // artificial variable
01415     // A_j^T * lambda
01416     mu_j = lambda_it[ j];
01417     if ( art_A[ j].second) mu_j = -mu_j;
01418 
01419     // c_j + ...
01420     mu_j += dd*NT(aux_c[ j]);
01421 
01422   }
01423 
01424   template < class NT, class It >  inline                     // has ineq.
01425   void
01426   mu_j__slack_or_artificial( NT& mu_j, int j, It lambda_it, const NT& dd, Tag_false) const
01427   {
01428     j -= qp_n;
01429 
01430     if ( j < (int)slack_A.size()) {                 // slack variable
01431 
01432       // A_Cj^T * lambda_C
01433       mu_j = lambda_it[ in_C[ slack_A[ j].first]];
01434       if ( slack_A[ j].second) mu_j = -mu_j;
01435 
01436     } else {                                        // artificial variable
01437       j -= slack_A.size();
01438 
01439       // A_Cj^T * lambda_C
01440       mu_j = lambda_it[ in_C[ art_A[ j].first]];
01441       if ( art_A[ j].second) mu_j = -mu_j;
01442 
01443       // c_j + ...
01444       mu_j += dd*NT(aux_c[ j]);
01445     }
01446   }
01447 
01448   template < class NT, class It >  inline
01449   void
01450   mu_j__slack_or_artificial( NT& mu_j, int j, It lambda_it, 
01451                              const NT& dd, bool has_no_inequalities) const {
01452     if (has_no_inequalities)
01453       mu_j__slack_or_artificial (mu_j, j, lambda_it, dd, Tag_true());
01454     else
01455       mu_j__slack_or_artificial (mu_j, j, lambda_it, dd, Tag_false());
01456   }
01457 };
01458 
01459 // ----------------------------------------------------------------------------
01460 
01461 // =============================
01462 // class implementation (inline)
01463 // =============================
01464 
01465 // initialization
01466 // --------------
01467 
01468 // transition
01469 // ----------
01470 template < class Q, typename ET, typename Tags >  inline                                 // QP case
01471 void  QP_solver<Q, ET, Tags>::
01472 transition( Tag_false)
01473 {
01474   typedef  Creator_2< D_iterator, int, 
01475     D_pairwise_accessor >  D_transition_creator_accessor;
01476 
01477   typedef  Creator_2< Index_iterator, D_pairwise_accessor,
01478     D_pairwise_iterator >  D_transition_creator_iterator;
01479 
01480   // initialization of vector w and vector r_B_O:
01481   if (!check_tag(Is_nonnegative())) {
01482     init_w();                      
01483     init_r_B_O();
01484   }
01485 
01486   // here is what we need in the transition: an iterator that steps through 
01487   // the basic indices, where dereferencing
01488   // yields an iterator through the corresponding row of D, restricted 
01489   // to the basic indices. This means that we select the principal minor of D 
01490   // corresponding to the current basis.
01491  
01492   // To realize this, we transform B_O.begin() via the function h where
01493   //   h(i) = D_pairwise_iterator
01494   //           (B_O.begin(), 
01495   //            D_pairwise_accessor(qp_D, i))
01496 
01497 
01498   inv_M_B.transition 
01499     (boost::make_transform_iterator 
01500      (B_O.begin(),
01501       boost::bind 
01502       (D_transition_creator_iterator(), B_O.begin(), 
01503        boost::bind (D_transition_creator_accessor(), qp_D, _1))));
01504 }
01505 
01506 template < typename Q, typename ET, typename Tags >  inline                                 // LP case
01507 void  QP_solver<Q, ET, Tags>::
01508 transition( Tag_true)
01509 {
01510   inv_M_B.transition();
01511 }
01512 
01513 // ratio test
01514 // ----------
01515 template < typename Q, typename ET, typename Tags > inline                                  // LP case
01516 void  QP_solver<Q, ET, Tags>::
01517 ratio_test_init__2_D_Bj( Value_iterator, int, Tag_true)
01518 {
01519   // nop
01520 }
01521 
01522 template < typename Q, typename ET, typename Tags > inline                                  // QP case
01523 void  QP_solver<Q, ET, Tags>::
01524 ratio_test_init__2_D_Bj( Value_iterator two_D_Bj_it, int j_, Tag_false)
01525 {
01526   if ( is_phaseII) {
01527     ratio_test_init__2_D_Bj( two_D_Bj_it, j_,
01528                              Tag_false(), no_ineq);
01529   }
01530 }
01531 
01532 template < typename Q, typename ET, typename Tags > inline                                  // QP, no ineq.
01533 void  QP_solver<Q, ET, Tags>::
01534 ratio_test_init__2_D_Bj( Value_iterator two_D_Bj_it, int j_, Tag_false,
01535                          Tag_true )
01536 {
01537   // store exact version of `2 D_{B_O,j}'
01538   D_pairwise_accessor  d_accessor( qp_D, j_);
01539   std::copy( D_pairwise_iterator( B_O.begin(), d_accessor),
01540              D_pairwise_iterator( B_O.end  (), d_accessor),
01541              two_D_Bj_it);
01542 }
01543 
01544 template < typename Q, typename ET, typename Tags > inline                                  // QP, has ineq
01545 void  QP_solver<Q, ET, Tags>::
01546 ratio_test_init__2_D_Bj( Value_iterator two_D_Bj_it, int j_, Tag_false,
01547                          Tag_false)
01548 {
01549   // store exact version of `2 D_{B_O,j}'
01550   if ( j_ < qp_n) {                               // original variable
01551     ratio_test_init__2_D_Bj( two_D_Bj_it, j_, Tag_false(), Tag_true());
01552   } else {                                        // slack variable
01553     std::fill_n( two_D_Bj_it, B_O.size(), et0);
01554   }
01555 }
01556 
01557 template < typename Q, typename ET, typename Tags >  inline                                 // LP case
01558 void  QP_solver<Q, ET, Tags>::
01559 ratio_test_1__q_x_O( Tag_true)
01560 {
01561   inv_M_B.multiply_x( A_Cj.begin(), q_x_O.begin());
01562 }
01563 
01564 template < typename Q, typename ET, typename Tags >  inline                                 // QP case
01565 void  QP_solver<Q, ET, Tags>::
01566 ratio_test_1__q_x_O( Tag_false)
01567 {
01568   if ( is_phaseI) {                                   // phase I
01569     inv_M_B.multiply_x(     A_Cj.begin(),    q_x_O.begin());
01570   } else {                                            // phase II
01571     inv_M_B.multiply  (     A_Cj.begin(), two_D_Bj.begin(),
01572                             q_lambda.begin(),    q_x_O.begin());
01573   }
01574 }
01575 
01576 template < typename Q, typename ET, typename Tags >  inline                                 // no ineq.
01577 void  QP_solver<Q, ET, Tags>::
01578 ratio_test_1__q_x_S( Tag_true)
01579 {
01580   // nop
01581 }
01582 
01583 template < typename Q, typename ET, typename Tags >  inline                                 // has ineq.
01584 void  QP_solver<Q, ET, Tags>::
01585 ratio_test_1__q_x_S( Tag_false)
01586 {
01587   // A_S_BxB_O * q_x_O
01588   multiply__A_S_BxB_O( q_x_O.begin(), q_x_S.begin());
01589 
01590   // ( A_S_BxB_O * q_x_O) - A_S_Bxj
01591   if ( j < qp_n) {
01592     std::transform( q_x_S.begin(),
01593                     q_x_S.begin()+S_B.size(),
01594                     A_by_index_iterator( S_B.begin(),
01595                                          A_by_index_accessor( *(qp_A + j))),
01596                     q_x_S.begin(),
01597                     compose2_2( std::minus<ET>(),
01598                                 Identity<ET>(),
01599                                 std::bind1st( std::multiplies<ET>(), d)));
01600   }
01601 
01602   // q_x_S = -+ ( A_S_BxB_O * q_x_O - A_S_Bxj)
01603   Value_iterator  q_it = q_x_S.begin();
01604   Index_iterator  i_it;
01605   for ( i_it = B_S.begin(); i_it != B_S.end(); ++i_it, ++q_it) {
01606     if ( ! slack_A[ *i_it - qp_n].second) *q_it = -(*q_it);
01607   }
01608 }
01609 
01610 template < typename Q, typename ET, typename Tags >  inline                                 // no check
01611 void  QP_solver<Q, ET, Tags>::
01612 ratio_test_1__t_i( Index_iterator, Index_iterator,
01613                    Value_iterator, Value_iterator, Tag_true)
01614 {
01615   // nop
01616 }
01617 
01618 template < typename Q, typename ET, typename Tags >  inline                                 // check
01619 void  QP_solver<Q, ET, Tags>::
01620 ratio_test_1__t_i( Index_iterator i_it, Index_iterator end_it,
01621                    Value_iterator x_it, Value_iterator   q_it, Tag_false)
01622 {
01623   // check `t_i's
01624   for ( ; i_it != end_it; ++i_it, ++x_it, ++q_it) {
01625     if ( ( *q_it > et0) && ( ( *x_it * q_i) < ( x_i * *q_it))) {
01626       i = *i_it; x_i = *x_it; q_i = *q_it;
01627     }
01628   }
01629 }
01630 
01631 template < typename Q, typename ET, typename Tags >  inline                                 // LP case
01632 void  QP_solver<Q, ET, Tags>::
01633 ratio_test_1__t_j( Tag_true)
01634 {
01635   // nop
01636 }
01637 
01638 template < typename Q, typename ET, typename Tags >  inline                                 // QP case
01639 void  QP_solver<Q, ET, Tags>::
01640 ratio_test_1__t_j( Tag_false)
01641 {
01642   if ( is_phaseII) {
01643 
01644     // compute `nu' and `mu_j' 
01645     mu = mu_j(j);
01646     nu = inv_M_B.inner_product(     A_Cj.begin(), two_D_Bj.begin(),
01647                                     q_lambda.begin(),    q_x_O.begin());
01648     if ( j < qp_n) {                                // original variable
01649       nu -= d*ET( (*(qp_D + j))[ j]);
01650     }
01651     CGAL_qpe_assertion_msg(nu <= et0,
01652                            "nu <= et0 violated -- is your D matrix positive semidefinite?");
01653 
01654     // check `t_j'
01655     CGAL_qpe_assertion(mu != et0);
01656     // bg: formula below compares abs values, assuming mu < 0
01657     if ( ( nu < et0) && ( ( (mu < et0 ? mu : -mu) * q_i) > ( x_i * nu))) {
01658       i = -1; q_i = et1;
01659     }
01660   }
01661 }
01662 
01663 template < typename Q, typename ET, typename Tags >  inline                                 // LP case
01664 void  QP_solver<Q, ET, Tags>::
01665 ratio_test_2( Tag_true)
01666 {
01667   // nop
01668 }
01669 
01670 template < typename Q, typename ET, typename Tags >  inline                                 // no ineq.
01671 void  QP_solver<Q, ET, Tags>::
01672 ratio_test_2__p( Tag_true)
01673 {
01674   // get column index of entering variable in basis
01675   int  col = in_B[ j];
01676  
01677   CGAL_qpe_assertion( col >= 0);
01678   col += l;
01679 
01680   // get (last) column of `M_B^{-1}' (Note: `p_...' is stored in `q_...')
01681   Value_iterator  it;
01682   int             row;
01683   unsigned int    k;
01684   for (   k = 0,            row = 0,   it = q_lambda.begin();
01685           k < C.size();
01686           ++k,              ++row,     ++it                   ) {
01687     *it = inv_M_B.entry( row, col);
01688   }
01689   for (   k = 0,            row = l,   it = q_x_O.begin();
01690           k < B_O.size();
01691           ++k,              ++row,     ++it                   ) {
01692     *it = inv_M_B.entry( row, col);
01693   }
01694 }
01695 
01696 template < typename Q, typename ET, typename Tags >  inline                                 // has ineq.
01697 void  QP_solver<Q, ET, Tags>::
01698 ratio_test_2__p( Tag_false)
01699 {
01700   Value_iterator  v_it;
01701   Index_iterator  i_it;
01702 
01703   // compute 'p_lambda' and 'p_x_O' (Note: `p_...' is stored in `q_...')
01704   // -------------------------------------------------------------------
01705 
01706   // type of entering variable
01707   if ( j < qp_n) {                                        // original
01708 
01709     // use 'no_ineq' variant
01710     ratio_test_2__p( Tag_true());
01711 
01712   } else {                                                // slack
01713 
01714     j -= qp_n;
01715 
01716     // get column A_{S_j,B_O}^T (i.e. row of A_{S_B,B_O})
01717     int             row  = slack_A[ j].first;
01718     bool            sign = slack_A[ j].second;
01719 
01720     for (   i_it =  B_O.begin(),   v_it = tmp_x.begin();
01721             i_it != B_O.end();
01722             ++i_it,                ++v_it                ) {
01723       *v_it = ( sign ? 
01724                 *((*(qp_A+ *i_it))+ row) : - (*((*(qp_A + *i_it))+ row)));
01725     }
01726 
01727     // compute  ( p_l | p_x_O )^T = M_B^{-1} * ( 0 | A_{S_j,B_O} )^T
01728     std::fill_n( tmp_l.begin(), C.size(), et0);
01729     inv_M_B.multiply( tmp_l     .begin(), tmp_x  .begin(),
01730                       q_lambda.begin(),   q_x_O.begin());
01731 
01732     j += qp_n;
01733   }
01734 
01735   // compute 'p_x_S'
01736   // ---------------
01737   // A_S_BxB_O * p_x_O
01738   multiply__A_S_BxB_O( q_x_O.begin(), q_x_S.begin());
01739 
01740   // p_x_S = +- ( A_S_BxB_O * p_x_O)
01741   for (   i_it =  B_S.begin(),   v_it = q_x_S.begin();
01742           i_it != B_S.end();
01743           ++i_it,                ++v_it                ) {
01744     if ( ! slack_A[ *i_it - qp_n].second) *v_it = -(*v_it);
01745   }
01746 }
01747 
01748 // update
01749 // ------
01750 template < typename Q, typename ET, typename Tags >  inline                                 // LP case
01751 void  QP_solver<Q, ET, Tags>::
01752 update_1( Tag_true)
01753 {
01754   // replace leaving with entering variable
01755   if ((i == j) && (i >= 0)) {
01756     enter_and_leave_variable();
01757   } else {
01758     replace_variable();
01759   }
01760 }
01761 
01762 template < typename Q, typename ET, typename Tags >  inline                                 // QP case
01763 void  QP_solver<Q, ET, Tags>::
01764 update_1( Tag_false)
01765 {
01766   if ( is_phaseI) {                                   // phase I
01767 
01768     // replace leaving with entering variable
01769     if ((i == j) && (i >= 0)) {
01770       enter_and_leave_variable();
01771     } else {
01772       replace_variable();
01773     }
01774 
01775   } else {                                            // phase II
01776         
01777     if ((i == j) && (i >= 0)) {
01778       enter_and_leave_variable();
01779     } else {
01780 
01781       if ( ( i >= 0) && basis_matrix_stays_regular()) {
01782 
01783         // leave variable from basis, if
01784         // - some leaving variable was found  and
01785         // - basis matrix stays regular
01786         leave_variable();
01787 
01788       } else {
01789 
01790         // enter variable into basis, if
01791         // - no leaving variable was found  or
01792         // - basis matrix would become singular when variable i leaves
01793 
01794         if ( i < 0 ) {
01795           enter_variable();
01796         } else {
01797           z_replace_variable();
01798         }
01799       }
01800     }
01801   }
01802 }
01803 
01804 template < typename Q, typename ET, typename Tags >  inline                                 // LP case
01805 void  QP_solver<Q, ET, Tags>::
01806 update_2( Tag_true)
01807 {
01808   // nop
01809 }
01810 
01811 template < typename Q, typename ET, typename Tags >  inline                                 // no ineq.
01812 void  QP_solver<Q, ET, Tags>::
01813 replace_variable( Tag_true)
01814 {
01815   replace_variable_original_original();
01816   strategyP->leaving_basis( i);
01817 }
01818 
01819 template < typename Q, typename ET, typename Tags >  inline                                 // has ineq.
01820 void  QP_solver<Q, ET, Tags>::
01821 replace_variable( Tag_false)
01822 {
01823   // determine type of variables
01824   bool  enter_original = ( (j < qp_n) || (j >= (int)( qp_n+slack_A.size())));
01825   bool  leave_original = ( (i < qp_n) || (i >= (int)( qp_n+slack_A.size())));
01826 
01827   // update basis & basis inverse
01828   if ( leave_original) {
01829     if ( enter_original) {                              // orig  <--> orig
01830       replace_variable_original_original();
01831     } else {                                            // slack <--> orig
01832       replace_variable_slack_original();
01833     }
01834 
01835     // special artificial variable removed?
01836     if ( is_phaseI && ( i == art_s_i)) {
01837       // remove the fake column - it corresponds
01838       // to the special artificial variable which is
01839       // (like all artificial variables) not needed
01840       // anymore once it leaves the basis. Note:
01841       // regular artificial variables are only removed
01842       // from the problem after phase I
01843       // art_s_i == -1 -> there is no special artificial variable
01844       // art_s_i == -2 -> there was a special artificial variable, 
01845       // but has been removed  
01846       art_s_i = -2;
01847       art_A.pop_back();
01848       CGAL_qpe_assertion(in_B[in_B.size()-1] == -1); // really removed?
01849       in_B.pop_back();
01850       // BG: shouldn't the pricing strategy be notfied also here?
01851     } else {
01852       strategyP->leaving_basis( i);
01853     }
01854   } else {
01855     if ( enter_original) {                              // orig  <--> slack
01856       replace_variable_original_slack();
01857     } else {                                            // slack <--> slack
01858       replace_variable_slack_slack();
01859     }
01860     strategyP->leaving_basis( i);
01861   }
01862 }
01863 
01864 template < typename Q, typename ET, typename Tags >  inline
01865 bool  QP_solver<Q, ET, Tags>::
01866 basis_matrix_stays_regular()
01867 {
01868   CGAL_qpe_assertion( is_phaseII);
01869   int new_row, k;
01870     
01871   if ( has_ineq && (i >= qp_n)) {       // slack variable
01872     new_row = slack_A[ i-qp_n].first;
01873     A_row_by_index_accessor  a_accessor =
01874       boost::bind (A_accessor( qp_A, 0, qp_n), _1, new_row);
01875     std::copy( A_row_by_index_iterator( B_O.begin(), a_accessor),
01876                A_row_by_index_iterator( B_O.end  (), a_accessor),
01877                tmp_x.begin());     
01878     inv_M_B.multiply( tmp_x.begin(),                        // dummy (not used)
01879                       tmp_x.begin(), tmp_l_2.begin(), tmp_x_2.begin(),
01880                       Tag_false(),                                 // QP
01881                       Tag_false());                             // ignore 1st argument
01882     return ( -inv_M_B.inner_product_x( tmp_x_2.begin(), tmp_x.begin()) != et0);
01883 
01884         
01885   } else {                                              // check original variable
01886     k = l+in_B[ i];
01887     return ( inv_M_B.entry( k, k) != et0);
01888   }
01889 
01890   /* ToDo: check, if really not needed in 'update_1':
01891      - basis has already minimal size  or
01892      || ( B_O.size()==C.size()) 
01893   */
01894 }
01895 
01896 // current solution
01897 // ----------------
01898 template < typename Q, typename ET, typename Tags >  inline             // no inequalities, upper bounded
01899 void  QP_solver<Q, ET, Tags>::
01900 compute__x_B_S( Tag_true  /*has_equalities_only_and_full_rank*/,
01901                 Tag_false /*is_nonnegative*/)
01902 {
01903   // nop
01904 }
01905 
01906 template < typename Q, typename ET, typename Tags >  inline             // no inequalities, standard form
01907 void  QP_solver<Q, ET, Tags>::
01908 compute__x_B_S( Tag_true /*has_equalities_only_and_full_rank*/,
01909                 Tag_true /*is_nonnegative*/)
01910 {
01911   // nop
01912 }
01913 
01914 
01915 template < typename Q, typename ET, typename Tags >  inline             // has inequalities, upper bounded
01916 void  QP_solver<Q, ET, Tags>::
01917 compute__x_B_S( Tag_false /*has_equalities_only_and_full_rank*/,
01918                 Tag_false /*is_nonnegative*/)
01919 {
01920   // A_S_BxB_O * x_B_O
01921   multiply__A_S_BxB_O( x_B_O.begin(), x_B_S.begin());
01922 
01923   // b_S_B - ( A_S_BxB_O * x_B_O)
01924   B_by_index_accessor  b_accessor( qp_b);
01925   std::transform( B_by_index_iterator( S_B.begin(), b_accessor),
01926                   B_by_index_iterator( S_B.end  (), b_accessor),
01927                   x_B_S.begin(),
01928                   x_B_S.begin(),
01929                   compose2_2( std::minus<ET>(),
01930                               std::bind1st( std::multiplies<ET>(), d),
01931                               Identity<ET>()));
01932                                 
01933   // b_S_B - ( A_S_BxB_O * x_B_O) - r_S_B
01934   std::transform(x_B_S.begin(), x_B_S.begin()+S_B.size(),
01935                  r_S_B.begin(), x_B_S.begin(),
01936                  compose2_2(std::minus<ET>(),
01937                             Identity<ET>(),
01938                             std::bind1st( std::multiplies<ET>(), d)));
01939                         
01940 
01941   // x_B_S = +- ( b_S_B - A_S_BxB_O * x_B_O)
01942   Value_iterator  x_it = x_B_S.begin();
01943   Index_iterator  i_it;
01944   for ( i_it = B_S.begin(); i_it != B_S.end(); ++i_it, ++x_it) {
01945     if ( slack_A[ *i_it - qp_n].second) *x_it = -(*x_it);
01946   }
01947        
01948 }
01949 
01950 
01951 
01952 template < typename Q, typename ET, typename Tags >  inline             // has inequalities, standard form
01953 void  QP_solver<Q, ET, Tags>::
01954 compute__x_B_S( Tag_false /*has_equalities_only_and_full_rank*/,
01955                 Tag_true  /*is_nonnegative*/)
01956 {
01957   // A_S_BxB_O * x_B_O
01958   multiply__A_S_BxB_O( x_B_O.begin(), x_B_S.begin());
01959 
01960   // b_S_B - ( A_S_BxB_O * x_B_O)
01961   B_by_index_accessor  b_accessor( qp_b);
01962   std::transform( B_by_index_iterator( S_B.begin(), b_accessor),
01963                   B_by_index_iterator( S_B.end  (), b_accessor),
01964                   x_B_S.begin(),
01965                   x_B_S.begin(),
01966                   compose2_2( std::minus<ET>(),
01967                               std::bind1st( std::multiplies<ET>(), d),
01968                               Identity<ET>()));
01969 
01970   // x_B_S = +- ( b_S_B - A_S_BxB_O * x_B_O)
01971   Value_iterator  x_it = x_B_S.begin();
01972   Index_iterator  i_it;
01973   for ( i_it = B_S.begin(); i_it != B_S.end(); ++i_it, ++x_it) {
01974     if ( slack_A[ *i_it - qp_n].second) *x_it = -(*x_it);
01975   }
01976        
01977 }
01978 
01979 CGAL_END_NAMESPACE
01980 
01981 #include <CGAL/QP_solver/Unbounded_direction.h>
01982 #include <CGAL/QP_solver/QP_solver_nonstandardform_impl.h>
01983 #include <CGAL/QP_solver/QP_solver_bounds_impl.h>
01984 #include <CGAL/QP_solver/QP_solver_impl.h>
01985 
01986 #endif // CGAL_QP_SOLVER_H
01987 
01988 // ===== EOF ==================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines