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