BWAPI
|
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_basis_inverse_impl.h $ 00015 // $Id: QP_basis_inverse_impl.h 38453 2007-04-27 00:34:44Z gaertner $ 00016 // 00017 // 00018 // Author(s) : Sven Schoenherr 00019 // Bernd Gaertner <gaertner@inf.ethz.ch> 00020 // Franz Wessendorp 00021 // Kaspar Fischer 00022 00023 CGAL_BEGIN_NAMESPACE 00024 00025 // ============================= 00026 // class implementation (cont'd) 00027 // ============================= 00028 00029 // creation and initialization 00030 // --------------------------- 00031 // set-up 00032 template < class ET_, class Is_LP_ > 00033 void QP_basis_inverse<ET_,Is_LP_>:: 00034 set( int n, int m, int nr_equalities) 00035 { 00036 CGAL_qpe_assertion( n >= 0); 00037 CGAL_qpe_assertion( m >= 0); 00038 b = s = 0; 00039 // l is the maximum size of the basis in phase I 00040 l = (std::min)( n+nr_equalities+1, m); 00041 if ( ! M.empty()) M.clear(); 00042 set( Is_LP()); 00043 00044 if ( ! x_l.empty()) x_l.clear(); 00045 if ( ! x_x.empty()) x_x.clear(); 00046 00047 x_l.insert( x_l.end(), l, et0); 00048 x_x.insert( x_x.end(), l, et0); // has to grow later QP-case 00049 00050 if ( ! tmp_l.empty()) tmp_l.clear(); 00051 if ( ! tmp_x.empty()) tmp_x.clear(); 00052 00053 tmp_l.insert( tmp_l.end(), l, et0); 00054 tmp_x.insert( tmp_x.end(), l, et0); // has to grow later QP-case 00055 00056 } 00057 00058 // update functions 00059 // ---------------- 00060 // leaving of original variable (update type U2) 00061 template < class ET_, class Is_LP_ > 00062 void QP_basis_inverse<ET_,Is_LP_>:: 00063 leave_original( ) 00064 { 00065 // assert QP case 00066 Assert_compile_time_tag( Tag_false(), Is_LP()); 00067 00068 // determine new denominator (`z') 00069 --b; 00070 ET z = M[ l+b][ l+b]; 00071 bool z_neg = ( z < et0); 00072 CGAL_qpe_assertion( z != et0); 00073 00074 // update matrix in place 00075 update_inplace_QP( M[ l+b].begin(), M[ l+b].begin()+l, 00076 -z, ( z_neg ? d : -d)); 00077 00078 // store new denominator 00079 d = ( z_neg ? -z : z); 00080 CGAL_qpe_assertion( d > et0); 00081 00082 CGAL_qpe_debug { 00083 if ( vout.verbose()) print(); 00084 } 00085 } 00086 00087 // entering of slack variable (update type U3) 00088 template < class ET_, class Is_LP_ > 00089 void QP_basis_inverse<ET_,Is_LP_>:: 00090 enter_slack( ) 00091 { 00092 // assert QP case 00093 Assert_compile_time_tag( Tag_false(), Is_LP()); 00094 00095 // determine new denominator (`z') 00096 --s; 00097 ET z = M[ s][ s]; 00098 bool z_neg = ( z < et0); 00099 CGAL_qpe_assertion( z != et0); 00100 00101 // update matrix in place 00102 typename Matrix::iterator col_it; 00103 typename Row ::iterator x_it; 00104 unsigned int col; 00105 for ( col = 0, col_it = M.begin()+l, x_it = x_x.begin(); 00106 col < b; 00107 ++col, ++col_it, ++x_it ) { 00108 *x_it = (*col_it)[ s]; 00109 } 00110 update_inplace_QP( M[ s].begin(), x_x.begin(), -z, ( z_neg ? d : -d)); 00111 00112 // store new denominator 00113 d = ( z_neg ? -z : z); 00114 CGAL_qpe_assertion( d > et0); 00115 00116 CGAL_qpe_debug { 00117 if ( vout.verbose()) print(); 00118 } 00119 } 00120 00121 // replacing of original by slack variable (update type U8) 00122 template < class ET_, class Is_LP_ > 00123 void QP_basis_inverse<ET_,Is_LP_>:: 00124 enter_slack_leave_original( ) 00125 { 00126 // assert LP case or phase I 00127 CGAL_qpe_assertion( is_LP || is_phaseI); 00128 00129 // update matrix in-place 00130 // ---------------------- 00131 typename Matrix::iterator matrix_it; 00132 typename Row ::iterator x_it; 00133 unsigned int row; 00134 00135 // QP (in phase I)? 00136 matrix_it = M.begin(); 00137 if ( is_QP) matrix_it += l; 00138 00139 // get last column of basis inverse (store it in 'x_x') 00140 --s; --b; 00141 for ( row = 0, x_it = x_x.begin(); 00142 row < s; 00143 ++row, ++x_it, ++matrix_it) { 00144 *x_it = (*matrix_it)[ b]; 00145 } 00146 ET z = (*matrix_it)[ b]; 00147 bool z_neg = ( z < et0); 00148 CGAL_qpe_assertion( z != et0); 00149 00150 // update matrix 00151 update_inplace_LP( matrix_it->begin(), x_x.begin(), -z, ( z_neg ? d : -d)); 00152 00153 // store new denominator 00154 // --------------------- 00155 d = ( z_neg ? -z : z); 00156 CGAL_qpe_assertion( d > et0); 00157 00158 CGAL_qpe_debug { 00159 if ( vout.verbose()) print(); 00160 } 00161 } 00162 00163 00164 // replacing of original by original variable with precondition in QP-case 00165 // for phaseII (update type UZ_1) 00166 template < class ET_, class Is_LP_ > 00167 template < class ForwardIterator > 00168 void QP_basis_inverse<ET_,Is_LP_>:: 00169 z_replace_original_by_original(ForwardIterator y_l_it, 00170 ForwardIterator y_x_it, const ET& s_delta, 00171 const ET& s_nu, unsigned int k_i) 00172 { 00173 00174 // assert QP case and phaseII 00175 CGAL_qpe_assertion(is_QP && is_phaseII); 00176 00177 00178 // prepare \hat{k}_{1} -scalar 00179 ET hat_k_1 = *(y_x_it + k_i); 00180 00181 // prepare \hat{\rho} -vector in x_l, x_x 00182 copy_row_in_B_O(x_l.begin(), x_x.begin(), k_i); 00183 00184 // prepare \hat{v} -vector in tmp_l, tmp_x 00185 00186 // tmp_l -part 00187 std::transform(y_l_it, (y_l_it+s), x_l.begin(), tmp_l.begin(), 00188 compose2_2(std::plus<ET>(), Identity<ET>(), 00189 std::bind1st(std::multiplies<ET>(), s_delta))); 00190 00191 // tmp_x -part 00192 std::transform(y_x_it, (y_x_it+b), x_x.begin(), tmp_x.begin(), 00193 compose2_2(std::plus<ET>(), Identity<ET>(), 00194 std::bind1st(std::multiplies<ET>(), s_delta))); 00195 tmp_x[k_i] -= d; 00196 00197 // prepare \hat{k}_{2} -scalar 00198 ET hat_k_2 = s_nu - (et2 * s_delta * hat_k_1); 00199 00200 CGAL_qpe_assertion( d != et0); 00201 00202 // update matrix in place 00203 z_update_inplace(x_l.begin(), x_x.begin(), tmp_l.begin(), tmp_x.begin(), 00204 hat_k_1 * hat_k_1, -hat_k_2, -hat_k_1, d*d); 00205 00206 // store new denominator 00207 d = CGAL::integral_division(hat_k_1 * hat_k_1, d); 00208 00209 CGAL_qpe_assertion( d > et0); 00210 00211 CGAL_qpe_debug { 00212 if ( vout.verbose()) print(); 00213 } 00214 00215 } 00216 00217 00218 // replacing of original by slack variable with precondition in QP-case 00219 // for phaseII (update type UZ_2) 00220 template < class ET_, class Is_LP_ > 00221 void QP_basis_inverse<ET_,Is_LP_>:: 00222 z_replace_original_by_slack( ) 00223 { 00224 00225 // assert QP case and phaseII 00226 CGAL_qpe_assertion(is_QP && is_phaseII); 00227 00228 // adapt s and b 00229 --s; --b; 00230 00231 // prepare \hat{\rho} -vector in x_l, x_x 00232 copy_row_in_B_O(x_l.begin(), x_x.begin(), b); 00233 00234 // prepare \hat{\varrho} -vector in tmp_l, tmp_x 00235 copy_row_in_C(tmp_l.begin(), tmp_x.begin(), s); 00236 00237 // prepare \hat{\kappa} -scalar 00238 ET hat_kappa = M[l+b][s]; 00239 00240 // prepare \hat{\xi} -scalar 00241 ET hat_xi = M[s][s]; 00242 00243 CGAL_qpe_assertion( d != et0); 00244 00245 // update matrix in place 00246 z_update_inplace(x_l.begin(), x_x.begin(), tmp_l.begin(), tmp_x.begin(), 00247 hat_kappa * hat_kappa, hat_xi, -hat_kappa, d * d); 00248 00249 // store new denominator 00250 d = CGAL::integral_division(hat_kappa * hat_kappa, d); 00251 00252 CGAL_qpe_assertion( d > et0); 00253 00254 CGAL_qpe_debug { 00255 if ( vout.verbose()) print(); 00256 } 00257 00258 } 00259 00260 00261 // replacing of slack by original variable with precondition in QP-case 00262 // for phaseII (update type UZ_3) 00263 template < class ET_, class Is_LP_ > 00264 template < class ForwardIterator > 00265 void QP_basis_inverse<ET_,Is_LP_>:: 00266 z_replace_slack_by_original(ForwardIterator y_l_it, 00267 ForwardIterator y_x_it, 00268 ForwardIterator u_x_it, const ET& hat_kappa, 00269 const ET& hat_nu) 00270 { 00271 // assert QP case and phaseII 00272 CGAL_qpe_assertion(is_QP && is_phaseII); 00273 00274 // get copies of y_l_it and y_x_it for later use 00275 ForwardIterator y_l_it_copy = y_l_it; 00276 ForwardIterator y_x_it_copy = y_x_it; 00277 00278 CGAL_qpe_assertion( d != et0); 00279 00280 // prepare \hat{\phi} 00281 00282 // prepare \hat{\varphi} -vector in x_l, x_x 00283 multiply(u_x_it, u_x_it, x_l.begin(), x_x.begin(), Tag_false(), 00284 Tag_false()); 00285 00286 // prepare \hat{\kappa} -scalar 00287 00288 // prepare \hat{\nu} -scalar 00289 00290 // update matrix in place 00291 z_update_inplace(x_l.begin(), x_x.begin(), y_l_it, y_x_it, 00292 hat_kappa * hat_kappa, -hat_nu, hat_kappa, d * d); 00293 00294 // append new rows and columns 00295 // --------------------------- 00296 typename Row ::iterator row_it, x_l_it, x_x_it; 00297 typename Matrix::iterator matrix_it; 00298 unsigned int count; 00299 00300 // insert new row and column at the end of block P 00301 CGAL_qpe_assertion(M.size()>=s+1); 00302 if (M[s].size()==0) { 00303 // row has to be filled first 00304 M[s].insert(M[s].end(), s+1, et0); 00305 } 00306 00307 00308 // P-block: left of diagonal (including element on diagonal) 00309 y_l_it = y_l_it_copy; 00310 for ( row_it = M[s].begin(), x_l_it = x_l.begin(); 00311 row_it != M[s].end() - 1; 00312 ++row_it, ++x_l_it, ++y_l_it ) { 00313 *row_it = 00314 CGAL::integral_division((hat_nu * *x_l_it)-(hat_kappa * *y_l_it), d); 00315 } 00316 *row_it = -hat_nu; 00317 00318 // Q-block 00319 y_x_it = y_x_it_copy; 00320 for ( matrix_it = M.begin()+l, count = 0, x_x_it = x_x.begin(); 00321 count < b; 00322 ++matrix_it, ++count, ++x_x_it, ++y_x_it ) { 00323 (*matrix_it)[s] = 00324 CGAL::integral_division((hat_nu * *x_x_it) - (hat_kappa * *y_x_it), d); 00325 } 00326 00327 // insert new row and column at the end of blocks Q and R 00328 ensure_physical_row(l+b); 00329 00330 // Q-block 00331 for ( row_it = M[l+b].begin(), count = 0, x_l_it = x_l.begin(); 00332 count < s; 00333 ++row_it, ++count, ++x_l_it ) { 00334 *row_it = CGAL::integral_division(-hat_kappa * *x_l_it, d); 00335 } 00336 *row_it = hat_kappa; 00337 00338 // R-block 00339 for ( row_it = M[l+b].begin()+l, count = 0, x_x_it = x_x.begin(); 00340 count < b; 00341 ++row_it, ++count, ++x_x_it ) { 00342 *row_it = CGAL::integral_division(-hat_kappa * *x_x_it, d); 00343 } 00344 *row_it = et0; 00345 00346 //adapt s and b 00347 ++s; ++b; 00348 00349 // store new denominator 00350 d = CGAL::integral_division(hat_kappa * hat_kappa, d); 00351 00352 CGAL_qpe_assertion( d > et0); 00353 00354 CGAL_qpe_debug { 00355 if ( vout.verbose()) print(); 00356 } 00357 00358 } 00359 00360 00361 // replacing of slack by slack variable with precondition in QP-case 00362 // for phaseII (update type UZ_4) 00363 template < class ET_, class Is_LP_ > 00364 template < class ForwardIterator > 00365 void QP_basis_inverse<ET_,Is_LP_>:: 00366 z_replace_slack_by_slack(ForwardIterator u_x_it, unsigned int k_j) 00367 { 00368 00369 // assert QP case and phaseII 00370 CGAL_qpe_assertion(is_QP && is_phaseII); 00371 00372 // prepare \hat{v} -vector in x_l, x_x 00373 multiply(u_x_it, u_x_it, x_l.begin(), x_x.begin(),Tag_false(), 00374 Tag_false()); 00375 x_l[k_j] -= d; 00376 00377 // prepare \hat{\varrho} -vector in tmp_l, tmp_x 00378 copy_row_in_C(tmp_l.begin(), tmp_x.begin(), k_j); 00379 00380 // prepare \hat{k}_{1} -scalar 00381 ET hat_k_1 = inner_product_x(tmp_x.begin(), u_x_it); 00382 00383 // prepare \hat{k}_{3} -scalar 00384 ET hat_k_3 = -M[k_j][k_j]; 00385 00386 CGAL_qpe_assertion( d != et0); 00387 00388 // update matrix in place 00389 z_update_inplace(x_l.begin(), x_x.begin(), tmp_l.begin(), tmp_x.begin(), 00390 hat_k_1 * hat_k_1, -hat_k_3, -hat_k_1, d * d); 00391 00392 // store new denominator 00393 d = CGAL::integral_division(hat_k_1 * hat_k_1, d); 00394 00395 CGAL_qpe_assertion( d > et0); 00396 00397 CGAL_qpe_debug { 00398 if ( vout.verbose()) print(); 00399 } 00400 00401 } 00402 00403 00404 // copying of reduced basis inverse row in (upper) C-half 00405 template < class ET_, class Is_LP_ > 00406 template < class OutIt > 00407 void QP_basis_inverse<ET_,Is_LP_>:: 00408 copy_row_in_C(OutIt y_l_it, OutIt y_x_it, unsigned int r) 00409 { 00410 typename Matrix::const_iterator matrix_it; 00411 typename Row ::const_iterator row_it; 00412 unsigned int count; 00413 00414 // P-block: left of diagonal (including element on diagonal) 00415 matrix_it = M.begin()+r; 00416 for ( row_it = matrix_it->begin(); 00417 row_it != matrix_it->end(); 00418 ++row_it, ++y_l_it ) { 00419 *y_l_it = *row_it; 00420 } 00421 00422 // P-block: right of diagonal (excluding element on diagonal) 00423 for ( matrix_it = M.begin()+r+1, count = r+1; 00424 count < s; 00425 ++matrix_it, ++count, ++y_l_it ) { 00426 *y_l_it = (*matrix_it)[r]; 00427 } 00428 00429 // Q-block 00430 for ( matrix_it = M.begin()+l, count = 0; 00431 count < b; 00432 ++matrix_it, ++count, ++y_x_it ) { 00433 *y_x_it = (*matrix_it)[r]; 00434 } 00435 } 00436 00437 00438 // copying of reduced basis inverse row in (lower) B_O-half 00439 template < class ET_, class Is_LP_ > 00440 template < class OutIt > 00441 void QP_basis_inverse<ET_,Is_LP_>:: 00442 copy_row_in_B_O(OutIt y_l_it, OutIt y_x_it, unsigned int r) 00443 { 00444 typename Matrix::const_iterator matrix_it; 00445 typename Row ::const_iterator row_it; 00446 unsigned int count; 00447 00448 // Q-block 00449 matrix_it = M.begin()+l+r; 00450 for ( row_it = matrix_it->begin(), count = 0; 00451 count < s; 00452 ++row_it, ++count, ++y_l_it ) { 00453 *y_l_it = *row_it; 00454 } 00455 00456 // R-block: left of diagonal (including element on diagonal) 00457 for ( row_it = matrix_it->begin()+l; 00458 row_it != matrix_it->end(); 00459 ++row_it, ++y_x_it ) { 00460 *y_x_it = *row_it; 00461 } 00462 00463 // R-block: right of diagonal (excluding element on diagonal) 00464 for ( matrix_it = M.begin()+l+r+1, count = r+1; 00465 count < b; 00466 ++matrix_it, ++count, ++y_x_it ) { 00467 *y_x_it = (*matrix_it)[l+r]; 00468 } 00469 00470 } 00471 00472 template < class ET_, class Is_LP_ > 00473 template < class ForIt > 00474 void QP_basis_inverse<ET_,Is_LP_>:: 00475 z_update_inplace( ForIt psi1_l_it, ForIt psi1_x_it, 00476 ForIt psi2_l_it, ForIt psi2_x_it, 00477 const ET& omega0, const ET& omega1, 00478 const ET& omega2, const ET& omega3) 00479 { 00480 typename Matrix:: iterator matrix_it; 00481 typename Row :: iterator row_it; 00482 typename Row ::const_iterator y_it1_r, y_it1_c, y_it2_r, y_it2_c; 00483 00484 unsigned int row, col, k = l+b; 00485 ET u_elem; 00486 00487 // rows: 0..s-1 ( P ) 00488 for ( row = 0, matrix_it = M.begin(), 00489 y_it1_r = psi1_l_it, y_it2_r = psi2_l_it; 00490 row < s; 00491 ++row, ++matrix_it, ++y_it1_r, ++y_it2_r ) { 00492 00493 // columns: 0..row ( P ) 00494 for ( row_it = matrix_it->begin(), 00495 y_it1_c = psi1_l_it, y_it2_c = psi2_l_it; 00496 row_it != matrix_it->end(); 00497 ++row_it, ++y_it1_c, ++y_it2_c ) { 00498 00499 u_elem = (*y_it1_r * *y_it2_c) + (*y_it2_r * *y_it1_c); 00500 u_elem *= omega2; 00501 u_elem += omega1 * *y_it1_r * *y_it1_c; 00502 update_entry( *row_it, omega0, u_elem, omega3); 00503 } 00504 } 00505 00506 // rows: l..k-1 ( Q R ) 00507 for ( row = l, matrix_it = M.begin()+l, 00508 y_it1_r = psi1_x_it, y_it2_r = psi2_x_it; 00509 row != k; 00510 ++row, ++matrix_it, ++y_it1_r, ++y_it2_r ) { 00511 00512 // columns: 0..s-1 ( Q ) 00513 for ( col = 0, row_it = matrix_it->begin(), 00514 y_it1_c = psi1_l_it, y_it2_c = psi2_l_it; 00515 col < s; 00516 ++col, ++row_it, ++y_it1_c, ++y_it2_c ){ 00517 00518 u_elem = (*y_it1_r * *y_it2_c) + (*y_it2_r * *y_it1_c); 00519 u_elem *= omega2; 00520 u_elem += omega1 * *y_it1_r * *y_it1_c; 00521 update_entry( *row_it, omega0, u_elem, omega3); 00522 } 00523 00524 // columns: l..k-1 ( R ) 00525 for ( row_it = matrix_it->begin()+l, 00526 y_it1_c = psi1_x_it, y_it2_c = psi2_x_it; 00527 row_it != matrix_it->end(); 00528 ++row_it, ++y_it1_c, ++y_it2_c ){ 00529 00530 u_elem = (*y_it1_r * *y_it2_c) + (*y_it2_r * *y_it1_c); 00531 u_elem *= omega2; 00532 u_elem += omega1 * *y_it1_r * *y_it1_c; 00533 update_entry( *row_it, omega0, u_elem, omega3); 00534 } 00535 00536 } 00537 00538 } 00539 00540 00541 // swap functions 00542 // -------------- 00543 // swap variable ``to the end'' of R 00544 template < class ET_, class Is_LP_ > // LP case 00545 void QP_basis_inverse<ET_,Is_LP_>:: 00546 swap_variable( unsigned int j, Tag_true) 00547 { 00548 unsigned int k = b-1; 00549 if ( j == k) return; 00550 00551 // swap rows 00552 // --------- 00553 typename Row::iterator row_j_it = M[ j].begin(); 00554 typename Row::iterator row_k_it = M[ k].begin(); 00555 unsigned int count; 00556 00557 // swap entries 0..b-1 (row <-> row) [in Q] 00558 for ( count = 0; 00559 count < b; 00560 ++count, ++row_j_it, ++row_k_it) { 00561 std::iter_swap( row_j_it, row_k_it); 00562 } 00563 } 00564 00565 template < class ET_, class Is_LP_ > // QP case 00566 void QP_basis_inverse<ET_,Is_LP_>:: 00567 swap_variable( unsigned int j, Tag_false) 00568 { 00569 unsigned int i = l+j, k = l+b-1; 00570 if ( i == k) return; 00571 00572 // swap rows and columns 00573 // --------------------- 00574 typename Row::iterator row_i_it = M[ i].begin(); 00575 typename Row::iterator row_k_it = M[ k].begin(); 00576 typename Matrix::iterator matrix_it = M.begin()+(i+1); 00577 unsigned int count; 00578 00579 // swap entries 0..s-1 (row <-> row) [in Q] 00580 for ( count = 0; 00581 count < s; 00582 ++count, ++row_i_it, ++row_k_it) { 00583 std::iter_swap( row_i_it, row_k_it); 00584 } 00585 00586 if ( is_phaseII) { 00587 00588 // swap entries l..i-1 (row <-> row) [in R] 00589 for ( count = l, row_i_it += l-s, row_k_it += l-s; 00590 count < i; 00591 ++count, ++row_i_it, ++row_k_it ) { 00592 std::iter_swap( row_i_it, row_k_it); 00593 } 00594 00595 // swap entries i+1..k-1 (column <-> row) [in R] 00596 for ( ++count, ++row_k_it; 00597 count < k; 00598 ++count, ++matrix_it, ++row_k_it) { 00599 std::swap( ( *matrix_it)[ i], *row_k_it); 00600 } 00601 00602 // swap entries i,i with k,k (entry <-> entry) [in R] 00603 std::iter_swap( row_i_it, row_k_it); 00604 } 00605 } 00606 00607 // swap constraint ``to the end'' of P 00608 template < class ET_, class Is_LP_ > // LP case 00609 void QP_basis_inverse<ET_,Is_LP_>:: 00610 swap_constraint( unsigned int i, Tag_true) 00611 { 00612 unsigned int k = s-1; 00613 if ( i == k) return; 00614 00615 // swap columns 00616 // ------------ 00617 typename Matrix::iterator matrix_it = M.begin(); 00618 unsigned int count; 00619 00620 // swap entries 0..s-1 (column <-> column) [in Q] 00621 for ( count = 0; 00622 count < s; 00623 ++count, ++matrix_it) { 00624 std::swap( ( *matrix_it)[ i], ( *matrix_it)[ k]); 00625 } 00626 } 00627 00628 template < class ET_, class Is_LP_ > // QP case 00629 void QP_basis_inverse<ET_,Is_LP_>:: 00630 swap_constraint( unsigned int i, Tag_false) 00631 { 00632 00633 if ( i == s-1) return; 00634 00635 // swap rows and columns 00636 // --------------------- 00637 typename Row::iterator row_i_it = M[ i].begin(); 00638 typename Row::iterator row_k_it = M[ s-1].begin(); 00639 typename Matrix::iterator matrix_it = M.begin()+i; 00640 unsigned int count; 00641 00642 if ( is_phaseI) { 00643 00644 // skip empty P 00645 matrix_it =M.begin() + l; 00646 00647 } else { 00648 00649 // swap entries 0..i-1 (row <-> row) [in P] 00650 for ( count = 0; 00651 count < i; 00652 ++count, ++row_i_it, ++row_k_it) { 00653 std::iter_swap( row_i_it, row_k_it); 00654 } 00655 00656 // swap entries i+1..s-2 (column <-> row) [in P] 00657 for ( count = i + 1, ++matrix_it, ++row_k_it; 00658 count < s-1; 00659 ++count, ++matrix_it, ++row_k_it) { 00660 std::swap( ( *matrix_it)[ i], *row_k_it); 00661 } 00662 // the remaining two entries to be swapped on the main diagonal 00663 std::swap(M[i][i], M[s-1][s-1]); 00664 00665 // advance to Q 00666 matrix_it = M.begin() + l; 00667 } 00668 00669 // swap entries l..l+b (column <-> column) [in Q] 00670 for ( count = 0; 00671 count < b; 00672 ++count, ++matrix_it) { 00673 std::swap( ( *matrix_it)[ i], ( *matrix_it)[ s-1]); 00674 } 00675 } 00676 00677 // diagnostic output 00678 // ----------------- 00679 template < class ET_, class Is_LP_ > 00680 void QP_basis_inverse<ET_,Is_LP_>:: 00681 print( ) 00682 { 00683 // P 00684 if ( is_LP || is_phaseII) { 00685 for ( unsigned int row = 0; row < s; ++row) { 00686 std::copy( M[ row].begin(), 00687 M[ row].begin() + ( is_LP ? s : row+1), 00688 std::ostream_iterator<ET>( vout.out(), " ")); 00689 vout.out() << std::endl; 00690 } 00691 if ( is_QP) vout.out() << "= = = = = = = = = =" << std::endl; 00692 } 00693 00694 // Q & R 00695 if ( is_QP) { 00696 for ( unsigned int row = l; row < l+b; ++row) { 00697 std::copy( M[ row].begin(), M[ row].begin()+s, 00698 std::ostream_iterator<ET>( vout.out(), " ")); 00699 if ( is_phaseII) { 00700 vout.out() << "|| "; 00701 std::copy( M[ row].begin()+l, M[ row].end(), 00702 std::ostream_iterator<ET>( vout.out(), " ")); 00703 } 00704 vout.out() << std::endl; 00705 } 00706 } 00707 vout.out() << "denominator = " << d << std::endl; 00708 } 00709 00710 CGAL_END_NAMESPACE 00711 00712 // ===== EOF ==================================================================