BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/QP_models.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 // Licensees 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_models.h $
00015 // $Id: QP_models.h 46451 2008-10-23 14:31:10Z gaertner $
00016 // 
00017 //
00018 // Author(s)     : Bernd Gaertner <gaertner@inf.ethz.ch>, Kaspar Fischer
00019 
00020 #ifndef CGAL_QP_MODELS_H
00021 #define CGAL_QP_MODELS_H
00022 
00023 #include <CGAL/basic.h>
00024 #include <CGAL/iterator.h>
00025 #include <CGAL/algorithm.h>
00026 #include <CGAL/QP_solver/basic.h>
00027 #include <CGAL/QP_solver/functors.h>
00028 #include <vector> 
00029 #include <map>
00030 #include <iomanip>
00031 #include <istream>
00032 #include <sstream>
00033 #include <boost/iterator/counting_iterator.hpp>
00034 #include <boost/iterator/transform_iterator.hpp>
00035 
00036 // this file defines the following models:
00037 // - Quadratic_program_from_iterators
00038 // - Quadratic_program
00039 // - Quadratic_program_from_mps
00040 // - Nonngative_quadratic_program_from_iterators
00041 // - Linear_program_from_iterators
00042 // - Nonngative_linear_program_from_iterators
00043 
00044 // for convenience, every model is actually a model of the
00045 // concept QuadraticProgramInterface:
00046 #define QP_MODEL_ITERATOR_TYPES \
00047   typedef typename Base::A_iterator A_iterator;\
00048   typedef typename Base::B_iterator B_iterator;\
00049   typedef typename Base::R_iterator R_iterator;\
00050   typedef typename Base::FL_iterator FL_iterator;\
00051   typedef typename Base::L_iterator L_iterator;\
00052   typedef typename Base::FU_iterator FU_iterator;\
00053   typedef typename Base::U_iterator U_iterator;\
00054   typedef typename Base::D_iterator D_iterator;\
00055   typedef typename Base::C_iterator C_iterator;\
00056   typedef typename Base::C_entry C_entry
00057 CGAL_BEGIN_NAMESPACE
00058 
00059 // default iterator types to used to make linear / nonnegative models
00060 // conform to QuadraticProgramInterface
00061 template <class Iterator>
00062 class QP_model_default_iterators {
00063 private:
00064   typedef typename std::iterator_traits<Iterator>::value_type value_type;
00065 public:
00066   typedef Const_oneset_iterator<value_type> 
00067   It_1d; // 1-dimensional random access iterator for a constant value
00068   typedef Const_oneset_iterator<Const_oneset_iterator<value_type> > 
00069   It_2d; // 2-dimensional random access iterator for a constant value
00070 };
00071 
00072 // Quadratic_program_from_iterators
00073 // --------------------------------
00074 // this is the base class for all non-mps models
00075 template <
00076   typename A_it,   // for constraint matrix A (columnwise)
00077   typename B_it,   // for right-hand side b 
00078   typename R_it,   // for relations (value type Comparison)
00079   typename FL_it,  // for finiteness of lower bounds (value type bool)
00080   typename L_it,   // for lower bounds
00081   typename FU_it,  // for finiteness of upper bounds (value type bool)
00082   typename U_it,   // for upper bounds
00083   typename D_it,   // for quadratic matrix D (rowwise)
00084   typename C_it >  // for objective function c
00085 class Quadratic_program_from_iterators 
00086 {
00087 public:
00088   // types
00089   typedef A_it   A_iterator;
00090   typedef B_it   B_iterator; 
00091   typedef R_it   R_iterator;
00092   typedef FL_it  FL_iterator;
00093   typedef L_it   L_iterator;
00094   typedef FU_it  FU_iterator;
00095   typedef U_it   U_iterator;  
00096   typedef D_it   D_iterator;
00097   typedef C_it   C_iterator;
00098   typedef typename std::iterator_traits<C_it>::value_type C_entry;
00099 protected:
00100   // data
00101   int n_;
00102   int m_;
00103   A_iterator a_it;
00104   B_iterator b_it; 
00105   R_iterator r_it;
00106   FL_iterator fl_it;
00107   L_iterator l_it;
00108   FU_iterator fu_it;
00109   U_iterator u_it; 
00110   D_iterator d_it;
00111   C_iterator c_it;
00112   C_entry c_0; // constant term
00113 public:
00114   // construction
00115   Quadratic_program_from_iterators (
00116      int n, int m, // number of variables / constraints
00117      const A_iterator& a, 
00118      const B_iterator& b,
00119      const R_iterator& r,
00120      const FL_iterator& fl,
00121      const L_iterator& l,
00122      const FU_iterator& fu,
00123      const U_iterator& u,
00124      const D_iterator& d,
00125      const C_iterator& c,
00126      const C_entry& c0 = C_entry(0))
00127     : n_ (n), m_ (m), a_it (a), b_it (b), r_it (r), fl_it (fl), l_it (l), 
00128       fu_it (fu), u_it (u), d_it (d), c_it (c), c_0 (c0)    
00129   {}
00130 
00131   // access
00132   int get_n() const {return n_;}
00133   int get_m() const {return m_;}
00134   A_iterator get_a() const {return a_it;}
00135   B_iterator get_b() const {return b_it;}
00136   R_iterator get_r() const {return r_it;}  
00137   FL_iterator get_fl() const {return fl_it;}
00138   L_iterator get_l() const {return l_it;}
00139   FU_iterator get_fu() const {return fu_it;}
00140   U_iterator get_u() const {return u_it;}
00141   D_iterator get_d() const {return d_it;}
00142   C_iterator get_c() const {return c_it;}
00143   C_entry get_c0() const {return c_0;}
00144 };
00145 
00146 // corresponding global function make_quadratic_program_from_iterators
00147 // -------------------------------------------------------------------
00148 template <
00149   typename A_it,   // for constraint matrix A (columnwise)
00150   typename B_it,   // for right-hand side b 
00151   typename R_it,   // for relations (value type Comparison)
00152   typename FL_it,  // for finiteness of lower bounds (value type bool)
00153   typename L_it,   // for lower bounds
00154   typename FU_it,  // for finiteness of upper bounds (value type bool)
00155   typename U_it,   // for upper bounds
00156   typename D_it,   // for quadratic matrix D (rowwise)
00157   typename C_it >  // for objective function c
00158 Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>
00159 make_quadratic_program_from_iterators (
00160    int n, int m, 
00161    const A_it& a, 
00162    const B_it& b, 
00163    const R_it& r, 
00164    const FL_it& fl, 
00165    const L_it& l,
00166    const FU_it& fu, 
00167    const U_it& u, 
00168    const D_it& d, 
00169    const C_it& c, 
00170    typename std::iterator_traits<C_it>::value_type c0 = 
00171    typename std::iterator_traits<C_it>::value_type(0))
00172 {
00173   return Quadratic_program_from_iterators
00174     <A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>
00175     (n, m, a, b, r, fl, l, fu, u, d, c, c0);
00176 }       
00177 
00178 
00179 // Linear_program_from_iterators
00180 // -----------------------------
00181 template <
00182   typename A_it,   // for constraint matrix A (columnwise)
00183   typename B_it,   // for right-hand side b 
00184   typename R_it,   // for relations (value type Comparison)
00185   typename FL_it,  // for finiteness of lower bounds (value type bool)
00186   typename L_it,   // for lower bounds
00187   typename FU_it,  // for finiteness of upper bounds (value type bool)
00188   typename U_it,   // for upper bounds
00189   typename C_it >  // for objective function c
00190 class Linear_program_from_iterators : 
00191   public Quadratic_program_from_iterators 
00192 <A_it, B_it, R_it, FL_it, L_it, FU_it, U_it,
00193  typename QP_model_default_iterators<C_it>::It_2d, C_it>
00194 {
00195 private:
00196   typedef Quadratic_program_from_iterators 
00197   <A_it, B_it, R_it, FL_it, L_it, FU_it, U_it,
00198    typename QP_model_default_iterators<C_it>::It_2d, C_it> Base;
00199   typedef typename QP_model_default_iterators<C_it>::It_2d Const_D_iterator;
00200 public:
00201    QP_MODEL_ITERATOR_TYPES;
00202    Linear_program_from_iterators (
00203                      int n, int m, // number of variables / constraints
00204                      const A_iterator& a, 
00205                      const B_iterator& b,
00206                      const R_iterator& r,
00207                      const FL_iterator& fl,
00208                      const L_iterator& l,
00209                      const FU_iterator& fu,
00210                      const U_iterator& u,
00211                      const C_iterator& c,
00212                      const C_entry& c0 = C_entry(0)
00213                      )
00214     : Base (n, m, a, b, r, fl, l, fu, u, 
00215             Const_D_iterator(C_entry(0)), c, c0)
00216   {}  
00217 }; 
00218 
00219 // corresponding global function make_linear_program_from_iterators
00220 // ----------------------------------------------------------------
00221 template <
00222   typename A_it,   // for constraint matrix A (columnwise)
00223   typename B_it,   // for right-hand side b 
00224   typename R_it,   // for relations (value type Comparison)
00225   typename FL_it,  // for finiteness of lower bounds (value type bool)
00226   typename L_it,   // for lower bounds
00227   typename FU_it,  // for finiteness of upper bounds (value type bool)
00228   typename U_it,   // for upper bounds
00229   typename C_it >  // for objective function c
00230 Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>
00231 make_linear_program_from_iterators (
00232    int n, int m, 
00233    const A_it& a, 
00234    const B_it& b, 
00235    const R_it& r, 
00236    const FL_it& fl, 
00237    const L_it& l,
00238    const FU_it& fu, 
00239    const U_it& u, 
00240    const C_it& c, 
00241    typename std::iterator_traits<C_it>::value_type c0 =
00242    typename std::iterator_traits<C_it>::value_type(0))
00243 {
00244   return Linear_program_from_iterators
00245     <A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>
00246     (n, m, a, b, r, fl, l, fu, u, c, c0);
00247 }       
00248 
00249 
00250 // Nonnegative_quadratic_program_from_iterators
00251 // --------------------------------------------
00252 template <
00253   typename A_it,   // for constraint matrix A (columnwise)
00254   typename B_it,   // for right-hand side b 
00255   typename R_it,   // for relations (value type Comparison)
00256   typename D_it,   // for quadratic matrix D (rowwise)
00257   typename C_it >  // for objective function c
00258 class Nonnegative_quadratic_program_from_iterators : 
00259   public Quadratic_program_from_iterators <A_it, B_it, R_it, 
00260      typename QP_model_default_iterators<bool*>::It_1d, 
00261      typename QP_model_default_iterators<C_it>::It_1d,
00262      typename QP_model_default_iterators<bool*>::It_1d, 
00263      typename QP_model_default_iterators<C_it>::It_1d,
00264      D_it, C_it>
00265 {
00266 private:
00267   typedef  Quadratic_program_from_iterators <A_it, B_it, R_it, 
00268      typename QP_model_default_iterators<bool*>::It_1d, 
00269      typename QP_model_default_iterators<C_it>::It_1d,
00270      typename QP_model_default_iterators<bool*>::It_1d, 
00271      typename QP_model_default_iterators<C_it>::It_1d,
00272      D_it, C_it> Base;
00273   typedef typename QP_model_default_iterators<bool*>::It_1d Const_FLU_iterator;
00274   typedef typename QP_model_default_iterators<C_it>::It_1d Const_LU_iterator;
00275 public:
00276    QP_MODEL_ITERATOR_TYPES;
00277    Nonnegative_quadratic_program_from_iterators (
00278                      int n, int m, // number of variables / constraints
00279                      const A_iterator& a, 
00280                      const B_iterator& b,
00281                      const R_iterator& r,                    
00282                      const D_iterator& d,
00283                      const C_iterator& c,
00284                      const C_entry& c0 = C_entry(0)
00285                      )
00286     : Base (n, m, a, b, r, 
00287             Const_FLU_iterator(true), Const_LU_iterator(C_entry(0)), 
00288             Const_FLU_iterator(false), Const_LU_iterator(C_entry(0)), 
00289             d, c, c0)
00290   {}  
00291 };
00292 
00293 // corresponding global function 
00294 // make_nonnegative_quadratic_program_from_iterators
00295 // -------------------------------------------------
00296 template <
00297   typename A_it,   // for constraint matrix A (columnwise)
00298   typename B_it,   // for right-hand side b 
00299   typename R_it,   // for relations (value type Comparison)
00300   typename D_it,   // for quadratic matrix D (rowwise)
00301   typename C_it >  // for objective function c
00302 Nonnegative_quadratic_program_from_iterators
00303 <A_it, B_it, R_it, D_it, C_it>
00304 make_nonnegative_quadratic_program_from_iterators (
00305    int n, int m, 
00306    const A_it& a, 
00307    const B_it& b, 
00308    const R_it& r, 
00309    const D_it& d, 
00310    const C_it& c, 
00311    typename std::iterator_traits<C_it>::value_type c0 =
00312    typename std::iterator_traits<C_it>::value_type(0))
00313 {
00314   return Nonnegative_quadratic_program_from_iterators
00315     <A_it, B_it, R_it, D_it, C_it>
00316     (n, m, a, b, r, d, c, c0);
00317 }       
00318 
00319 
00320 // Nonnegative_linear_program_from_iterators
00321 // -----------------------------------------
00322 template <
00323   typename A_it,   // for constraint matrix A (columnwise)
00324   typename B_it,   // for right-hand side b 
00325   typename R_it,   // for relations (value type Comparison)
00326   typename C_it >  // for objective function c
00327 class Nonnegative_linear_program_from_iterators : 
00328   public Quadratic_program_from_iterators <A_it, B_it, R_it, 
00329      typename QP_model_default_iterators<bool*>::It_1d, 
00330      typename QP_model_default_iterators<C_it>::It_1d,
00331      typename QP_model_default_iterators<bool*>::It_1d, 
00332      typename QP_model_default_iterators<C_it>::It_1d,
00333      typename QP_model_default_iterators<C_it>::It_2d, C_it>
00334 {
00335 private:
00336   typedef Quadratic_program_from_iterators <A_it, B_it, R_it, 
00337      typename QP_model_default_iterators<bool*>::It_1d, 
00338      typename QP_model_default_iterators<C_it>::It_1d,
00339      typename QP_model_default_iterators<bool*>::It_1d, 
00340      typename QP_model_default_iterators<C_it>::It_1d,
00341      typename QP_model_default_iterators<C_it>::It_2d, C_it> Base;
00342   typedef typename QP_model_default_iterators<bool*>::It_1d Const_FLU_iterator;
00343   typedef typename QP_model_default_iterators<C_it>::It_1d Const_LU_iterator;
00344   typedef typename QP_model_default_iterators<C_it>::It_2d Const_D_iterator;
00345 public:
00346    QP_MODEL_ITERATOR_TYPES;
00347    Nonnegative_linear_program_from_iterators (
00348                      int n, int m, // number of variables / constraints
00349                      const A_iterator& a, 
00350                      const B_iterator& b,
00351                      const R_iterator& r,                    
00352                      const C_iterator& c,
00353                      const C_entry& c0 = C_entry(0)
00354                      )
00355     : Base (n, m, a, b, r, 
00356             Const_FLU_iterator(true), Const_LU_iterator(C_entry(0)), 
00357             Const_FLU_iterator(false), Const_LU_iterator(C_entry(0)), 
00358             Const_D_iterator(C_entry(0)), c, c0)
00359   {}  
00360 }; 
00361 
00362 // corresponding global function 
00363 // make_nonnegative_linear_program_from_iterators
00364 // ----------------------------------------------
00365 template <
00366   typename A_it,   // for constraint matrix A (columnwise)
00367   typename B_it,   // for right-hand side b 
00368   typename R_it,   // for relations (value type Comparison)
00369   typename C_it >  // for objective function c
00370 Nonnegative_linear_program_from_iterators
00371 <A_it, B_it, R_it, C_it>
00372 make_nonnegative_linear_program_from_iterators (
00373    int n, int m, 
00374    const A_it& a, 
00375    const B_it& b, 
00376    const R_it& r, 
00377    const C_it& c, 
00378    typename std::iterator_traits<C_it>::value_type c0 =
00379    typename std::iterator_traits<C_it>::value_type(0))
00380 {
00381   return Nonnegative_linear_program_from_iterators
00382     <A_it, B_it, R_it, C_it>
00383     (n, m, a, b, r, c, c0);
00384 }
00385         
00386 
00387 namespace QP_model_detail {
00388   // maps a container to its begin-iterator, as specified by HowToBegin
00389   template<typename Container, typename Iterator, typename HowToBegin>
00390   struct Begin
00391     : public std::unary_function< Container, Iterator >
00392   {
00393     typedef Iterator result_type;
00394     result_type operator () ( const Container& v) const 
00395     { 
00396       return HowToBegin()(v); 
00397     }
00398   };
00399 }
00400 
00401 // Quadratic_program
00402 // -----------------
00403 // sparse representation, entries can be set one by one, overriding
00404 // defaults;
00405 template <typename NT_>
00406 class Quadratic_program
00407 {
00408 public:
00409   typedef NT_ NT;
00410 private:
00411   // Sparse_vectors
00412   typedef std::map<int, NT>                   
00413   Sparse_vector;
00414   typedef std::map<int, CGAL::Comparison_result>
00415   Sparse_r_vector;
00416   typedef std::map<int, bool>                   
00417   Sparse_f_vector;
00418 
00419   // Sparse_matrix
00420   typedef std::vector<Sparse_vector>                  
00421   Sparse_matrix;   
00422 
00423   // Sparse_vector_iterators
00424   //typedef CGAL::Fake_random_access_const_iterator<Sparse_vector> 
00425   typedef boost::transform_iterator<CGAL::Map_with_default<Sparse_vector>,
00426                                     boost::counting_iterator<int> >
00427   Sparse_vector_iterator;  
00428   typedef boost::transform_iterator<CGAL::Map_with_default<Sparse_r_vector>,
00429                                     boost::counting_iterator<int> >
00430   Sparse_r_vector_iterator;
00431   typedef boost::transform_iterator<CGAL::Map_with_default<Sparse_f_vector>,
00432                                     boost::counting_iterator<int> >
00433   Sparse_f_vector_iterator;
00434 
00435   // Sparse_matrix_iterator
00436   struct HowToBegin
00437   {
00438     Sparse_vector_iterator operator() (const Sparse_vector& v) const
00439     { return Sparse_vector_iterator
00440         (boost::counting_iterator<int>(0),
00441          CGAL::Map_with_default<Sparse_vector>(&v, NT(0)));}
00442   };
00443 
00444   typedef QP_model_detail::Begin
00445   <Sparse_vector, Sparse_vector_iterator, HowToBegin> Beginner;
00446   typedef boost::transform_iterator
00447   <Beginner, typename Sparse_matrix::const_iterator>
00448   Sparse_matrix_iterator;
00449   
00450   // program data; we maintain the invariant that only the 
00451   // non-default elements are stored; this means that entries
00452   // may get removed again, and n_, m_ might be larger than
00453   // absolutely needed; we also maintain the invariants that
00454   // a_matrix and d_matrix always have n_ elements
00455 
00456   int                                  n_; 
00457   int                                  m_;
00458   Sparse_matrix                        a_matrix;
00459   Sparse_vector                        b_vector;
00460   Sparse_r_vector                      r_vector;
00461   Sparse_f_vector                      fl_vector;
00462   Sparse_vector                        l_vector;
00463   Sparse_f_vector                      fu_vector;
00464   Sparse_vector                        u_vector;
00465   Sparse_vector                        c_vector;  
00466   Sparse_matrix                        d_matrix;
00467   NT                                   c0_;
00468 
00469   // default settings
00470   CGAL::Comparison_result              default_r;   // from constructor
00471   bool                                 default_fl;  // from constructor
00472   NT                                   default_l;   // from constructor
00473   bool                                 default_fu;  // from constructor
00474   NT                                   default_u;   // from constructor
00475 protected: 
00476   bool                                 is_valid_;
00477 private:
00478   std::string                          error_msg;
00479 
00480   // methods
00481   // enlarges a_matrix, d_matrix to size s, under the
00482   // precondition that the previous sizes were smaller
00483   void grow_a_d (int s) 
00484   {
00485     CGAL_qpe_assertion( a_matrix.size() == d_matrix.size() );
00486     CGAL_qpe_assertion( a_matrix.size() < (unsigned int)s);
00487     for (int k = a_matrix.size(); k < s; ++k) {
00488       a_matrix.push_back(Sparse_vector());
00489       d_matrix.push_back(Sparse_vector());
00490     }
00491   }
00492 
00493 public:
00494   // interface types  
00495   typedef Sparse_matrix_iterator                     A_iterator;
00496   typedef Sparse_vector_iterator                     B_iterator;
00497   typedef Sparse_r_vector_iterator                   R_iterator;
00498   typedef Sparse_f_vector_iterator                   FL_iterator;
00499   typedef Sparse_vector_iterator                     L_iterator;
00500   typedef Sparse_f_vector_iterator                   FU_iterator;
00501   typedef Sparse_vector_iterator                     U_iterator;
00502   typedef Sparse_vector_iterator                     C_iterator;
00503   typedef Sparse_matrix_iterator                     D_iterator;
00504   typedef NT                                         C_entry;
00505 
00506   // concept methods
00507   int get_n() const 
00508   { 
00509     CGAL_qpe_assertion(is_valid());
00510     return n_;
00511   }
00512   int get_m() const  
00513   { 
00514     CGAL_qpe_assertion(is_valid());
00515     return m_;
00516   }
00517   A_iterator get_a() const    
00518   { 
00519     CGAL_qpe_assertion(is_valid());
00520     return A_iterator (a_matrix.begin(), Beginner());
00521   }
00522   B_iterator get_b() const    
00523   { 
00524     CGAL_qpe_assertion(is_valid());
00525     return B_iterator (boost::counting_iterator<int>(0),
00526                         CGAL::Map_with_default<Sparse_vector>
00527                        (&b_vector, NT(0)));
00528   }
00529   R_iterator get_r() const    
00530   { 
00531     CGAL_qpe_assertion(is_valid());
00532     return R_iterator (boost::counting_iterator<int>(0),
00533                         CGAL::Map_with_default<Sparse_r_vector>
00534                        (&r_vector, default_r));
00535   }
00536   FL_iterator get_fl() const  
00537   { 
00538     CGAL_qpe_assertion(is_valid());
00539     return FL_iterator (boost::counting_iterator<int>(0),
00540                         CGAL::Map_with_default<Sparse_f_vector>
00541                         (&fl_vector, default_fl)); 
00542   }
00543   L_iterator get_l() const    
00544   { 
00545     CGAL_qpe_assertion(is_valid());
00546     return L_iterator (boost::counting_iterator<int>(0),
00547                         CGAL::Map_with_default<Sparse_vector>
00548                        (&l_vector, default_l));
00549   }
00550   FU_iterator get_fu() const  
00551   {
00552     CGAL_qpe_assertion(is_valid());
00553     return FU_iterator (boost::counting_iterator<int>(0),
00554                         CGAL::Map_with_default<Sparse_f_vector>
00555                         (&fu_vector, default_fu));
00556   }
00557   U_iterator get_u() const    
00558   { 
00559     CGAL_qpe_assertion(is_valid());
00560     return U_iterator (boost::counting_iterator<int>(0),
00561                         CGAL::Map_with_default<Sparse_vector>
00562                        (&u_vector, default_u));
00563   }
00564   C_iterator get_c() const    
00565   { 
00566     CGAL_qpe_assertion(is_valid());
00567     return C_iterator (boost::counting_iterator<int>(0),
00568                         CGAL::Map_with_default<Sparse_vector>
00569                        (&c_vector, NT(0)));
00570   }
00571   D_iterator get_d() const    
00572   { 
00573     CGAL_qpe_assertion(is_valid());
00574     return D_iterator (d_matrix.begin(), Beginner());
00575   }
00576   C_entry get_c0() const 
00577   { 
00578     CGAL_qpe_assertion(is_valid());
00579     return c0_;
00580   }
00581 
00582   bool is_valid() const
00583   {
00584     return is_valid_;
00585   }
00586 
00587   const std::string& get_error() const
00588   {
00589     CGAL_qpe_assertion(!is_valid());
00590     return error_msg;
00591   }
00592 
00593   // default constructor
00594   Quadratic_program 
00595   (CGAL::Comparison_result relation = CGAL::EQUAL,
00596    bool finite_lower = true,
00597    NT lower = 0,
00598    bool finite_upper = false,
00599    NT upper = 0) 
00600     : n_(0), m_(0), c0_(0), 
00601       default_r(relation), default_fl(finite_lower),
00602       default_l(lower), default_fu(finite_upper), 
00603       default_u(upper), is_valid_(true) 
00604   {
00605     CGAL_qpe_assertion(!finite_lower || !finite_upper || lower <= upper);
00606   }
00607 
00608 
00609   // constructor from iterators
00610   template <typename A_it, typename B_it, typename R_it, typename FL_it, 
00611             typename L_it, typename FU_it, typename U_it, typename D_it, 
00612             typename C_it>
00613   Quadratic_program
00614   (
00615    int n, int m, // number of variables / constraints
00616    const A_it& a, 
00617    const B_it& b,
00618    const R_it& r,
00619    const FL_it& fl,
00620    const L_it& l,
00621    const FU_it& fu,
00622    const U_it& u,
00623    const D_it& d,
00624    const C_it& c,
00625    const typename std::iterator_traits<C_it>::value_type& c0 = 0) 
00626     : n_(0), m_(0), c0_(0), 
00627       default_r(CGAL::EQUAL), default_fl(true),
00628       default_l(0), default_fu(false), default_u(0), is_valid_(true)
00629   {
00630     // now copy, using the set methods
00631     for (int j=0; j<n; ++j) {
00632       for (int i=0; i<m; ++i) 
00633         set_a (j, i, (*(a+j))[i]);
00634       set_l (j, *(fl+j), *(l+j));
00635       set_u (j, *(fu+j), *(u+j));
00636       set_c (j, *(c+j));
00637     }
00638     for (int i=0; i<m; ++i) {
00639       set_b (i, *(b+i));
00640       set_r (i, *(r+i));
00641     }
00642     for (int i=0; i<n; ++i)
00643       for (int j=0; j<=i; ++j)
00644         set_d (i, j, (*(d+i))[j]);
00645     set_c0 (c0);
00646   }
00647 
00648   // type of problem
00649   bool is_linear() const
00650   {
00651     CGAL_qpe_assertion(d_matrix.size() == (unsigned int)(n_));
00652     for (int i=0; i<n_; ++i)
00653       if (!d_matrix[i].empty()) return false;
00654     return true;
00655   }
00656 
00657 private:
00658   // helpers to determine bound status
00659   // checks whether all bounds in flu are as given by the parameter "finite"
00660   // default_flu is the default-value of the underlying map that is not 
00661   // stored
00662   bool all_bounds_are
00663   (bool finite, const Sparse_f_vector& flu, bool default_flu) const
00664   {
00665     if (finite == default_flu)
00666       return flu.empty();
00667     else
00668       // are there exactly n non-default values "finite"?
00669       return flu.size() == (unsigned int)(n_);
00670   }
00671 
00672   bool all_bounds_are_zero 
00673   // checks whether all bounds in lu are 0. default_lu is the default-value 
00674   // of the underlying map that is not stored
00675   (const Sparse_vector& lu, const NT& default_lu) const
00676   {
00677     if (CGAL::is_zero(default_lu))
00678       return lu.empty();
00679     else {
00680       // are there exactly n non-default values?
00681       if (lu.size() != (unsigned int)(n_)) return false;
00682       // ok, we have to test each of the non-default values against zero
00683       for (typename Sparse_vector::const_iterator 
00684              j = lu.begin(); j != lu.end(); ++j)
00685         if (!CGAL::is_zero(j->second)) return false;
00686       return true;
00687     }
00688   }
00689   
00690 public:
00691 
00692   bool is_nonnegative() const
00693   {
00694     return 
00695       all_bounds_are (true, fl_vector, default_fl) &&
00696       all_bounds_are_zero (l_vector, default_l) &&
00697       all_bounds_are (false, fu_vector, default_fu);
00698   }
00699 
00700   bool is_nonpositive() const
00701   {
00702      return 
00703       all_bounds_are (false, fl_vector, default_fl) &&
00704       all_bounds_are_zero (u_vector, default_u) &&
00705       all_bounds_are (true, fu_vector, default_fu);
00706   }
00707 
00708   bool is_free() const
00709   {
00710     return 
00711       all_bounds_are (false, fl_vector, default_fl) &&
00712       all_bounds_are (false, fu_vector, default_fu);
00713   }
00714 
00715   // set methods
00716   void set_a (int j, int i, const NT& val) 
00717   { 
00718     CGAL_qpe_assertion (j >= 0); 
00719     CGAL_qpe_assertion (i >= 0);    
00720     if (j >= n_) {
00721       n_ = j+1;  
00722       grow_a_d(n_);
00723     }
00724     if (i >= m_) m_ = i+1;
00725     if (CGAL::is_zero(val))
00726       a_matrix[j].erase(i);
00727     else
00728       a_matrix[j][i] = val;
00729   }
00730 
00731   void set_b (int i,  const NT& val)
00732   {
00733     CGAL_qpe_assertion (i >= 0);
00734     if (i >= m_) m_ = i+1;    
00735     if (CGAL::is_zero(val)) 
00736       b_vector.erase(i);
00737     else
00738       b_vector[i] = val;
00739   }
00740 
00741   void set_r (int i, CGAL::Comparison_result val)
00742   {    
00743     CGAL_qpe_assertion (i >= 0); 
00744     if (i >= m_) m_ = i+1;        
00745     if (val == default_r)
00746       r_vector.erase(i);
00747     else
00748       r_vector[i] = val;
00749   }
00750 
00751   void set_l (int j, bool is_finite, const NT& val = NT(0))
00752   {   
00753     CGAL_qpe_assertion (j >= 0);  
00754     if (j >= n_) {
00755       n_ = j+1; 
00756       grow_a_d(n_);
00757     }
00758     if (is_finite == default_fl)
00759       fl_vector.erase(j);
00760     else
00761       fl_vector[j] = is_finite;
00762     if (val == default_l)
00763       l_vector.erase(j);
00764     else
00765       l_vector[j] = val;
00766   }
00767   
00768   void set_u (int j, bool is_finite, const NT& val = NT(0))
00769   { 
00770     CGAL_qpe_assertion (j >= 0); 
00771     if (j >= n_) {
00772       n_ = j+1; 
00773       grow_a_d(n_);
00774     }
00775       if (is_finite == default_fu)
00776       fu_vector.erase(j);
00777     else
00778       fu_vector[j] = is_finite;
00779     if (val == default_u)
00780       u_vector.erase(j);
00781     else
00782       u_vector[j] = val;  
00783   }
00784 
00785   void set_c (int j, const NT& val)
00786   {   
00787     CGAL_qpe_assertion (j >= 0);  
00788     if (j >= n_) {
00789       n_ = j+1; 
00790       grow_a_d(n_);
00791     }
00792     if (CGAL::is_zero(val)) 
00793       c_vector.erase(j);
00794     else
00795       c_vector[j] = val;
00796   }
00797 
00798   void set_c0 (const NT& val)
00799   {
00800     c0_ = val;
00801   }
00802 
00803   void set_d (int i, int j, const NT& val) 
00804   { 
00805     CGAL_qpe_assertion (i >= 0);    
00806     CGAL_qpe_assertion (j >= 0);
00807     CGAL_qpe_assertion (j <= i); // lower-diagonal entry  
00808     if (i >= n_) {
00809       n_ = i+1;
00810       grow_a_d(n_);
00811     }  
00812     if (CGAL::is_zero(val)) 
00813       d_matrix[i].erase(j);
00814     else
00815       d_matrix[i][j] = val;
00816   }
00817 
00818 protected:
00819   // helpers for errors/warnings
00820   std::string replace1
00821   (const std::string& msg,const std::string& replacement) const
00822   {
00823     std::string result(msg);
00824     const std::string::size_type pos = result.find('%');
00825     CGAL_qpe_assertion(pos < result.size());
00826     result.replace(pos,1,replacement);
00827     return result;
00828   }
00829 
00830   bool err(const char* msg) {
00831     error_msg = msg;
00832     is_valid_ = false;
00833     return false;
00834   }
00835 
00836   bool err1(const char* msg,
00837             const std::string& parameter1) {
00838     error_msg = replace1(msg,parameter1);
00839     is_valid_ = false;
00840     return false;
00841   }
00842 
00843   bool err2(const char* msg,
00844             const std::string& parameter1,
00845             const std::string& parameter2) {
00846     error_msg = replace1(replace1(msg,parameter1),parameter2);
00847     is_valid_ = false;
00848     return false;
00849   }
00850 
00851   bool err3(const char* msg,
00852             const std::string& parameter1,
00853             const std::string& parameter2,
00854             const std::string& parameter3) {
00855     error_msg = 
00856     replace1(replace1(replace1(msg,parameter1),parameter2),parameter3);
00857     is_valid_ = false;
00858     return false;
00859   }
00860 
00861   void warn(const std::string& msg) const {
00862     std::cerr << "Warning: " << msg << '.' << std::endl;
00863   }
00864 
00865   void warn1(const std::string& msg,const std::string& parameter1) const {
00866     warn(replace1(msg,parameter1));
00867   }
00868 
00869 
00870 };
00871 
00872 // Quadratic_program_from_mps
00873 // --------------------------
00874 // for reading a QP from a stream in MPS format
00875 
00876 template <typename NT_>
00877 class Quadratic_program_from_mps : 
00878   public Quadratic_program<NT_> 
00879 {
00880 public:
00881   typedef NT_ NT;
00882 private:
00883   typedef Quadratic_program<NT> Base;
00884 public:
00885   QP_MODEL_ITERATOR_TYPES;
00886 private:
00887   // types 
00888   typedef std::map<std::string,unsigned int> Index_map;   
00889   typedef std::pair<std::string,unsigned int> String_int_pair;
00890 public:
00891   // constructor
00892   Quadratic_program_from_mps 
00893   (std::istream& in)
00894     : Base(), from(in), nt0(0), use_put_back_token(false)
00895   {
00896     // read NAME section:
00897     if (!name_section())
00898       return;
00899 
00900     // read ROWS section:
00901     if (!rows_section())
00902       return;
00903 
00904     // read COLUMNS section:
00905     if (!columns_section())
00906       return;
00907 
00908     // read RHS section:
00909     if (!rhs_section())
00910       return;
00911 
00912     // check for (optional) RANGES section:
00913     if (!ranges_section())
00914       return; 
00915 
00916     // read optional BOUNDS section:
00917     if (!bounds_section())
00918       return;
00919 
00920     // read optional QMATRIX section:
00921     if (!qmatrix_section())
00922       return;
00923 
00924     // check for ENDATA:
00925     const std::string end = token();
00926     if (end != "ENDATA") {
00927       this->err1("ENDDATA expected but found '%'",end);
00928       return;
00929     }
00930 
00931     // remember the number of variables/constraint that we have now
00932     n_after_construction = this->get_n();
00933     m_after_construction = this->get_m();
00934   }
00935 
00936   // returns the first comment that was read from the MPS stream
00937   const std::string& get_comment() const 
00938   {
00939     return comment_;
00940   }
00941 
00942   // returns name of the problem
00943   const std::string& get_problem_name() const 
00944   {
00945     return name;
00946   }
00947 
00948   const std::string& variable_name_by_index(int j) const
00949   {
00950     CGAL_qpe_assertion(this->is_valid());
00951     CGAL_qpe_assertion(0<=j && j<n_after_construction);
00952     return var_by_index[j];
00953   } 
00954 
00955   int variable_index_by_name (const std::string& name) const
00956   {
00957     const Index_map::const_iterator var_name = var_names.find(name);
00958     if (var_name == var_names.end()) // unknown variable
00959       return -1;
00960     else 
00961       return var_name->second;
00962   }
00963     
00964   const std::string& constraint_name_by_index(int i) const
00965   {
00966     CGAL_qpe_assertion(this->is_valid());
00967     CGAL_qpe_assertion(0<=i && i<m_after_construction);
00968     return row_by_index[i];
00969   } 
00970 
00971   int constraint_index_by_name (const std::string& name) const
00972   {
00973     const Index_map::const_iterator row_name = row_names.find(name);
00974     if (row_name == row_names.end()) // unknown constraint
00975       return -1;
00976     else 
00977       return row_name->second;
00978   }
00979 
00980 private:
00981   // data
00982   // ----
00983   std::istream& from;    // input stream
00984   NT nt0;
00985 
00986   std::string D_section; // name of the section from which D was read
00987   std::string name;      // name of the problem
00988   std::string comment_;  // first comment in the input, if any
00989   std::string obj;       // name of the objective "constraint"
00990   int n_after_construction;
00991   int m_after_construction;
00992 
00993   Index_map row_names;
00994   Index_map duplicated_row_names; // to handle RANGES section
00995   Index_map var_names;
00996   std::vector<std::string> var_by_index; // name of i-th column  
00997   std::vector<std::string> row_by_index; // name of i-th row
00998 
00999   // variables used in token() (see below):
01000   bool use_put_back_token;
01001   std::string put_back_token;
01002 
01003   // parsing routines
01004   // (Note: returns true iff a line-break was eaten.)
01005   bool whitespace()
01006   {
01007     // support for put_token_back():
01008     if (use_put_back_token)
01009       return false;
01010     bool lineBreakFound = false;
01011 
01012     char c;
01013     bool in_comment = false; // true iff we are within a comment
01014     const bool remember_comment = comment_.size() == 0;
01015     while (from.get(c))
01016       if (in_comment) {
01017         if (c!='\r' && c!='\n') {
01018           if (remember_comment)
01019             comment_.push_back(c);
01020         } else
01021           in_comment = false;
01022       } else { // not in comment?
01023         if (!isspace(c)) {
01024           if (c!='$' && c!='*') {
01025             from.putback(c);
01026             break;
01027           }
01028           in_comment = true;
01029           lineBreakFound = true;
01030         } else {
01031           if (c=='\r' || c=='\n')
01032             lineBreakFound = true;
01033         }
01034       }
01035     return lineBreakFound;
01036   }
01037     
01038   std::string token() {
01039     if (use_put_back_token) {
01040       use_put_back_token = false;
01041       return put_back_token;
01042     }
01043     whitespace();
01044     std::string token;
01045     char c;
01046     while (from.get(c)) {
01047       if (isspace(c)) {
01048         from.putback(c);
01049         break;
01050       }
01051       token.push_back(c);
01052     }
01053     return token;
01054   }
01055 
01056   void put_token_back(const std::string& token) {
01057     CGAL_qpe_assertion(!use_put_back_token);
01058     use_put_back_token = true;
01059     put_back_token = token;
01060   }
01061 
01062   template<typename NumberType>
01063   bool number(NumberType& entry) {
01064     // whitespace(); the following >> should care for this
01065     from >> entry;
01066     return from.good();
01067   }
01068 
01069   bool name_section() 
01070   {
01071     const std::string t = token();
01072     if (t != "NAME")
01073       return this->err("expected 'NAME'");
01074     // NAME: everything found until line break; whitespaces are allowed
01075     char c;
01076     std::string token;
01077     std::string whitespaces;
01078     if (whitespace()) 
01079       // line break eaten, name is empty
01080       return true;
01081     do {
01082       from.get(c);
01083       if (c == '\r' || c == '\n') break;
01084       if (isspace(c)) 
01085         whitespaces.push_back(c); // save whitespace
01086       else {
01087         // new actual character found: previous whitespaces belong to name
01088         name += whitespaces;
01089         whitespaces.clear();
01090         name.push_back(c);
01091       }
01092     } while (true);
01093     return true;
01094   }
01095 
01096   bool rows_section()
01097   {
01098     std::string t = token();
01099     if (t != "ROWS")
01100       return this->err1("expected 'ROWS' but found '%'",t);
01101 
01102     // read 'N', 'G', 'L', or 'E', and the name of the constraint:
01103     t = token();
01104     int i = 0; // row index
01105     while (t != "COLUMNS") {
01106       const char type = t[0];
01107       const std::string symbol(t); // for error message below
01108       t = token();
01109       switch (type) {
01110       case 'N':
01111         // register name of objective row:
01112         if (obj.size() == 0) // remember first (and ignore others)
01113           obj = t;
01114         break;
01115       case 'G':
01116       case 'L':
01117       case 'E':
01118         {
01119           // register name of >=, <=, or = constraint:
01120           this->set_r (i, 
01121                  type == 'G'? CGAL::LARGER :
01122                  (type == 'E'? CGAL::EQUAL : CGAL::SMALLER));
01123           if (row_names.find(t) != row_names.end())
01124             return this->err1("duplicate row name '%' in section ROWS",t);
01125           row_names.insert(String_int_pair(t,i));
01126           row_by_index.push_back(t);
01127           ++i;
01128         }
01129         break;
01130       default:
01131         return 
01132           this->err1
01133           ("expected 'N', 'L', 'E', or 'G' in ROWS section but found '%'",
01134            symbol);
01135       }
01136       t = token();
01137     }
01138     put_token_back(t);
01139 
01140     return true;
01141   }
01142 
01143   bool columns_section() 
01144   {
01145     std::string t = token();
01146     if (t != "COLUMNS")
01147       return this->err1("expected 'COLUMNS' but found '%'",t);
01148 
01149     t = token();
01150     while (t != "RHS") {
01151       // find variable name:
01152       unsigned int var_index;
01153       std::string col_name;
01154       const Index_map::const_iterator var_name = var_names.find(t);
01155       if (var_name == var_names.end()) { // new variable?
01156         var_index = var_names.size();
01157         col_name = t;
01158         var_names.insert(String_int_pair(t,var_index));
01159         var_by_index.push_back(t);
01160       } else { // variable that is already known?
01161         var_index = var_name->second;
01162         col_name = var_name->first;
01163       }
01164       
01165       bool doItAgain = true;
01166       for (int i=0; doItAgain; ++i) {
01167         // read row identifier:
01168         t = token();
01169 
01170         // read number:
01171         NT val;
01172         if (!number(val))
01173           return this->err2
01174             ("number expected after row identifier '%' in '%' COLUMNS record",
01175              t,col_name);
01176 
01177         // store number:
01178         if (t == obj) { // objective row?
01179           this->set_c(var_index, val);
01180         } else { // not objective row?
01181           const Index_map::const_iterator row_name = row_names.find(t);
01182           if (row_name == row_names.end())
01183             return this->err1
01184               ("unknown row identifier '%' in section COLUMNS",t);
01185           this->set_a (var_index, row_name->second, val);
01186         }
01187 
01188         // determine if we need to read another number:
01189         doItAgain = i==0 && !whitespace();
01190       }
01191       
01192       // read next token:
01193       t = token();
01194     }
01195     put_token_back(t);
01196 
01197     return true;
01198   }
01199 
01200   bool rhs_section()
01201   {
01202     this->set_c0 (nt0);  // no constant term yet
01203     std::string t = token();
01204     if (t != "RHS")
01205       return this->err1("expected 'RHS' but found '%'",t);
01206 
01207     t = token();
01208     std::string rhs_id;
01209     while (t != "RANGES" && t != "BOUNDS" &&
01210            t != "DMATRIX" && t != "QMATRIX" && t != "QUADOBJ" &&
01211            t != "ENDATA") {
01212       // read rhs identifier and if it is different from the one
01213       // from the previous iteration, ignore the whole row:
01214       bool ignore = false;
01215       std::string ignored;
01216       if (rhs_id.size() == 0) { // first time we enter the loop?
01217         rhs_id = t;
01218       } else {                  // rhs_id already set
01219         if (t != rhs_id) { 
01220           ignore = true;        // ignore other rhs identifiers
01221           ignored = t;
01222         }
01223       }
01224 
01225       bool doItAgain = true;
01226       for (int i=0; doItAgain; ++i) {
01227         // read row identifier:
01228         t = token();
01229 
01230         // read number:
01231         NT val;
01232         if (!number(val))
01233           return this->err1("number expected after '%' in this RHS record",t);
01234 
01235         // store number:
01236         const Index_map::const_iterator row_name = row_names.find(t);
01237         if (row_name == row_names.end()) {
01238           // no corresponding constraint; is it the constant term?
01239           if (t == obj) 
01240             this->set_c0(-val);
01241           else 
01242             return this->err1("unknown row identifier '%' in section RHS",t);
01243         } else {
01244           // we have an actual constraint
01245           if (!ignore) {
01246             this->set_b(row_name->second, val);
01247           } else {
01248             this->warn1("rhs with identifier '%' ignored", ignored);
01249           }
01250         }
01251 
01252         // determine if we need to read another number:
01253         doItAgain = i==0 && !whitespace();
01254       }
01255       
01256       // read next token:
01257       t = token();
01258     }
01259     put_token_back(t);
01260 
01261     return true;  
01262   }
01263 
01264   bool ranges_section()
01265   {
01266     std::string t = token();
01267     if (t != "RANGES") { // (Note: RANGES section is optional.)
01268       put_token_back(t);
01269       return true;
01270     }
01271 
01272     t = token();
01273     std::string range_id;
01274     while ((t != "BOUNDS" && t != "QMATRIX" && 
01275             t != "DMATRIX" && t != "QUADOBJ" && t != "ENDATA")) {
01276       // read rhs identifier and if it is different from the one
01277       // from the previous iteration, ignore the whole row:
01278       bool ignore = false;
01279       std::string ignored;
01280       if (range_id.size() == 0) { // first time we enter the loop?
01281         range_id = t;
01282       } else {                    // range_id already set
01283         if (t != range_id) { 
01284           ignore = true;          // ignore other range identifiers
01285           ignored = t;
01286         }
01287       }
01288       bool doItAgain = true;
01289       for (int i=0; doItAgain; ++i) {
01290         // read row identifier:
01291         t = token();
01292 
01293         // read number:
01294         NT val;
01295         if (!number(val))
01296           return this->err1
01297             ("number expected after '%' in this RANGES record",t);
01298 
01299         // duplicate the constraint, depending on sign of val and type
01300         // of constraint
01301         const Index_map::const_iterator row_name = row_names.find(t);
01302         if (row_name == row_names.end()) {
01303           return this->err1("unknown row identifier '%' in section RANGES",t);
01304         } else {
01305           if (!ignore) {
01306             int index = row_name->second;
01307             CGAL::Comparison_result type = *(this->get_r()+index);
01308             // duplicate the row, unless it has already been duplicated
01309             const Index_map::const_iterator duplicated_row_name = 
01310               duplicated_row_names.find(t);
01311             if (duplicated_row_name != duplicated_row_names.end())
01312               return this->err1
01313                 ("duplicate row identifier '%' in section RANGES",t);
01314             duplicated_row_names.insert(*row_name);
01315             std::string dup_name = row_name->first+std::string("_DUPLICATED"); 
01316             int new_index = this->get_m();
01317             row_names.insert(String_int_pair (dup_name, new_index)); 
01318             row_by_index.push_back (dup_name);      
01319             for (unsigned int j=0; j<var_names.size(); ++j) {
01320               NT val = (*(this->get_a()+j))[index];
01321               this->set_a (j, new_index, val);
01322             }
01323             // determine rhs for this new row. Here are the rules:
01324             // if r is the ranges value and b is the old right-hand 
01325             // side, then we have h <= constraint <= u according to
01326             // this table:
01327             //
01328             // row type       sign of r       h          u
01329             // ----------------------------------------------
01330             // G            + or -         b        b + |r|
01331             // L            + or -       b - |r|      b
01332             // E              +            b        b + |r|
01333             // E              -          b - |r|      b
01334           
01335             switch (type) {
01336             case CGAL::LARGER: // introduce "<= b+|r|" 
01337               this->set_r(new_index, CGAL::SMALLER);
01338               this->set_b(new_index, *(this->get_b()+index) + CGAL::abs(val));
01339               break;
01340             case CGAL::SMALLER:   // introduce ">=  b-|r|" 
01341               this->set_r(new_index, CGAL::LARGER);
01342               this->set_b(new_index, *(this->get_b()+index) - CGAL::abs(val));
01343               break;
01344             case CGAL::EQUAL:   
01345               if (CGAL_NTS is_positive (val)) {
01346                 // introduce "<= b+|r|"
01347                 this->set_r(new_index, CGAL::SMALLER);
01348               } else {
01349                 // introduce ">=  b-|r|"  
01350                 this->set_r(new_index, CGAL::LARGER);
01351               }
01352               this->set_b(new_index, *(this->get_b()+index) + val);
01353               break;
01354             default:
01355               CGAL_qpe_assertion(false);
01356             }  
01357           } else {
01358             this->warn1("range with identifier '%' ignored", ignored);
01359           }
01360         }
01361 
01362         // determine if we need to read another number:
01363         doItAgain = i==0 && !whitespace();
01364       }
01365       
01366       // read next token:
01367       t = token();
01368     }
01369     put_token_back(t);
01370 
01371     return true;   
01372   }
01373 
01374   bool bounds_section()
01375   {
01376     std::string t = token();
01377     if (t != "BOUNDS") { // (Note: BOUNDS section is optional.)
01378       put_token_back(t);
01379       return true;
01380     }
01381 
01382     t = token();
01383     std::string bound_id;
01384     while (t != "QMATRIX" && t != "DMATRIX" && t != "QUADOBJ" && t != "ENDATA") {
01385       // process type of bound:
01386       enum Bound_type { LO, UP, FX, FR, MI, PL};
01387       Bound_type type;
01388       if (t=="LO")
01389         type = LO;
01390       else if (t=="UP")
01391         type = UP;
01392       else if (t=="FX")
01393         type = FX;
01394       else if (t=="FR")
01395         type = FR;
01396       else if (t=="MI")
01397         type = MI;
01398       else if (t=="PL")
01399         type = PL;
01400       else    
01401         return
01402           this->err1
01403           ("expected 'LO', 'UP', 'FX', 'FR', 'MI', or 'PL' here but found '%'",
01404            t);
01405     
01406       // remember bound:
01407       const std::string bound = t;
01408 
01409       // find bound label; there may be several, but we only process
01410       // the bounds having the first bound label that occurs. This 
01411       // label may be empty, though
01412       t = token(); // bound label or variable name (case of empty bound label) 
01413       if (bound_id.size() == 0) { // first time we see a bound label / variable?
01414         const Index_map::const_iterator var_name = var_names.find(t);
01415         if (var_name != var_names.end()) { // is the token a variable?
01416           bound_id = " ";    // there is no bound label
01417           put_token_back(t); // the variable name is processed below
01418         } else
01419           bound_id = t; // we found a bound label
01420       } else {
01421         // now we already know the bound label
01422         if (bound_id == " ") // empty bound label? 
01423           put_token_back(t); // the variable name is processed below
01424         else 
01425           if (t != bound_id) {
01426             this->warn1("ignoring all bounds for bound label '%'",t);
01427             this->warn1("(only bounds for bound label '%' are accepted)",
01428                         bound_id);
01429           }
01430       }
01431 
01432       // find variable name;
01433       t = token();
01434       const Index_map::const_iterator var_name = var_names.find(t);
01435       if (var_name == var_names.end()) // unknown variable?
01436         return this->err1("unknown variable '%' in BOUNDS section",t);
01437       const unsigned int var_index = var_name->second;;
01438 
01439       // read value of bound, if appropriate:
01440       NT val;
01441       if (type==LO || type==UP || type==FX)
01442         if (!number(val))
01443           return this->err2("expected number after '%' in % bound",t,bound);
01444 
01445       // store bound:
01446       switch (type) {
01447       case FX:
01448         this->set_u (var_index, true, val);
01449         // no break here!!
01450       case LO:
01451         this->set_l (var_index, true, val);
01452         break;
01453       case UP:
01454         this->set_u (var_index, true, val);
01455         if (val <= 0 && *(this->get_fl()+var_index) 
01456             && *(this->get_l()+var_index) == 0)
01457           if (val < 0)
01458             this->set_l(var_index, false);
01459         break;
01460       case FR:
01461         this->set_u(var_index, false);
01462         this->set_l(var_index, false);
01463         break;
01464       case MI:
01465         this->set_l(var_index, false);
01466         break;
01467       case PL:
01468         this->set_u(var_index, false);
01469         break;
01470       default:
01471         CGAL_qpe_assertion(false);
01472       }
01473       
01474       // read next token:
01475       t = token();
01476     }
01477     put_token_back(t);
01478 
01479     return true;
01480   }
01481 
01482   bool qmatrix_section()
01483   {
01484     std::string t = token();
01485     if (t!="QMATRIX" && t!="DMATRIX" && t!="QUADOBJ") { // optional
01486       put_token_back(t);
01487       return true;
01488     }   
01489 
01490     // remember section name:
01491     D_section = t;
01492     const bool multiply_by_two = t=="DMATRIX";
01493 
01494     t = token();
01495     std::string bound_id;
01496     while (t != "ENDATA") {
01497       // find first variable name;
01498       const Index_map::const_iterator var1_name = var_names.find(t);
01499       if (var1_name == var_names.end()) // unknown variable?
01500         return this->err2("unknown first variable '%' in '%' section", 
01501                           t, D_section);
01502       const unsigned int var1_index = var1_name->second;    
01503       
01504       // find second variable name;
01505       t = token();
01506       const Index_map::const_iterator var2_name = var_names.find(t);
01507       if (var2_name == var_names.end()) // unknown variable?
01508         return this->err2("unknown second variable '%' in '%' section",
01509                           t, D_section);
01510       const unsigned int var2_index = var2_name->second;;
01511       
01512       // read value:
01513       NT val;
01514       if (!number(val))
01515         return this->err2("expected number after '%' in section '%'",
01516                           t, D_section);
01517 
01518       // multiply by two if approriate:
01519       if (multiply_by_two)
01520         val *= NT(2);
01521 
01522       // set entry in D:
01523       int i, j;
01524       if (var2_index <= var1_index) {
01525         i = var1_index; j = var2_index;
01526       } else {
01527         i = var2_index; j = var1_index;
01528       }
01529       // rule out that we previously put a different (nonzero) value at (i,j)
01530       NT old_val = (*(this->get_d()+i))[j];
01531       if (!CGAL::is_zero(old_val) && old_val != val)
01532         return this->err3("nonsymmetric '%' section at variables '%' and '%'",
01533                           D_section, var1_name->first, var2_name->first);
01534       this->set_d(i, j, val);
01535 
01536       // read next token:
01537       t = token();
01538     }
01539     put_token_back(t);
01540  
01541     return true;
01542   }
01543   
01544 };
01545 
01546 CGAL_END_NAMESPACE
01547 
01548 #endif // CGAL_QP_MODELS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines