BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/QP_solver/QP_solver_impl.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_solver/QP_solver_impl.h $
00015 // $Id: QP_solver_impl.h 46194 2008-10-09 13:07:49Z gaertner $
00016 // 
00017 //
00018 // Author(s)     : Sven Schoenherr
00019 //                 Bernd Gaertner <gaertner@inf.ethz.ch>
00020 //                 Franz Wessendorp
00021 //                 Kaspar Fischer
00022 
00023 #include <CGAL/QP_solver/Initialization.h>
00024 
00025 CGAL_BEGIN_NAMESPACE
00026 
00027 // =============================
00028 // class implementation (cont'd)
00029 // =============================
00030 
00031 // transition (to phase II)
00032 // ------------------------
00033 template < typename Q, typename ET, typename Tags >
00034 void
00035 QP_solver<Q, ET, Tags>::
00036 transition( )
00037 {
00038     CGAL_qpe_debug {
00039         if ( vout.verbose()) {
00040             vout2 << std::endl
00041                   << "----------------------" << std::endl
00042                   << 'T';
00043             vout1 << "[ t"; vout  << "ransition to phase II"; vout1 << " ]";
00044             vout  << std::endl;
00045             vout2 << "----------------------";
00046         }
00047     }
00048 
00049     // update status
00050     m_phase    = 2;
00051     is_phaseI  = false;
00052     is_phaseII = true;
00053 
00054     // remove artificial variables
00055     in_B.erase( in_B.begin()+qp_n+slack_A.size(), in_B.end());
00056     //ensure_size(tmp_x_2, tmp_x.size());
00057     // update basis inverse
00058     CGAL_qpe_debug {
00059         vout4 << std::endl << "basis-inverse:" << std::endl;
00060     }
00061     transition( Is_linear());
00062     CGAL_qpe_debug {
00063         check_basis_inverse();
00064     }
00065 
00066     // initialize exact version of `-qp_c' (implicit conversion to ET)
00067     C_by_index_accessor  c_accessor( qp_c);
00068     std::transform( C_by_index_iterator( B_O.begin(), c_accessor),
00069                     C_by_index_iterator( B_O.end  (), c_accessor),
00070                     minus_c_B.begin(), std::negate<ET>());
00071     
00072     // compute initial solution of phase II
00073     compute_solution(Is_nonnegative());
00074 
00075     // diagnostic output
00076     CGAL_qpe_debug {
00077         if ( vout.verbose()) print_solution();
00078     }
00079 
00080     // notify pricing strategy
00081     strategyP->transition();
00082 }
00083 
00084 // access
00085 // ------
00086 // numerator of current solution; the denominator is 2*d*d, so we should
00087 // compute here d*d*(x^T2Dx + x^T2c + 2c0)
00088 template < typename Q, typename ET, typename Tags >
00089 ET QP_solver<Q, ET, Tags>::
00090 solution_numerator( ) const
00091 {
00092     ET   s, z = et0;
00093     int  i, j;
00094 
00095     if (check_tag(Is_nonnegative()) || is_phaseI) {
00096       // standard form or phase I; it suffices to go
00097       // through the basic variables; all D- and c-entries
00098       // are obtained through the appropriate iterators 
00099       Index_const_iterator  i_it;
00100       Value_const_iterator  x_i_it, c_it;
00101 
00102       // foreach i
00103       x_i_it =       x_B_O.begin();
00104       c_it = minus_c_B  .begin();
00105       for ( i_it = B_O.begin(); i_it != B_O.end(); ++i_it, ++x_i_it, ++c_it){
00106         i = *i_it;
00107 
00108         // compute quadratic part: 2D_i x
00109         s = et0;
00110         if ( is_QP && is_phaseII) {
00111           // half the off-diagonal contribution
00112           s += std::inner_product(x_B_O.begin(), x_i_it,
00113                                   D_pairwise_iterator(
00114                                          B_O.begin(),
00115                                          D_pairwise_accessor( qp_D, i)),
00116                                   et0);
00117           // the other half
00118           s *= et2;
00119           // diagonal contribution
00120           s += ET( (*(qp_D + i))[ i]) * *x_i_it;
00121         }
00122         // add linear part: 2c_i
00123         s -= d * et2 * ET( *c_it);
00124 
00125         // add x_i(2D_i x + 2c_i)
00126         z += s * *x_i_it; // endowed with a factor of d*d now
00127       }
00128     } else {
00129       // nonstandard form and phase II, 
00130       // take all original variables into account; all D- and c-entries
00131       // are obtained from the input data directly
00132       // order in i_it and j_it matches original variable order
00133       if (is_QP) {
00134         // quadratic part
00135         i=0;
00136         for (Variable_numerator_iterator 
00137                i_it = this->original_variables_numerator_begin(); 
00138              i_it < this->original_variables_numerator_end(); ++i_it, ++i) {
00139           // do something only if *i_it != 0
00140           if (*i_it == et0) continue;
00141           s = et0; // contribution of i-th row
00142           Variable_numerator_iterator j_it = 
00143             this->original_variables_numerator_begin();
00144           // half the off-diagonal contribution
00145           j=0;
00146           for (; j<i; ++j_it, ++j)
00147             s += ET(*((*(qp_D+i))+j)) * *j_it;
00148           // the other half
00149           s *= et2;
00150           // the diagonal entry
00151           s += ET(*((*(qp_D+i))+j)) * *j_it;
00152           // accumulate
00153           z += s * *i_it;
00154         }
00155       }
00156       // linear part
00157       j=0; s = et0;
00158       for (Variable_numerator_iterator 
00159              j_it = this->original_variables_numerator_begin();
00160            j_it < this->original_variables_numerator_end(); ++j_it, ++j)
00161         s +=  et2 * ET(*(qp_c+j)) * *j_it;
00162       z += d * s;
00163     }
00164     // finally, add the constant term (phase II only)
00165     if (is_phaseII) z += et2 * ET(qp_c0) * d * d;
00166     return z;
00167 }
00168 
00169 // pivot step
00170 // ----------
00171 template < typename Q, typename ET, typename Tags >
00172 void
00173 QP_solver<Q, ET, Tags>::
00174 pivot_step( )
00175 {
00176     ++m_pivots;
00177 
00178     // diagnostic output
00179     CGAL_qpe_debug {
00180         vout2 << std::endl
00181               << "==========" << std::endl
00182               << "Pivot Step" << std::endl
00183               << "==========" << std::endl;
00184     }
00185     vout  << "[ phase " << ( is_phaseI ? "I" : "II")
00186           << ", iteration " << m_pivots << " ]" << std::endl;
00187     
00188             
00189     // pricing
00190     // -------
00191     pricing();
00192 
00193             
00194     // check for optimality
00195     if ( j < 0) {
00196 
00197         if ( is_phaseI) {                               // phase I
00198             // since we no longer assume full row rank and subsys assumption
00199             // we have to strengthen the precondition for infeasibility
00200             if (this->solution_numerator() > et0) {    
00201               // problem is infeasible
00202                 m_phase  = 3;
00203                 m_status = QP_INFEASIBLE;
00204                 
00205                 vout << "  ";
00206                 vout << "problem is INFEASIBLE" << std::endl;
00207                
00208             } else {  // Drive/remove artificials out of basis
00209                 expel_artificial_variables_from_basis();
00210                 transition();
00211             }
00212         } else {                                        // phase II
00213 
00214             // optimal solution found
00215             m_phase  = 3;
00216             m_status = QP_OPTIMAL;
00217   
00218             vout << "  ";
00219             vout  << "solution is OPTIMAL" << std::endl;
00220             
00221         }
00222         return;
00223     }
00224 
00225             
00226     // ratio test & update (step 1)
00227     // ----------------------------
00228     // initialize ratio test
00229     ratio_test_init();
00230     
00231 
00232     // diagnostic output
00233     CGAL_qpe_debug {
00234         if ( vout2.verbose() && is_QP && is_phaseII) {
00235             vout2.out() << std::endl
00236                         << "----------------------------" << std::endl
00237                         << "Ratio Test & Update (Step 1)" << std::endl
00238                         << "----------------------------" << std::endl;
00239         }
00240     }
00241 
00242     // loop (step 1)
00243     do {
00244 
00245         // ratio test
00246         ratio_test_1();
00247 
00248         // check for unboundedness
00249         if ( q_i == et0) {
00250             m_phase  = 3;
00251             m_status = QP_UNBOUNDED;
00252             
00253             vout << "  ";
00254             vout << "problem is UNBOUNDED" << std::endl;
00255             
00256             CGAL_qpe_debug {
00257                 //nu should be zero in this case
00258                 // note: (-1)/hat{\nu} is stored instead of \hat{\nu}
00259                 // todo kf: as this is just used for an assertion check,
00260                 // all the following lines should only be executed if
00261                 // assertions are enabled...
00262                 nu = inv_M_B.inner_product(     A_Cj.begin(), two_D_Bj.begin(),
00263                     q_lambda.begin(),    q_x_O.begin());
00264                 if (is_QP) {
00265                     if (j < qp_n) {
00266                         nu -= d*ET(*((*(qp_D+j))+j));
00267                     }
00268                 }
00269                 CGAL_qpe_assertion(nu == et0);
00270             }
00271             return;
00272         }
00273         
00274         // update
00275         update_1();
00276 
00277     } while ( j >= 0);
00278 
00279     // ratio test & update (step 2)
00280     // ----------------------------
00281 /*    
00282     if ( i >= 0) {
00283 
00284         // diagnostic output
00285         CGAL_qpe_debug {
00286             vout2 << std::endl
00287                   << "----------------------------" << std::endl
00288                   << "Ratio Test & Update (Step 2)" << std::endl
00289                   << "----------------------------" << std::endl;
00290         }
00291 
00292         // compute index of entering variable
00293         j += in_B.size();
00294 
00295         // loop (step 2)
00296         while ( ( i >= 0) && basis_matrix_stays_regular()) {
00297 
00298             // update
00299             update_2( Is_linear());
00300 
00301             // ratio test
00302             ratio_test_2( Is_linear());
00303         }
00304     }
00305 */
00306     // instead of the above piece of code we now have
00307     // diagnostic output
00308     if (is_RTS_transition) {
00309         is_RTS_transition = false;
00310      
00311         CGAL_qpe_debug {
00312             vout2 << std::endl
00313                   << "----------------------------" << std::endl
00314                   << "Ratio Test & Update (Step 2)" << std::endl
00315                   << "----------------------------" << std::endl;
00316         }
00317 
00318         // compute index of entering variable
00319         j += in_B.size();
00320 
00321         ratio_test_2( Is_linear());
00322     
00323         while ((i >= 0) && basis_matrix_stays_regular()) {
00324         
00325             update_2(Is_linear());
00326         
00327             ratio_test_2(Is_linear());
00328         
00329         }
00330     } 
00331 
00332 
00333 
00334     // ratio test & update (step 3)
00335     // ----------------------------
00336     CGAL_qpe_assertion_msg( i < 0, "Step 3 should never be reached!");
00337 
00338     // diagnostic output
00339     
00340     if ( vout.verbose()) print_basis();
00341     if ( vout.verbose()) print_solution();
00342 
00343     // transition to phase II (if possible)
00344     // ------------------------------------
00345     if ( is_phaseI && ( art_basic == 0)) {
00346         CGAL_qpe_debug {
00347             if ( vout2.verbose()) {
00348                 vout2.out() << std::endl
00349                             << "all artificial variables are nonbasic"
00350                             << std::endl;
00351             }
00352         }
00353         transition();
00354     }
00355 }
00356 
00357 // pricing
00358 template < typename Q, typename ET, typename Tags >
00359 void
00360 QP_solver<Q, ET, Tags>::
00361 pricing( )
00362 {
00363     // diagnostic output
00364     CGAL_qpe_debug {
00365         if ( vout2.verbose()) {
00366             vout2 << std::endl
00367                   << "-------" << std::endl
00368                   << "Pricing" << std::endl
00369                   << "-------" << std::endl;
00370         }
00371     }
00372 
00373     // call pricing strategy
00374     j = strategyP->pricing(direction);
00375 
00376     // diagnostic output
00377 
00378     if ( vout.verbose()) {
00379       if ( j < 0) {
00380         CGAL_qpe_debug {
00381           vout2 << "entering variable: none" << std::endl;
00382         }
00383       } else {
00384         vout  << "  ";
00385         vout  << "entering: ";
00386         vout  << j;
00387         CGAL_qpe_debug {
00388           vout2 << " (" << variable_type( j) << ')' << std::endl;
00389           vout2 << "direction: "
00390                 << ((direction == 1) ? "positive" : "negative") << std::endl;
00391         }
00392       }
00393     }
00394 }
00395 
00396 // initialization of ratio-test
00397 template < typename Q, typename ET, typename Tags >
00398 void
00399 QP_solver<Q, ET, Tags>::
00400 ratio_test_init( )
00401 {
00402     // store exact version of `A_Cj' (implicit conversion)
00403     ratio_test_init__A_Cj( A_Cj.begin(), j, no_ineq);
00404 
00405     // store exact version of `2 D_{B_O,j}'
00406     ratio_test_init__2_D_Bj( two_D_Bj.begin(), j, Is_linear());
00407 }
00408 
00409 template < typename Q, typename ET, typename Tags >                                         // no ineq.
00410 void  QP_solver<Q, ET, Tags>::
00411 ratio_test_init__A_Cj( Value_iterator A_Cj_it, int j_, Tag_true)
00412 {
00413     // store exact version of `A_Cj' (implicit conversion)
00414     if ( j_ < qp_n) {                                   // original variable
00415 
00416         CGAL::copy_n( *(qp_A + j_), qp_m, A_Cj_it);
00417 
00418     } else {                                            // artificial variable
00419 
00420         unsigned int  k = j_;
00421         k -= qp_n;
00422         std::fill_n( A_Cj_it, qp_m, et0);
00423         A_Cj_it[ k] = ( art_A[ k].second ? -et1 : et1);
00424     }
00425 }
00426 
00427 template < typename Q, typename ET, typename Tags >                                        // has ineq.
00428 void  QP_solver<Q, ET, Tags>::
00429 ratio_test_init__A_Cj( Value_iterator A_Cj_it, int j_, Tag_false)
00430 {
00431     // store exact version of `A_Cj' (implicit conversion)
00432     if ( j_ < qp_n) {                                   // original variable
00433         A_by_index_accessor  a_accessor( *(qp_A + j_));
00434         std::copy( A_by_index_iterator( C.begin(), a_accessor),
00435                    A_by_index_iterator( C.end  (), a_accessor),
00436                    A_Cj_it);
00437 
00438     } else {
00439         unsigned int  k = j_;
00440         k -= qp_n;
00441         std::fill_n( A_Cj_it, C.size(), et0);
00442 
00443         if ( k < slack_A.size()) {                      // slack variable
00444 
00445             A_Cj_it[ in_C[ slack_A[ k].first]] = ( slack_A[ k].second ? -et1
00446                                                                       :  et1);
00447 
00448         } else {                                        // artificial variable
00449             k -= slack_A.size();
00450 
00451             if ( j_ != art_s_i) {                           // normal art.
00452 
00453                 A_Cj_it[ in_C[ art_A[ k].first]] = ( art_A[ k].second ? -et1
00454                                                                       :  et1);
00455 
00456             } else {                                        // special art.
00457                 S_by_index_accessor  s_accessor( art_s.begin());
00458                 std::copy( S_by_index_iterator( C.begin(), s_accessor),
00459                            S_by_index_iterator( C.end  (), s_accessor),
00460                            A_Cj_it);
00461             }   
00462         }
00463     }
00464 }
00465 
00466 // ratio test (step 1)
00467 template < typename Q, typename ET, typename Tags >
00468 void
00469 QP_solver<Q, ET, Tags>::
00470 ratio_test_1( )
00471 {
00472 
00473     // diagnostic output
00474     CGAL_qpe_debug {
00475         if ( vout2.verbose()) {
00476             vout2.out() << std::endl;
00477             if ( is_LP || is_phaseI) {
00478                 vout2.out() << "----------" << std::endl
00479                             << "Ratio Test" << std::endl
00480                             << "----------" << std::endl;
00481             } else {
00482                 vout2.out() << "Ratio Test (Step 1)" << std::endl
00483                             << "-------------------" << std::endl;
00484             }
00485             if ( vout3.verbose()) {
00486                 vout3.out() << "    A_Cj: ";
00487                 std::copy( A_Cj.begin(), A_Cj.begin()+C.size(),
00488                            std::ostream_iterator<ET>( vout3.out()," "));
00489                 vout3.out() << std::endl;
00490                 if ( is_QP && is_phaseII) {
00491                     vout3.out() << "  2 D_Bj: ";
00492                     std::copy( two_D_Bj.begin(), two_D_Bj.begin()+B_O.size(),
00493                                std::ostream_iterator<ET>( vout3.out()," "));
00494                     vout3.out() << std::endl;
00495                 }
00496                 vout3.out() << std::endl;
00497             }
00498         }
00499     }
00500     
00501     // compute `q_lambda' and `q_x'
00502     ratio_test_1__q_x_O( Is_linear());
00503     ratio_test_1__q_x_S( no_ineq);
00504 
00505     // diagnostic output
00506     CGAL_qpe_debug {
00507         if ( vout3.verbose()) {
00508             if ( is_QP && is_phaseII) {
00509                 vout3.out() << "q_lambda: ";
00510                 std::copy( q_lambda.begin(), q_lambda.begin()+C.size(),
00511                            std::ostream_iterator<ET>( vout3.out()," "));
00512                 vout3.out() << std::endl;
00513             }
00514             vout3.out() << "   q_x_O: ";
00515             std::copy( q_x_O.begin(), q_x_O.begin()+B_O.size(),
00516                        std::ostream_iterator<ET>( vout3.out()," "));
00517             vout3.out() << std::endl;
00518 
00519             if ( has_ineq) {
00520                 vout3.out() << "   q_x_S: ";
00521                 std::copy( q_x_S.begin(), q_x_S.begin()+B_S.size(),
00522                            std::ostream_iterator<ET>( vout3.out()," "));
00523                 vout3.out() << std::endl;
00524             }
00525             vout3.out() << std::endl;
00526         }
00527     }
00528 
00529     // check `t_i's
00530     x_i = et1;                                          // trick: initialize
00531     q_i = et0;                                          // minimum with +oo
00532 
00533     // computation of t_{min}^{j}
00534     ratio_test_1__t_min_j(Is_nonnegative());
00535     CGAL_qpe_debug { // todo kf: at first sight, this debug message should
00536                      // only be output for problems in nonstandard form...
00537         if (vout2.verbose()) {
00538             vout2.out() << "t_min_j: " << x_i << '/' << q_i << std::endl;
00539             vout2.out() << std::endl;
00540         }
00541     }    
00542 
00543     // what happens, if all original variables are nonbasic?
00544 /*
00545     ratio_test_1__t_i(   B_O.begin(),   B_O.end(),
00546                        x_B_O.begin(), q_x_O.begin(), Tag_false());
00547     ratio_test_1__t_i(   B_S.begin(),   B_S.end(),
00548                        x_B_S.begin(), q_x_S.begin(), no_ineq);
00549 */                     
00550     ratio_test_1__t_min_B(no_ineq);    
00551 
00552     // check `t_j'
00553     ratio_test_1__t_j( Is_linear());
00554 
00555     // diagnostic output
00556     CGAL_qpe_debug {
00557         if ( vout2.verbose()) {
00558             for ( unsigned int k = 0; k < B_O.size(); ++k) {
00559                 print_ratio_1_original(k, x_B_O[k], q_x_O[k]);
00560             }     
00561             if ( has_ineq) {
00562                 for ( unsigned int k = 0; k < B_S.size(); ++k) {
00563                     /*
00564                     vout2.out() << "t_S_" << k << ": "
00565                                     << x_B_S[ k] << '/' << q_x_S[ k]
00566                                     << ( ( q_i > et0) && ( i == B_S[ k]) ? " *":"")
00567                                     << std::endl;
00568                                     */
00569                                     print_ratio_1_slack(k, x_B_S[k], q_x_S[k]);
00570                 }
00571             }
00572             if ( is_QP && is_phaseII) {
00573                 vout2.out() << std::endl
00574                             << "  t_j: " << mu << '/' << nu
00575                             << ( ( q_i > et0) && ( i < 0) ? " *" : "")
00576                             << std::endl;
00577             }
00578             vout2.out() << std::endl;
00579         }
00580     }
00581     if ( q_i > et0) {
00582       if ( i < 0) {
00583         vout2 << "leaving variable: none" << std::endl;
00584       } else {
00585         vout << ", ";
00586         vout  << "leaving: ";
00587         vout  << i;
00588         CGAL_qpe_debug {
00589           if ( vout2.verbose()) {
00590             if ( ( i < qp_n) || ( i >= (int)( qp_n+slack_A.size()))) {
00591               vout2.out() << " (= B_O[ " << in_B[ i] << "]: "
00592                           << variable_type( i) << ')';
00593             } else {
00594               vout2.out() << " (= B_S[ " << in_B[ i] << "]: slack)";
00595             }
00596           }
00597           vout2 << std::endl;
00598         }
00599         
00600       }
00601     }
00602     
00603 }
00604 
00605 
00606 template < typename Q, typename ET, typename Tags >                         // Standard form
00607 void  QP_solver<Q, ET, Tags>::
00608 ratio_test_1__t_min_j(Tag_true /*is_nonnegative*/)
00609 {
00610 }
00611 
00612 // By the pricing step we have the following precondition
00613 // direction == +1 => x_O_v_i[j] == (LOWER v ZERO)
00614 // direction == -1 => x_O_v_i[j] == (UPPER v ZERO) 
00615 template < typename Q, typename ET, typename Tags >                         // Upper bounded
00616 void  QP_solver<Q, ET, Tags>::
00617 ratio_test_1__t_min_j(Tag_false /*is_nonnegative*/)
00618 {
00619     if (j < qp_n) {                                 // original variable
00620         if (direction == 1) {
00621             if (x_O_v_i[j] == LOWER) {              // has lower bound value
00622                 if (*(qp_fu+j)) {                   // has finite upper bound
00623                     x_i = (*(qp_u+j) - *(qp_l+j));
00624                     q_i = et1;
00625                     i = j;
00626                     ratio_test_bound_index = UPPER;
00627                 } else {                            // has infinite upper bound
00628                     x_i = et1;
00629                     q_i = et0;
00630                 }
00631             } else {                                // has value zero
00632                 if (*(qp_fu+j)) {                   // has finite upper bound
00633                     x_i = *(qp_u+j);
00634                     q_i = et1;
00635                     i = j;
00636                     ratio_test_bound_index = UPPER;
00637                 } else {                            // has infinite upper bound
00638                     x_i = et1;
00639                     q_i = et0;                    
00640                 }
00641             }
00642         } else {                                    // direction == -1
00643             if (x_O_v_i[j] == UPPER) {              // has upper bound value
00644                 if (*(qp_fl+j)) {                   // has finite lower bound
00645                     x_i = (*(qp_u+j) - *(qp_l+j));
00646                     q_i = et1;
00647                     i = j;
00648                     ratio_test_bound_index = LOWER;
00649                 } else {                            // has infinite lower bound
00650                     x_i = et1;
00651                     q_i = et0;
00652                 }
00653             } else {                                // has value zero
00654                 if (*(qp_fl+j)) {                   // has finite lower bound
00655                     x_i = -(*(qp_l+j));
00656                     q_i = et1;
00657                     i = j;
00658                     ratio_test_bound_index = LOWER;
00659                 } else {                            // has infinite lower bound
00660                     x_i = et1;
00661                     q_i = et0;
00662                 }
00663             }
00664         }
00665     } else {                                        // slack or artificial var
00666         x_i = et1;
00667         q_i = et0;
00668     }
00669 }
00670 
00671 template < typename Q, typename ET, typename Tags >
00672 void  QP_solver<Q, ET, Tags>::
00673 ratio_test_1__t_min_B(Tag_true  /*has_equalities_only_and_full_rank*/)
00674 {
00675     ratio_test_1_B_O__t_i(B_O.begin(), B_O.end(), x_B_O.begin(),
00676                         q_x_O.begin(), Is_nonnegative());
00677 }
00678 
00679 template < typename Q, typename ET, typename Tags >
00680 void  QP_solver<Q, ET, Tags>::
00681 ratio_test_1__t_min_B(Tag_false /*has_equalities_only_and_full_rank*/)
00682 {
00683     ratio_test_1_B_O__t_i(B_O.begin(), B_O.end(), x_B_O.begin(),
00684                         q_x_O.begin(), Is_nonnegative());
00685     ratio_test_1_B_S__t_i(B_S.begin(), B_S.end(), x_B_S.begin(),
00686                         q_x_S.begin(), Is_nonnegative());
00687 }    
00688 
00689 // ratio test for the basic original variables
00690 template < typename Q, typename ET, typename Tags >                         // Standard form
00691 void  QP_solver<Q, ET, Tags>::
00692 ratio_test_1_B_O__t_i(Index_iterator i_it, Index_iterator end_it,
00693                     Value_iterator x_it, Value_iterator q_it,
00694                     Tag_true  /*is_nonnegative*/)
00695 {    
00696     for ( ; i_it != end_it; ++i_it, ++x_it, ++q_it ) {
00697         test_implicit_bounds_dir_pos(*i_it, *x_it, *q_it, i, x_i, q_i);
00698     }
00699 }
00700 
00701 // ratio test for the basic original variables                    
00702 template < typename Q, typename ET, typename Tags >                         // Upper bounded
00703 void  QP_solver<Q, ET, Tags>::
00704 ratio_test_1_B_O__t_i(Index_iterator i_it, Index_iterator end_it,
00705                     Value_iterator x_it, Value_iterator q_it,
00706                     Tag_false /*is_nonnegative*/)
00707 {
00708     if (is_phaseI) {
00709         if (direction == 1) {
00710             for ( ; i_it != end_it; ++i_it, ++x_it, ++q_it ) {
00711                 test_mixed_bounds_dir_pos(*i_it, *x_it, *q_it, i, x_i, q_i);
00712             }
00713         } else {
00714             for ( ; i_it != end_it; ++i_it, ++x_it, ++q_it ) {
00715                 test_mixed_bounds_dir_neg(*i_it, *x_it, *q_it, i, x_i, q_i);
00716             }
00717         }
00718     } else {
00719         if (direction == 1) {
00720             for ( ; i_it != end_it; ++i_it, ++x_it, ++q_it ) {
00721                 test_explicit_bounds_dir_pos(*i_it, *x_it, *q_it, i, x_i, q_i);
00722             }
00723         } else {
00724             for ( ; i_it != end_it; ++i_it, ++x_it, ++q_it ) {
00725                 test_explicit_bounds_dir_neg(*i_it, *x_it, *q_it, i, x_i, q_i);
00726             }
00727         }
00728     }
00729 }
00730 
00731 // ratio test for the basic slack variables
00732 template < typename Q, typename ET, typename Tags >                         // Standard form
00733 void  QP_solver<Q, ET, Tags>::
00734 ratio_test_1_B_S__t_i(Index_iterator i_it, Index_iterator end_it,
00735                 Value_iterator x_it, Value_iterator q_it,
00736                 Tag_true  /*is_nonnegative*/)
00737 {
00738     for ( ; i_it != end_it; ++i_it, ++x_it, ++q_it ) {
00739         test_implicit_bounds_dir_pos(*i_it, *x_it, *q_it, i, x_i, q_i);
00740     }
00741 }
00742 
00743 // ratio test for the basic slack variables
00744 template < typename Q, typename ET, typename Tags >                         // Upper bounded
00745 void  QP_solver<Q, ET, Tags>::
00746 ratio_test_1_B_S__t_i(Index_iterator i_it, Index_iterator end_it,
00747                 Value_iterator x_it, Value_iterator q_it,
00748                 Tag_false /*is_nonnegative*/)
00749 {
00750     if (direction == 1) {
00751         for ( ; i_it != end_it; ++i_it, ++x_it, ++q_it ) {
00752             test_implicit_bounds_dir_pos(*i_it, *x_it, *q_it, i, x_i, q_i);
00753         }
00754     } else {
00755         for ( ; i_it != end_it; ++i_it, ++x_it, ++q_it ) {
00756             test_implicit_bounds_dir_neg(*i_it, *x_it, *q_it, i, x_i, q_i);
00757         }    
00758     }
00759 }
00760 
00761 // test for one basic variable with implicit bounds only,
00762 // note that this function writes the member variables i, x_i, q_i
00763 template < typename Q, typename ET, typename Tags >
00764 void  QP_solver<Q, ET, Tags>::
00765 test_implicit_bounds_dir_pos(int k, const ET& x_k, const ET& q_k, 
00766                                 int& i_min, ET& d_min, ET& q_min)
00767 {
00768     if ((q_k > et0) && (x_k * q_min < d_min * q_k)) {
00769         i_min = k;
00770         d_min = x_k;
00771         q_min = q_k;
00772     }
00773 }
00774 
00775 // test for one basic variable with implicit bounds only,
00776 // note that this function writes the member variables i, x_i, q_i
00777 template < typename Q, typename ET, typename Tags >
00778 void  QP_solver<Q, ET, Tags>::
00779 test_implicit_bounds_dir_neg(int k, const ET& x_k, const ET& q_k, 
00780                                 int& i_min, ET& d_min, ET& q_min)
00781 {
00782     if ((q_k < et0) && (x_k * q_min < -(d_min * q_k))) {
00783         i_min = k;
00784         d_min = x_k;
00785         q_min = -q_k;
00786     }
00787 }
00788 
00789 // test for one basic variable with explicit bounds only,
00790 // note that this function writes the member variables i, x_i, q_i and
00791 // ratio_test_bound_index, although the second and third variable name
00792 // are in the context of upper bounding misnomers
00793 template < typename Q, typename ET, typename Tags >
00794 void  QP_solver<Q, ET, Tags>::
00795 test_explicit_bounds_dir_pos(int k, const ET& x_k, const ET& q_k, 
00796                                 int& i_min, ET& d_min, ET& q_min)
00797 {
00798     if (q_k > et0) {                                // check for lower bound
00799         if (*(qp_fl+k)) {
00800             ET  diff = x_k - (d * ET(*(qp_l+k))); 
00801             if (diff * q_min < d_min * q_k) {
00802                 i_min = k;
00803                 d_min = diff;
00804                 q_min = q_k;
00805                 ratio_test_bound_index = LOWER;
00806             }
00807         }
00808     } else {                                        // check for upper bound
00809         if ((q_k < et0) && (*(qp_fu+k))) {
00810             ET  diff = (d * ET(*(qp_u+k))) - x_k;
00811             if (diff * q_min < -(d_min * q_k)) {
00812                 i_min = k;
00813                 d_min = diff;
00814                 q_min = -q_k;
00815                 ratio_test_bound_index = UPPER;
00816             }    
00817         }
00818     }
00819 }
00820 
00821 // test for one basic variable with explicit bounds only,
00822 // note that this function writes the member variables i, x_i, q_i and
00823 // ratio_test_bound_index, although the second and third variable name
00824 // are in the context of upper bounding misnomers
00825 template < typename Q, typename ET, typename Tags >
00826 void  QP_solver<Q, ET, Tags>::
00827 test_explicit_bounds_dir_neg(int k, const ET& x_k, const ET& q_k, 
00828                                 int& i_min, ET& d_min, ET& q_min)
00829 {
00830     if (q_k < et0) {                                // check for lower bound
00831         if (*(qp_fl+k)) {
00832             ET  diff = x_k - (d * ET(*(qp_l+k))); 
00833             if (diff * q_min < -(d_min * q_k)) {
00834                 i_min = k;
00835                 d_min = diff;
00836                 q_min = -q_k;
00837                 ratio_test_bound_index = LOWER;
00838             }
00839         }
00840     } else {                                        // check for upper bound
00841         if ((q_k > et0) && (*(qp_fu+k))) {
00842             ET  diff = (d * ET(*(qp_u+k))) - x_k;
00843             if (diff * q_min < d_min * q_k) {
00844                 i_min = k;
00845                 d_min = diff;
00846                 q_min = q_k;
00847                 ratio_test_bound_index = UPPER;
00848             }    
00849         }
00850     }
00851 }
00852 
00853 // test for one basic variable with mixed bounds,
00854 // note that this function writes the member variables i, x_i, q_i and
00855 // ratio_test_bound_index, although the second and third variable name
00856 // are in the context of upper bounding misnomers
00857 template < typename Q, typename ET, typename Tags >
00858 void  QP_solver<Q, ET, Tags>::
00859 test_mixed_bounds_dir_pos(int k, const ET& x_k, const ET& q_k, 
00860                                 int& i_min, ET& d_min, ET& q_min)
00861 {
00862     if (q_k > et0) {                                // check for lower bound
00863         if (k < qp_n) {                             // original variable
00864             if (*(qp_fl+k)) {
00865                 ET  diff = x_k - (d * ET(*(qp_l+k)));
00866                 if (diff * q_min < d_min * q_k) {
00867                     i_min = k;
00868                     d_min = diff;
00869                     q_min = q_k;
00870                     ratio_test_bound_index = LOWER;
00871                 }
00872             }
00873         } else {                                    // artificial variable
00874             if (x_k * q_min < d_min * q_k) {
00875                 i_min = k;
00876                 d_min = x_k;
00877                 q_min = q_k;
00878             }
00879         }
00880     } else {                                        // check for upper bound
00881         if ((q_k < et0) && (k < qp_n) && *(qp_fu+k)) {
00882             ET  diff = (d * ET(*(qp_u+k))) - x_k;
00883             if (diff * q_min < -(d_min * q_k)) {
00884                 i_min = k;
00885                 d_min = diff;
00886                 q_min = -q_k;
00887                 ratio_test_bound_index = UPPER;
00888             }
00889         }
00890     }
00891 }
00892 
00893 // test for one basic variable with mixed bounds,
00894 // note that this function writes the member variables i, x_i, q_i and
00895 // ratio_test_bound_index, although the second and third variable name
00896 // are in the context of upper bounding misnomers
00897 template < typename Q, typename ET, typename Tags >
00898 void  QP_solver<Q, ET, Tags>::
00899 test_mixed_bounds_dir_neg(int k, const ET& x_k, const ET& q_k, 
00900                                 int& i_min, ET& d_min, ET& q_min)
00901 {
00902     if (q_k < et0) {                                // check for lower bound
00903         if (k < qp_n) {                             // original variable
00904             if (*(qp_fl+k)) {
00905                 ET  diff = x_k - (d * ET(*(qp_l+k)));
00906                 if (diff * q_min < -(d_min * q_k)) {
00907                     i_min = k;
00908                     d_min = diff;
00909                     q_min = -q_k;
00910                     ratio_test_bound_index = LOWER;
00911                 }
00912             }
00913         } else {                                    // artificial variable
00914             if (x_k * q_min < -(d_min * q_k)) {
00915                 i_min = k;
00916                 d_min = x_k;
00917                 q_min = -q_k;
00918             }
00919         }
00920     } else {                                        // check for upper bound
00921         if ((q_k > et0) && (k < qp_n) && *(qp_fu+k)) {
00922             ET  diff = (d * ET(*(qp_u+k))) - x_k;
00923             if (diff * q_min < d_min * q_k) {
00924                 i_min = k;
00925                 d_min = diff;
00926                 q_min = q_k;
00927                 ratio_test_bound_index = UPPER;
00928             }
00929         }
00930     }
00931 }    
00932 
00933 
00934 template < typename Q, typename ET, typename Tags >                                         // QP case
00935 void
00936 QP_solver<Q, ET, Tags>::
00937 ratio_test_2( Tag_false)
00938 {
00939     // diagnostic output
00940     CGAL_qpe_debug {
00941         if ( vout2.verbose()) {
00942             vout2.out() << std::endl
00943                         << "Ratio Test (Step 2)" << std::endl
00944                         << "-------------------" << std::endl;
00945         }
00946     }
00947 
00948     // compute `p_lambda' and `p_x' (Note: `p_...' is stored in `q_...')
00949     ratio_test_2__p( no_ineq);
00950  
00951     // diagnostic output
00952     CGAL_qpe_debug {
00953         if ( vout3.verbose()) {
00954             vout3.out() << "p_lambda: ";
00955             std::copy( q_lambda.begin(), q_lambda.begin()+C.size(),
00956                        std::ostream_iterator<ET>( vout3.out()," "));
00957             vout3.out() << std::endl;
00958             vout3.out() << "   p_x_O: ";
00959             std::copy( q_x_O.begin(), q_x_O.begin()+B_O.size(),
00960                        std::ostream_iterator<ET>( vout3.out()," "));
00961             vout3.out() << std::endl;
00962             if ( has_ineq) {
00963                 vout3.out() << "   p_x_S: ";
00964                 std::copy( q_x_S.begin(), q_x_S.begin()+B_S.size(),
00965                            std::ostream_iterator<ET>( vout3.out()," "));
00966                 vout3.out() << std::endl;
00967             }
00968             vout3.out() << std::endl;
00969         }
00970     }
00971     
00972     // Idea here: At this point, the goal is to increase \mu_j until either we
00973     // become optimal (\mu_j=0), or one of the variables in x^*_\hat{B} drops
00974     // down to zero.
00975     //
00976     // Let us see first how this is done in the standard-form case (where
00977     // Sven's thesis applies).  Eq. (2.11) in Sven's thesis holds, and by
00978     // multlying it by $M_\hat{B}^{-1}$ we obtain an equation for \lambda and
00979     // x^*_\hat{B}.  The interesting equation (the one for x^*_\hat{B}) looks
00980     // more or less as follows:
00981     //
00982     //    x(mu_j)      = x(0) + mu_j      q_it                          (1)
00983     //
00984     // where q_it is the vector from (2.12).  In paritcular, for
00985     // mu_j=mu_j(t_1) (i.e., if we plug the value of mu_j at the beginning of
00986     // this ratio step 2 into (1)) we have
00987     //
00988     //    x(mu_j(t_1)) = x(0) + mu_j(t_1) q_it                          (2)
00989     //
00990     // where x(mu_j(t_1)) is the current solution of the solver at this point
00991     // (i.e., at the beginning of ratio step 2).
00992     //
00993     // By subtracting (2) from (1) we can thus eliminate the "unkown" x(0)
00994     // (which is cheaper than computing it):
00995     //
00996     //    x(mu_j) = x(mu_j(t_1)) + (mu_j-mu_j(t_1)) q_it
00997     //                             ----------------
00998     //                                  := delta
00999     //
01000     // In order to compute for each variable x_k in \hat{B} the value of mu_j
01001     // for which x_k(mu_j) = 0, we thus evaluate
01002     //
01003     //                x(mu_j(t_1))_k
01004     //    delta_k:= - --------------
01005     //                    q_it_k
01006     //
01007     // The first variable in \hat{B} that hits zero "in the future" is then
01008     // the one whose delta_k equals
01009     //
01010     //    delta_min:= min {delta_k | k in \hat{B} and (q_it)_k < 0 }
01011     //    
01012     // So in order to handle the standard-form case, we would compute this
01013     // minimum.  Once we have delta_min, we need to check whether we get
01014     // optimal BEFORE a variable drops to zero.  As delta = mu_j - mu_j(t_1),
01015     // the latter is precisely the case if delta_min >= -mu_j(t_1).
01016     //
01017     // (Note: please forget the crap identitiy between (2.11) and (2.12); the
01018     // notation is misleading.)
01019     //
01020     // Now to the nonstandard-form case.
01021     
01022     // fw: By definition delta_min >= 0, such that initializing
01023     // delta_min with -mu_j(t_1) has the desired effect that a basic variable
01024     // is leaving only if 0 <= delta_min < -mu_j(t_1).
01025     //
01026     // The only initialization of delta_min as fraction x_i/q_i that works is
01027     // x_i=mu_j(t_1); q_i=-1; (see below).
01028     //
01029     // Since mu_j(t_1) has been computed in ratio test step 1 we can
01030     // reuse it.
01031       
01032     x_i = mu;                                     // initialize minimum
01033     q_i = -et1;                                        // with -mu_j(t_1) 
01034 
01035     Value_iterator  x_it = x_B_O.begin();
01036     Value_iterator  q_it = q_x_O.begin();
01037     Index_iterator  i_it;
01038     for ( i_it = B_O.begin(); i_it != B_O.end(); ++i_it, ++x_it, ++q_it) {
01039         if ( ( *q_it < et0) && ( ( *x_it * q_i) < ( x_i * *q_it))) {
01040             i = *i_it; x_i = *x_it; q_i = *q_it;
01041         }
01042     }
01043     x_it = x_B_S.begin();
01044     q_it = q_x_S.begin();
01045     for ( i_it = B_S.begin(); i_it != B_S.end(); ++i_it, ++x_it, ++q_it) {
01046         if ( ( *q_it < et0) && ( ( *x_it * q_i) < ( x_i * *q_it))) {
01047             i = *i_it; x_i = *x_it; q_i = *q_it;
01048         }
01049     }
01050 
01051     CGAL_qpe_debug {
01052         if ( vout2.verbose()) {
01053             for ( unsigned int k = 0; k < B_O.size(); ++k) {
01054                 vout2.out() << "mu_j_O_" << k << ": - "
01055                             << x_B_O[ k] << '/' << q_x_O[ k]
01056                             << ( ( q_i < et0) && ( i == B_O[ k]) ? " *" : "")
01057                             << std::endl;
01058             }
01059             for ( unsigned int k = 0; k < B_S.size(); ++k) {
01060                 vout2.out() << "mu_j_S_" << k << ": - "
01061                             << x_B_S[ k] << '/' << q_x_S[ k]
01062                             << ( ( q_i < et0) && ( i == B_S[ k]) ? " *" : "")
01063                             << std::endl;
01064             }
01065             vout2.out() << std::endl;
01066         }
01067     }
01068     if ( i < 0) {
01069       vout2 << "leaving variable: none" << std::endl;
01070     } else {
01071       vout1 << ", ";
01072       vout  << "leaving"; vout2 << " variable"; vout << ": ";
01073       vout  << i;
01074       if ( vout2.verbose()) {
01075         if ( i < qp_n) {
01076           vout2.out() << " (= B_O[ " << in_B[ i] << "]: original)"
01077                       << std::endl;
01078         } else {
01079           vout2.out() << " (= B_S[ " << in_B[ i] << "]: slack)"
01080                       << std::endl;
01081         }
01082       }
01083     }
01084     
01085 }
01086 
01087 // update (step 1)
01088 template < typename Q, typename ET, typename Tags >
01089 void
01090 QP_solver<Q, ET, Tags>::
01091 update_1( )
01092 {
01093     CGAL_qpe_debug {
01094         if ( vout2.verbose()) {
01095             vout2.out() << std::endl;
01096             if ( is_LP || is_phaseI) {
01097                 vout2.out() << "------" << std::endl
01098                             << "Update" << std::endl
01099                             << "------" << std::endl;
01100             } else {
01101                 vout2.out() << "Update (Step 1)" << std::endl
01102                             << "---------------" << std::endl;
01103             }
01104         }
01105     }
01106 
01107     // update basis & basis inverse
01108     update_1( Is_linear());
01109     CGAL_qpe_assertion(check_basis_inverse());
01110     
01111     // check the updated vectors r_C and r_S_B
01112     CGAL_expensive_assertion(check_r_C(Is_nonnegative()));
01113     CGAL_expensive_assertion(check_r_S_B(Is_nonnegative()));
01114     
01115     // check the vectors r_B_O and w in phaseII for QPs
01116     CGAL_qpe_debug {
01117         if (is_phaseII && is_QP) {
01118             CGAL_expensive_assertion(check_r_B_O(Is_nonnegative()));
01119             CGAL_expensive_assertion(check_w(Is_nonnegative()));
01120         }
01121     }
01122 
01123     // compute current solution
01124     compute_solution(Is_nonnegative());
01125     
01126     // check feasibility 
01127     CGAL_qpe_debug {
01128       if (j < 0 && !is_RTS_transition) // todo kf: is this too conservative?
01129                  // Note: the above condition is necessary because of the
01130                  // following.  In theory, it is true that the current
01131                  // solution is at this point in the solver always
01132                  // feasible. However, the solution has its x_j-entry equal to
01133                  // the current t from the pricing, and is not zero (in the
01134                  // standard-form case) or the current lower/upper bound
01135                  // of the variable (in the non-standard-form case), resp., as
01136                  // the routines is_solution_feasible() and
01137                  // is_solution_feasible_for_auxiliary_problem() assume.
01138         if (is_phaseI) {
01139           CGAL_expensive_assertion(
01140             is_solution_feasible_for_auxiliary_problem());
01141         } else {
01142           CGAL_expensive_assertion(is_solution_feasible());
01143         }
01144       else
01145         vout2 << "(feasibility not checked in intermediate step)" << std::endl;
01146       CGAL_expensive_assertion(check_tag(Is_nonnegative()) ||
01147                                r_C.size() == C.size());
01148     }
01149          
01150 }
01151 
01152 // update (step 2)
01153 template < typename Q, typename ET, typename Tags >                                         // QP case
01154 void
01155 QP_solver<Q, ET, Tags>::
01156 update_2( Tag_false)
01157 {
01158     CGAL_qpe_debug {
01159         vout2 << std::endl
01160               << "Update (Step 2)" << std::endl
01161               << "---------------" << std::endl;
01162     }
01163 
01164     // leave variable from basis
01165     leave_variable();
01166     CGAL_qpe_debug {
01167         check_basis_inverse();
01168     }
01169     
01170     // check the updated vectors r_C, r_S_B, r_B_O and w
01171     CGAL_expensive_assertion(check_r_C(Is_nonnegative()));
01172     CGAL_expensive_assertion(check_r_S_B(Is_nonnegative()));
01173     CGAL_expensive_assertion(check_r_B_O(Is_nonnegative()));
01174     CGAL_expensive_assertion(check_w(Is_nonnegative()));
01175 
01176     // compute current solution
01177     compute_solution(Is_nonnegative());
01178 }
01179  
01180 template < typename Q, typename ET, typename Tags >
01181 void
01182 QP_solver<Q, ET, Tags>::
01183 expel_artificial_variables_from_basis( )
01184 {
01185     int row_ind;
01186     ET r_A_Cj;
01187     
01188     CGAL_qpe_debug {
01189         vout2 << std::endl
01190               << "---------------------------------------------" << std::endl
01191               << "Expelling artificial variables from the basis" << std::endl
01192               << "---------------------------------------------" << std::endl;
01193     }
01194     
01195     // try to pivot the artificials out of the basis
01196     // Note that we do not notify the pricing strategy about variables
01197     // leaving the basis, furthermore the pricing strategy does not
01198     // know about variables entering the basis.
01199     // The partial pricing strategies that keep the set of nonbasic vars
01200     // explicitly are synchronized during transition from phaseI to phaseII 
01201     for (unsigned int i_ = qp_n + slack_A.size(); i_ < in_B.size(); ++i_) {
01202         if (is_basic(i_)) {                                     // is basic
01203             if (has_ineq) {
01204                 row_ind = in_C[ art_A[i_ - qp_n - slack_A.size()].first];
01205             } else {
01206                 row_ind = art_A[i_ - qp_n].first;
01207             }
01208             
01209             // determine first possible entering variable,
01210             // if there is any
01211             for (unsigned int j_ = 0; j_ < qp_n + slack_A.size(); ++j_) {
01212                 if (!is_basic(j_)) {                            // is nonbasic 
01213                     ratio_test_init__A_Cj( A_Cj.begin(), j_, no_ineq);
01214                     r_A_Cj = inv_M_B.inv_M_B_row_dot_col(row_ind, A_Cj.begin());
01215                     if (r_A_Cj != et0) {
01216                         ratio_test_1__q_x_O(Is_linear());
01217                         i = i_;
01218                         j = j_;
01219                         update_1(Is_linear());
01220                         break;
01221                     } 
01222                 }
01223             }
01224         }
01225     }
01226     if ((art_basic != 0) && no_ineq) {
01227       // the vector in_C was not used in phase I, but now we remove redundant
01228       // constraints and switch to has_ineq treatment, hence we need it to
01229       // be correct at this stage
01230       for (int i=0; i<qp_m; ++i)
01231         in_C.push_back(i);
01232     }
01233     diagnostics.redundant_equations = (art_basic != 0);
01234 
01235     // now reset the no_ineq and has_ineq flags to match the situation
01236     no_ineq = no_ineq && !diagnostics.redundant_equations;
01237     has_ineq = !no_ineq;
01238     
01239     // remove the remaining ones with their corresponding equality constraints
01240     // Note: the special artificial variable can always be driven out of the
01241     // basis
01242     for (unsigned int i_ = qp_n + slack_A.size(); i_ < in_B.size(); ++i_) {
01243         if (in_B[i_] >= 0) {
01244             i = i_;
01245             CGAL_qpe_debug {
01246                 vout2 << std::endl
01247                       << "~~> removing artificial variable " << i
01248                       << " and its equality constraint" << std::endl
01249                       << std::endl;
01250             }
01251             remove_artificial_variable_and_constraint();
01252         }
01253     }
01254 }
01255 
01256 
01257 // replace variable in basis
01258 template < typename Q, typename ET, typename Tags >
01259 void
01260 QP_solver<Q, ET, Tags>::
01261 replace_variable( )
01262 {
01263     CGAL_qpe_debug {
01264         vout2 <<   "<--> nonbasic (" << variable_type( j) << ") variable " << j
01265               << " replaces basic (" << variable_type( i) << ") variable " << i
01266               << std::endl << std::endl;
01267     }
01268 
01269     // replace variable
01270     replace_variable( no_ineq);
01271 
01272     // pivot step done
01273     i = j = -1;
01274 }
01275 
01276 template < typename Q, typename ET, typename Tags >
01277 void  QP_solver<Q, ET, Tags>::
01278 replace_variable_original_original( )
01279 {
01280     // updates for the upper bounded case
01281     replace_variable_original_original_upd_r(Is_nonnegative());
01282     
01283     int  k = in_B[ i];
01284 
01285     // replace original variable [ in: j | out: i ]
01286     in_B  [ i] = -1;
01287     in_B  [ j] = k;
01288        B_O[ k] = j;
01289 
01290     minus_c_B[ k] = 
01291       ( is_phaseI ? 
01292         ( j < qp_n ? et0 : -aux_c[j-qp_n-slack_A.size()]) : -ET( *(qp_c+ j)));
01293 
01294     if ( is_phaseI) {
01295         if ( j >= qp_n) ++art_basic;
01296         if ( i >= qp_n) --art_basic;
01297     }
01298 
01299     // diagnostic output
01300     CGAL_qpe_debug {
01301         if ( vout2.verbose()) print_basis();
01302     }
01303             
01304     // update basis inverse
01305     inv_M_B.enter_original_leave_original( q_x_O.begin(), k);
01306 }
01307 
01308 // update of the vector r for U_5 with upper bounding, note that we 
01309 // need the headings C, and S_{B} before they are updated
01310 template < typename Q, typename ET, typename Tags >                            // Standard form      
01311 void  QP_solver<Q, ET, Tags>::
01312 replace_variable_original_original_upd_r(Tag_true )
01313 {
01314 }
01315 
01316 // update of the vector r for U_5 with upper bounding, note that we 
01317 // need the headings C, and S_{B} before they are updated
01318 template < typename Q, typename ET, typename Tags >                            // Upper bounded      
01319 void  QP_solver<Q, ET, Tags>::
01320 replace_variable_original_original_upd_r(Tag_false )
01321 {
01322     ET      x_j, x_i;
01323     
01324     if (is_artificial(j)) {
01325         if (!is_artificial(i)) {
01326             x_i = (ratio_test_bound_index == LOWER) ? *(qp_l+i) : *(qp_u+i);
01327             update_r_C_r_S_B__i(x_i);
01328             // update x_O_v_i
01329             x_O_v_i[i] = ratio_test_bound_index;
01330         }
01331     } else {
01332         x_j = nonbasic_original_variable_value(j);
01333         if (is_artificial(i)) {
01334             update_r_C_r_S_B__j(x_j);
01335         } else {
01336             x_i = (ratio_test_bound_index == LOWER) ? *(qp_l+i) : *(qp_u+i);
01337             update_r_C_r_S_B__j_i(x_j, x_i);
01338             // update x_O_v_i
01339             x_O_v_i[i] = ratio_test_bound_index;
01340         }
01341         // update x_O_v_i
01342         x_O_v_i[j] = BASIC;
01343     }
01344 }
01345 
01346 
01347 template < typename Q, typename ET, typename Tags >
01348 void  QP_solver<Q, ET, Tags>::
01349 replace_variable_slack_slack( )
01350 {
01351     
01352     // updates for the upper bounded case
01353     replace_variable_slack_slack_upd_r(Is_nonnegative()); 
01354     
01355     int  k = in_B[ i];
01356 
01357     // replace slack variable [ in: j | out: i ]
01358     in_B  [ i] = -1;
01359     in_B  [ j] = k;
01360        B_S[ k] = j;
01361        S_B[ k] = slack_A[ j-qp_n].first;
01362 
01363     // replace inequality constraint [ in: i | out: j ]
01364     int old_row = S_B[ k];
01365     int new_row = slack_A[ i-qp_n].first;
01366     k = in_C[ old_row];
01367 
01368     in_C[ old_row] = -1;
01369     in_C[ new_row] = k;
01370        C[ k      ] = new_row;
01371 
01372      b_C[ k] = ET( *(qp_b+ new_row));
01373 
01374     // diagnostic output
01375     CGAL_qpe_debug {
01376         if ( vout2.verbose()) print_basis();
01377     }
01378 
01379     // update basis inverse
01380     A_row_by_index_accessor  a_accessor =
01381       boost::bind( A_accessor( qp_A, 0, qp_n), _1, new_row);
01382     std::copy( A_row_by_index_iterator( B_O.begin(), a_accessor),
01383                A_row_by_index_iterator( B_O.end  (), a_accessor),
01384                tmp_x.begin());
01385     if ( art_s_i > 0) {                                 // special artificial
01386         tmp_x[ in_B[ art_s_i]] = ET( art_s[ new_row]);
01387     }
01388     inv_M_B.enter_slack_leave_slack( tmp_x.begin(), k);
01389 }
01390 
01391 // update of the vector r for U_6 with upper bounding, note that we 
01392 // need the headings C, and S_{B} before they are updated
01393 template < typename Q, typename ET, typename Tags >                            // Standard form      
01394 void  QP_solver<Q, ET, Tags>::
01395 replace_variable_slack_slack_upd_r(Tag_true )
01396 {
01397 }
01398 
01399 // update of the vector r for U_6 with upper bounding, note that we 
01400 // need the headings C, and S_{B} before they are updated
01401 template < typename Q, typename ET, typename Tags >                            // Upper bounded      
01402 void  QP_solver<Q, ET, Tags>::
01403 replace_variable_slack_slack_upd_r(Tag_false )
01404 {
01405     int     sigma_j = slack_A[ j-qp_n].first;
01406     
01407     // swap r_gamma_C(sigma_j) in r_C with r_gamma_S_B(sigma_i) in r_S_B
01408     std::swap(r_C[in_C[sigma_j]], r_S_B[in_B[i]]); 
01409 }
01410 
01411 
01412 template < typename Q, typename ET, typename Tags >
01413 void  QP_solver<Q, ET, Tags>::
01414 replace_variable_slack_original( )
01415 {
01416     // updates for the upper bounded case
01417     replace_variable_slack_original_upd_r(Is_nonnegative()); 
01418      
01419     int  k = in_B[ i];
01420 
01421     // leave original variable [ out: i ]
01422     in_B  [ B_O.back()] = k;
01423        B_O[ k] = B_O.back();
01424        in_B  [ i         ] = -1;
01425        B_O.pop_back();
01426 
01427     minus_c_B[ k] = minus_c_B[ B_O.size()];
01428 
01429     if ( is_phaseI && ( i >= qp_n)) --art_basic;
01430 
01431     // enter slack variable [ in: j ]
01432     int  old_row = slack_A[ j-qp_n].first;
01433     in_B  [ j] = B_S.size();
01434        B_S.push_back( j);
01435        S_B.push_back( old_row);
01436 
01437     // leave inequality constraint [ out: j ]
01438     int  l = in_C[ old_row];
01439      b_C[ l       ] = b_C[ C.size()-1];
01440        C[ l       ] = C.back();
01441     in_C[ C.back()] = l;
01442     in_C[ old_row ] = -1;
01443        C.pop_back();
01444     // diagnostic output
01445     CGAL_qpe_debug {
01446         if ( vout2.verbose()) print_basis();
01447     }
01448 
01449     // update basis inverse
01450     inv_M_B.swap_variable( k);
01451     inv_M_B.swap_constraint( l);
01452     inv_M_B.enter_slack_leave_original();
01453 }
01454 
01455 // update of the vector r for U_8 with upper bounding, note that we 
01456 // need the headings C, and S_{B} before they are updated
01457 template < typename Q, typename ET, typename Tags >                            // Standard form      
01458 void  QP_solver<Q, ET, Tags>::
01459 replace_variable_slack_original_upd_r(Tag_true )
01460 {
01461 }
01462 
01463 // update of the vector r for U_8 with upper bounding, note that we 
01464 // need the headings C, and S_{B} before they are updated
01465 template < typename Q, typename ET, typename Tags >                            // Upper bounded      
01466 void  QP_solver<Q, ET, Tags>::
01467 replace_variable_slack_original_upd_r(Tag_false )
01468 {
01469     if (!is_artificial(i)) {
01470         ET  x_i = (ratio_test_bound_index == LOWER) ? *(qp_l+i) : *(qp_u+i);
01471         update_r_C_r_S_B__i(x_i);
01472     }
01473     
01474     int     sigma_j = slack_A[ j-qp_n].first;
01475     
01476     // append r_gamma_C(sigma_j) from r_C to r_S_B:
01477     r_S_B.push_back(r_C[in_C[sigma_j]]);
01478     
01479     // remove r_gamma_C(sigma_j) from r_C:
01480     r_C[in_C[sigma_j]] = r_C.back();
01481     r_C.pop_back();
01482     
01483     // update x_O_v_i
01484     if (!is_artificial(i)) // original and not artificial?
01485       x_O_v_i[i] = ratio_test_bound_index;
01486 }
01487 
01488 
01489 template < typename Q, typename ET, typename Tags >
01490 void  QP_solver<Q, ET, Tags>::
01491 replace_variable_original_slack( )
01492 {
01493     // updates for the upper bounded case
01494     replace_variable_original_slack_upd_r(Is_nonnegative());
01495     
01496     int  k = in_B[ i];
01497 
01498     // enter original variable [ in: j ]
01499 
01500     minus_c_B[ B_O.size()]
01501       = ( is_phaseI ? 
01502           ( j < qp_n ? et0 : -aux_c[j-qp_n-slack_A.size()]) 
01503           : -ET( *(qp_c+ j)));
01504     
01505 
01506     in_B  [ j] = B_O.size();
01507        B_O.push_back( j);
01508 
01509     if ( is_phaseI && ( j >= qp_n)) ++art_basic;
01510 
01511     // leave slack variable [ out: i ]
01512        B_S[ k         ] = B_S.back();
01513        S_B[ k         ] = S_B.back();
01514     in_B  [ B_S.back()] = k;
01515     in_B  [ i         ] = -1; 
01516        B_S.pop_back();
01517        S_B.pop_back();
01518 
01519     // enter inequality constraint [ in: i ]
01520     int new_row = slack_A[ i-qp_n].first;
01521 
01522      b_C[ C.size()] = ET( *(qp_b+ new_row));
01523     in_C[ new_row ] = C.size();
01524        C.push_back( new_row);
01525     // diagnostic output
01526     CGAL_qpe_debug {
01527         if ( vout2.verbose()) print_basis();
01528     }
01529 
01530     // update basis inverse
01531     A_row_by_index_accessor  a_accessor =
01532       boost::bind (A_accessor( qp_A, 0, qp_n), _1, new_row);
01533     std::copy( A_row_by_index_iterator( B_O.begin(), a_accessor),
01534                A_row_by_index_iterator( B_O.end  (), a_accessor),
01535                tmp_x.begin());
01536     if ( art_s_i > 0) {                                 // special art.
01537         tmp_x[ in_B[ art_s_i]] = ET( art_s[ new_row]);
01538     }
01539     inv_M_B.enter_original_leave_slack( q_x_O.begin(), tmp_x.begin());
01540     
01541 }
01542 
01543 // update of the vector r for U_7 with upper bounding, note that we 
01544 // need the headings C, and S_{B} before they are updated
01545 template < typename Q, typename ET, typename Tags >                            // Standard form      
01546 void  QP_solver<Q, ET, Tags>::
01547 replace_variable_original_slack_upd_r(Tag_true )
01548 {
01549 }
01550 
01551 // update of the vector r for U_7 with upper bounding, note that we 
01552 // need the headings C, and S_{B} before they are updated
01553 template < typename Q, typename ET, typename Tags >                            // Upper bounded      
01554 void  QP_solver<Q, ET, Tags>::
01555 replace_variable_original_slack_upd_r(Tag_false )
01556 {
01557     if (!is_artificial(j)) {
01558         ET x_j = nonbasic_original_variable_value(j);
01559         update_r_C_r_S_B__j(x_j);
01560     }
01561     
01562     // append r_gamma_S_B(sigma_i) from r_S_B to r_C
01563     r_C.push_back(r_S_B[in_B[i]]);
01564     
01565     // remove r_gamma_S_B(sigma_i) from r_S_B
01566     r_S_B[in_B[i]] = r_S_B.back();
01567     r_S_B.pop_back();
01568     
01569     // update x_O_v_i
01570     if (!is_artificial(j)) {
01571         x_O_v_i[j] = BASIC;
01572     }
01573 }
01574 
01575 
01576 template < typename Q, typename ET, typename Tags >
01577 void  QP_solver<Q, ET, Tags>::
01578 remove_artificial_variable_and_constraint( )
01579 {
01580     // updates for the upper bounded case
01581     remove_artificial_variable_and_constraint_upd_r(Is_nonnegative());
01582     
01583     int  k = in_B[ i];
01584 
01585     // leave artificial (original) variable [ out: i ]
01586     in_B  [ B_O.back()] = k;
01587        B_O[ k] = B_O.back();
01588        in_B  [ i         ] = -1;
01589        B_O.pop_back();
01590 
01591     minus_c_B[ k] = minus_c_B[ B_O.size()];
01592 
01593     if ( is_phaseI && ( i >= qp_n)) --art_basic;
01594 
01595     int old_row = art_A[i - qp_n - slack_A.size()].first;
01596 
01597     // leave its equality constraint 
01598     int  l = in_C[ old_row];
01599      b_C[ l       ] = b_C[ C.size()-1];
01600        C[ l       ] = C.back();
01601     in_C[ C.back()] = l;
01602     in_C[ old_row ] = -1;
01603        C.pop_back();
01604     // diagnostic output
01605     CGAL_qpe_debug {
01606         if ( vout2.verbose()) print_basis();
01607     }
01608 
01609     // update basis inverse
01610     inv_M_B.swap_variable( k);
01611     inv_M_B.swap_constraint( l);
01612     inv_M_B.enter_slack_leave_original();
01613 }
01614 
01615 // update of the vector r with upper bounding for the removal of an
01616 // artificial variable with its equality constraint, note that we 
01617 // need the headings C before it is updated
01618 template < typename Q, typename ET, typename Tags >                                 // Standard form
01619 void  QP_solver<Q, ET, Tags>::
01620 remove_artificial_variable_and_constraint_upd_r(Tag_true )
01621 {
01622 }
01623 
01624 // update of the vector r with upper bounding for the removal of an
01625 // artificial variable with its equality constraint, note that we 
01626 // need the headings C before it is updated
01627 template < typename Q, typename ET, typename Tags >                                 // Upper bounded
01628 void  QP_solver<Q, ET, Tags>::
01629 remove_artificial_variable_and_constraint_upd_r(Tag_false )
01630 {
01631     int sigma_i = art_A[i - qp_n - slack_A.size()].first;
01632     
01633     // remove r_gamma_C(sigma_i) from r_C
01634     r_C[in_C[sigma_i]] = r_C.back();
01635     r_C.pop_back();
01636 }
01637 
01638 // update that occurs only with upper bounding in ratio test step 1
01639 template < typename Q, typename ET, typename Tags >            
01640 void  QP_solver<Q, ET, Tags>::
01641 enter_and_leave_variable( )
01642 {
01643     
01644     CGAL_qpe_assertion((i == j) && (i >= 0));
01645     
01646     CGAL_qpe_debug {
01647         vout2 <<   "<--> nonbasic (" << variable_type( j) << ") variable " << j
01648               << " enters and leaves basis" << std::endl << std::endl;
01649     }
01650 
01651     
01652     ET diff;
01653     ET x_j = nonbasic_original_variable_value(j);
01654     
01655     if (ratio_test_bound_index == LOWER) {
01656         diff = x_j - ET(*(qp_l+j));
01657     } else {
01658         diff = x_j - ET(*(qp_u+j));
01659     }
01660     
01661     if (is_phaseI) {
01662         update_r_C_r_S_B__j(diff);
01663     } else {
01664         update_w_r_B_O__j(diff);
01665         update_r_C_r_S_B__j(diff);
01666     }
01667     
01668     x_O_v_i[j] = ratio_test_bound_index;
01669     
01670     // notify pricing strategy (it has called enter_basis on i before)
01671     strategyP->leaving_basis (i);
01672 
01673     // variable entered and left basis
01674     i = -1; j = -1;
01675 }
01676 
01677 
01678 
01679 // enter variable into basis
01680 template < typename Q, typename ET, typename Tags >
01681 void
01682 QP_solver<Q, ET, Tags>::
01683 enter_variable( )
01684 {
01685   CGAL_qpe_assertion (is_phaseII);
01686     CGAL_qpe_debug {
01687         vout2 << "--> nonbasic (" << variable_type( j) << ") variable "
01688               << j << " enters basis" << std::endl << std::endl;
01689     }
01690 
01691     // update basis & basis inverse:
01692     if (no_ineq || (j < qp_n)) {              // original variable
01693     
01694         // updates for the upper bounded case:
01695         enter_variable_original_upd_w_r(Is_nonnegative());
01696 
01697         // enter original variable [ in: j ]:
01698         if (minus_c_B.size() <= B_O.size()) { // Note: minus_c_B and the
01699                                               // containers resized in this
01700                                               // if-block are only enlarged
01701                                               // and never made smaller
01702                                               // (while B_O always has the
01703                                               // correct size). We check here
01704                                               // whether we need to enlarge
01705                                               // them.
01706           CGAL_qpe_assertion(minus_c_B.size() == B_O.size());
01707             minus_c_B.push_back(et0);
01708                 q_x_O.push_back(et0);
01709               tmp_x  .push_back(et0);
01710               tmp_x_2.push_back(et0);
01711              two_D_Bj.push_back(et0);
01712                 x_B_O.push_back(et0);
01713         }
01714         minus_c_B[B_O.size()] = -ET(*(qp_c+ j)); // Note: B_O has always the
01715                                                // correct size.
01716         
01717         in_B[j] = B_O.size();
01718         B_O.push_back(j);
01719 
01720         // diagnostic output
01721         CGAL_qpe_debug {
01722             if (vout2.verbose())
01723               print_basis();
01724         }
01725             
01726         // update basis inverse
01727         // note: (-1)\hat{\nu} is stored instead of \hat{\nu}
01728         inv_M_B.enter_original(q_lambda.begin(), q_x_O.begin(), -nu);
01729         
01730     } else {                                  // slack variable
01731 
01732         // updates for the upper bounded case:
01733         enter_variable_slack_upd_w_r(Is_nonnegative());
01734 
01735         // enter slack variable [ in: j ]:
01736         in_B  [ j] = B_S.size();
01737            B_S.push_back( j);
01738            S_B.push_back( slack_A[ j-qp_n].first);
01739 
01740         // leave inequality constraint [ out: j ]:
01741         int old_row = slack_A[ j-qp_n].first;
01742         int k = in_C[old_row];
01743         
01744         // reflect change of active constraints heading C in b_C:
01745         b_C[ k] = b_C[C.size()-1];
01746                 
01747            C[ k] = C.back();
01748         in_C[ C.back()      ] = k;
01749         in_C[ old_row       ] = -1;
01750            C.pop_back();
01751         
01752         // diagnostic output:
01753         CGAL_qpe_debug {
01754             if (vout2.verbose())
01755               print_basis();
01756         }
01757 
01758         // update basis inverse:
01759         inv_M_B.swap_constraint(k);  // swap to back
01760         inv_M_B.enter_slack();       // drop drop
01761     }
01762 
01763     // variable entered:
01764     j -= in_B.size();
01765 }
01766 
01767 // update of the vectors w and r for U_1 with upper bounding, note that we 
01768 // need the headings C, S_{B}, B_{O} before they are updated
01769 template < typename Q, typename ET, typename Tags >                            // Standard form      
01770 void  QP_solver<Q, ET, Tags>::
01771 enter_variable_original_upd_w_r(Tag_true )
01772 {
01773 }
01774 
01775 // update of the vectors w and r for U_1 with upper bounding, note that we 
01776 // need the headings C, S_{B}, B_{O} before they are updated
01777 template < typename Q, typename ET, typename Tags >                            // Upper bounded     
01778 void  QP_solver<Q, ET, Tags>::
01779 enter_variable_original_upd_w_r(Tag_false )
01780 {
01781 
01782     ET      x_j = nonbasic_original_variable_value(j);
01783 
01784     // Note: w needs to be updated before r_C, r_S_B
01785     update_w_r_B_O__j(x_j);
01786     update_r_C_r_S_B__j(x_j);
01787     
01788     // append w_j to r_B_O
01789     if (!check_tag(Is_linear())) // (kf.)
01790       r_B_O.push_back(w[j]);
01791     
01792     // update x_O_v_i
01793     x_O_v_i[j] = BASIC;
01794 }
01795 
01796 // update of the vectors w and r for U_3 with upper bounding, note that we 
01797 // need the headings C, S_{B}, B_{O} before they are updated
01798 template < typename Q, typename ET, typename Tags >                            // Standard form      
01799 void  QP_solver<Q, ET, Tags>::
01800 enter_variable_slack_upd_w_r(Tag_true )
01801 {
01802 }
01803 
01804 // update of the vectors w and r for U_3 with upper bounding, note that we 
01805 // need the headings C, S_{B}, B_{O} before they are updated
01806 template < typename Q, typename ET, typename Tags >                            // Upper bounded     
01807 void  QP_solver<Q, ET, Tags>::
01808 enter_variable_slack_upd_w_r(Tag_false )
01809 {
01810     
01811     int     sigma_j = slack_A[ j-qp_n].first;       
01812     
01813     // append r_gamma_C(sigma_j) to r_S_B
01814     r_S_B.push_back(r_C[in_C[sigma_j]]);
01815     
01816     // remove r_gamma_C(sigma_j) from r_C   
01817     r_C[in_C[sigma_j]] = r_C.back();
01818     r_C.pop_back();
01819 }
01820 
01821 // leave variable from basis
01822 template < typename Q, typename ET, typename Tags >
01823 void
01824 QP_solver<Q, ET, Tags>::
01825 leave_variable( )
01826 {
01827     CGAL_qpe_debug {
01828         vout2 << "<-- basic (" << variable_type( i) << ") variable "
01829               << i << " leaves basis" << std::endl << std::endl;
01830     }
01831 
01832     // update basis & basis inverse
01833     int  k = in_B[ i];
01834     if ( no_ineq || ( i < qp_n)) {                      // original variable
01835         
01836         // updates for the upper bounded case
01837         leave_variable_original_upd_w_r(Is_nonnegative());
01838 
01839         // leave original variable [ out: i ]
01840         in_B  [ B_O.back()] = k;
01841         in_B  [ i         ] = -1; 
01842         //in_B  [ B_O.back()] = k;
01843            B_O[ k] = B_O.back(); B_O.pop_back();
01844 
01845         minus_c_B [ k] = minus_c_B [ B_O.size()];
01846           two_D_Bj[ k] =   two_D_Bj[ B_O.size()];
01847           
01848 
01849         // diagnostic output
01850         CGAL_qpe_debug {
01851             if ( vout2.verbose()) print_basis();
01852         }
01853 
01854         // update basis inverse
01855         inv_M_B.swap_variable( k);
01856         inv_M_B.leave_original();
01857 
01858     } else {                                            // slack variable
01859         
01860         // updates for the upper bounded case
01861         leave_variable_slack_upd_w_r(Is_nonnegative());
01862 
01863         // leave slack variable [ out: i ]
01864         in_B  [ B_S.back()] = k;      // former last var moves to position k
01865         in_B  [ i         ] = -1;     // i gets deleted
01866            B_S[ k] = B_S.back(); B_S.pop_back();
01867            S_B[ k] = S_B.back(); S_B.pop_back();
01868 
01869         // enter inequality constraint [ in: i ]
01870         int new_row = slack_A[ i-qp_n].first;
01871 
01872         A_Cj[ C.size()] = ( j < qp_n ? ET( *((*(qp_A + j))+ new_row)) : et0);
01873 
01874          b_C[ C.size()] = ET( *(qp_b+ new_row));
01875         in_C[ new_row ] = C.size();
01876            C.push_back( new_row);
01877 
01878         // diagnostic output
01879         CGAL_qpe_debug {
01880             if ( vout2.verbose()) print_basis();
01881         }
01882 
01883         // update basis inverse
01884         A_row_by_index_accessor  a_accessor =
01885           boost::bind (A_accessor( qp_A, 0, qp_n), _1, new_row);
01886         std::copy( A_row_by_index_iterator( B_O.begin(), a_accessor),
01887                    A_row_by_index_iterator( B_O.end  (), a_accessor),
01888                    tmp_x.begin());
01889         inv_M_B.leave_slack( tmp_x.begin());
01890     }
01891 
01892     // notify pricing strategy
01893     strategyP->leaving_basis( i);
01894 
01895     // variable left
01896     i = -1;
01897 }
01898 
01899 // update of the vectors w and r for U_2 with upper bounding, note that we 
01900 // need the headings C, S_{B}, B_{O} before they are updated
01901 template < typename Q, typename ET, typename Tags >                            // Standard form      
01902 void  QP_solver<Q, ET, Tags>::
01903 leave_variable_original_upd_w_r(Tag_true )
01904 {
01905 }
01906 
01907 // update of the vectors w and r for U_2 with upper bounding, note that we 
01908 // need the headings C, S_{B}, B_{O} before they are updated
01909 template < typename Q, typename ET, typename Tags >                            // Upper bounded      
01910 void  QP_solver<Q, ET, Tags>::
01911 leave_variable_original_upd_w_r(Tag_false )
01912 {
01913 
01914     ET      x_i = (ratio_test_bound_index == LOWER) ? *(qp_l+i) : *(qp_u+i);
01915     
01916     // Note: w needs to be updated before r_C, r_S_B
01917     update_w_r_B_O__i(x_i);
01918     update_r_C_r_S_B__i(x_i);    
01919     
01920     // remove r_beta_O(i) from r_B_O
01921     if (!check_tag(Is_linear())) { // (kf.)
01922       r_B_O[in_B[i]] = r_B_O.back();
01923       r_B_O.pop_back();
01924     }
01925     
01926     // update x_O_v_i
01927     x_O_v_i[i] = ratio_test_bound_index;
01928 }
01929 
01930 // update of the vectors w and r for U_4 with upper bounding, note that we 
01931 // need the headings C, S_{B}, B_{O} before they are updated
01932 template < typename Q, typename ET, typename Tags >                            // Standard form      
01933 void  QP_solver<Q, ET, Tags>::
01934 leave_variable_slack_upd_w_r(Tag_true )
01935 {
01936 }
01937 
01938 // update of the vectors w and r for U_4 with upper bounding, note that we 
01939 // need the headings C, S_{B}, B_{O} before they are updated
01940 template < typename Q, typename ET, typename Tags >                            // Upper bounded      
01941 void  QP_solver<Q, ET, Tags>::
01942 leave_variable_slack_upd_w_r(Tag_false )
01943 {
01944     
01945     // append r_gamma_S_B(sigma_i) to r_C
01946     r_C.push_back(r_S_B[in_B[i]]);
01947     
01948     // remove r_gamma_S_B(sigma_i) from r_S_B
01949     r_S_B[in_B[i]] = r_S_B.back();
01950     r_S_B.pop_back();
01951 }
01952 
01953 
01954 // replace variable in basis QP-case, transition to Ratio Test Step 2
01955 template < typename Q, typename ET, typename Tags >
01956 void QP_solver<Q, ET, Tags>::
01957 z_replace_variable( )
01958 {
01959     CGAL_qpe_debug {
01960         vout2 <<   "<--> nonbasic (" << variable_type( j) << ") variable " << j
01961               << " z_replaces basic (" << variable_type( i) << ") variable " << i
01962               << std::endl << std::endl;
01963     }
01964 
01965     // replace variable
01966     z_replace_variable( no_ineq);
01967 
01968     // pivot step not yet completely done
01969     i = -1;
01970     j -= in_B.size();
01971     is_RTS_transition = true;
01972 }
01973 
01974 
01975 template < typename Q, typename ET, typename Tags >  inline                           // no inequalities
01976 void QP_solver<Q, ET, Tags>::
01977 z_replace_variable( Tag_true)
01978 {
01979     z_replace_variable_original_by_original();
01980     strategyP->leaving_basis(i);
01981 
01982 }
01983 
01984 
01985 template < typename Q, typename ET, typename Tags >  inline                          // has inequalities
01986 void QP_solver<Q, ET, Tags>::
01987 z_replace_variable( Tag_false)
01988 {
01989     // determine type of variables
01990     bool  enter_original = ( (j < qp_n) || (j >= (int)( qp_n+slack_A.size())));
01991     bool  leave_original = ( (i < qp_n) || (i >= (int)( qp_n+slack_A.size())));
01992 
01993     // update basis and basis inverse
01994     if ( leave_original) {
01995         if ( enter_original) {               
01996             z_replace_variable_original_by_original();
01997         } else {                             
01998             z_replace_variable_original_by_slack();
01999         }
02000     } else {
02001         if ( enter_original) {
02002             z_replace_variable_slack_by_original();
02003         } else {
02004             z_replace_variable_slack_by_slack();
02005         }
02006     }
02007     strategyP->leaving_basis( i);
02008 }
02009 
02010 
02011 // replacement with precond det(M_{B \setminus \{i\}})=0
02012 template < typename Q, typename ET, typename Tags >
02013 void  QP_solver<Q, ET, Tags>::
02014 z_replace_variable_original_by_original( )
02015 {
02016     // updates for the upper bounded case
02017     z_replace_variable_original_by_original_upd_w_r(Is_nonnegative());
02018     
02019     int  k = in_B[ i];
02020 
02021     // replace original variable [ in: j | out: i ]
02022     in_B  [ i] = -1;
02023     in_B  [ j] = k;
02024        B_O[ k] = j;
02025 
02026     minus_c_B[ k] = -ET( *(qp_c+ j));
02027 
02028     // diagnostic output
02029     CGAL_qpe_debug {
02030         if ( vout2.verbose()) print_basis();
02031     }
02032         
02033     // compute s_delta
02034     D_pairwise_accessor  d_accessor( qp_D, j);
02035     ET                   s_delta =d_accessor(j)-d_accessor(i); 
02036             
02037     // update basis inverse
02038     // note: (-1)\hat{\nu} is stored instead of \hat{\nu}
02039     inv_M_B.z_replace_original_by_original( q_lambda.begin(), q_x_O.begin(), 
02040         s_delta, -nu, k);
02041 
02042 }
02043 
02044 // update of the vectors w and r for U_Z_1 with upper bounding, note that we 
02045 // need the headings C, S_{B}, B_{O} before they are updated
02046 template < typename Q, typename ET, typename Tags >                            // Standard form      
02047 void  QP_solver<Q, ET, Tags>::
02048 z_replace_variable_original_by_original_upd_w_r(Tag_true )
02049 {
02050 }
02051 
02052 // update of the vectors w and r for U_Z_1 with upper bounding, note that we 
02053 // need the headings C, S_{B}, B_{O} before they are updated
02054 template < typename Q, typename ET, typename Tags >                           
02055 // Upper bounded      
02056 void  QP_solver<Q, ET, Tags>::
02057 z_replace_variable_original_by_original_upd_w_r(Tag_false )
02058 {
02059 
02060     ET      x_j = nonbasic_original_variable_value(j);
02061     ET      x_i = (ratio_test_bound_index == LOWER) ? *(qp_l+i) : *(qp_u+i);
02062     
02063     // Note: w needs to be updated before r_C, r_S_B
02064     update_w_r_B_O__j_i(x_j, x_i);
02065     update_r_C_r_S_B__j_i(x_j, x_i);
02066     
02067     // replace r_beta_O(i) with w_j    
02068     r_B_O[in_B[i]] = w[j];
02069     
02070     // update x_O_v_i
02071     x_O_v_i[j] = BASIC;
02072     x_O_v_i[i] = ratio_test_bound_index;    
02073 }
02074 
02075 
02076 // replacement with precond det(M_{B \setminus \{i\}})=0
02077 template < typename Q, typename ET, typename Tags >
02078 void  QP_solver<Q, ET, Tags>::
02079 z_replace_variable_original_by_slack( )
02080 {
02081     // updates for the upper bounded case
02082     z_replace_variable_original_by_slack_upd_w_r(Is_nonnegative());
02083     
02084     int  k = in_B[ i];
02085 
02086     // leave original variable [ out: i ]
02087     in_B  [ B_O.back()] = k;
02088        B_O[ k] = B_O.back();
02089        in_B  [ i         ] = -1;
02090        B_O.pop_back();
02091 
02092     minus_c_B[ k] = minus_c_B[ B_O.size()];
02093 
02094     // enter slack variable [ in: j ]
02095     int  old_row = slack_A[ j-qp_n].first;
02096     in_B  [ j] = B_S.size();
02097        B_S.push_back( j);
02098        S_B.push_back( old_row);
02099 
02100     // leave inequality constraint [ out: j ]
02101     int  l = in_C[ old_row];
02102      b_C[ l       ] = b_C[ C.size()-1];
02103        C[ l       ] = C.back();
02104     in_C[ C.back()] = l;
02105     in_C[ old_row ] = -1;
02106        C.pop_back();
02107     
02108     // diagnostic output
02109     CGAL_qpe_debug {
02110         if ( vout2.verbose()) print_basis();
02111     }
02112 
02113     // update basis inverse
02114     inv_M_B.swap_variable( k);
02115     inv_M_B.swap_constraint( l);
02116     inv_M_B.z_replace_original_by_slack( );
02117 
02118 }
02119 
02120 // update of the vectors w and r for U_Z_2 with upper bounding, note that we 
02121 // need the headings C, S_{B}, B_{O} before they are updated
02122 template < typename Q, typename ET, typename Tags >                         // Standard form
02123 void  QP_solver<Q, ET, Tags>::
02124 z_replace_variable_original_by_slack_upd_w_r(Tag_true )
02125 {
02126 }
02127 
02128 
02129 // update of the vectors w and r for U_Z_2 with upper bounding, note that we 
02130 // need the headings C, S_{B}, B_{O} before they are updated
02131 template < typename Q, typename ET, typename Tags >                         // Upper bounded
02132 void  QP_solver<Q, ET, Tags>::
02133 z_replace_variable_original_by_slack_upd_w_r(Tag_false )
02134 {
02135 
02136     ET      x_i = (ratio_test_bound_index == LOWER) ? *(qp_l+i) : *(qp_u+i);
02137     
02138     // Note: w needs to be updated before r_C, r_S_B
02139     update_w_r_B_O__i(x_i);
02140     update_r_C_r_S_B__i(x_i);
02141     
02142     int     sigma_j = slack_A[ j-qp_n].first;
02143     
02144     // append r_gamma_C(sigma_j) to r_S_B
02145     r_S_B.push_back(r_C[in_C[sigma_j]]);
02146     
02147     // remove r_gamma_C(sigma_j) from r_C
02148     r_C[in_C[sigma_j]] = r_C.back();
02149     r_C.pop_back();
02150     
02151     // remove r_beta_O(i) from r_B_O    
02152     if (!check_tag(Is_linear())) { // (kf.)
02153       r_B_O[in_B[i]] = r_B_O.back();
02154       r_B_O.pop_back();
02155     }
02156     
02157     // update x_O_v_i
02158     x_O_v_i[i] = ratio_test_bound_index;
02159 }
02160 
02161 
02162 // replacement with precond det(M_{B \setminus \{i\}})=0
02163 template < typename Q, typename ET, typename Tags >
02164 void  QP_solver<Q, ET, Tags>::
02165 z_replace_variable_slack_by_original( )
02166 {
02167     // updates for the upper bounded case
02168     z_replace_variable_slack_by_original_upd_w_r(Is_nonnegative());
02169     
02170     int  k = in_B[ i];
02171     if (minus_c_B.size() <= B_O.size()) {  // Note: minus_c_B and the
02172                                            // containers resized in this
02173                                            // if-block are only enlarged
02174                                            // and never made smaller
02175                                            // (while B_O always has the
02176                                            // correct size). We check here
02177                                            // whether we need to enlarge
02178                                            // them.
02179       CGAL_qpe_assertion(minus_c_B.size() == B_O.size());
02180          minus_c_B.push_back(et0);
02181              q_x_O.push_back(et0);
02182            tmp_x  .push_back(et0);
02183            tmp_x_2.push_back(et0);
02184           two_D_Bj.push_back(et0);
02185              x_B_O.push_back(et0);
02186     }
02187 
02188     // enter original variable [ in: j ]
02189 
02190     minus_c_B[ B_O.size()] = -ET( *(qp_c+ j));
02191     
02192 
02193     in_B  [ j] = B_O.size();
02194        B_O.push_back( j);
02195 
02196 
02197     // leave slack variable [ out: i ]
02198        B_S[ k         ] = B_S.back();
02199        S_B[ k         ] = S_B.back();
02200     in_B  [ B_S.back()] = k;
02201     in_B  [ i         ] = -1; 
02202        B_S.pop_back();
02203        S_B.pop_back();
02204 
02205     // enter inequality constraint [ in: i ]
02206     int new_row = slack_A[ i-qp_n].first;
02207 
02208      b_C[ C.size()] = ET( *(qp_b+ new_row));
02209     in_C[ new_row ] = C.size();
02210        C.push_back( new_row);
02211     
02212     // diagnostic output
02213     CGAL_qpe_debug {
02214         if ( vout2.verbose()) print_basis();
02215     }
02216 
02217     // update basis inverse
02218     // --------------------
02219 
02220     // prepare u
02221     A_row_by_index_accessor  a_accessor =
02222       boost::bind (A_accessor( qp_A, 0, qp_n), _1, new_row);
02223     std::copy( A_row_by_index_iterator( B_O.begin(), a_accessor),
02224                A_row_by_index_iterator( B_O.end  (), a_accessor),
02225                tmp_x.begin());
02226     
02227     
02228     // prepare kappa
02229     ET  kappa = d * ET(*((*(qp_A + j))+new_row)) 
02230                 - inv_M_B.inner_product_x( tmp_x.begin(), q_x_O.begin());
02231                 
02232         // note: (-1)/hat{\nu} is stored instead of \hat{\nu}    
02233     inv_M_B.z_replace_slack_by_original( q_lambda.begin(), q_x_O.begin(),
02234                                           tmp_x.begin(), kappa, -nu);    
02235 }
02236 
02237 // update of the vectors w and r for U_Z_3 with upper bounding, note that we 
02238 // need the headings C, S_{B}, B_{O} before they are updated
02239 template < typename Q, typename ET, typename Tags >                            // Standard form
02240 void  QP_solver<Q, ET, Tags>::
02241 z_replace_variable_slack_by_original_upd_w_r(Tag_true )
02242 {
02243 }
02244 
02245 // update of the vectors w and r for U_Z_3 with upper bounding, note that we 
02246 // need the headings C, S_{B}, B_{O} before they are updated
02247 template < typename Q, typename ET, typename Tags >                             // Upper bounded
02248 void  QP_solver<Q, ET, Tags>::
02249 z_replace_variable_slack_by_original_upd_w_r(Tag_false )
02250 {
02251 
02252     ET      x_j = nonbasic_original_variable_value(j);
02253 
02254     // Note: w needs to be updated before r_C, r_S_B    
02255     update_w_r_B_O__j(x_j);
02256     update_r_C_r_S_B__j(x_j);
02257         
02258     // append r_gamma_S_B(sigma_i) to r_C
02259     r_C.push_back(r_S_B[in_B[i]]);
02260     
02261     // remove r_gamma_S_B(sigma_i) from r_S_B
02262     r_S_B[in_B[i]] = r_S_B.back();
02263     r_S_B.pop_back();
02264     
02265     // append w_j to r_B_O    
02266     if (!check_tag(Is_linear())) // (kf.)
02267       r_B_O.push_back(w[j]);
02268     
02269     // update x_O_v_i
02270     x_O_v_i[j] = BASIC;
02271 }
02272 
02273 
02274 // replacement with precond det(M_{B \setminus \{i\}})=0
02275 template < typename Q, typename ET, typename Tags >
02276 void  QP_solver<Q, ET, Tags>::
02277 z_replace_variable_slack_by_slack( )
02278 {
02279     // updates for the upper bounded case
02280     z_replace_variable_slack_by_slack_upd_w_r(Is_nonnegative());
02281     
02282     int  k = in_B[ i];
02283 
02284     // replace slack variable [ in: j | out: i ]
02285     in_B  [ i] = -1;
02286     in_B  [ j] = k;
02287        B_S[ k] = j;
02288        S_B[ k] = slack_A[ j-qp_n].first;
02289 
02290     // replace inequality constraint [ in: i | out: j ]
02291     int old_row = S_B[ k];
02292     int new_row = slack_A[ i-qp_n].first;
02293     k = in_C[ old_row];
02294 
02295     in_C[ old_row] = -1;
02296     in_C[ new_row] = k;
02297        C[ k      ] = new_row;
02298 
02299      b_C[ k] = ET( *(qp_b+ new_row));
02300 
02301     // diagnostic output
02302     CGAL_qpe_debug {
02303             if ( vout2.verbose()) print_basis();
02304     }
02305 
02306     // update basis inverse
02307     // --------------------
02308     A_row_by_index_accessor  a_accessor =
02309       boost::bind ( A_accessor( qp_A, 0, qp_n), _1, new_row);
02310     std::copy( A_row_by_index_iterator( B_O.begin(), a_accessor),
02311                A_row_by_index_iterator( B_O.end  (), a_accessor),
02312                tmp_x.begin());
02313 
02314 
02315     inv_M_B.z_replace_slack_by_slack( tmp_x.begin(), k);
02316 }
02317 
02318 // update of the vectors w and r for U_Z_4 with upper bounding, note that we 
02319 // need the headings C, S_{B}, B_{O} before they are updated
02320 template < typename Q, typename ET, typename Tags >                             // Standard form
02321 void  QP_solver<Q, ET, Tags>::
02322 z_replace_variable_slack_by_slack_upd_w_r(Tag_true )
02323 {
02324 }
02325 
02326 
02327 // update of the vectors w and r for U_Z_4 with upper bounding, note that we 
02328 // need the headings C, S_{B}, B_{O} before they are updated
02329 template < typename Q, typename ET, typename Tags >                             // Upper bounded
02330 void  QP_solver<Q, ET, Tags>::
02331 z_replace_variable_slack_by_slack_upd_w_r(Tag_false )
02332 {
02333     
02334     int     sigma_j = slack_A[ j-qp_n].first;
02335     
02336     // swap r_sigma_j in r_C with r_sigma_i in r_S_B
02337     std::swap(r_C[in_C[sigma_j]], r_S_B[in_B[i]]);           
02338 }
02339 
02340 // update of the vectors r_C and r_S_B with "x_j" column
02341 template < typename Q, typename ET, typename Tags >
02342 void  QP_solver<Q, ET, Tags>::
02343 update_r_C_r_S_B__j(ET& x_j)
02344 {
02345     // update of vector r_{C}
02346     A_by_index_accessor     a_accessor_j(*(qp_A + j));
02347     
02348     A_by_index_iterator     A_C_j_it(C.begin(), a_accessor_j);
02349     
02350     for (Value_iterator r_C_it = r_C.begin(); r_C_it != r_C.end();
02351                                                     ++r_C_it, ++A_C_j_it) {
02352         *r_C_it -= x_j * ET(*A_C_j_it); 
02353     }
02354     
02355     // update of r_{S_{B}}
02356     A_by_index_iterator     A_S_B_j_it(S_B.begin(), a_accessor_j);
02357         
02358     for (Value_iterator r_S_B_it = r_S_B.begin(); r_S_B_it != r_S_B.end();
02359                                                 ++r_S_B_it, ++A_S_B_j_it) {
02360         *r_S_B_it -= x_j * ET(*A_S_B_j_it);
02361     }   
02362 }
02363 
02364 // update of the vectors r_C and r_S_B with "x_j" and "x_i" column
02365 template < typename Q, typename ET, typename Tags >
02366 void  QP_solver<Q, ET, Tags>::
02367 update_r_C_r_S_B__j_i(ET& x_j, ET& x_i)
02368 {
02369     // update of vector r_{C}
02370     A_by_index_accessor     a_accessor_j(*(qp_A+j));
02371     A_by_index_accessor     a_accessor_i(*(qp_A+i));
02372     
02373     A_by_index_iterator     A_C_j_it(C.begin(), a_accessor_j);
02374     A_by_index_iterator     A_C_i_it(C.begin(), a_accessor_i);
02375     
02376     for (Value_iterator r_C_it = r_C.begin(); r_C_it != r_C.end();
02377                                         ++r_C_it, ++A_C_j_it, ++A_C_i_it) {
02378         *r_C_it += (x_i * ET(*A_C_i_it)) - (x_j * ET(*A_C_j_it)); 
02379     }
02380     
02381     // update of vector r_{S_{B}}
02382     A_by_index_iterator     A_S_B_j_it(S_B.begin(), a_accessor_j);
02383     A_by_index_iterator     A_S_B_i_it(S_B.begin(), a_accessor_i);
02384 
02385     for (Value_iterator r_S_B_it = r_S_B.begin(); r_S_B_it != r_S_B.end();
02386                                     ++r_S_B_it, ++A_S_B_j_it, ++A_S_B_i_it) {
02387         *r_S_B_it += (x_i * ET(*A_S_B_i_it)) - (x_j * ET(*A_S_B_j_it)); 
02388     }
02389 }
02390 
02391 // update of the vectors r_C and r_S_B with "x_i'" column
02392 template < typename Q, typename ET, typename Tags >
02393 void  QP_solver<Q, ET, Tags>::
02394 update_r_C_r_S_B__i(ET& x_i)
02395 {
02396     // update of vector r_{C}
02397     A_by_index_accessor     a_accessor_i(*(qp_A+i));
02398     A_by_index_iterator     A_C_i_it(C.begin(), a_accessor_i);
02399     
02400     for (Value_iterator r_C_it = r_C.begin(); r_C_it != r_C.end(); 
02401                                                     ++r_C_it, ++A_C_i_it) {
02402         *r_C_it += x_i * ET(*A_C_i_it); 
02403     }
02404     
02405     // update of r_{S_{B}}
02406     A_by_index_iterator     A_S_B_i_it(S_B.begin(), a_accessor_i);
02407     
02408     for (Value_iterator r_S_B_it = r_S_B.begin(); r_S_B_it != r_S_B.end();
02409                                                 ++r_S_B_it, ++A_S_B_i_it) {
02410         *r_S_B_it += x_i * ET(*A_S_B_i_it);
02411     }   
02412 }
02413 
02414 
02415 // Update of w and r_B_O with "x_j" column.
02416 //
02417 // todo: could be optimized slightly by factoring out the factor 2
02418 // (which is implicitly contained in the pairwise accessor for D).
02419 template < typename Q, typename ET, typename Tags >
02420 void  QP_solver<Q, ET, Tags>::
02421 update_w_r_B_O__j(ET& x_j)
02422 {
02423   // assertion checking:
02424   CGAL_expensive_assertion(!check_tag(Is_nonnegative()));
02425 
02426   // Note: we only do anything it we are dealing with a QP.
02427   if (!check_tag(Is_linear())) {
02428     D_pairwise_accessor     d_accessor_j(qp_D, j);
02429     
02430     // update of vector w:
02431     for (int it = 0; it < qp_n; ++it)
02432       w[it] -= d_accessor_j(it) * x_j;
02433     
02434     // update of r_B_O:
02435     D_pairwise_iterator D_B_O_j_it(B_O.begin(), d_accessor_j);
02436     for (Value_iterator r_B_O_it = r_B_O.begin();
02437          r_B_O_it != r_B_O.end();
02438          ++r_B_O_it, ++D_B_O_j_it)
02439         *r_B_O_it -= *D_B_O_j_it * x_j;
02440   }
02441 }
02442 
02443 // update of w and r_B_O with "x_j" and "x_i" column
02444 template < typename Q, typename ET, typename Tags >
02445 void  QP_solver<Q, ET, Tags>::
02446 update_w_r_B_O__j_i(ET& x_j, ET& x_i)
02447 {
02448   // assertion checking:
02449   CGAL_expensive_assertion(!check_tag(Is_nonnegative()));
02450 
02451   // Note: we only do anything it we are dealing with a QP.
02452   if (!check_tag(Is_linear())) {
02453     D_pairwise_accessor     d_accessor_i(qp_D, i);
02454     D_pairwise_accessor     d_accessor_j(qp_D, j);
02455     
02456     // update of vector w
02457     for (int it = 0; it < qp_n; ++it)
02458         w[it] += (d_accessor_i(it) * x_i) - (d_accessor_j(it) * x_j);
02459     
02460     // update of r_B_O
02461     D_pairwise_iterator D_B_O_j_it(B_O.begin(), d_accessor_j);
02462     D_pairwise_iterator D_B_O_i_it(B_O.begin(), d_accessor_i);
02463     for (Value_iterator r_B_O_it = r_B_O.begin();
02464          r_B_O_it != r_B_O.end();
02465          ++r_B_O_it, ++D_B_O_j_it, ++D_B_O_i_it)
02466         *r_B_O_it += (*D_B_O_i_it * x_i) - (*D_B_O_j_it * x_j);
02467   }
02468 }
02469 
02470 // update of w and r_B_O with "x_i" column
02471 template < typename Q, typename ET, typename Tags >
02472 void  QP_solver<Q, ET, Tags>::
02473 update_w_r_B_O__i(ET& x_i)
02474 {
02475   CGAL_expensive_assertion(!check_tag(Is_nonnegative()));
02476 
02477   // Note: we only do anything it we are dealing with a QP.
02478   if (!check_tag(Is_linear())) {
02479 
02480     // update of vector w:
02481     D_pairwise_accessor     d_accessor_i(qp_D, i);
02482     
02483     for (int it = 0; it < qp_n; ++it)
02484         w[it] += d_accessor_i(it) * x_i;
02485     
02486     // update of r_B_O:
02487     D_pairwise_iterator D_B_O_i_it(B_O.begin(), d_accessor_i);
02488     for (Value_iterator r_B_O_it = r_B_O.begin();
02489          r_B_O_it != r_B_O.end();
02490          ++r_B_O_it, ++D_B_O_i_it)
02491         *r_B_O_it += *D_B_O_i_it * x_i;
02492   }
02493 }
02494 
02495 // Compute solution, meaning compute the solution vector x and the KKT
02496 // coefficients lambda.
02497 template < typename Q, typename ET, typename Tags >                                      // Standard form
02498 void  QP_solver<Q, ET, Tags>::
02499 compute_solution(Tag_true)
02500 {
02501   // compute current solution, original variables and lambdas
02502   inv_M_B.multiply( b_C.begin(), minus_c_B.begin(),
02503                     lambda.begin(), x_B_O.begin());
02504   
02505   // compute current solution, slack variables
02506   compute__x_B_S(no_ineq, Is_nonnegative());
02507 }
02508 
02509 // Compute solution, meaning compute the solution vector x and the KKT
02510 // coefficients lambda.
02511 template < typename Q, typename ET, typename Tags >                                      // Upper bounded
02512 void  QP_solver<Q, ET, Tags>::
02513 compute_solution(Tag_false)
02514 { 
02515   // compute the difference b_C - r_C
02516   std::transform(b_C.begin(), b_C.begin()+C.size(), // Note: r_C.size() ==
02517                                                     // C.size() always holds,
02518                                                     // whereas b_C.size() >=
02519                                                     // C.size() in general.
02520                  r_C.begin(),  tmp_l.begin(), std::minus<ET>());
02521         
02522   // compute the difference minus_c_B - r_B_O:
02523   if (is_phaseII && is_QP) {
02524     std::transform(minus_c_B.begin(), minus_c_B.begin() + B_O.size(), 
02525                    r_B_O.begin(), tmp_x.begin(), std::minus<ET>());
02526     
02527     // compute current solution, original variables and lambdas:
02528     inv_M_B.multiply( tmp_l.begin(), tmp_x.begin(),
02529                       lambda.begin(), x_B_O.begin());
02530   } else {                                          // r_B_O == 0
02531     
02532     // compute current solution, original variables and lambdas        
02533     inv_M_B.multiply( tmp_l.begin(), minus_c_B.begin(),
02534                       lambda.begin(), x_B_O.begin());
02535   }
02536   
02537   // compute current solution, slack variables
02538   compute__x_B_S( no_ineq, Is_nonnegative());
02539 }
02540 
02541 template < typename Q, typename ET, typename Tags >
02542 void  QP_solver<Q, ET, Tags>::
02543 multiply__A_S_BxB_O(Value_iterator in, Value_iterator out) const
02544 {
02545   // initialize with zero vector
02546   std::fill_n( out, B_S.size(), et0);
02547   
02548   // foreach original column of A in B_O (artificial columns are zero in S_B
02549   A_column              a_col;                             // except special)
02550   Index_const_iterator  row_it, col_it;
02551   Value_iterator        out_it;
02552   //ET                    in_value;
02553   for ( col_it = B_O.begin(); col_it != B_O.end(); ++col_it, ++in) {
02554     const ET in_value = *in;
02555     out_it   = out;
02556     
02557     if ( *col_it < qp_n) {                              // original variable
02558       a_col = *(qp_A+ *col_it);
02559       
02560       // foreach row of A in S_B
02561       for ( row_it = S_B.begin(); row_it != S_B.end(); ++row_it,
02562               ++out_it) {
02563         *out_it += ET( a_col[ *row_it]) * in_value;
02564       }
02565     } else {
02566       if ( *col_it == art_s_i) {                  // special artificial
02567         
02568         // foreach row of 'art_s'
02569         for ( row_it = S_B.begin(); row_it != S_B.end(); ++row_it,
02570                 ++out_it) {
02571           *out_it += ET( art_s[ *row_it]) * in_value;
02572         }
02573       }
02574     }
02575   }
02576 }
02577 
02578 // compare the updated vector r_{C} with t_r_C=A_{C, N_O}x_{N_O}
02579 template < typename Q, typename ET, typename Tags >                         // Standard form
02580 bool  QP_solver<Q, ET, Tags>::
02581 check_r_C(Tag_true) const
02582 {
02583     return true;
02584 }
02585 
02586 // compare the updated vector r_{C} with t_r_C=A_{C, N_O}x_{N_O}
02587 template < typename Q, typename ET, typename Tags >                         // Upper bounded
02588 bool  QP_solver<Q, ET, Tags>::
02589 check_r_C(Tag_false) const
02590 {
02591     Values                  t_r_C;
02592     // compute t_r_C from scratch
02593     t_r_C.resize(C.size(), et0);
02594     multiply__A_CxN_O(t_r_C.begin());
02595     
02596     // compare r_C and the from scratch computed t_r_C
02597     bool failed = false;
02598     int count = 0;
02599     Value_const_iterator t_r_C_it = r_C.begin();
02600     for (Value_const_iterator r_C_it = r_C.begin(); r_C_it != r_C.end();
02601                                     ++r_C_it, ++t_r_C_it, ++count) {
02602         if (*r_C_it != *t_r_C_it) {
02603             failed = true;
02604         }
02605     }
02606     return (!failed);
02607 }
02608 
02609 // compare the updated vector r_{S_B} with t_r_S_B=A_{S_B, N_O}x_{N_O}
02610 template < typename Q, typename ET, typename Tags >                             // Standard form
02611 bool  QP_solver<Q, ET, Tags>::
02612 check_r_S_B(Tag_true) const
02613 {
02614     return true;
02615 }
02616 
02617 // compare the updated vector r_{S_B} with t_r_S_B=A_{S_B, N_O}x_{N_O}
02618 template < typename Q, typename ET, typename Tags >                             // Upper bounded
02619 bool  QP_solver<Q, ET, Tags>::
02620 check_r_S_B(Tag_false) const
02621 {
02622     Values                  t_r_S_B;
02623     // compute t_r_S_B from scratch
02624     t_r_S_B.resize(S_B.size(), et0);
02625     multiply__A_S_BxN_O(t_r_S_B.begin());
02626     
02627     // compare r_S_B and the from scratch computed t_r_S_B
02628     bool failed = false;
02629     int count = 0;
02630     Value_const_iterator    t_r_S_B_it = t_r_S_B.begin();
02631     for (Value_const_iterator r_S_B_it = r_S_B.begin(); r_S_B_it != r_S_B.end();
02632                                     ++r_S_B_it, ++t_r_S_B_it, ++count) {
02633         if (*r_S_B_it != *t_r_S_B_it) {
02634             failed = true;
02635         }
02636     }
02637     return (!failed);
02638 }
02639 
02640 
02641 // computes r_{B_{O}}:=2D_{B_O, N_O}x_{N_O} with upper bounding
02642 // OPTIMIZATION: If D is symmetric we can multiply by two at the end of the
02643 // computation of entry of r_B_O instead of each access to D
02644 template < typename Q, typename ET, typename Tags >
02645 void  QP_solver<Q, ET, Tags>::
02646 multiply__2D_B_OxN_O(Value_iterator out) const
02647 {
02648     //initialize
02649     std::fill_n( out, B_O.size(), et0);
02650 
02651     Value_iterator          out_it;
02652     ET                      value;
02653     
02654     // foreach entry in r_B_O
02655     out_it = out;
02656     for (Index_const_iterator row_it = B_O.begin(); row_it != B_O.end();
02657                                                         ++row_it, ++out_it) {
02658         D_pairwise_accessor d_accessor_i(qp_D, *row_it);
02659         for (int i = 0; i < qp_n; ++i) {
02660             if (!is_basic(i)) {
02661                 value = nonbasic_original_variable_value(i);
02662                 *out_it += d_accessor_i(i) * value;
02663             }
02664         }    
02665     }
02666 }
02667 
02668 // compares the updated vector r_{B_O} with t_r_B_O=2D_{B_O, N_O}x_{N_O}
02669 template < typename Q, typename ET, typename Tags >                                // Standard form
02670 bool  QP_solver<Q, ET, Tags>::
02671 check_r_B_O(Tag_true) const
02672 {
02673     return true;
02674 }
02675 
02676 // compares the updated vector r_{B_O} with t_r_B_O=2D_{B_O, N_O}x_{N_O}
02677 template < typename Q, typename ET, typename Tags >                                 // Upper bounded
02678 bool  QP_solver<Q, ET, Tags>::
02679 check_r_B_O(Tag_false) const
02680 {
02681     Values                  t_r_B_O;
02682     // compute t_r_B_O from scratch
02683     t_r_B_O.resize(B_O.size(), et0);
02684     multiply__2D_B_OxN_O(t_r_B_O.begin());
02685     
02686     // compare r_B_O and the from scratch computed t_r_B_O
02687     bool failed = false;
02688     int count = 0;
02689     Value_const_iterator    t_r_B_O_it = t_r_B_O.begin();
02690     for (Value_const_iterator r_B_O_it = r_B_O.begin(); r_B_O_it != r_B_O.end();
02691                                     ++r_B_O_it, ++t_r_B_O_it, ++count) {
02692         if (*r_B_O_it != *t_r_B_O_it) {
02693             failed = true;
02694         }
02695     }
02696     return (!failed);   
02697 }
02698 
02699 // compares the updated vector w with t_w=2D_{O,N_O}*x_N_O
02700 template < typename Q, typename ET, typename Tags >                             // Standard form
02701 bool  QP_solver<Q, ET, Tags>::
02702 check_w(Tag_true) const
02703 {
02704     return true;
02705 }
02706 
02707 // compares the updated vector w with t_w=2D_O_N_O*x_N_O
02708 template < typename Q, typename ET, typename Tags >                             // Upper bounded
02709 bool  QP_solver<Q, ET, Tags>::
02710 check_w(Tag_false) const
02711 {
02712     Values              t_w;
02713     // compute t_w from scratch
02714     t_w.resize( qp_n, et0);
02715     multiply__2D_OxN_O(t_w.begin());
02716     
02717     // compare w and the from scratch computed t_w
02718     bool  failed = false;
02719     Value_const_iterator    t_w_it = t_w.begin();
02720     for (int i = 0; i < qp_n; ++i, ++t_w_it) {
02721         if (w[i] != *t_w_it) {
02722             failed = true;
02723         }
02724     }
02725     return (!failed);
02726 }
02727 
02728 // check basis inverse
02729 template < typename Q, typename ET, typename Tags >
02730 bool
02731 QP_solver<Q, ET, Tags>::
02732 check_basis_inverse()
02733 {
02734     // diagnostic output
02735     CGAL_qpe_debug {
02736         vout4 << "check: " << std::flush;
02737     }
02738     bool ok;
02739     if (is_phaseI) {
02740         ok = check_basis_inverse(Tag_true());
02741     } else {
02742         ok = check_basis_inverse( Is_linear());
02743     }
02744 
02745     // diagnostic output
02746     CGAL_qpe_debug {
02747         if ( ok) {
02748             vout4 << "check ok";
02749         } else {
02750             vout4 << "check failed";
02751         }
02752         vout4 << std::endl;
02753     }
02754 
02755     return ok;
02756 }
02757 
02758 template < typename Q, typename ET, typename Tags >                                         // LP case
02759 bool  QP_solver<Q, ET, Tags>::
02760 check_basis_inverse( Tag_true)
02761 {
02762     CGAL_qpe_debug {
02763         vout4 << std::endl;
02764     }
02765     bool res = true;
02766     unsigned int    row, rows =   C.size();
02767     unsigned int    col, cols = B_O.size();
02768     Index_iterator  i_it = B_O.begin();
02769     Value_iterator  q_it;
02770 
02771     
02772     // BG: is this a real check?? How does the special artifical
02773     // variable come in, e.g.? OK: it comes in through
02774     // ratio_test_init__A_Cj
02775     for ( col = 0; col < cols; ++col, ++i_it) {
02776         ratio_test_init__A_Cj( tmp_l.begin(), *i_it,
02777                                no_ineq);
02778         inv_M_B.multiply_x( tmp_l.begin(), q_x_O.begin());
02779 
02780         CGAL_qpe_debug {
02781             if ( vout4.verbose()) {
02782                 std::copy( tmp_l.begin(), tmp_l.begin()+rows,
02783                            std::ostream_iterator<ET>( vout4.out(), " "));
02784                 vout4.out() << " ||  ";
02785                 std::copy( q_x_O.begin(), q_x_O.begin()+cols,
02786                            std::ostream_iterator<ET>( vout4.out(), " "));
02787                 vout4.out() << std::endl;
02788             }
02789         }
02790 
02791         q_it = q_x_O.begin();
02792         for ( row = 0; row < rows; ++row, ++q_it) {
02793             if ( *q_it != ( row == col ? d : et0)) {
02794                 if ( ! vout4.verbose()) {
02795                     std::cerr << std::endl << "basis-inverse check: ";
02796                 }
02797                 std::cerr << "failed ( row=" << row << " | col=" << col << " )"
02798                           << std::endl;
02799                 res = false;
02800             }
02801         }
02802     }
02803 
02804     return res;
02805 }
02806 
02807 template < typename Q, typename ET, typename Tags >                                         // QP case
02808 bool  QP_solver<Q, ET, Tags>::
02809 check_basis_inverse( Tag_false)
02810 {
02811     bool res = true;
02812     unsigned int    row, rows =   C.size();
02813     unsigned int    col, cols = B_O.size();
02814     Value_iterator  v_it;
02815     Index_iterator  i_it;
02816 
02817     CGAL_qpe_debug {
02818         vout4 << std::endl;
02819     }
02820     // left part of M_B
02821     std::fill_n( tmp_l.begin(), rows, et0);
02822     for ( col = 0; col < rows; ++col) {
02823 
02824         // get column of A_B^T (i.e. row of A_B)
02825         row = ( has_ineq ? C[ col] : col);
02826         v_it = tmp_x.begin();
02827         for ( i_it = B_O.begin(); i_it != B_O.end(); ++i_it, ++v_it) {
02828             *v_it = ( *i_it < qp_n ? *((*(qp_A+ *i_it))+ row) :  // original
02829                       art_A[ *i_it - qp_n].first != (int)row ? et0 :// artific.
02830                       ( art_A[ *i_it - qp_n].second ? -et1 : et1));
02831         }
02832 //      if ( art_s_i >= 0) {              // special artificial variable?
02833 //        CGAL_qpe_assertion ((int)in_B.size() == art_s_i+1);  
02834 //        // the special artificial variable has never been
02835 //        // removed from the basis, consider it
02836 //        tmp_x[ in_B[ art_s_i]] = art_s[ row];
02837 //      } 
02838 // BG: currently, this check only runs in phase II, where we have no
02839 // articficials
02840         CGAL_qpe_assertion (art_s_i < 0);
02841         
02842         inv_M_B.multiply( tmp_l.begin(), tmp_x.begin(),
02843                           q_lambda.begin(), q_x_O.begin());
02844 
02845         CGAL_qpe_debug {
02846             if ( vout4.verbose()) {
02847                 std::copy( tmp_l.begin(), tmp_l.begin()+rows,
02848                            std::ostream_iterator<ET>( vout4.out(), " "));
02849                 vout4.out() << "| ";
02850                 std::copy( tmp_x.begin(), tmp_x.begin()+cols,
02851                            std::ostream_iterator<ET>( vout4.out(), " "));
02852                 vout4.out() << " ||  ";
02853                 std::copy( q_lambda.begin(), q_lambda.begin()+rows,
02854                            std::ostream_iterator<ET>( vout4.out(), " "));
02855                 vout4.out() << " |  ";
02856                 std::copy( q_x_O.begin(), q_x_O.begin()+cols,
02857                            std::ostream_iterator<ET>( vout4.out(), " "));
02858                 vout4.out() << std::endl;
02859             }
02860         }
02861 
02862         v_it = q_lambda.begin();
02863         for ( row = 0; row < rows; ++row, ++v_it) {
02864             if ( *v_it != ( row == col ? d : et0)) {
02865                 if ( ! vout4.verbose()) {
02866                     std::cerr << std::endl << "basis-inverse check: ";
02867                 }
02868                 std::cerr << "failed ( row=" << row << " | col=" << col << " )"
02869                           << std::endl;
02870                 //              return false;
02871                 res = false;
02872             }
02873         }
02874         v_it = std::find_if( q_x_O.begin(), q_x_O.begin()+cols,
02875                              std::bind2nd( std::not_equal_to<ET>(), et0));
02876         if ( v_it != q_x_O.begin()+cols) {
02877             if ( ! vout4.verbose()) {
02878                 std::cerr << std::endl << "basis-inverse check: ";
02879             }
02880             std::cerr << "failed ( row=" << rows+(v_it-q_x_O.begin())
02881                       << " | col=" << col << " )" << std::endl;
02882             // ToDo: return false;
02883             res = false;
02884         }
02885     }
02886     vout4 << "= = = = = = = = = =" << std::endl;
02887 
02888     // right part of M_B
02889     if ( is_phaseI) std::fill_n( tmp_x.begin(), B_O.size(), et0);
02890     i_it = B_O.begin();
02891     for ( col = 0; col < cols; ++col, ++i_it) {
02892         ratio_test_init__A_Cj  ( tmp_l.begin(), *i_it, 
02893                                  no_ineq);
02894         ratio_test_init__2_D_Bj( tmp_x.begin(), *i_it, Tag_false());
02895         inv_M_B.multiply( tmp_l.begin(), tmp_x.begin(),
02896                           q_lambda.begin(), q_x_O.begin());
02897 
02898         CGAL_qpe_debug {
02899             if ( vout4.verbose()) {
02900                 std::copy( tmp_l.begin(), tmp_l.begin()+rows,
02901                            std::ostream_iterator<ET>( vout4.out(), " "));
02902                 vout4.out() << "| ";
02903                 std::copy( tmp_x.begin(), tmp_x.begin()+cols,
02904                            std::ostream_iterator<ET>( vout4.out(), " "));
02905                 vout4.out() << " ||  ";
02906                 std::copy( q_lambda.begin(), q_lambda.begin()+rows,
02907                            std::ostream_iterator<ET>( vout4.out(), " "));
02908                 vout4.out() << " |  ";
02909                 std::copy( q_x_O.begin(), q_x_O.begin()+cols,
02910                            std::ostream_iterator<ET>( vout4.out(), " "));
02911                 vout4.out() << std::endl;
02912             }
02913         }
02914 
02915         v_it = std::find_if( q_lambda.begin(), q_lambda.begin()+rows,
02916                              std::bind2nd( std::not_equal_to<ET>(), et0));
02917         if ( v_it != q_lambda.begin()+rows) {
02918             if ( ! vout4.verbose()) {
02919                 std::cerr << std::endl << "basis-inverse check: ";
02920             }
02921             std::cerr << "failed ( row=" << v_it-q_lambda.begin()
02922                       << " | col=" << col << " )" << std::endl;
02923             //      return false;
02924             res = false;
02925         }
02926         v_it = q_x_O.begin();
02927         for ( row = 0; row < cols; ++row, ++v_it) {
02928             if ( *v_it != ( row == col ? d : et0)) {
02929                 if ( ! vout4.verbose()) {
02930                     std::cerr << std::endl << "basis-inverse check: ";
02931                 }
02932                 std::cerr << "failed ( row=" << row+rows << " | col="
02933                           << col << " )" << std::endl;
02934                 //              return false;
02935                 res = false;
02936             }
02937         }
02938     }
02939     return res;
02940 }
02941 
02942 // filtered strategies are only allowed if the input type as
02943 // indicated by C_entry is double; this may still fail if the
02944 // types of some other program entries are not double, but 
02945 // since the filtered stuff is internal anyway, we can probably
02946 // live with this simple check
02947 template < typename Q, typename ET, typename Tags >
02948 void  QP_solver<Q, ET, Tags>::
02949 set_pricing_strategy
02950 ( Quadratic_program_pricing_strategy strategy)
02951 {
02952     CGAL_qpe_assertion( phase() != 1);
02953     CGAL_qpe_assertion( phase() != 2);
02954 
02955     if (strategy == QP_DANTZIG)
02956       strategyP = new QP_full_exact_pricing<Q, ET, Tags>;
02957     else if (strategy == QP_FILTERED_DANTZIG)    
02958       // choose between FF (double) and FE (anything else)
02959       strategyP = 
02960         new typename QP_solver_impl::Filtered_pricing_strategy_selector
02961         <Q, ET, Tags, C_entry>::FF;
02962     else if (strategy == QP_PARTIAL_DANTZIG)
02963       strategyP = new QP_partial_exact_pricing<Q, ET, Tags>;
02964     else if (strategy == QP_PARTIAL_FILTERED_DANTZIG
02965              || strategy == QP_CHOOSE_DEFAULT)   
02966       // choose between PF (double) and PE (anything else)
02967       strategyP = 
02968         new typename QP_solver_impl::Filtered_pricing_strategy_selector
02969         <Q, ET, Tags, C_entry>::PF;
02970     else if (strategy == QP_BLAND) 
02971       strategyP = new QP_exact_bland_pricing<Q, ET, Tags>;
02972     CGAL_qpe_assertion(strategyP != static_cast<Pricing_strategy*>(0));
02973    
02974     if ( phase() != -1) strategyP->set( *this, vout2);
02975 }
02976 
02977 // diagnostic output
02978 // -----------------
02979 template < typename Q, typename ET, typename Tags >
02980 void  QP_solver<Q, ET, Tags>::
02981 set_verbosity( int verbose, std::ostream& stream)
02982 {
02983     vout  = Verbose_ostream( verbose >  0, stream);
02984     vout1 = Verbose_ostream( verbose == 1, stream);
02985     vout2 = Verbose_ostream( verbose >= 2, stream);
02986     vout3 = Verbose_ostream( verbose >= 3, stream);
02987     vout4 = Verbose_ostream( verbose == 4, stream);
02988     vout5 = Verbose_ostream( verbose == 5, stream);
02989 }
02990 
02991 template < typename Q, typename ET, typename Tags >
02992 void  QP_solver<Q, ET, Tags>::
02993 print_program( ) const
02994 {
02995     int  row, i;
02996 
02997     // objective function
02998     vout4.out() << std::endl << "objective function:" << std::endl;
02999     if ( is_QP) {
03000         vout4.out() << "--> output of MATRIX must go here <--";
03001         vout4.out() << std::endl;
03002     }
03003     std::copy( qp_c, qp_c+qp_n,
03004                std::ostream_iterator<C_entry>( vout4.out(), " "));
03005     vout4.out() << "(+ " << qp_c0 << ") ";
03006     vout4.out() << std::endl;
03007     vout4.out() << std::endl;
03008 
03009     // constraints
03010     vout4.out() << "constraints:" << std::endl;
03011     for ( row = 0; row < qp_m; ++row) {
03012 
03013         // original variables
03014         for (i = 0; i < qp_n; ++i) 
03015           vout4.out() << *((*(qp_A+ i))+row) << ' ';
03016 
03017         // slack variables
03018         if ( ! slack_A.empty()) {
03019             vout4.out() << " |  ";
03020             for ( i = 0; i < (int)slack_A.size(); ++i) {
03021                 vout4.out() << ( slack_A[ i].first != row ? " 0" :
03022                                ( slack_A[ i].second ? "-1" : "+1")) << ' ';
03023             }
03024         }
03025 
03026         // artificial variables
03027         if ( ! art_A.empty()) {
03028             vout4.out() << " |  ";
03029             for ( i = 0; i < (int)art_A.size(); ++i) {
03030               if (art_s_i == i+qp_n+(int)slack_A.size())
03031                 vout4.out() << " * ";          // for special artificial column
03032               vout4.out() << ( art_A[ i].first != row ? " 0" :
03033                              ( art_A[ i].second ? "-1" : "+1")) << ' ';
03034             }
03035         }
03036         if ( ! art_s.empty()) vout4.out() << " |  " << art_s[ row] << ' ';
03037 
03038         // rhs
03039         vout4.out() << " |  "
03040                     << ( *(qp_r+ row) == CGAL::EQUAL      ? ' ' :
03041                        ( *(qp_r+ row) == CGAL::SMALLER ? '<' : '>')) << "=  "
03042                     << *(qp_b+ row);
03043                     if (!is_nonnegative) {
03044                         vout4.out() << " - " << multiply__A_ixO(row);
03045                     }
03046                     vout4.out() << std::endl;
03047     }
03048     vout4.out() << std::endl;
03049     
03050     // explicit bounds
03051     if (!is_nonnegative) {
03052         vout4.out() << "explicit bounds:" << std::endl; 
03053         for (int i = 0; i < qp_n; ++i) {
03054             if (*(qp_fl+i)) {                   // finite lower bound
03055                 vout4.out() << *(qp_l+i);
03056             } else {                            // infinite lower bound
03057                 vout4.out() << "-inf";
03058             }
03059             vout4.out() << " <= x_" << i << " <= ";
03060             if (*(qp_fu+i)) {
03061                 vout4.out() << *(qp_u+i);
03062             } else {
03063                 vout4.out() << "inf";
03064             }
03065             vout4.out() << std::endl;
03066         }
03067     }
03068 }
03069 
03070 template < typename Q, typename ET, typename Tags >
03071 void  QP_solver<Q, ET, Tags>::
03072 print_basis( ) const
03073 {
03074     char label;
03075     vout << "  basis: ";
03076     CGAL_qpe_debug {
03077       vout2 << "basic variables" << ( has_ineq ? "  " : "") << ":  ";
03078     }
03079     std::copy( B_O.begin(), B_O.end  (),
03080                std::ostream_iterator<int>( vout.out(), " "));
03081     CGAL_qpe_debug {
03082       if ( vout2.verbose()) {
03083         if ( has_ineq && ( ! slack_A.empty())) {
03084           vout2.out() << " |  ";
03085           std::copy( B_S.begin(), B_S.end(),
03086                      std::ostream_iterator<int>( vout2.out(), " "));
03087         }
03088         if ( is_phaseI) {
03089           vout2.out() << " (# of artificials: " << art_basic << ')';
03090         }
03091         if ( has_ineq) {
03092           vout2.out() << std::endl
03093                       << "basic constraints:  ";
03094           for (Index_const_iterator i_it = 
03095                  C.begin(); i_it != C.end(); ++i_it) {
03096             label = (*(qp_r+ *i_it) == CGAL::EQUAL) ? 'e' : 'i';
03097             vout2.out() << *i_it << ":" << label << " ";
03098           }
03099           /*
03100             std::copy( C.begin(), C.begin()+(C.size()-slack_A.size()),
03101             std::ostream_iterator<int>( vout2.out(), " "));
03102             if ( ! slack_A.empty()) {
03103             vout2.out() << " |  ";
03104             std::copy( C.end() - slack_A.size(), C.end(),
03105             std::ostream_iterator<int>( vout2.out(), " "));
03106             }
03107           */
03108         }
03109         if ( vout3.verbose()) {
03110           vout3.out() << std::endl
03111                       << std::endl
03112                       << "    in_B: ";
03113           std::copy( in_B.begin(), in_B.end(),
03114                      std::ostream_iterator<int>( vout3.out(), " "));
03115           if ( has_ineq) {
03116             vout3.out() << std::endl
03117                         << "    in_C: ";
03118             std::copy( in_C.begin(), in_C.end(),
03119                        std::ostream_iterator<int>( vout3.out(), " "));
03120           }
03121         }
03122       }
03123     }
03124     vout.out() << std::endl;
03125     CGAL_qpe_debug {
03126       vout4 << std::endl << "basis-inverse:" << std::endl;
03127     }
03128 }
03129 
03130 template < typename Q, typename ET, typename Tags >
03131 void  QP_solver<Q, ET, Tags>::
03132 print_solution( ) const
03133 {
03134   CGAL_qpe_debug {
03135     if ( vout3.verbose()) {
03136            vout3.out() << std::endl
03137             << "     b_C: ";
03138            std::copy( b_C.begin(), b_C.begin()+C.size(),
03139                    std::ostream_iterator<ET>( vout3.out()," "));
03140            vout3.out() << std::endl
03141             << "  -c_B_O: ";
03142            std::copy( minus_c_B.begin(), minus_c_B.begin()+B_O.size(),
03143                    std::ostream_iterator<ET>( vout3.out()," "));
03144            if (!is_nonnegative) {
03145                vout3.out() << std::endl
03146                 << "     r_C: ";
03147                std::copy( r_C.begin(), r_C.begin()+r_C.size(),
03148                    std::ostream_iterator<ET>( vout3.out(), " "));
03149                vout3.out() << std::endl
03150                    << "   r_B_O: ";
03151                std::copy( r_B_O.begin(), r_B_O.begin()+r_B_O.size(),
03152                    std::ostream_iterator<ET>( vout3.out(), " "));
03153                if (r_B_O.size() == 0)
03154                  vout3.out() << "< will only be allocated in phase II>";
03155 
03156            }
03157            vout3.out() << std::endl;
03158     }
03159     if ( vout2.verbose()) {
03160         vout2.out() << std::endl << "  lambda: ";
03161         std::copy( lambda.begin(), lambda.begin()+C.size(),
03162             std::ostream_iterator<ET>( vout2.out(), " "));
03163         vout2.out() << std::endl << "   x_B_O: ";
03164         std::copy( x_B_O.begin(), x_B_O.begin()+B_O.size(),
03165             std::ostream_iterator<ET>( vout2.out(), " "));
03166         vout2.out() << std::endl;
03167         if (!is_nonnegative) {
03168             vout2.out() << "   x_N_O: ";
03169             for (int i = 0; i < qp_n; ++i) {
03170                 if (!is_basic(i)) {
03171                     vout2.out() << d * 
03172                       nonbasic_original_variable_value(i);
03173                     vout2.out() << " ";    
03174                 }
03175             }
03176             vout2.out() << std::endl;
03177         }
03178         if ( has_ineq) {
03179             vout2.out() << "   x_B_S: ";
03180             std::copy( x_B_S.begin(), x_B_S.begin()+B_S.size(),
03181                 std::ostream_iterator<ET>( vout2.out()," "));
03182             vout2.out() << std::endl;
03183         }
03184         const ET denom = inv_M_B.denominator();
03185         vout2.out() << "   denominator: " << denom << std::endl;
03186         vout2.out() << std::endl;
03187     }
03188   }
03189   vout << "  ";
03190   vout.out() 
03191     << "solution: " 
03192     << solution_numerator() << " / " << solution_denominator() 
03193     << "  ~= " 
03194     << to_double
03195     (CGAL::Quotient<ET>(solution_numerator(), solution_denominator()))
03196     << std::endl;
03197   CGAL_qpe_debug {
03198       vout2 << std::endl;
03199   }
03200 }
03201 
03202 template < typename Q, typename ET, typename Tags >
03203 void  QP_solver<Q, ET, Tags>::
03204 print_ratio_1_original(int k, const ET& x_k, const ET& q_k)
03205 {
03206     if (is_nonnegative) {                      // => direction== 1
03207         if (q_k > et0) {                            // check for lower bound
03208             vout2.out() << "t_O_" << k << ": "
03209             << x_k << '/' << q_k
03210             << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03211             << std::endl;
03212         } else if (q_k < et0) {                     // check for upper bound
03213             vout2.out() << "t_O_" << k << ": "
03214             << "inf" << '/' << q_k
03215             << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03216             << std::endl;
03217         } else {                                    // q_k == 0
03218             vout2.out() << "t_O_" << k << ": "
03219             << "inf"
03220             << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03221             << std::endl;
03222         }
03223     } else {                                        // upper bounded
03224         if (q_k * ET(direction) > et0) {            // check for lower bound
03225             if (B_O[k] < qp_n) {                         // original variable
03226                 if (*(qp_fl+B_O[k])) {                   // finite lower bound
03227                     vout2.out() << "t_O_" << k << ": "
03228                     << x_k - (d * ET(*(qp_l+B_O[k]))) << '/' << q_k
03229                     << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03230                     << std::endl;
03231                 } else {                            // lower bound -infinity
03232                     vout2.out() << "t_O_" << k << ": "
03233                     << "-inf" << '/' << q_k
03234                     << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03235                     << std::endl;                
03236                 }
03237             } else {                                // artificial variable
03238                 vout2.out() << "t_O_" << k << ": "
03239                 << x_k << '/' << q_k
03240                 << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03241                 << std::endl;
03242             }
03243         } else if (q_k * ET(direction) < et0) {     // check for upper bound
03244             if (B_O[k] < qp_n) {                         // original variable
03245                 if (*(qp_fu+B_O[k])) {                   // finite upper bound
03246                     vout2.out() << "t_O_" << k << ": "
03247                     << (d * ET(*(qp_l+B_O[k]))) - x_k << '/' << q_k
03248                     << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03249                     << std::endl;                    
03250                 } else {                            // upper bound infinity
03251                     vout2.out() << "t_O_" << k << ": "
03252                     << "inf" << '/' << q_k
03253                     << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03254                     << std::endl;
03255                 }
03256             } else {                                // artificial variable
03257                 vout2.out() << "t_O_" << k << ": "
03258                 << "inf" << '/' << q_k
03259                 << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03260                 << std::endl;
03261             }
03262         } else {                                    // q_k == 0
03263             vout2.out() << "t_O_" << k << ": "
03264             <<  "inf"
03265             << ( ( q_i != et0) && ( i == B_O[ k]) ? " *" : "")
03266             << std::endl;
03267         }
03268     }
03269 }
03270 
03271 template < typename Q, typename ET, typename Tags >
03272 void  QP_solver<Q, ET, Tags>::
03273 print_ratio_1_slack(int k, const ET& x_k, const ET& q_k)
03274 {
03275     if (is_nonnegative) {                      // => direction == 1
03276         if (q_k > et0) {                            // check for lower bound
03277             vout2.out() << "t_S_" << k << ": "
03278             << x_k << '/' << q_k
03279             << ( ( q_i != et0) && ( i == B_S[ k]) ? " *" : "")
03280             << std::endl;
03281         } else {                                    // check for upper bound
03282             vout2.out() << "t_S_" << k << ": "
03283             << "inf" << '/' << q_k
03284             << ( ( q_i != et0) && ( i == B_S[ k]) ? " *" : "")
03285             << std::endl;        
03286         }
03287     } else {                                        // upper bounded
03288         if (q_k * ET(direction) > et0) {            // check for lower bound
03289             vout2.out() << "t_S_" << k << ": "
03290             << x_k << '/' << q_k
03291             << ( ( q_i != et0) && ( i == B_S[ k]) ? " *" : "")
03292             << std::endl;            
03293         } else if (q_k * ET(direction) < et0) {     // check for upper bound
03294             vout2.out() << "t_S_" << k << ": "
03295             << "inf" << '/' << q_k
03296             << ( ( q_i != et0) && ( i == B_S[ k]) ? " *" : "")
03297             << std::endl;
03298         } else {                                    // q_k == 0
03299             vout2.out() << "t_S_" << k << ": "
03300             << "inf"
03301             << ( ( q_i != et0) && ( i == B_S[ k]) ? " *" : "")
03302             << std::endl;
03303         }
03304     }
03305 }
03306 
03307 
03308 template < typename Q, typename ET, typename Tags >
03309 const char*  QP_solver<Q, ET, Tags>::
03310 variable_type( int k) const
03311 {
03312     return ( k <        qp_n                 ? "original"  :
03313            ( k < (int)( qp_n+slack_A.size()) ? "slack"     :
03314                                                "artificial"));
03315 }
03316 
03317 template < typename Q, typename ET, typename Tags > 
03318 bool QP_solver<Q, ET, Tags>::
03319 is_artificial(int k) const
03320 {
03321     return (k >= (int)(qp_n+slack_A.size())); 
03322 }
03323 
03324 template < typename Q, typename ET, typename Tags > 
03325 int QP_solver<Q, ET, Tags>::
03326 get_l() const
03327 {
03328     return l;
03329 }
03330 
03331 CGAL_END_NAMESPACE
03332 
03333 // ===== EOF ==================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines