INMOST
Mathematical Modelling Toolkit
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inmost_sparse.h
Go to the documentation of this file.
1 #ifndef INMOST_SPARSE_INCLUDED
2 #define INMOST_SPARSE_INCLUDED
3 
4 
5 #include "inmost_common.h"
6 
7 
8 #if defined(USE_SOLVER)
9 
10 #define MTX_ALLOW_ANNOTATION
11 #define MTX_ANNOTATION_SIZE 1024
12 
13 namespace INMOST
14 {
15  namespace Sparse
16  {
18  void CreateRowEntryType();
19  void DestroyRowEntryType();
20  bool HaveRowEntryType();
21 
26  class Vector
27  {
28  public:
32  private:
33  INMOST_MPI_Comm comm;
34  Entries data;
35  std::string name;
36  bool is_parallel;
37  public:
43  Vector(std::string _name = "", INMOST_DATA_ENUM_TYPE start = 0, INMOST_DATA_ENUM_TYPE end = 0, INMOST_MPI_Comm _comm = INMOST_MPI_COMM_WORLD);
44  Vector(const Vector & other);
45  Vector & operator =(Vector const & other);
46  ~Vector();
52  INMOST_DATA_ENUM_TYPE Size() const { return static_cast<INMOST_DATA_ENUM_TYPE>(data.size()); }
53  iterator Begin() {return data.begin();}
54  const_iterator Begin() const {return data.begin();}
55  iterator End() {return data.end();}
56  const_iterator End() const {return data.end();}
57  bool Empty() const {return data.empty();}
59  void SetInterval(INMOST_DATA_ENUM_TYPE start, INMOST_DATA_ENUM_TYPE end) {assert(start<=end); data.set_interval_beg(start); data.set_interval_end(end);}
61  void GetInterval(INMOST_DATA_ENUM_TYPE & start, INMOST_DATA_ENUM_TYPE & end) const {start = data.get_interval_beg(); end = data.get_interval_end();}
66  INMOST_MPI_Comm GetCommunicator() const {return comm;}
67 
68  void Swap(Vector & other) {data.swap(other.data); name.swap(other.name); std::swap(is_parallel,other.is_parallel); std::swap(comm,other.comm);}
69 
70 
72  void Save(std::string file);
76  void Load(std::string file, INMOST_DATA_ENUM_TYPE mbeg = ENUMUNDEF, INMOST_DATA_ENUM_TYPE mend = ENUMUNDEF);
77 
78  bool & isParallel() {return is_parallel;}
80  std::string GetName() {return name;}
81 
83  void Clear() {data.clear();}
84 
85  };
86 
87 
88 
90  class Row
91  {
92  public:
93  #if defined(MTX_ALLOW_ANNOTATION)
95  #endif
96  typedef struct entry_s
98  {
101  //entry_s() :first(0), second(0.0) {}
102  //entry_s(const entry_s & other) :first(other.first), second(other.second) {}//{std::cout << __FUNCTION__ << " " << first << " " << second << std::endl;}
103  //entry_s(INMOST_DATA_ENUM_TYPE first, INMOST_DATA_REAL_TYPE second):first(first),second(second){}
104  //entry_s & operator =(entry_s const & other) {first = other.first, second = other.second; return *this;}
105  bool operator < (const entry_s & other) const { return first < other.first || (first == other.first && second < other.second); }
106  } entry;
108  {
109  entry ret;
110  ret.first = ind;
111  ret.second = val;
112  return ret;
113  }
114 
115  private:
116  typedef dynarray<entry,16> Entries; //replace later with more memory-efficient chunk_array, with first chunk in stack
117  //typedef array<entry> Entries;
118  //typedef std::vector<entry> Entries;
119  //typedef sparse_data<INMOST_DATA_ENUM_TYPE,INMOST_DATA_REAL_TYPE> Entries;
120  //typedef Entries::pair entry; //for sparse_data
121 
122  public:
127 
128  bool modified_pattern; //remove this in future
129  private:
130  #if defined(USE_OMP)
131  omp_lock_t lock;
132  #endif
133  bool marker;
134  Entries data;
135  public:
136 
137  std::string GetAnnotation();
138  void SetAnnotation(std::string input);
139  void Report() {data.report_addr();}
140  void SetMarker() { marker = true; }
141  void RemMarker() { marker = false; }
142  bool GetMarker() { return marker; }
143  Row();
144  Row(const Row & other);
145  Row(entry * pbegin, entry * pend);
146  bool HaveLock()
147  {
148  #if defined(USE_OMP)
149  return true;
150  #else
151  return false;
152  #endif
153  }
154  void Lock()
155  {
156  #if defined(USE_OMP)
157  omp_set_lock(&lock);
158  #endif
159  }
160  void Unlock()
161  {
162  #if defined(USE_OMP)
163  omp_unset_lock(&lock);
164  #endif
165  }
166  ~Row();
167  Row & operator = (Row const & other);
169  INMOST_DATA_REAL_TYPE & operator [](INMOST_DATA_ENUM_TYPE i) // use to fill matrix, not to access individual elements
170  {
171  //for sparse_data type
172  //return data[i];
173  //for dynarray or array
174 
175  for(Entries::size_type it = 0; it < data.size(); ++it)
176  if( data[it].first == i ) return data[it].second;
177  entry new_entry;
178  new_entry.first = i;
179  new_entry.second = 0;
180  data.push_back(new_entry);
181  modified_pattern = true;
182  return data.back().second;
183 
184  }
187  {
188  //for sparse data type
189  //return data[i];
190 
191  for (Entries::size_type it = 0; it < data.size(); ++it) if (data[it].first == i) return data[it].second;
192 
193  //you should not come here
194  assert(false);
195  return 1.0e20;
196  }
197  //void Reserve(INMOST_DATA_ENUM_TYPE num) { data.reserve(num);}
199  void Clear() { data.clear(); }
200  void Swap(Row & other);
202  INMOST_DATA_ENUM_TYPE Size() const { return static_cast<INMOST_DATA_ENUM_TYPE>(data.size()); }
203  bool Empty() const { return data.empty(); }
204  INMOST_DATA_ENUM_TYPE & GetIndex(INMOST_DATA_ENUM_TYPE k) {assert(k < data.size()); return (data.begin()+k)->first;}
205  INMOST_DATA_REAL_TYPE & GetValue(INMOST_DATA_ENUM_TYPE k) {assert(k < data.size()); return (data.begin()+k)->second;}
206  INMOST_DATA_ENUM_TYPE GetIndex(INMOST_DATA_ENUM_TYPE k) const {assert(k < data.size()); return (data.begin()+k)->first;}
207  INMOST_DATA_REAL_TYPE GetValue(INMOST_DATA_ENUM_TYPE k) const {assert(k < data.size()); return (data.begin()+k)->second;}
208 
209  iterator Begin() {return data.begin();}
210  iterator End() {return data.end();}
211  const_iterator Begin() const {return data.begin();}
212  const_iterator End() const {return data.end();}
213  reverse_iterator rBegin() { return data.rbegin(); }
214  reverse_iterator rEnd() { return data.rend(); }
215  const_reverse_iterator rBegin() const { return data.rbegin(); }
216  const_reverse_iterator rEnd() const { return data.rend(); }
218  INMOST_DATA_REAL_TYPE RowVec(Vector & x) const; // returns A(row) * x
219  void MoveRow(Row & new_pos) {data = new_pos.data;} //here move constructor and std::move may be used in future
221  void Zero() {for(iterator it = Begin(); it != End(); ++it) it->second = 0;}
229  void Resize(INMOST_DATA_ENUM_TYPE size) {data.resize(size);}
230 
231  void Print()
232  {
233  for(iterator it = Begin(); it != End(); ++it) std::cout << "(" << it->first << "," << it->second << ") ";
234  std::cout << std::endl;
235  }
236  };
237 
238 
239 
240 
244  class Matrix
245  {
246  public:
250  private:
251  INMOST_MPI_Comm comm;
252  Rows data;
253  std::string name;
254  bool is_parallel;
255  public:
261  Matrix(std::string _name = "", INMOST_DATA_ENUM_TYPE start = 0, INMOST_DATA_ENUM_TYPE end = 0, INMOST_MPI_Comm _comm = INMOST_MPI_COMM_WORLD);
262  Matrix(const Matrix & other);
263  Matrix & operator =(Matrix const & other);
264  ~Matrix();
266  Row & operator [](INMOST_DATA_ENUM_TYPE i) {return data[i];}
268  const Row & operator [](INMOST_DATA_ENUM_TYPE i) const {return data[i];}
270  INMOST_DATA_ENUM_TYPE Size() const { return static_cast<INMOST_DATA_ENUM_TYPE>(data.size()); }
271  bool Empty() const {return data.empty();}
272  iterator Begin() {return data.begin();}
273  iterator End() {return data.end();}
274  const_iterator Begin() const {return data.begin();}
275  const_iterator End() const {return data.end();}
279  void GetInterval(INMOST_DATA_ENUM_TYPE & start, INMOST_DATA_ENUM_TYPE & end) const {start = data.get_interval_beg(); end = data.get_interval_end();}
284  INMOST_MPI_Comm GetCommunicator() const {return comm;}
286  void Swap(Matrix & other)
287  {
288  data.swap(other.data);
289  name.swap(other.name);
290  INMOST_MPI_Comm ctmp = comm;
291  comm = other.comm;
292  other.comm = ctmp;
293  bool ptmp = is_parallel;
294  is_parallel = other.is_parallel;
295  other.is_parallel = ptmp;
296  }
299  void MatVec(INMOST_DATA_REAL_TYPE alpha, Vector & x, INMOST_DATA_REAL_TYPE beta, Vector & y) const;
302  void MatVecTranspose(INMOST_DATA_REAL_TYPE alpha, Vector & x, INMOST_DATA_REAL_TYPE beta, Vector & y) const;
304  void Clear() {for(Matrix::iterator it = Begin(); it != End(); ++it) it->Clear(); data.clear();}
308  void Load(std::string file, INMOST_DATA_ENUM_TYPE beg = ENUMUNDEF, INMOST_DATA_ENUM_TYPE end = ENUMUNDEF);
311  void Save(std::string file);
313  bool & isParallel() { return is_parallel; }
315  std::string GetName() {return name;}
316  };
317 
332  class RowMerger
333  {
334  public:
337  class iterator
338  {
339  private:
342  iterator(interval< INMOST_DATA_ENUM_TYPE, Row::entry > * pLinkedList) : pos(pLinkedList->get_interval_beg()), LinkedList(pLinkedList) {}
343  public:
344  iterator(const iterator & other) : pos(other.pos), LinkedList(other.LinkedList) {}
346  INMOST_DATA_REAL_TYPE & operator *() {return (*LinkedList)[pos].second;}
347  INMOST_DATA_REAL_TYPE operator *() const {return (*LinkedList)[pos].second;}
348  INMOST_DATA_REAL_TYPE * operator ->() {return &(*LinkedList)[pos].second;}
349  const INMOST_DATA_REAL_TYPE * operator ->() const {return &(*LinkedList)[pos].second;}
350  iterator & operator ++(){ pos = (*LinkedList)[pos].first; return *this;}
351  iterator operator ++(int){ iterator ret(LinkedList); ret.pos = (*LinkedList)[pos].first; return ret; }
352  iterator & operator = (const iterator & other) {LinkedList = other.LinkedList; pos = other.pos;}
353  bool operator ==(const iterator & other) const {return LinkedList == other.LinkedList && pos == other.pos;}
354  bool operator !=(const iterator & other) const {return LinkedList != other.LinkedList || pos != other.pos;}
355  bool operator < (const iterator & other) const {return LinkedList == other.LinkedList && pos < other.pos;}
356  bool operator <=(const iterator & other) const {return LinkedList == other.LinkedList && pos <= other.pos;}
357  bool operator > (const iterator & other) const {return LinkedList == other.LinkedList && pos > other.pos;}
358  bool operator >=(const iterator & other) const {return LinkedList == other.LinkedList && pos >= other.pos;}
359  friend class RowMerger;
360  };
361  private:
362  bool Sorted;
363  INMOST_DATA_ENUM_TYPE Nonzeros;
365  public:
367  RowMerger();
372  RowMerger(INMOST_DATA_ENUM_TYPE interval_begin, INMOST_DATA_ENUM_TYPE interval_end, bool Sorted = true);
376  RowMerger(Matrix & A, bool Sorted = true);
378  ~RowMerger();
386  void Resize(INMOST_DATA_ENUM_TYPE interval_begin, INMOST_DATA_ENUM_TYPE interval_end, bool Sorted = true);
393  void Resize(Matrix & A, bool Sorted = true);
395  void Clear();
403  void PushRow(INMOST_DATA_REAL_TYPE coef, Row & r, bool PreSortRow = false);
409  void AddRow(INMOST_DATA_REAL_TYPE coef, Row & r, bool PreSortRow = false);
412  void Multiply(INMOST_DATA_REAL_TYPE coef);
419  void RetriveRow(Row & r);
420  //INMOST_DATA_REAL_TYPE ScalarProd(RowMerger & other);
422  INMOST_DATA_ENUM_TYPE Size() {return Nonzeros;}
439  void Merge(Row & c, INMOST_DATA_REAL_TYPE alpha, Row & a, INMOST_DATA_REAL_TYPE beta, Row & b)
440  {
441  PushRow(alpha,a);
442  AddRow(beta,b);
443  RetriveRow(c);
444  Clear();
445  }
446  iterator Begin() {return iterator(&LinkedList);}
447  iterator End() {iterator ret(&LinkedList); ret.pos = EOL; return ret;}
448  };
449  }
450 }
451 #endif
452 
453 #endif
struct INMOST::Sparse::Row::entry_s entry
Entry of the sparse matrix row.
__INLINE iterator begin()
Definition: container.hpp:1854
INMOST_MPI_Type GetRowEntryType()
void set_interval_end(IndType end)
Definition: container.hpp:1325
static __INLINE entry make_entry(INMOST_DATA_ENUM_TYPE ind, INMOST_DATA_REAL_TYPE val)
INMOST_MPI_Comm GetCommunicator() const
Get the communicator which the vector is associated with.
Definition: inmost_sparse.h:66
__INLINE reverse_iterator rbegin()
Definition: container.hpp:1858
INMOST_DATA_REAL_TYPE * operator->()
void Swap(Row &other)
_reverse_iterator< entry > reverse_iterator
Definition: container.hpp:1608
iterator begin()
Definition: container.hpp:1355
bool operator<(const iterator &other) const
void GetInterval(INMOST_DATA_ENUM_TYPE &start, INMOST_DATA_ENUM_TYPE &end) const
Get the start and the end of the distributed vector interval.
Definition: inmost_sparse.h:61
__INLINE iterator end()
Definition: container.hpp:1855
Class to store the sparse matrix row.
Definition: inmost_sparse.h:90
void PushRow(INMOST_DATA_REAL_TYPE coef, Row &r, bool PreSortRow=false)
const_reverse_iterator rEnd() const
void Zero()
Set the vector entries by zeroes.
INMOST_DATA_ENUM_TYPE Size() const
Return the total number of rows in the matrix.
void Load(std::string file, INMOST_DATA_ENUM_TYPE beg=ENUMUNDEF, INMOST_DATA_ENUM_TYPE end=ENUMUNDEF)
void Save(std::string file)
void Clear()
Clear linked list.
bool operator>=(const iterator &other) const
bool operator!=(const iterator &other) const
RowMerger()
Default constructor without size specified.
bool operator<=(const iterator &other) const
#define INMOST_MPI_Comm
void resize(size_type n, element c=element())
Definition: container.hpp:1772
void GetInterval(INMOST_DATA_ENUM_TYPE &start, INMOST_DATA_ENUM_TYPE &end) const
Get the start and the end row numbers of the distributed matrix interval.
#define INMOST_MPI_COMM_WORLD
void SetAnnotation(std::string input)
#define INMOST_DATA_REAL_TYPE
int size() const
Definition: container.hpp:1363
void Swap(Vector &other)
Definition: inmost_sparse.h:68
Vector & operator=(Vector const &other)
void Resize(INMOST_DATA_ENUM_TYPE interval_begin, INMOST_DATA_ENUM_TYPE interval_end, bool Sorted=true)
reverse_iterator rEnd()
INMOST_DATA_ENUM_TYPE Size() const
The size of the sparse row, i.e. the total number of nonzero elements.
Row & operator[](INMOST_DATA_ENUM_TYPE i)
Return reference to i-th Row of the matrix.
_iterator< entry > iterator
Definition: container.hpp:1570
INMOST_DATA_REAL_TYPE RowVec(Vector &x) const
Return the scalar product of the current sparse row by a dense Vector.
bool operator>(const iterator &other) const
std::string GetAnnotation()
void Swap(Matrix &other)
void MatVecTranspose(INMOST_DATA_REAL_TYPE alpha, Vector &x, INMOST_DATA_REAL_TYPE beta, Vector &y) const
void Clear()
Clear all data of the current row.
static const INMOST_DATA_ENUM_TYPE UNDEF
Value not defined in linked list.
_reverse_iterator< const entry > const_reverse_iterator
Definition: container.hpp:1609
void Merge(Row &c, INMOST_DATA_REAL_TYPE alpha, Row &a, INMOST_DATA_REAL_TYPE beta, Row &b)
INMOST_DATA_REAL_TYPE & GetValue(INMOST_DATA_ENUM_TYPE k)
INMOST_DATA_REAL_TYPE & operator[](INMOST_DATA_ENUM_TYPE pos)
const_iterator Begin() const
void set_interval_beg(IndType beg)
Definition: container.hpp:1320
const_iterator End() const
void MatVec(INMOST_DATA_REAL_TYPE alpha, Vector &x, INMOST_DATA_REAL_TYPE beta, Vector &y) const
reverse_iterator rBegin()
std::string GetName()
Get the matrix name specified in the main constructor.
const_iterator Begin() const
Entries::const_reverse_iterator const_reverse_iterator
interval< INMOST_DATA_ENUM_TYPE, Row > Rows
char annotation[MTX_ANNOTATION_SIZE]
Definition: inmost_sparse.h:94
Matrix(std::string _name="", INMOST_DATA_ENUM_TYPE start=0, INMOST_DATA_ENUM_TYPE end=0, INMOST_MPI_Comm _comm=INMOST_MPI_COMM_WORLD)
#define INMOST_MPI_Type
#define MTX_ANNOTATION_SIZE
Definition: inmost_sparse.h:11
void Save(std::string file)
Save the distributed vector to a single data file using parallel MPI I/O.
bool operator==(const iterator &other) const
void ShiftInterval(INMOST_DATA_ENUM_TYPE shift)
Definition: inmost_sparse.h:62
Entries::iterator iterator
const_reverse_iterator rBegin() const
void Push(INMOST_DATA_ENUM_TYPE ind, INMOST_DATA_REAL_TYPE val)
void CreateRowEntryType()
const_iterator End() const
void Load(std::string file, INMOST_DATA_ENUM_TYPE mbeg=ENUMUNDEF, INMOST_DATA_ENUM_TYPE mend=ENUMUNDEF)
__INLINE element & back()
Definition: container.hpp:1766
INMOST_DATA_REAL_TYPE operator[](INMOST_DATA_ENUM_TYPE i) const
The operator [] used to access individual elements of the row.
bool empty() const
Definition: container.hpp:1364
INMOST_DATA_ENUM_TYPE & GetIndex(INMOST_DATA_ENUM_TYPE k)
const_iterator End() const
Definition: inmost_sparse.h:56
IndType get_interval_beg() const
Definition: container.hpp:1361
static const INMOST_DATA_ENUM_TYPE EOL
End of linked list.
__INLINE size_type size() const
Definition: container.hpp:1780
INMOST_DATA_REAL_TYPE & operator[](INMOST_DATA_ENUM_TYPE i)
Return reference to i-th element of the vector.
Definition: inmost_sparse.h:48
INMOST_DATA_ENUM_TYPE GetIndex(INMOST_DATA_ENUM_TYPE k) const
INMOST_DATA_ENUM_TYPE GetFirstIndex() const
Get the first index of the distributed vector interval.
Definition: inmost_sparse.h:64
void Clear()
Clear all data of the matrix.
#define __INLINE
Definition: inmost_common.h:75
void MoveRow(Row &new_pos)
void ShiftInterval(INMOST_DATA_ENUM_TYPE shift)
Entries::reverse_iterator reverse_iterator
IndType get_interval_end() const
Definition: container.hpp:1362
Matrix & operator=(Matrix const &other)
void Clear()
Clear all data of the current vector.
Definition: inmost_sparse.h:83
Entries::const_iterator const_iterator
Definition: inmost_sparse.h:31
INMOST_DATA_REAL_TYPE & operator[](INMOST_DATA_ENUM_TYPE i)
The operator [] used to fill the sparse matrix row, but not to access individual elements of the row...
bool operator<(const entry_s &other) const
_iterator< const entry > const_iterator
Definition: container.hpp:1571
void Resize(INMOST_DATA_ENUM_TYPE size)
#define ENUMUNDEF
INMOST_DATA_ENUM_TYPE Size()
Get current number of nonzeros from linked list.
Row & operator=(Row const &other)
void Multiply(INMOST_DATA_REAL_TYPE coef)
#define INMOST_DATA_ENUM_TYPE
INMOST_MPI_Comm GetCommunicator() const
Get the communicator which the matrix is associated with.
Entries::iterator iterator
Definition: inmost_sparse.h:30
void MoveRows(INMOST_DATA_ENUM_TYPE from, INMOST_DATA_ENUM_TYPE to, INMOST_DATA_ENUM_TYPE size)
void push_back(const element &e)
Definition: container.hpp:1757
Entries::const_iterator const_iterator
iterator end()
Definition: container.hpp:1358
INMOST_DATA_ENUM_TYPE first
the column number of the row element.
Definition: inmost_sparse.h:99
bool Empty() const
Rows::iterator iterator
Vector(std::string _name="", INMOST_DATA_ENUM_TYPE start=0, INMOST_DATA_ENUM_TYPE end=0, INMOST_MPI_Comm _comm=INMOST_MPI_COMM_WORLD)
void shift_interval(IndType shift)
Definition: container.hpp:1348
void SetInterval(INMOST_DATA_ENUM_TYPE start, INMOST_DATA_ENUM_TYPE end)
Set the start and the end of the distributed vector interval.
Definition: inmost_sparse.h:59
INMOST_DATA_ENUM_TYPE Size() const
Return the global size of the vector.
Definition: inmost_sparse.h:52
const_iterator Begin() const
Definition: inmost_sparse.h:54
INMOST_DATA_REAL_TYPE GetValue(INMOST_DATA_ENUM_TYPE k) const
__INLINE reverse_iterator rend()
Definition: container.hpp:1859
void AddRow(INMOST_DATA_REAL_TYPE coef, Row &r, bool PreSortRow=false)
iterator(const iterator &other)
void DestroyRowEntryType()
bool HaveRowEntryType()
__INLINE bool empty() const
Definition: container.hpp:1771
Rows::const_iterator const_iterator
iterator & operator=(const iterator &other)
interval< INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE > Entries
Definition: inmost_sparse.h:29
INMOST_DATA_REAL_TYPE & operator*()
std::string GetName()
Get the vector name specified in the main constructor.
Definition: inmost_sparse.h:80
void swap(interval< IndType, ValType > &other)
Definition: container.hpp:1183
bool & isParallel()
Check that matrix is in parallel state.
void SetInterval(INMOST_DATA_ENUM_TYPE start, INMOST_DATA_ENUM_TYPE end)
Set the start and the end row numbers of the distributed matrix interval.
INMOST_DATA_REAL_TYPE second
the real value of the row element.
INMOST_DATA_ENUM_TYPE GetFirstIndex() const
Get the first row index of the distributed matrix interval.
Entry of the sparse matrix row.
Definition: inmost_sparse.h:97