All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CPG.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SOLVERS_CPG_H_
36 #define _BLAZE_MATH_SOLVERS_CPG_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
48 #include <blaze/math/shims/IsNaN.h>
50 #include <blaze/util/Assert.h>
51 #include <blaze/util/ColorMacros.h>
53 #include <blaze/util/Types.h>
54 
55 
56 namespace blaze {
57 
58 //=================================================================================================
59 //
60 // CLASS DEFINITION
61 //
62 //=================================================================================================
63 
64 //*************************************************************************************************
72 class CPG : public Solver
73 {
74  public:
75  //**Constructors********************************************************************************
78  explicit CPG();
80  //**********************************************************************************************
81 
82  //**Utility functions***************************************************************************
85  template< typename CP > bool solve( CP& cp );
87  //**********************************************************************************************
88 
89  private:
90  //**Member variables****************************************************************************
93  VecN r_;
94  VecN w_;
95  VecN p_;
97 
98  //**********************************************************************************************
99 };
100 //*************************************************************************************************
101 
102 
103 
104 
105 //=================================================================================================
106 //
107 // UTILITY FUNCTIONS
108 //
109 //=================================================================================================
110 
111 //*************************************************************************************************
119 template< typename CP > // Type of the complementarity problem
120 bool CPG::solve( CP& cp )
121 {
122  const size_t n( cp.size() );
123  const CMatMxN& A( cp.A_ );
124  const VecN& b( cp.b_ );
125 
126  bool converged( false );
127  VecN& x( cp.x_ );
128  size_t activeSetChanges( 0 );
129  real alpha( 0 ), alpha_nom( 0 ), alpha_denom( 1 );
130  real beta( 0 ), beta_nom( 0 ), beta_denom( 0 );
131  real tmp( 0 );
132 
133  BLAZE_INTERNAL_ASSERT( isSymmetric( A ), "The CPG solver requires that the system matrix is symmetric" );
134 
135  // Allocating helper data
136  r_.resize( n, false );
137  w_.resize( n, false );
138  p_.resize( n, false );
139  activity_.resize( n, false );
140 
141  // Determining activity and project initial solution to feasible region
142  for( size_t i=0; i<n; ++i ) {
143  if( x[i] <= cp.lbound( i ) ) {
144  x[i] = cp.lbound( i );
145  ++activeSetChanges;
146  activity_[i] = -1;
147  }
148  else if( x[i] >= cp.ubound( i ) ) {
149  x[i] = cp.ubound( i );
150  ++activeSetChanges;
151  activity_[i] = 1;
152  }
153  else {
154  activity_[i] = 0;
155  }
156  }
157 
158  // Computing the initial residual
159  lastPrecision_ = cp.residual();
160  if( lastPrecision_ < threshold_ )
161  converged = true;
162 
163  // Choosing the initial values such that the descent direction conjugation process is disabled
164  p_ = real(0);
165  w_ = real(0);
166 
167  size_t it( 0 );
168  for( ; !converged && it < maxIterations_; ++it )
169  {
170  // Computing the steepest descent direction
171  r_ = -( A*x + b );
172 
173  // Projecting the gradient and the previous descent direction
174  beta_nom = real(0);
175  beta_denom = alpha_denom;
176 
177  for( size_t i=0; i<n; ++i ) {
178  tmp = r_[i];
179  if( activity_[i] == -1 ) {
180  tmp = max( tmp, 0 );
181  p_[i] = max( p_[i], 0 );
182  }
183  else if( activity_[i] == 1 ) {
184  tmp = min( tmp, 0 );
185  p_[i] = min( p_[i], 0 );
186  }
187  beta_nom += w_[i] * tmp;
188  w_[i] = tmp;
189  }
190 
191  if( beta_denom == 0 ) {
192  // No conjugation can be performed, fallback to steepest descent
193  beta = 0;
194  }
195  else {
196  beta = -beta_nom / beta_denom;
197  }
198 
199  BLAZE_INTERNAL_ASSERT( !isnan( beta ), "Conjugation coefficient is nan" );
200 
201  // Choosing the next descent direction conjugated to all previous directions
202  p_ = w_ + beta * p_;
203 
204  // Finding the minimum along the descent direction p
205  alpha_nom = trans(r_) * p_;
206  alpha_denom = trans(p_) * A * p_;
207 
208  if( alpha_denom == 0 )
209  // In case p^T A p is zero, no reduction of the objective function can be obtained
210  // in direction p no matter which alpha we choose
211  alpha = 0;
212  else
213  alpha = alpha_nom / alpha_denom;
214 
215  if( alpha == 0 ) {
216  if( beta == 0 ) {
217  // p is the steepest descent direction since beta = 0 but we still cannot
218  // make any progress along p => minimum
219  break;
220  }
221  else {
222  // Retry with steepest descent direction
223  continue;
224  }
225  }
226 
227  // Descending along p and projecting
228  activeSetChanges = 0;
229 
230  for( size_t i=0; i<n; ++i ) {
231  if( activity_[i] != 0 && p_[i] == real(0) ) {
232  // In case the bounds are depending on the unknowns this ensures that
233  // the unknowns stay at the bounds
234  if( activity_[i] == -1 )
235  x[i] = cp.lbound( i );
236  else
237  x[i] = cp.ubound( i );
238  }
239  else {
240  x[i] += alpha * p_[i];
241 
242  if( x[i] <= cp.lbound( i ) ) {
243  x[i] = cp.lbound( i );
244  if( activity_[i] != -1 )
245  ++activeSetChanges;
246  activity_[i] = -1;
247  }
248  else if( x[i] >= cp.ubound( i ) ) {
249  x[i] = cp.ubound( i );
250  if( activity_[i] != +1 )
251  ++activeSetChanges;
252  activity_[i] = +1;
253  }
254  else {
255  if( activity_[i] != 0 )
256  ++activeSetChanges;
257  activity_[i] = 0;
258  }
259  }
260  }
261 
262  // Computing the residual (TODO we should improve this)
263  lastPrecision_ = cp.residual();
264  if( lastPrecision_ < threshold_ )
265  converged = true;
266  }
267 
268  BLAZE_LOG_DEBUG_SECTION( log ) {
269  if( converged )
270  log << " Solved the quadratic program in " << it << " CPG iterations.";
271  else
272  log << BLAZE_YELLOW << " WARNING: Did not solve the quadratic program within accuracy. (" << lastPrecision_ << ")" << BLAZE_OLDCOLOR;
273  }
274 
275  lastIterations_ = it;
276 
277  return converged;
278 }
279 //*************************************************************************************************
280 
281 
282 
283 
284 //=================================================================================================
285 //
286 // EXPLICIT TEMPLATE INSTANTIATIONS
287 //
288 //=================================================================================================
289 
290 //*************************************************************************************************
292 #if !defined(_MSC_VER)
293 extern template bool CPG::solve<LCP>( LCP& );
294 extern template bool CPG::solve<BoxLCP>( BoxLCP& );
295 extern template bool CPG::solve<ContactLCP>( ContactLCP& );
296 #endif
297 
298 //*************************************************************************************************
299 
300 } // namespace blaze
301 
302 #endif
Header file for the isnan shim.
A data structure for box linear complementarity problems.
A data structure for linear complementarity problems for contact mechanics.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:723
real lastPrecision_
The precision of the solution after the solution process.
Definition: Solver.h:99
Header file for color macros.
Header file for the log debug section.
bool isnan(const DenseMatrix< MT, SO > &dm)
Checks the given dense matrix for not-a-number elements.
Definition: DenseMatrix.h:640
A box linear complementarity problem (BLCP) data structure.The BoxLCP class represent a box linear co...
Definition: BoxLCP.h:66
#define BLAZE_YELLOW
Switches the text color to yellow in case the BLAZE_COLOR_OUTPUT macro is set.
Definition: ColorMacros.h:147
void resize(size_t n, bool preserve=true)
Changing the size of the vector.
Definition: DynamicVector.h:1158
size_t maxIterations_
The maximum number of iterations.
Definition: Solver.h:95
DynamicVector< int > activity_
TODO.
Definition: CPG.h:96
Implementation of the conjugate projected gradient algorithm.TODO: description of the CPG solver TODO...
Definition: CPG.h:72
#define BLAZE_LOG_DEBUG_SECTION(NAME)
Logging section for debug information.This macro starts a log section for debug information. These messages are written to the log file(s) in case the blaze::loglevel has been set to debug or higher. The following example demonstrates how this log section is used:
Definition: DebugSection.h:96
bool solve(CP &cp)
TODO.
Definition: CPG.h:120
VecN r_
TODO.
Definition: CPG.h:93
Header file for the complete DynamicVector implementation.
CPG()
The default constructor for the CPG class.
Definition: CPG.cpp:54
Header file for the base class of all solvers.
#define BLAZE_OLDCOLOR
Switches the text color back to the default color.
Definition: ColorMacros.h:162
Header file for run time assertion macros.
A data structure for linear complementarity problems.
VecN w_
TODO.
Definition: CPG.h:94
double real
Floating point data type of the Blaze library.This type definition offers the possibility to switch t...
Definition: Precision.h:47
Header file for the complete CompressedMatrix implementation.
real threshold_
Precision threshold for the solution.
Definition: Solver.h:100
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:907
A data structure for linear complementarity problems (LCPs) for contact mechanics.TODO.
Definition: ContactLCP.h:66
Header file for basic type definitions.
size_t lastIterations_
The number of iterations spent in the last solution process.
Definition: Solver.h:98
A linear complementarity problem (LCP) data structure.The LCP class represent a linear complementarit...
Definition: LCP.h:67
Base class for all solver classes.TODO: description of the Solver class TODO: description of its func...
Definition: Solver.h:63
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
VecN p_
TODO.
Definition: CPG.h:95