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