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-2022 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 "vector"
28 #include "algorithm"
29 
30 #include "soplex/spxdefines.h"
31 #include "soplex/stablesum.h"
32 #include "soplex/rational.h"
33 
34 namespace soplex
35 {
36 template < class R > class SVectorBase;
37 template < class R > class SSVectorBase;
38 
39 /**@brief Dense vector.
40  * @ingroup Algebra
41  *
42  * Class VectorBase provides dense linear algebra vectors. Internally, VectorBase wraps std::vector.
43  *
44  * After construction, the values of a VectorBase can be accessed with the subscript operator[](). Safety is provided by
45  * qchecking of array bound when accessing elements with the subscript operator[]() (only when compiled without \c
46  * -DNDEBUG).
47  *
48  * A VectorBase is distinguished from a simple array of %Reals or %Rationals by providing a set of mathematical
49  * operations.
50  *
51  * The following mathematical operations are provided by class VectorBase (VectorBase \p a, \p b; R \p x):
52  *
53  * <TABLE>
54  * <TR><TD>Operation</TD><TD>Description </TD><TD></TD>&nbsp;</TR>
55  * <TR><TD>\c -= </TD><TD>subtraction </TD><TD>\c a \c -= \c b </TD></TR>
56  * <TR><TD>\c += </TD><TD>addition </TD><TD>\c a \c += \c b </TD></TR>
57  * <TR><TD>\c * </TD><TD>scalar product</TD>
58  * <TD>\c x = \c a \c * \c b </TD></TR>
59  * <TR><TD>\c *= </TD><TD>scaling </TD><TD>\c a \c *= \c x </TD></TR>
60  * <TR><TD>maxAbs() </TD><TD>infinity norm </TD>
61  * <TD>\c a.maxAbs() == \f$\|a\|_{\infty}\f$ </TD></TR>
62  * <TR><TD>minAbs() </TD><TD> </TD>
63  * <TD>\c a.minAbs() == \f$\min |a_i|\f$ </TD></TR>
64  *
65  * <TR><TD>length() </TD><TD>euclidian norm</TD>
66  * <TD>\c a.length() == \f$\sqrt{a^2}\f$ </TD></TR>
67  * <TR><TD>length2()</TD><TD>square norm </TD>
68  * <TD>\c a.length2() == \f$a^2\f$ </TD></TR>
69  * <TR><TD>multAdd(\c x,\c b)</TD><TD>add scaled vector</TD>
70  * <TD> \c a += \c x * \c b </TD></TR>
71  * </TABLE>
72  *
73  * When using any of these operations, the vectors involved must be of the same dimension. Also an SVectorBase \c b is
74  * allowed if it does not contain nonzeros with index greater than the dimension of \c a.q
75  */
76 template < class R >
77 class VectorBase
78 {
79 
80  // VectorBase is a friend of VectorBase of different template type. This is so
81  // that we can do conversions.
82  template <typename S>
83  friend class VectorBase;
84 
85 
86 protected:
87 
88  // ------------------------------------------------------------------------------------------------------------------
89  /**@name Data */
90  ///@{
91 
92  /// Values of vector.
93  std::vector<R> val;
94 
95  ///@}
96 
97 public:
98 
99  // ------------------------------------------------------------------------------------------------------------------
100  /**@name Construction and assignment */
101  ///@{
102 
103  /// Constructor.
104  /** There is no default constructor since the storage for a VectorBase must be provided externally. Storage must be
105  * passed as a memory block val at construction. It must be large enough to fit at least dimen values.
106  */
107 
108  // Default constructor
110  {
111  // Default constructor
112  ;
113  }
114 
115  // Construct from pointer, copies the values into the VectorBase
116  VectorBase<R>(int dimen, R* p_val)
117  {
118  val.assign(p_val, p_val + dimen);
119  }
120 
121  // do not convert int to empty vectorbase
122  explicit VectorBase<R>(int p_dimen)
123  {
124  val.resize(p_dimen);
125  }
126 
127  // Constructing an element (usually involving casting Real to Rational and
128  // vice versa.)
129  template <typename S>
131  {
132  this->operator=(vec);
133  }
134 
135  // The move constructor
136  VectorBase<R>(const VectorBase<R>&& vec)noexcept: val(std::move(vec.val))
137  {
138  }
139 
140  // Copy constructor
142  {
143  }
144 
145 
146  /// Assignment operator.
147  // Supports assignment from a Rational vector to Real and vice versa
148  template < class S >
150  {
151  if((VectorBase<S>*)this != &vec)
152  {
153  val.clear();
154  val.reserve(vec.dim());
155 
156  for(auto& v : vec.val)
157  {
158  val.push_back(R(v));
159  }
160  }
161 
162  return *this;
163  }
164 
165  /// Assignment operator.
167  {
168  if(this != &vec)
169  {
170  val.reserve(vec.dim());
171 
172  val = vec.val;
173  }
174 
175  return *this;
176  }
177 
178  /// Move assignment operator
180  {
181  val = std::move(vec.val);
182  return *this;
183  }
184 
185  /// scale and assign
187  {
188  if(this != &vec)
189  {
190  assert(dim() == vec.dim());
191 
192  auto dimen = dim();
193 
194  for(decltype(dimen) i = 0 ; i < dimen; i++)
195  val[i] = spxLdexp(vec[i], scaleExp);
196 
197  }
198 
199  return *this;
200  }
201 
202  /// scale and assign
203  VectorBase<R>& scaleAssign(const int* scaleExp, const VectorBase<R>& vec, bool negateExp = false)
204  {
205  if(this != &vec)
206  {
207  assert(dim() == vec.dim());
208 
209  if(negateExp)
210  {
211  auto dimen = dim();
212 
213  for(decltype(dimen) i = 0; i < dimen; i++)
214  val[i] = spxLdexp(vec[i], -scaleExp[i]);
215  }
216  else
217  {
218  auto dimen = dim();
219 
220  for(decltype(dimen) i = 0; i < dimen; i++)
221  val[i] = spxLdexp(vec[i], scaleExp[i]);
222  }
223 
224  }
225 
226  return *this;
227  }
228 
229 
230  /// Assignment operator.
231  /** Assigning an SVectorBase to a VectorBase using operator=() will set all values to 0 except the nonzeros of \p vec.
232  * This is diffent in method assign().
233  */
234  template < class S >
236 
237  /// Assignment operator.
238  /** Assigning an SSVectorBase to a VectorBase using operator=() will set all values to 0 except the nonzeros of \p
239  * vec. This is diffent in method assign().
240  */
241  /**@todo do we need this also in non-template version, because SSVectorBase can be automatically cast to VectorBase? */
242  template < class S >
244 
245  /// Assign values of \p vec.
246  /** Assigns all nonzeros of \p vec to the vector. All other values remain unchanged. */
247  template < class S >
248  VectorBase<R>& assign(const SVectorBase<S>& vec);
249 
250  /// Assign values of \p vec.
251  /** Assigns all nonzeros of \p vec to the vector. All other values remain unchanged. */
252  template < class S >
253  VectorBase<R>& assign(const SSVectorBase<S>& vec);
254 
255  ///@}
256 
257  // ------------------------------------------------------------------------------------------------------------------
258  /**@name Access */
259  ///@{
260 
261  /// Dimension of vector.
262  int dim() const
263  {
264  return int(val.size());
265  }
266 
267  /// Return \p n 'th value by reference.
268  R& operator[](int n)
269  {
270  assert(n >= 0 && n < dim());
271  return val[n];
272  }
273 
274  /// Return \p n 'th value.
275  const R& operator[](int n) const
276  {
277  assert(n >= 0 && n < dim());
278  return val[n];
279  }
280 
281  /// Equality operator.
282  friend bool operator==(const VectorBase<R>& vec1, const VectorBase<R>& vec2)
283  {
284  return (vec1.val == vec2.val);
285  }
286 
287  /// Return underlying std::vector.
288  const std::vector<R>& vec()
289  {
290  return val;
291  }
292 
293  ///@}
294 
295  // ------------------------------------------------------------------------------------------------------------------
296  /**@name Arithmetic operations */
297  ///@{
298 
299  /// Set vector to contain all-zeros (keeping the same length)
300  void clear()
301  {
302  for(auto& v : val)
303  v = 0;
304  }
305 
306  /// Addition.
307  template < class S >
309  {
310  assert(dim() == vec.dim());
311 
312  auto dimen = dim();
313 
314  for(decltype(dimen) i = 0; i < dimen; i++)
315  val[i] += vec[i];
316 
317  return *this;
318  }
319 
320  /// Addition.
321  template < class S >
323 
324  /// Addition.
325  template < class S >
327 
328  /// Subtraction.
329  template < class S >
331  {
332  assert(dim() == vec.dim());
333 
334  auto dimen = dim();
335 
336  for(decltype(dimen) i = 0; i < dimen; i++)
337  val[i] -= vec[i];
338 
339  return *this;
340  }
341 
342  /// Subtraction.
343  template < class S >
345 
346  /// Subtraction.
347  template < class S >
349 
350  /// Scaling.
351  template < class S >
353  {
354 
355  auto dimen = dim();
356 
357  for(decltype(dimen) i = 0; i < dimen; i++)
358  val[i] *= x;
359 
360  return *this;
361  }
362 
363  /// Division.
364  template < class S >
366  {
367  assert(x != 0);
368 
369  auto dimen = dim();
370 
371  for(decltype(dimen) i = 0; i < dimen; i++)
372  val[i] /= x;
373 
374  return *this;
375  }
376 
377  /// Inner product.
378  R operator*(const VectorBase<R>& vec) const
379  {
380  StableSum<R> x;
381 
382  auto dimen = dim();
383 
384  for(decltype(dimen) i = 0; i < dimen; i++)
385  x += val[i] * vec.val[i];
386 
387  return x;
388  }
389 
390  /// Inner product.
391  R operator*(const SVectorBase<R>& vec) const;
392 
393  /// Inner product.
394  R operator*(const SSVectorBase<R>& vec) const;
395 
396  /// Maximum absolute value, i.e., infinity norm.
397  R maxAbs() const
398  {
399  assert(dim() > 0);
400 
401  // A helper function for the std::max_element. Because we compare the absolute value.
402  auto absCmpr = [](R a, R b)
403  {
404  return (spxAbs(a) < spxAbs(b));
405  };
406 
407  auto maxReference = std::max_element(val.begin(), val.end(), absCmpr);
408 
409  R maxi = spxAbs(*maxReference);
410 
411  assert(maxi >= 0.0);
412 
413  return maxi;
414  }
415 
416  /// Minimum absolute value.
417  R minAbs() const
418  {
419  assert(dim() > 0);
420 
421  // A helper function for the std::min_element. Because we compare the absolute value.
422  auto absCmpr = [](R a, R b)
423  {
424  return (spxAbs(a) < spxAbs(b));
425  };
426 
427  auto minReference = std::min_element(val.begin(), val.end(), absCmpr);
428 
429  R mini = spxAbs(*minReference);
430 
431  assert(mini >= 0.0);
432 
433  return mini;
434  }
435 
436  /// Floating point approximation of euclidian norm (without any approximation guarantee).
437  R length() const
438  {
439  return spxSqrt(length2());
440  }
441 
442  /// Squared norm.
443  R length2() const
444  {
445  return (*this) * (*this);
446  }
447 
448  /// Addition of scaled vector.
449  template < class S, class T >
450  VectorBase<R>& multAdd(const S& x, const VectorBase<T>& vec)
451  {
452  assert(vec.dim() == dim());
453 
454  auto dimen = dim();
455 
456  for(decltype(dimen) i = 0; i < dimen; i++)
457  val[i] += x * vec.val[i];
458 
459  return *this;
460  }
461 
462  /// Addition of scaled vector.
463  template < class S, class T >
464  VectorBase<R>& multAdd(const S& x, const SVectorBase<T>& vec);
465 
466  /// Subtraction of scaled vector.
467  template < class S, class T >
468  VectorBase<R>& multSub(const S& x, const SVectorBase<T>& vec);
469 
470  /// Addition of scaled vector.
471  template < class S, class T >
472  VectorBase<R>& multAdd(const S& x, const SSVectorBase<T>& vec);
473 
474  ///@}
475 
476  // ------------------------------------------------------------------------------------------------------------------
477  /**@name Utilities */
478  ///@{
479 
480  /// Conversion to C-style pointer.
481  /** This function serves for using a VectorBase in an C-style function. It returns a pointer to the first value of
482  * the array.
483  *
484  * @todo check whether this non-const c-style access should indeed be public
485  */
486  R* get_ptr()
487  {
488  return val.data();
489  }
490 
491  /// Conversion to C-style pointer.
492  /** This function serves for using a VectorBase in an C-style function. It returns a pointer to the first value of
493  * the array.
494  */
495  const R* get_const_ptr() const
496  {
497  return val.data();
498  }
499 
500  // Provides access to the iterators of std::vector<R> val
501  typename std::vector<R>::const_iterator begin() const
502  {
503  return val.begin();
504  }
505 
506  typename std::vector<R>::iterator begin()
507  {
508  return val.begin();
509  }
510 
511  // Provides access to the iterators of std::vector<R> val
512  typename std::vector<R>::const_iterator end() const
513  {
514  return val.end();
515  }
516 
517  typename std::vector<R>::iterator end()
518  {
519  return val.end();
520  }
521 
522  // Functions from VectorBase
523 
524  // This used to be VectorBase's way of having std::vector's capacity. This
525  // represents the maximum number of elements the std::vector can have without,
526  // needing any more resizing. Bigger than size, mostly.
527  int memSize() const
528  {
529  return int(val.capacity());
530  }
531 
532  /// Resets \ref soplex::VectorBase "VectorBase"'s dimension to \p newdim.
533  void reDim(int newdim, const bool setZero = true)
534  {
535  if(setZero && newdim > dim())
536  {
537  // Inserts 0 to the rest of the vectors.
538  //
539  // TODO: Is this important after the change of raw pointers to
540  // std::vector. This is just a waste of operations, I think.
541  val.insert(val.end(), newdim - VectorBase<R>::dim(), 0);
542  }
543  else
544  {
545  val.resize(newdim);
546  }
547 
548  }
549 
550 
551  /// Resets \ref soplex::VectorBase "VectorBase"'s memory size to \p newsize.
552  void reSize(int newsize)
553  {
554  assert(newsize > VectorBase<R>::dim());
555 
556  // Problem: This is not a conventional resize for std::vector. This only
557  // updates the capacity, i.e., by pushing elements to the vector after this,
558  // there will not be any (internal) resizes.
559  val.reserve(newsize);
560  }
561 
562  // For operations such as vec1 - vec2
563  const VectorBase<R> operator-(const VectorBase<R>& vec) const
564  {
565  assert(vec.dim() == dim());
566  VectorBase<R> res;
567  res.val.reserve(dim());
568 
569  auto dimen = dim();
570 
571  for(decltype(dimen) i = 0; i < dimen; i++)
572  {
573  res.val.push_back(val[i] - vec[i]);
574  }
575 
576  return res;
577  }
578 
579  // Addition
580  const VectorBase<R> operator+(const VectorBase<R>& v) const
581  {
582  assert(v.dim() == dim());
583  VectorBase<R> res;
584  res.val.reserve(dim());
585 
586  auto dimen = dim();
587 
588  for(decltype(dimen) i = 0; i < dimen; i++)
589  {
590  res.val.push_back(val[i] + v[i]);
591  }
592 
593  return res;
594  }
595 
596  // The negation operator. e.g. -vec1;
598  {
599  VectorBase<R> res;
600 
601  res.val.reserve(vec.dim());
602 
603  for(auto& v : vec.val)
604  {
605  res.val.push_back(-(v));
606  }
607 
608  return res;
609  }
610 
611 
612  ///@}
613  /// Consistency check.
614  bool isConsistent() const
615  {
616  return true;
617  }
618 
619 };
620 
621 /// Inner product.
622 template<>
623 inline
625 {
626  assert(vec.dim() == dim());
627 
628  if(dim() <= 0 || vec.dim() <= 0)
629  return Rational();
630 
631  Rational x = val[0];
632  x *= vec.val[0];
633 
634  auto dimen = dim();
635 
636  for(decltype(dimen) i = 1; i < dimen; i++)
637  x += val[i] * vec.val[i];
638 
639  return x;
640 }
641 
642 } // namespace soplex
643 #endif // _VECTORBASE_H_
number< gmp_rational, et_off > Rational
Definition: rational.h:30
R minAbs() const
Minimum absolute value.
Definition: vectorbase.h:417
VectorBase< R > & operator=(const VectorBase< S > &vec)
Assignment operator.
Definition: vectorbase.h:149
R length2() const
Squared norm.
Definition: vectorbase.h:443
Dense vector.Class VectorBase provides dense linear algebra vectors. Internally, VectorBase wraps std...
Definition: dsvectorbase.h:28
const VectorBase< R > operator+(const VectorBase< R > &v) const
Definition: vectorbase.h:580
const VectorBase< R > operator-(const VectorBase< R > &vec) const
Definition: vectorbase.h:563
VectorBase< R > & scaleAssign(int scaleExp, const VectorBase< R > &vec)
scale and assign
Definition: vectorbase.h:186
R length() const
Floating point approximation of euclidian norm (without any approximation guarantee).
Definition: vectorbase.h:437
std::vector< R >::iterator end()
Definition: vectorbase.h:517
VectorBase< R > & operator+=(const VectorBase< S > &vec)
Addition.
Definition: vectorbase.h:308
Semi sparse vector.This class implements semi-sparse vectors. Such are VectorBases where the indices ...
Definition: dsvectorbase.h:29
const R * get_const_ptr() const
Conversion to C-style pointer.
Definition: vectorbase.h:495
R * get_ptr()
Conversion to C-style pointer.
Definition: vectorbase.h:486
int memSize() const
Definition: vectorbase.h:527
Real spxSqrt(Real a)
returns square root
Definition: spxdefines.h:371
VectorBase< R > & operator*=(const S &x)
Scaling.
Definition: vectorbase.h:352
VectorBase< R > & operator=(const VectorBase< R > &&vec)
Move assignment operator.
Definition: vectorbase.h:179
void reSize(int newsize)
Resets VectorBase&#39;s memory size to newsize.
Definition: vectorbase.h:552
friend bool operator==(const VectorBase< R > &vec1, const VectorBase< R > &vec2)
Equality operator.
Definition: vectorbase.h:282
bool isConsistent() const
Consistency check.
Definition: vectorbase.h:614
boost::multiprecision::number< T > spxLdexp(boost::multiprecision::number< T, eto > x, int exp)
Definition: spxdefines.h:472
Debugging, floating point type and parameter definitions.
R & operator[](int n)
Return n &#39;th value by reference.
Definition: vectorbase.h:268
VectorBase< R > & multAdd(const S &x, const VectorBase< T > &vec)
Addition of scaled vector.
Definition: vectorbase.h:450
int dim() const
Dimension of vector.
Definition: vectorbase.h:262
friend VectorBase< R > operator-(const VectorBase< R > &vec)
Definition: vectorbase.h:597
Everything should be within this namespace.
VectorBase< R > & operator-=(const VectorBase< S > &vec)
Subtraction.
Definition: vectorbase.h:330
std::vector< R >::iterator begin()
Definition: vectorbase.h:506
std::vector< R >::const_iterator begin() const
Definition: vectorbase.h:501
void reDim(int newdim, const bool setZero=true)
Resets VectorBase&#39;s dimension to newdim.
Definition: vectorbase.h:533
VectorBase< R > & scaleAssign(const int *scaleExp, const VectorBase< R > &vec, bool negateExp=false)
scale and assign
Definition: vectorbase.h:203
R operator*(const VectorBase< R > &vec) const
Inner product.
Definition: vectorbase.h:378
void clear()
Set vector to contain all-zeros (keeping the same length)
Definition: vectorbase.h:300
const R & operator[](int n) const
Return n &#39;th value.
Definition: vectorbase.h:275
std::vector< R > val
Values of vector.
Definition: vectorbase.h:93
R spxAbs(R a)
Definition: spxdefines.h:338
VectorBase< R > & operator/=(const S &x)
Division.
Definition: vectorbase.h:365
Sparse vectors.Class SVectorBase provides packed sparse vectors. Such are a sparse vectors...
Definition: ssvectorbase.h:34
std::vector< R >::const_iterator end() const
Definition: vectorbase.h:512
VectorBase< R > & assign(const SVectorBase< S > &vec)
Assign values of vec.
Definition: basevectors.h:78
R maxAbs() const
Maximum absolute value, i.e., infinity norm.
Definition: vectorbase.h:397
const std::vector< R > & vec()
Return underlying std::vector.
Definition: vectorbase.h:288
VectorBase< R > & multSub(const S &x, const SVectorBase< T > &vec)
Subtraction of scaled vector.
Definition: basevectors.h:289
VectorBase< R > & operator=(const VectorBase< R > &vec)
Assignment operator.
Definition: vectorbase.h:166