Scippy

SoPlex

Sequential object-oriented simPlex

vectorbase.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996 Roland Wunderling */
7 /* 1996-2015 Konrad-Zuse-Zentrum */
8 /* fuer Informationstechnik Berlin */
9 /* */
10 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
11 /* */
12 /* You should have received a copy of the ZIB Academic License */
13 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
14 /* */
15 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 
17 /**@file vectorbase.h
18  * @brief Dense vector.
19  */
20 #ifndef _VECTORBASE_H_
21 #define _VECTORBASE_H_
22 
23 #include <assert.h>
24 #include <string.h>
25 #include <math.h>
26 #include <iostream>
27 
28 namespace soplex
29 {
30 template < class R > class SVectorBase;
31 template < class R > class SSVectorBase;
32 
33 /**@brief Dense vector.
34  * @ingroup Algebra
35  *
36  * Class VectorBase provides dense linear algebra vectors. It does not provide memory management for the %array of
37  * values. Instead, the constructor requires a pointer to a memory block large enough to fit the desired dimension of
38  * Real or Rational values.
39  *
40  * After construction, the values of a VectorBase can be accessed with the subscript operator[](). Safety is provided by
41  * qchecking of array bound when accessing elements with the subscript operator[]() (only when compiled without \c
42  * -DNDEBUG).
43  *
44  * A VectorBase is distinguished from a simple array of %Reals or %Rationals by providing a set of mathematical
45  * operations. Since VectorBase does not provide any memory management features, no operations are available that would
46  * require allocation of temporary memory space.
47  *
48  * The following mathematical operations are provided by class VectorBase (VectorBase \p a, \p b; R \p x):
49  *
50  * <TABLE>
51  * <TR><TD>Operation</TD><TD>Description </TD><TD></TD>&nbsp;</TR>
52  * <TR><TD>\c -= </TD><TD>subtraction </TD><TD>\c a \c -= \c b </TD></TR>
53  * <TR><TD>\c += </TD><TD>addition </TD><TD>\c a \c += \c b </TD></TR>
54  * <TR><TD>\c * </TD><TD>scalar product</TD>
55  * <TD>\c x = \c a \c * \c b </TD></TR>
56  * <TR><TD>\c *= </TD><TD>scaling </TD><TD>\c a \c *= \c x </TD></TR>
57  * <TR><TD>maxAbs() </TD><TD>infinity norm </TD>
58  * <TD>\c a.maxAbs() == \f$\|a\|_{\infty}\f$ </TD></TR>
59  * <TR><TD>minAbs() </TD><TD> </TD>
60  * <TD>\c a.minAbs() == \f$\min |a_i|\f$ </TD></TR>
61  *
62  * <TR><TD>length() </TD><TD>euclidian norm</TD>
63  * <TD>\c a.length() == \f$\sqrt{a^2}\f$ </TD></TR>
64  * <TR><TD>length2()</TD><TD>square norm </TD>
65  * <TD>\c a.length2() == \f$a^2\f$ </TD></TR>
66  * <TR><TD>multAdd(\c x,\c b)</TD><TD>add scaled vector</TD>
67  * <TD> \c a += \c x * \c b </TD></TR>
68  * </TABLE>
69  *
70  * When using any of these operations, the vectors involved must be of the same dimension. Also an SVectorBase \c b is
71  * allowed if it does not contain nonzeros with index greater than the dimension of \c a.q
72  */
73 template < class R >
75 {
76 protected:
77 
78  // ------------------------------------------------------------------------------------------------------------------
79  /**@name Data */
80  //@{
81 
82  /// Dimension of vector.
83  int dimen;
84 
85  /// Values of vector.
86  /** The memory block pointed to by val must at least have size dimen * sizeof(R). */
87  R* val;
88 
89  //@}
90 
91 public:
92 
93  // ------------------------------------------------------------------------------------------------------------------
94  /**@name Construction and assignment */
95  //@{
96 
97  /// Constructor.
98  /** There is no default constructor since the storage for a VectorBase must be provided externally. Storage must be
99  * passed as a memory block val at construction. It must be large enough to fit at least dimen values.
100  */
101  VectorBase<R>(int p_dimen, R* p_val)
102  : dimen(p_dimen)
103  , val(p_val)
104  {
105  assert(dimen >= 0);
106  assert(isConsistent());
107  }
108 
109  /// Assignment operator.
110  template < class S >
112  {
113  if( (VectorBase<S>*)this != &vec )
114  {
115  assert(dim() == vec.dim());
116 
117  for( int i = 0; i < dimen; i++ )
118  val[i] = vec[i];
119 
120  assert(isConsistent());
121  }
122 
123  return *this;
124  }
125 
126  /// Assignment operator.
128  {
129  if( this != &vec )
130  {
131  assert(dim() == vec.dim());
132 
133  for( int i = 0; i < dimen; i++ )
134  val[i] = vec[i];
135 
136  assert(isConsistent());
137  }
138 
139  return *this;
140  }
141 
142  /// Assignment operator.
143  /** Assigning an SVectorBase to a VectorBase using operator=() will set all values to 0 except the nonzeros of \p vec.
144  * This is diffent in method assign().
145  */
146  template < class S >
148 
149  /// Assignment operator.
150  /** Assigning an SSVectorBase to a VectorBase using operator=() will set all values to 0 except the nonzeros of \p
151  * vec. This is diffent in method assign().
152  */
153  /**@todo do we need this also in non-template version, because SSVectorBase can be automatically cast to VectorBase? */
154  template < class S >
156 
157  /// Assign values of \p vec.
158  /** Assigns all nonzeros of \p vec to the vector. All other values remain unchanged. */
159  template < class S >
160  VectorBase<R>& assign(const SVectorBase<S>& vec);
161 
162  /// Assign values of \p vec.
163  /** Assigns all nonzeros of \p vec to the vector. All other values remain unchanged. */
164  template < class S >
165  VectorBase<R>& assign(const SSVectorBase<S>& vec);
166 
167  //@}
168 
169  // ------------------------------------------------------------------------------------------------------------------
170  /**@name Access */
171  //@{
172 
173  /// Dimension of vector.
174  int dim() const
175  {
176  return dimen;
177  }
178 
179  /// Return \p n 'th value by reference.
180  R& operator[](int n)
181  {
182  assert(n >= 0 && n < dimen);
183  return val[n];
184  }
185 
186  /// Return \p n 'th value.
187  const R& operator[](int n) const
188  {
189  assert(n >= 0 && n < dimen);
190  return val[n];
191  }
192 
193  /// Equality operator.
194  friend bool operator==(const VectorBase<R>& vec1, const VectorBase<R>& vec2)
195  {
196  if( &vec1 == &vec2 )
197  return true;
198  else if( vec1.dim() != vec2.dim() )
199  return false;
200  else
201  {
202  for( int i = 0; i < vec1.dim(); i++ )
203  {
204  if( vec1[i] != vec2[i] )
205  return false;
206  }
207  }
208 
209  return true;
210  }
211 
212  //@}
213 
214  // ------------------------------------------------------------------------------------------------------------------
215  /**@name Arithmetic operations */
216  //@{
217 
218  /// Set vector to 0.
219  void clear()
220  {
221  if( dimen > 0 )
222  {
223  for( int i = 0; i < dimen; i++ )
224  val[i] = 0;
225  }
226  }
227 
228  /// Addition.
229  template < class S >
231  {
232  assert(dim() == vec.dim());
233  assert(dim() == dimen);
234 
235  for( int i = 0; i < dimen; i++ )
236  val[i] += vec[i];
237 
238  return *this;
239  }
240 
241  /// Addition.
242  template < class S >
244 
245  /// Addition.
246  template < class S >
248 
249  /// Subtraction.
250  template < class S >
252  {
253  assert(dim() == vec.dim());
254  assert(dim() == dimen);
255 
256  for( int i = 0; i < dimen; i++ )
257  val[i] -= vec[i];
258 
259  return *this;
260  }
261 
262  /// Subtraction.
263  template < class S >
265 
266  /// Subtraction.
267  template < class S >
269 
270  /// Scaling.
271  template < class S >
273  {
274  assert(dim() == dimen);
275 
276  for( int i = 0; i < dimen; i++ )
277  val[i] *= x;
278 
279  return *this;
280  }
281 
282  /// Division.
283  template < class S >
285  {
286  assert(x != 0);
287 
288  for( int i = 0; i < dim(); i++ )
289  val[i] /= x;
290 
291  return *this;
292  }
293 
294  /// Inner product.
295  R operator*(const VectorBase<R>& vec) const
296  {
297  assert(vec.dim() == dimen);
298 
299  R x = 0;
300 
301  for( int i = 0; i < dimen; i++ )
302  x += val[i] * vec.val[i];
303 
304  return x;
305  }
306 
307  /// Inner product.
308  R operator*(const SVectorBase<R>& vec) const;
309 
310  /// Inner product.
311  R operator*(const SSVectorBase<R>& vec) const;
312 
313  /// Maximum absolute value, i.e., infinity norm.
314  R maxAbs() const
315  {
316  assert(dim() > 0);
317  assert(dim() == dimen);
318 
319  R maxi = 0;
320 
321  for( int i = 0; i < dimen; i++ )
322  {
323  R x = spxAbs(val[i]);
324 
325  if( x > maxi )
326  maxi = x;
327  }
328 
329  assert(maxi >= 0);
330 
331  return maxi;
332  }
333 
334  /// Minimum absolute value.
335  R minAbs() const
336  {
337  assert(dim() > 0);
338  assert(dim() == dimen);
339 
340  R mini = spxAbs(val[0]);
341 
342  for( int i = 1; i < dimen; i++ )
343  {
344  R x = spxAbs(val[i]);
345 
346  if( x < mini )
347  mini = x;
348  }
349 
350  assert(mini >= 0);
351 
352  return mini;
353  }
354 
355  /// Floating point approximation of euclidian norm (without any approximation guarantee).
356  Real length() const
357  {
358  return spxSqrt((Real)length2());
359  }
360 
361  /// Squared norm.
362  R length2() const
363  {
364  return (*this) * (*this);
365  }
366 
367  /// Addition of scaled vector.
368  template < class S, class T >
369  VectorBase<R>& multAdd(const S& x, const VectorBase<T>& vec)
370  {
371  assert(vec.dim() == dimen);
372 
373  for( int i = 0; i < dimen; i++ )
374  val[i] += x * vec.val[i];
375 
376  return *this;
377  }
378 
379  /// Addition of scaled vector.
380  template < class S, class T >
381  VectorBase<R>& multAdd(const S& x, const SVectorBase<T>& vec);
382 
383  /// Subtraction of scaled vector.
384  template < class S, class T >
385  VectorBase<R>& multSub(const S& x, const SVectorBase<T>& vec);
386 
387  /// Addition of scaled vector.
388  template < class S, class T >
389  VectorBase<R>& multAdd(const S& x, const SSVectorBase<T>& vec);
390 
391  //@}
392 
393  // ------------------------------------------------------------------------------------------------------------------
394  /**@name Utilities */
395  //@{
396 
397  /// Conversion to C-style pointer.
398  /** This function serves for using a VectorBase in an C-style function. It returns a pointer to the first value of
399  * the array.
400  *
401  * @todo check whether this non-const c-style access should indeed be public
402  */
403  R* get_ptr()
404  {
405  return val;
406  }
407 
408  /// Conversion to C-style pointer.
409  /** This function serves for using a VectorBase in an C-style function. It returns a pointer to the first value of
410  * the array.
411  */
412  const R* get_const_ptr() const
413  {
414  return val;
415  }
416 
417  /// Consistency check.
418  bool isConsistent() const
419  {
420 #ifdef ENABLE_CONSISTENCY_CHECKS
421  if( dim() > 0 && val == 0 )
422  return MSGinconsistent("VectorBase");
423 #endif
424 
425  return true;
426  }
427 
428  //@}
429 
430 private:
431 
432  // ------------------------------------------------------------------------------------------------------------------
433  /**@name Blocked */
434  //@{
435 
436  /// Blocked default constructor.
438  {
439  }
440 
441  //@}
442 };
443 
444 
445 
446 /// Assignment operator (specialization for Real).
447 template <>
448 inline
450 {
451  if( this != &vec )
452  {
453  assert(dim() == vec.dim());
454 
455  memcpy(val, vec.val, (unsigned int)dimen*sizeof(Real));
456 
457  assert(isConsistent());
458  }
459  return *this;
460 }
461 
462 
463 
464 /// Assignment operator (specialization for Real).
465 template <>
466 template <>
467 inline
469 {
470  if( (VectorBase<Rational>*)this != &vec )
471  {
472  assert(dim() == vec.dim());
473 
474  for( int i = 0; i < dimen; i++ )
475  val[i] = Real(vec[i]);
476 
477  assert(isConsistent());
478  }
479 
480  return *this;
481 }
482 
483 
484 
485 /// Set vector to 0 (specialization for Real).
486 template<>
487 inline
489 {
490  if( dimen > 0 )
491  memset(val, 0, (unsigned int)dimen * sizeof(Real));
492 }
493 
494 
495 
496 #ifndef SOPLEX_LEGACY
497 /// Inner product.
498 template<>
499 inline
501 {
502  assert(vec.dim() == dimen);
503 
504  if( dimen <= 0 || vec.dim() <= 0 )
505  return 0;
506 
507  Rational x = val[0];
508  x *= vec.val[0];
509 
510  for( int i = 1; i < dimen && i < vec.dim(); i++ )
511  x.addProduct(val[i], vec.val[i]);
512 
513  return x;
514 }
515 #endif
516 
517 } // namespace soplex
518 #endif // _VECTORBASE_H_