SoPlex Doxygen Documentation
svset.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-2012 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file svset.h
17  * @brief Set of sparse vectors.
18  */
19 
20 #ifndef _SVSET_H_
21 #define _SVSET_H_
22 
23 #include <assert.h>
24 
25 #include "spxdefines.h"
26 #include "svector.h"
27 #include "dataset.h"
28 #include "dataarray.h"
29 #include "idlist.h"
30 #include "datakey.h"
31 
32 namespace soplex
33 {
35 
36 /**@brief sparse vector set.
37  @ingroup Algebra
38 
39  Class SVSet provides a set of sparse vectors SVector. All SVector%s
40  in a SVSet share one big memory block for their nonzeros. This
41  memory is reffered to as the \em nonzero \em memory. The SVector%s
42  themselfs are saved in another memory block refered to as the
43  \em vector \em memory. Both memory blocks will grow automatically if
44  required, when adding more SVector%s to the set or enlarging
45  SVector%s within the set. For controlling memory consumption,
46  methods are provided to inquire and reset the size of the memory
47  blocks used for vectors and nonzeros.
48 
49  SVector%s in an SVSet are numbered from 0 thru num()-1. They can be
50  accessed using the index operator[](). When removing SVector%s of a
51  SVSet the remaining ones will be renumbered. However, all SVector
52  with a smaller number than the lowest number of the removed
53  SVector%s will remain unchanged.
54 
55  For providing a uniform access to SVector%s in a %set even if others
56  are removed or added, SVSet assigns a DataKey to each SVector in the
57  %set. Such a DataKey remains unchanged as long as the corresponding
58  SVector is in the SVSet, no matter what other SVector%s are added
59  to or removed from the SVSet. Methods are provided for getting the
60  DataKey to a SVector or its number and vice versa. Further, each add()
61  method for enlarging an SVSet is provided with two signatures. One
62  of them returns the DataKey%s assigned to the SVector%s added to the
63  SVSet.
64 */
65 class SVSet : protected SVSetBase
66 {
67 private:
68 
69  /**@class DLPSV
70  @brief SVector with prev/next pointers
71  @todo Check whether SVSet::DLPSV can be implemented as IdElement<SVector>
72 
73  The management of the SVectors is implemented by a DataSet<DLPSV>,
74  the keys used externally are DataKey%s.
75 
76  The management of nonzeros is done by a Real linked list
77  IdList<DLPSV>, where the SVector%s are kept in the order in which
78  their indices occurr in the DataArray. The SVector%s are kept
79  without holes: If one is removed or moved to the end, the SVector
80  preceeding it obtains the space for all the nonzeros that previously
81  belonged to the (re-)moved one. However, the nonzeros in use are
82  uneffected by this.
83  */
84  class DLPSV : public SVector
85  {
86  private:
87 
88  //------------------------------------
89  /**@name Data */
90  //@{
91  DLPSV *thenext; ///< previous SVector
92  DLPSV *theprev; ///< next SVector
93  //@}
94 
95  public:
96 
97  //------------------------------------
98  /**@name Construction / destruction */
99  //@{
100  /// default constructor.
102  {}
103  /// copy constructor.
104  DLPSV(const DLPSV& copy) : SVector(copy)
105  {}
106  //@}
107 
108  //------------------------------------
109  /**@name Successor / predecessor */
110  //@{
111  /// next SVector
113  {
114  return thenext;
115  }
116  /// next SVector
117  DLPSV* const& next() const
118  {
119  return thenext;
120  }
121  /// previous SVector
122  DLPSV* const& prev() const
123  {
124  return theprev;
125  }
126  /// previous SVector
128  {
129  return theprev;
130  }
131  //@}
132  };
133 
134  //------------------------------------
135  /**@name Data */
136  //@{
137  DataSet < DLPSV > set; ///< %set of SVectors
138  IdList < DLPSV > list; ///< doubly linked list for non-zero management
139  int possiblyUnusedMem; ///< an estimate of the used memory due to xtends
140  //@}
141 
142  //------------------------------------
143  /**@name Helpers */
144  //@{
145  /// provides enough vector memory for \p n more SVector%s.
146  void ensurePSVec(int n)
147  {
148  if (num() + n > max())
149  {
150  assert(factor > 1);
151  reMax(int(factor*max()) + 8 + n);
152  }
153  }
154  /// provides enough nonzero memory for \p n more Elements%s.
155  void ensureMem(int n);
156 
157  /// deleting a vector from the dataarray
158  void deleteVec(DLPSV* ps);
159  //@}
160 
161  //------------------------------------
162  /**@name Control Parameters */
163  //@{
164  /// Sparse vector memory enlargment factor.
165  /** If the SVSet runs out of vector memory, it is enlarged by \p factor.
166  */
168  //@}
169 
170 
171 public:
172 
173  //------------------------------------
174  /**@name Extension */
175  //@{
176  /// Add \p svec to the %set.
177  /** This includes copying its nonzeros to the sets nonzero memory and
178  * creating an additional SVector entry in vector memory. If
179  * neccessary, the memory blocks are enlarged appropriately.
180  */
181  void add(const SVector& svec)
182  {
183  ensurePSVec(1);
184  SVector* new_svec = create(svec.size());
185  *new_svec = svec;
186  }
187 
188  /// Add \p svec to SVSet.
189  /** Adds SVector \p svec to the %set. This includes copying its nonzeros
190  * to the sets nonzero memory and creating an additional SVector
191  * entry in vector memory. If neccessary, the memory blocks are
192  * enlarged appropriately.
193  * @return \p nkey contains the DataKey, that
194  * the SVSet has assosicated to the new SVector.
195  */
196  void add(DataKey& nkey, const SVector& svec)
197  {
198  ensurePSVec(1);
199  SVector* new_svec = create(nkey, svec.size());
200  *new_svec = svec;
201  }
202 
203  /// Add all \p n SVector%s in the array \p svec to the %set.
204  /** @pre \p svec must be not larger than \p n
205  */
206  void add(const SVector svec[], int n);
207 
208  /// Add n SVector%s to SVSet.
209  /** Adds all \p n SVector%s in the array \p svec to the %set.
210  * @return \p nkey contains the DataKey%s, that the SVSet has assosicated to the
211  * new SVector%s.
212  * @pre \p nkey must be large enough to fit \p n
213  * DataKey%s.
214  */
215  void add(DataKey nkey[], const SVector svec[], int n);
216 
217  /// Add all SVector%s in \p pset to an SVSet.
218  void add(const SVSet& pset);
219 
220  /// Add all SVector%s of \p pset to SVSet.
221  /** Adds all \p n SVector%s in the \p pset to an SVSet.
222  * @return \p nkey contains the DataKey%s, that the SVSet has assosicated to the
223  * new SVector%s.
224  * @pre \p nkey must be large enough to fit
225  * \p pset.num() DataKey%s.
226  */
227  void add(DataKey nkey[], const SVSet& pset);
228 
229  /// Creates new SVector in %set.
230  /** The new SVector will be ready to fit at least \p idxmax nonzeros.
231  */
232  SVector* create(int idxmax = -1);
233 
234  /// Creates new SVector in %set.
235  /** The new SVector will be ready to fit at least \p idxmax nonzeros.
236  * @return \p nkey contains the DataKey associated to the new
237  * SVector.
238  */
239  SVector* create(DataKey& nkey, int idxmax = -1);
240 
241  /// Extend \p svec to fit \p newmax nonzeros.
242  /** @pre \p svec must be an SVector of the SVSet.
243  */
244  void xtend(SVector& svec, int newmax);
245 
246  /// Add nonzero (\p idx, \p val) to \p svec of this SVSet.
247  /** Adds one nonzero (\p idx, \p val) to SVector \p svec in the SVSet.
248  * If \p svec is not large enough to hold the additional nonzero, it will be
249  * automatically enlarged within the %set.
250  * @pre \p svec must be an SVector of the SVSet.
251  */
252  void add2(SVector &svec, int idx, Real val);
253 
254  /// Add \p n nonzeros to \p svec of this SVSet.
255  /** Adds \p n nonzeros to SVector \p svec in the SVSet. If \p svec is not large
256  * enough to hold the additional nonzeros, it will be automatically
257  * enlarged within the %set.
258  * @pre \p svec must be an SVector of the SVSet.
259  */
260  void add2(SVector &svec, int n, const int idx[], const Real val[]);
261  //@}
262 
263 
264  //------------------------------------
265  /**@name Shrinking */
266  //@{
267 
268  /// removes the vector with key \p removekey from the %set
269  /** @pre \p removekey must be a key from SVSet */
270  void remove(const DataKey& removekey);
271 
272  /// removes the vector with number \p removenum from the %set
273  /** @pre \p removenum must be a valid vector number from SVSet */
274  void remove(int removenum)
275  {
276  remove(key(removenum));
277  }
278 
279  /// remove one SVector from %set.
280  /** @pre \p svec must be from SVSet */
281  void remove(const SVector *svec)
282  {
283  remove(key(svec));
284  }
285 
286  /// remove multiple elements.
287  /** Removes all SVector%s for the SVSet with an
288  index \c i such that \p perm[i] < 0. Upon completion, \p perm[i] >= 0
289  indicates the new index where the \c i 'th SVector has been moved to
290  due to this removal.
291  @pre \p perm must point to an array of at
292  least num() integers.
293  */
294  void remove(int perm[]);
295 
296  /// Remove \p n SVector%s from %set.
297  /**
298  * @pre \p keys must be at least of size \p n and valid keys
299  */
300  void remove(const DataKey keys[], int n)
301  {
302  DataArray < int > perm(num());
303  remove(keys, n, perm.get_ptr());
304  }
305 
306  /// Remove \p n SVector%s from %set.
307  /**
308  * @pre \p nums must be at least of size \p n and valid vector numbers
309  */
310  void remove(const int nums[], int n)
311  {
312  DataArray < int > perm(num());
313  remove(nums, n, perm.get_ptr());
314  }
315 
316  ///
317  void remove(const DataKey keys[], int n, int* perm);
318 
319  /// Remove \p n SVector%s from %set.
320  /**
321  * @pre \p perm must be at least of size num()
322  * @pre \p nums must be at least of size \p n
323  * @return \p perm is the permutations resulting from this removal: \p perm[i] < 0
324  * indicates, that the element to index \c i has been removed. Otherwise, \p perm[i]
325  * is the new index of the element with index \c i before the removal.
326  */
327  void remove(const int nums[], int n, int* perm);
328 
329  /// remove all SVector%s from %set.
330  void clear()
331  {
334  set.clear();
335  list.clear();
336  }
337  //@}
338 
339 
340  //------------------------------------
341  /**@name Access */
342  //@{
343  /// get SVector by number, writeable
345  {
346  return set[n];
347  }
348 
349  ///get SVector by number
350  const SVector& operator[](int n) const
351  {
352  return set[n];
353  }
354 
355  ///get SVector by DataKey, writeable
357  {
358  return set[k];
359  }
360 
361  ///get SVector by DataKey
362  const SVector& operator[](const DataKey& k) const
363  {
364  return set[k];
365  }
366  //@}
367 
368 
369  //------------------------------------
370  /**@name Inquiry */
371  //@{
372  /// current number of SVector%s.
373  int num() const
374  {
375  return set.num();
376  }
377 
378  /// current maximum number of SVector%s.
379  int max() const
380  {
381  return set.max();
382  }
383 
384  /// get DataKey of vector number
385  DataKey key(int n) const
386  {
387  return set.key(n);
388  }
389 
390  ///get DataKey of SVector
391  DataKey key(const SVector* svec) const
392  {
393  return set.key(static_cast<const DLPSV*>(svec));
394  }
395 
396  ///get vector number of DataKey
397  int number(const DataKey& k) const
398  {
399  return set.number(k);
400  }
401 
402  ///get vector number of SVector
403  int number(const SVector* svec) const
404  {
405  return set.number(static_cast<const DLPSV*>(svec));
406  }
407 
408  /// true iff SVSet contains a SVector for DataKey \p k
409  bool has(const DataKey& k) const
410  {
411  return set.has(k);
412  }
413 
414  ///true iff SVSet contains a SVector for vector number n
415  bool has(int n) const
416  {
417  return set.has(n);
418  }
419 
420  /// is an SVector in the %set.
421  bool has(const SVector* svec) const
422  {
423  return set.has(static_cast<const DLPSV*>(svec));
424  }
425  //@}
426 
427  //------------------------------------
428  /**@name Memory Management */
429  //@{
430  /// used nonzero memory.
431  int memSize() const
432  {
434  }
435 
436  /// length of nonzero memory.
437  int memMax() const
438  {
440  }
441 
442  /// reset length of nonzero memory.
443  void memRemax(int newmax);
444 
445  /// garbage collection in nonzero memory.
446  void memPack();
447  //@}
448 
449 
450  //------------------------------------
451  /**@name Miscellaneous */
452  //@{
453  /// reset maximum number of SVector%s.
454  void reMax(int newmax = 0);
455 
456  /// consistency check.
457  bool isConsistent() const;
458  //@}
459 
460  //------------------------------------
461  /**@name Constructors / destructors */
462  //@{
463  /// default constructor.
464  explicit
465  SVSet( int pmax = -1,
466  int pmemmax = -1,
467  Real pfac = 1.1,
468  Real pmemFac = 1.2 )
469  : DataArray < SVector::Element >
470  (0, (pmemmax > 0) ? pmemmax : 8 * ((pmax > 0) ? pmax : 8), pmemFac)
471  , set ((pmax > 0) ? pmax : 8)
472  , possiblyUnusedMem (0)
473  , factor (pfac)
474  {
475  assert(isConsistent());
476  }
477  /// destructor
479  {}
480  /// assignment operator.
481  SVSet& operator=(const SVSet& rhs);
482  /// copy constructor.
483  SVSet(const SVSet& old);
484  //@}
485 };
486 
487 } // namespace soplex
488 #endif // _SVSET_H_
489 
490 //-----------------------------------------------------------------------------
491 //Emacs Local Variables:
492 //Emacs mode:c++
493 //Emacs c-basic-offset:3
494 //Emacs tab-width:8
495 //Emacs indent-tabs-mode:nil
496 //Emacs End:
497 //-----------------------------------------------------------------------------
498 
499