BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/QP_solver/QP_solver_nonstandardform_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_nonstandardform_impl.h $
00015 // $Id: QP_solver_nonstandardform_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 CGAL_BEGIN_NAMESPACE
00024 
00025 // Looks in x_O_v_i which bound is present for variable i and returns
00026 // the variable's value corresponding to this bound.
00027 //
00028 // Precondition: Is_nonnegative is Tag_false.
00029 template < typename Q, typename ET, typename Tags >
00030 ET QP_solver<Q, ET, Tags>::original_variable_value_under_bounds(int i) const
00031 {
00032   CGAL_assertion(!check_tag(Is_nonnegative()) && i<qp_n);
00033   switch (x_O_v_i[i]) {
00034   case UPPER:
00035     return *(qp_u+i);
00036   case ZERO:
00037     return et0;
00038   case LOWER:
00039   case FIXED:
00040     return *(qp_l+i);
00041   case BASIC:
00042     CGAL_qpe_assertion(false);
00043   }
00044   return et0; // dummy
00045 }
00046 
00047 template < typename Q, typename ET, typename Tags >
00048 ET QP_solver<Q, ET, Tags>::variable_numerator_value(int i) const
00049 {
00050   // Returns the current value of an *original* variable.
00051   CGAL_qpe_assertion( 0 <= i && i < qp_n );
00052   if (check_tag(Is_nonnegative())) {
00053     if (in_B[i] < 0) 
00054       return et0;
00055     else 
00056       return x_B_O[in_B[i]];
00057   }
00058 
00059   // now we have nonstandard form
00060   typedef QP_solver<Q, ET, Tags> QP;
00061   switch (x_O_v_i[i]) {
00062   case QP::UPPER:
00063     return ET(*(qp_u+i)) * d;
00064   case QP::ZERO:
00065     return et0;
00066   case QP::LOWER:
00067   case QP::FIXED:
00068     return ET(*(qp_l+i)) * d;
00069   case QP::BASIC:
00070     return x_B_O[in_B[i]];
00071   default: // never reached
00072     return et0;
00073   }
00074 }
00075 
00076 template < typename Q, typename ET, typename Tags >
00077 ET QP_solver<Q, ET, Tags>::nonbasic_original_variable_value
00078 (int i) const
00079 {
00080   if (check_tag(Is_nonnegative()))
00081     return et0;
00082 
00083   CGAL_assertion(!is_basic(i));
00084   return original_variable_value_under_bounds(i);
00085 }
00086 
00087 // Computes r_i:= A_i x_init, for i=row, where x_init is the solution
00088 // with which the solver starts the computation. I.e., computes the
00089 // scalar product of the row-th row of A and the vector x_init which
00090 // contains as its entries the values original_variable_value(i),
00091 // 0<=i<qp_n.
00092 template < typename Q, typename ET, typename Tags >
00093 ET  QP_solver<Q, ET, Tags>::multiply__A_ixO(int row) const
00094 {
00095   ET value = et0;
00096 
00097   for (int i = 0; i < qp_n; ++i)
00098     // Note: the following computes
00099     //
00100     //   value += original_variable_value(i) * qp_A[i][row];
00101     //
00102     // but for efficiency, we only add summands that are known to be
00103     // nonzero.
00104     switch (x_O_v_i[i]) {
00105     case UPPER:
00106       value += ET(*(qp_u+i)) * ET(*((*(qp_A+i))+row));
00107       break;
00108     case LOWER:
00109     case FIXED:
00110       value += ET(*(qp_l+i)) * ET(*((*(qp_A+i))+row));
00111       break;
00112     case BASIC:
00113       CGAL_qpe_assertion(false);
00114     default:
00115       break;
00116     }
00117 
00118   return value;
00119 }
00120 
00121 // Computes r_{C}:= A_{C, N_O} x_{N_O}.
00122 //
00123 // Precondition: this routine should only be called for nonstandard form
00124 // problems.
00125 template < typename Q, typename ET, typename Tags >
00126 void  QP_solver<Q, ET, Tags>::
00127 multiply__A_CxN_O(Value_iterator out) const
00128 {
00129   CGAL_qpe_assertion(!check_tag(Is_nonnegative()));
00130   
00131   // initialize with zero vector:
00132   std::fill_n(out, C.size(), et0);
00133   
00134   for (int i = 0; i < qp_n; ++i)
00135     if (!is_basic(i)) {
00136       const ET x_i = nonbasic_original_variable_value(i);
00137       const A_column a_col = *(qp_A+i);
00138       Value_iterator out_it = out;
00139       for (Index_const_iterator row_it = C.begin();
00140            row_it != C.end();
00141            ++row_it, ++out_it)
00142         *out_it += x_i * ET(*(a_col+ *row_it));
00143     }
00144 }
00145 
00146 // Computes w:= 2D_{O, N_O} x_{N_O}.
00147 //
00148 // Precondition: this routine should only be called for nonstandard form
00149 // problems.
00150 //
00151 // todo: In order to optimize this routine, we can if D is symmetric,
00152 // multiply by two at the end of the computation instead of at each
00153 // access to D. (Maybe its also faster to call
00154 // nonbasic_original_variable_value() only O(n) times and not O(n^2)
00155 // times.)
00156 template < typename Q, typename ET, typename Tags >
00157 void  QP_solver<Q, ET, Tags>::
00158 multiply__2D_OxN_O(Value_iterator out) const
00159 {
00160   CGAL_qpe_assertion(!check_tag(Is_nonnegative()));
00161 
00162   // initialize with zero vector:
00163   std::fill_n(out, B_O.size(), et0);
00164   
00165   for (int row_it = 0; row_it < qp_n; ++row_it, ++out) {
00166     D_pairwise_accessor d_row(qp_D, row_it);
00167     for (int i = 0; i < qp_n; ++i)
00168       if (!is_basic(i)) {
00169         const ET value = nonbasic_original_variable_value(i);
00170         *out += d_row(i) * value;
00171       }
00172   }
00173 }
00174 
00175 // Computes r_{S_B}:= A_{S_B, N_O} x_{N_O}.
00176 //
00177 // Precondition: this routine should only be called for nonstandard form
00178 // problems.
00179 template < typename Q, typename ET, typename Tags >
00180 void  QP_solver<Q, ET, Tags>::
00181 multiply__A_S_BxN_O(Value_iterator out) const
00182 {
00183   // initialize with zero vector:
00184   std::fill_n(out, S_B.size(), et0);
00185   
00186   for (int i = 0; i < qp_n; ++i)
00187     if (!is_basic(i)) {
00188       const ET x_i = nonbasic_original_variable_value(i);
00189       const A_column a_col = *(qp_A+i);
00190       Value_iterator out_it = out;
00191       for (Index_const_iterator row_it = S_B.begin();
00192            row_it != S_B.end();
00193            ++row_it, ++out_it)
00194         *out_it += x_i * ET(*(a_col+ *row_it));
00195     }
00196 }
00197 
00198 // Initialize r_B_O.
00199 //
00200 // Note: this routine is called from transition() (and not during the
00201 // initialization of the QP-solver).
00202 template < typename Q, typename ET, typename Tags >
00203 void  QP_solver<Q, ET, Tags>::
00204 init_r_B_O()
00205 {
00206   CGAL_qpe_assertion(!check_tag(Is_nonnegative()) &&
00207                         !check_tag(Is_linear()));
00208   r_B_O.resize(B_O.size());
00209   multiply__2D_B_OxN_O(r_B_O.begin());
00210 }
00211 
00212 // Initialize w.
00213 //
00214 // Note: this routine is called from transition() (and not during the
00215 // initialization of the QP-solver).
00216 template < typename Q, typename ET, typename Tags >
00217 void  QP_solver<Q, ET, Tags>::
00218 init_w()
00219 {
00220   CGAL_qpe_assertion(!check_tag(Is_nonnegative()) &&
00221                         !check_tag(Is_linear()));
00222   w.resize(qp_n);
00223   multiply__2D_OxN_O(w.begin());
00224 }
00225 
00226 CGAL_END_NAMESPACE
00227 
00228 // ===== EOF ==================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines