INMOST
A toolkit for distributed mathematical modeling
inmost_sparse.h
1 #ifndef INMOST_SPARSE_INCLUDED
2 #define INMOST_SPARSE_INCLUDED
3 
4 
5 #include "inmost_common.h"
6 #include <unordered_map>
7 #include "robin_hood.h"
8 
9 namespace INMOST
10 {
11  namespace Sparse
12  {
13 #if defined(USE_SOLVER) || defined(USE_AUTODIFF)
15  INMOST_MPI_Type GetRowEntryType();
17  void CreateRowEntryType();
19  void DestroyRowEntryType();
21  bool HaveRowEntryType();
28  {
30  public:
34  AnnotationService(INMOST_DATA_ENUM_TYPE start = 0, INMOST_DATA_ENUM_TYPE end = 0) { if( end != start ) SetInterval(start,end); }
37  AnnotationService(const AnnotationService & other) : text(other.text) { }
40  AnnotationService & operator = (AnnotationService const & other) {text = other.text; return *this;}
44  INMOST_DATA_ENUM_TYPE GetFirstIndex() const {return text.get_interval_beg();}
46  INMOST_DATA_ENUM_TYPE GetLastIndex() const {return text.get_interval_end();}
48  bool Empty() const {return text.empty();}
52  void SetInterval(INMOST_DATA_ENUM_TYPE beg, INMOST_DATA_ENUM_TYPE end) { text.set_interval_beg(beg); text.set_interval_end(end); }
56  void GetInterval(INMOST_DATA_ENUM_TYPE & start, INMOST_DATA_ENUM_TYPE & end) const {start = text.get_interval_beg(); end = text.get_interval_end();}
59  std::string & GetAnnotation(INMOST_DATA_ENUM_TYPE row) {assert(!text.empty()); return text[row];}
62  const std::string & GetAnnotation(INMOST_DATA_ENUM_TYPE row) const {assert(!text.empty()); return text[row];}
66  void SetAnnotation(INMOST_DATA_ENUM_TYPE row, std::string str) {assert(!text.empty()); text[row] = str;}
67  };
68 #endif
69 #if defined(USE_SOLVER)
74  class Vector
75  {
76  public:
78  typedef Entries::iterator iterator;
79  typedef Entries::const_iterator const_iterator;
80  private:
81  INMOST_MPI_Comm comm;
82  Entries data;
83  std::string name;
84  bool is_parallel;
85  public:
91  Vector(std::string _name = "", INMOST_DATA_ENUM_TYPE start = 0, INMOST_DATA_ENUM_TYPE end = 0, INMOST_MPI_Comm _comm = INMOST_MPI_COMM_WORLD);
94  Vector(const Vector & other);
97  Vector & operator =(Vector const & other);
101  INMOST_DATA_REAL_TYPE & operator [](INMOST_DATA_ENUM_TYPE i) {return data[i];}
103  INMOST_DATA_REAL_TYPE operator [](INMOST_DATA_ENUM_TYPE i) const {return data[i];}
106 #if defined(USE_AUTODIFF)
109 #endif //USE_AUTODIFF
111  INMOST_DATA_ENUM_TYPE Size() const { return static_cast<INMOST_DATA_ENUM_TYPE>(data.size()); }
113  iterator Begin() {return data.begin();}
115  const_iterator Begin() const {return data.begin();}
117  iterator End() {return data.end();}
119  const_iterator End() const {return data.end();}
121  bool Empty() const {return data.empty();}
125  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);}
129  void GetInterval(INMOST_DATA_ENUM_TYPE & start, INMOST_DATA_ENUM_TYPE & end) const {start = data.get_interval_beg(); end = data.get_interval_end();}
132  void ShiftInterval(INMOST_DATA_ENUM_TYPE shift) {data.shift_interval(shift);}
134  INMOST_DATA_ENUM_TYPE GetFirstIndex() const {return data.get_interval_beg();}
136  INMOST_DATA_ENUM_TYPE GetLastIndex() const {return data.get_interval_end();}
138  INMOST_MPI_Comm GetCommunicator() const {return comm;}
141  void Swap(Vector & other) {data.swap(other.data); name.swap(other.name); std::swap(is_parallel,other.is_parallel); std::swap(comm,other.comm);}
143  void Save(std::string file);
147  void Load(std::string file, INMOST_DATA_ENUM_TYPE mbeg = ENUMUNDEF, INMOST_DATA_ENUM_TYPE mend = ENUMUNDEF, std::string file_ord = "");
149  bool & isParallel() {return is_parallel;}
151  std::string GetName() {return name;}
153  void Clear() {data.clear();}
154  };
155 
156 #endif //defined(USE_SOLVER)
157 #if defined(USE_SOLVER) || defined(USE_AUTODIFF)
161  class Row
162  {
163  public:
164 //#pragma pack(push,r1,4)
166  typedef struct entry_s
167  {
168  INMOST_DATA_ENUM_TYPE first;
169  INMOST_DATA_REAL_TYPE second;
171  bool operator < (const entry_s & other) const { return first < other.first || (first == other.first && second < other.second); }
172  //entry_s& operator =(entry_s const& b) { first = b.first; second = b.second; return *this; }
173  //entry_s(const entry_s& b) : first(b.first), second(b.second) {}
174  entry_s() : first(ENUMUNDEF), second(0.0) {}
175  } entry;
176 //#pragma pack(pop,r1)
180  __INLINE static entry make_entry(INMOST_DATA_ENUM_TYPE ind, INMOST_DATA_REAL_TYPE val)
181  {
182  entry ret;
183  ret.first = ind;
184  ret.second = val;
185  return ret;
186  }
187  private:
188  typedef std::vector<entry> Entries;
189  public:
190  typedef Entries::iterator iterator;
191  typedef Entries::const_iterator const_iterator;
192  typedef Entries::reverse_iterator reverse_iterator;
193  typedef Entries::const_reverse_iterator const_reverse_iterator;
194  private:
195  Entries data;
196  public:
198  Row() : data() {}
201  Row(const Row & other) : data(other.data) {}
205  Row(entry * pbegin, entry * pend) :data(pbegin, pend) {}
207  ~Row() {}
210  Row & operator = (Row const & other) { data = other.data; return *this; }
217  INMOST_DATA_REAL_TYPE & operator [](INMOST_DATA_ENUM_TYPE i)
218  {
219  for(Entries::size_type it = 0; it < data.size(); ++it)
220  if( data[it].first == i ) return data[it].second;
221  data.push_back(make_entry(i,0));
222  return data.back().second;
223  }
231  INMOST_DATA_REAL_TYPE operator[](INMOST_DATA_ENUM_TYPE i) const
232  {
233  for (Entries::size_type it = 0; it < data.size(); ++it) if (data[it].first == i) return data[it].second;
234  //you should not come here
235  assert(false);
236  return 1.0e20;
237  }
242  INMOST_DATA_REAL_TYPE get_safe(INMOST_DATA_ENUM_TYPE i) const
243  {
244  for (Entries::size_type it = 0; it < data.size(); ++it) if (data[it].first == i) return data[it].second;
245  return 0.0;
246  }
248  void Clear() { data.clear(); }
251  void Swap(Row & other) { data.swap(other.data); }
253  INMOST_DATA_ENUM_TYPE Size() const { return static_cast<INMOST_DATA_ENUM_TYPE>(data.size()); }
255  bool Empty() const { return data.empty(); }
259  INMOST_DATA_ENUM_TYPE & GetIndex(INMOST_DATA_ENUM_TYPE k) {assert(k < data.size()); return (data.begin()+k)->first;}
263  INMOST_DATA_REAL_TYPE & GetValue(INMOST_DATA_ENUM_TYPE k) {assert(k < data.size()); return (data.begin()+k)->second;}
267  INMOST_DATA_ENUM_TYPE GetIndex(INMOST_DATA_ENUM_TYPE k) const {assert(k < data.size()); return (data.begin()+k)->first;}
271  INMOST_DATA_REAL_TYPE GetValue(INMOST_DATA_ENUM_TYPE k) const {assert(k < data.size()); return (data.begin()+k)->second;}
273  //void GetInterval(INMOST_DATA_ENUM_TYPE& beg, INMOST_DATA_ENUM_TYPE& end, INMOST_DATA_ENUM_TYPE& cnt) const;
275  iterator Begin() {return data.begin();}
277  iterator End() {return data.end();}
279  const_iterator Begin() const {return data.begin();}
281  const_iterator End() const {return data.end();}
283  reverse_iterator rBegin() { return data.rbegin(); }
285  reverse_iterator rEnd() { return data.rend(); }
287  const_reverse_iterator rBegin() const { return data.rbegin(); }
289  const_reverse_iterator rEnd() const { return data.rend(); }
290 #if defined(USE_SOLVER)
292  INMOST_DATA_REAL_TYPE RowVec(Vector & x) const; // returns A(row) * x
293 #endif
296  void MoveRow(Row & source) {data = source.data;} //here move constructor and std::move may be used in future
298  void Zero() {for(iterator it = Begin(); it != End(); ++it) it->second = 0;}
301  void Push(INMOST_DATA_ENUM_TYPE ind, INMOST_DATA_REAL_TYPE val) {data.push_back(make_entry(ind,val));}
303  void Pop() { data.pop_back(); }
308  void Resize(INMOST_DATA_ENUM_TYPE size) {data.resize(size);}
310  void Print(double eps = -1, std::ostream & sout = std::cout) const
311  {
312  int k = 0;
313  for(const_iterator it = Begin(); it != End(); ++it) if( fabs(it->second) > eps ) {sout << "(" << it->first << "," << it->second << ") "; k++; }
314  if( k ) sout << std::endl;
315  }
317  void Sort() { std::sort(data.begin(), data.end()); }
319  bool isSorted() const;
326  static void MergeSortedRows(INMOST_DATA_REAL_TYPE alpha, const Row & left, INMOST_DATA_REAL_TYPE beta, const Row & right, Row & output);
327  };
328 
329 #endif //defined(USE_SOLVER) || defined(USE_AUTODIFF)
330 
331 #if defined(USE_SOLVER) || defined(USE_AUTODIFF)
334  {
335  public:
337  typedef struct hessian_index_s
338  {
339  INMOST_DATA_ENUM_TYPE first;
340  INMOST_DATA_ENUM_TYPE second;
341  bool operator < (const hessian_index_s & other) const {return first < other.first || (first == other.first && second < other.second); }
342  bool operator ==(const hessian_index_s & other) const {return first == other.first && second == other.second;}
343  } index;
344  __INLINE static index make_index(INMOST_DATA_ENUM_TYPE _first, INMOST_DATA_ENUM_TYPE _second)
345  {
346  index ret;
347  ret.first = _first >_second ? _second : _first;
348  ret.second = _first < _second ? _second : _first;
349  return ret;
350  }
351  typedef struct hessian_entry_s
352  {
354  INMOST_DATA_REAL_TYPE second;
355  bool operator < (const hessian_entry_s & other) const { return first < other.first || (first == other.first && second < other.second); }
356  } entry;
357  __INLINE static entry make_entry(index ind, INMOST_DATA_REAL_TYPE val)
358  {
359  entry ret;
360  ret.first = ind;
361  ret.second = val;
362  return ret;
363  }
364  private:
365  typedef std::vector<entry> Entries; //replace later with more memory-efficient chunk_array, with first chunk in stack
366  public:
367  typedef Entries::iterator iterator;
368  typedef Entries::const_iterator const_iterator;
369  typedef Entries::reverse_iterator reverse_iterator;
370  typedef Entries::const_reverse_iterator const_reverse_iterator;
371  private:
372  Entries data;
373  public:
374  HessianRow() : data() {}
375  HessianRow(const HessianRow & other) : data(other.data) {}
376  HessianRow(entry * pbegin, entry * pend) : data(pbegin,pend) {}
377  ~HessianRow() {}
378  HessianRow & operator = (HessianRow const & other) {data = other.data; return *this;}
380  INMOST_DATA_REAL_TYPE & operator [](index i) // use to fill matrix, not to access individual elements
381  {
382  for(Entries::size_type it = 0; it < data.size(); ++it)
383  if( data[it].first == i ) return data[it].second;
384  data.push_back(make_entry(i,0));
385  return data.back().second;
386  }
388  INMOST_DATA_REAL_TYPE operator[](index i) const
389  {
390  for (Entries::size_type it = 0; it < data.size(); ++it) if (data[it].first == i) return data[it].second;
391  //you should not come here
392  assert(false);
393  return 1.0e20;
394  }
395  INMOST_DATA_REAL_TYPE get_safe(index i) const
396  {
397  for (Entries::size_type it = 0; it < data.size(); ++it) if (data[it].first == i) return data[it].second;
398  return 0.0;
399  }
400  //void Reserve(INMOST_DATA_ENUM_TYPE num) { data.reserve(num);}
402  void Clear() { data.clear(); }
403  void Swap(HessianRow & other) { data.swap(other.data); }
405  INMOST_DATA_ENUM_TYPE Size() const { return static_cast<INMOST_DATA_ENUM_TYPE>(data.size()); }
406  bool Empty() const { return data.empty(); }
407  index & GetIndex(INMOST_DATA_ENUM_TYPE k) {assert(k < data.size()); return (data.begin()+k)->first;}
408  INMOST_DATA_REAL_TYPE & GetValue(INMOST_DATA_ENUM_TYPE k) {assert(k < data.size()); return (data.begin()+k)->second;}
409  index GetIndex(INMOST_DATA_ENUM_TYPE k) const {assert(k < data.size()); return (data.begin()+k)->first;}
410  INMOST_DATA_REAL_TYPE GetValue(INMOST_DATA_ENUM_TYPE k) const {assert(k < data.size()); return (data.begin()+k)->second;}
411  iterator Begin() {return data.begin();}
412  iterator End() {return data.end();}
413  const_iterator Begin() const {return data.begin();}
414  const_iterator End() const {return data.end();}
415  reverse_iterator rBegin() { return data.rbegin(); }
416  reverse_iterator rEnd() { return data.rend(); }
417  const_reverse_iterator rBegin() const { return data.rbegin(); }
418  const_reverse_iterator rEnd() const { return data.rend(); }
420  void RowVec(INMOST_DATA_REAL_TYPE alpha, const Row & rU, INMOST_DATA_REAL_TYPE beta, Row & rJ) const; // returns A(row) * x
421  void MoveRow(HessianRow & new_pos) {data = new_pos.data;} //here move constructor and std::move may be used in future
423  void Zero() {for(iterator it = Begin(); it != End(); ++it) it->second = 0;}
426  void Push(index ind, INMOST_DATA_REAL_TYPE val) {data.push_back(make_entry(ind,val));}
431  void Resize(INMOST_DATA_ENUM_TYPE size) {data.resize(size);}
432  void Print() const
433  {
434  for(const_iterator it = Begin(); it != End(); ++it) std::cout << "(" << it->first.first << "," << it->first.second << "," << it->second << ") ";
435  std::cout << std::endl;
436  }
437  bool isSorted() const;
439  static void MergeSortedRows(INMOST_DATA_REAL_TYPE alpha, const HessianRow & left, INMOST_DATA_REAL_TYPE beta, const HessianRow & right, HessianRow & output);
440  static void MergeJacobianHessian(INMOST_DATA_REAL_TYPE a, const Row & JL, const Row & JR, INMOST_DATA_REAL_TYPE b, const HessianRow & HL, INMOST_DATA_REAL_TYPE c, const HessianRow & HR, HessianRow & output);
441  static void MergeJacobianHessian(INMOST_DATA_REAL_TYPE a, const Row & JL, const Row & JR, INMOST_DATA_REAL_TYPE b, const HessianRow & H, HessianRow & output);
442  };
443 
444 #endif //defined(USE_SOLVER) || defined(USE_AUTODIFF)
445 
446 #if defined(USE_SOLVER)
447 
450  {
452  void DestroyLocks();
453  public:
454  LockService(INMOST_DATA_ENUM_TYPE start = 0, INMOST_DATA_ENUM_TYPE end = 0) { if( end != start ) SetInterval(start,end); }
455  LockService(const LockService & other) { SetInterval(other.GetFirstIndex(),other.GetLastIndex()); }
456  LockService & operator = (LockService const & other) { SetInterval(other.GetFirstIndex(),other.GetLastIndex()); return *this;}
457  ~LockService() {DestroyLocks();}
459  INMOST_DATA_ENUM_TYPE GetFirstIndex() const;
461  INMOST_DATA_ENUM_TYPE GetLastIndex() const;
462  bool Empty() const;
463  void SetInterval(INMOST_DATA_ENUM_TYPE beg, INMOST_DATA_ENUM_TYPE end);
464  void GetInterval(INMOST_DATA_ENUM_TYPE & start, INMOST_DATA_ENUM_TYPE & end) const;
465  bool HaveLocks() const;
466  bool Lock(INMOST_DATA_ENUM_TYPE row);
467  bool TestLock(INMOST_DATA_ENUM_TYPE row);
468  bool UnLock(INMOST_DATA_ENUM_TYPE row);
469  };
470 
474  class Matrix
475  {
477  public:
478  typedef Rows::iterator iterator;
479  typedef Rows::const_iterator const_iterator;
480  private:
481  INMOST_MPI_Comm comm;
482  Rows data;
483  std::string name;
484  bool is_parallel;
485  public:
491  Matrix(std::string _name = "", INMOST_DATA_ENUM_TYPE start = 0, INMOST_DATA_ENUM_TYPE end = 0, INMOST_MPI_Comm _comm = INMOST_MPI_COMM_WORLD);
492  Matrix(const Matrix & other);
493  Matrix & operator =(Matrix const & other);
494  ~Matrix();
496  Row & operator [](INMOST_DATA_ENUM_TYPE i) {return data[i];}
498  const Row & operator [](INMOST_DATA_ENUM_TYPE i) const {return data[i];}
500  INMOST_DATA_ENUM_TYPE Size() const { return static_cast<INMOST_DATA_ENUM_TYPE>(data.size()); }
501  bool Empty() const {return data.empty();}
502  iterator Begin() {return data.begin();}
503  iterator End() {return data.end();}
504  const_iterator Begin() const {return data.begin();}
505  const_iterator End() const {return data.end();}
507  void SetInterval(INMOST_DATA_ENUM_TYPE start, INMOST_DATA_ENUM_TYPE end) {data.set_interval_beg(start); data.set_interval_end(end);}
509  void GetInterval(INMOST_DATA_ENUM_TYPE & start, INMOST_DATA_ENUM_TYPE & end) const {start = data.get_interval_beg(); end = data.get_interval_end();}
510  void ShiftInterval(INMOST_DATA_ENUM_TYPE shift) {data.shift_interval(shift);}
512  INMOST_DATA_ENUM_TYPE GetFirstIndex() const {return data.get_interval_beg();}
514  INMOST_DATA_ENUM_TYPE GetLastIndex() const {return data.get_interval_end();}
516  INMOST_MPI_Comm GetCommunicator() const {return comm;}
517  void MoveRows(INMOST_DATA_ENUM_TYPE from, INMOST_DATA_ENUM_TYPE to, INMOST_DATA_ENUM_TYPE size); //for parallel
518  void Swap(Matrix & other);
521  void MatVec(INMOST_DATA_REAL_TYPE alpha, Vector & x, INMOST_DATA_REAL_TYPE beta, Vector & y) const;
524  void MatVecTranspose(INMOST_DATA_REAL_TYPE alpha, Vector & x, INMOST_DATA_REAL_TYPE beta, Vector & y) const;
526  void Clear() {for(Matrix::iterator it = Begin(); it != End(); ++it) it->Clear(); data.clear();}
528  INMOST_DATA_ENUM_TYPE Nonzeros() {INMOST_DATA_ENUM_TYPE nnz = 0; for(Matrix::iterator it = Begin(); it != End(); ++it) nnz += it->Size(); return nnz;}
532  void Load(std::string file, INMOST_DATA_ENUM_TYPE beg = ENUMUNDEF, INMOST_DATA_ENUM_TYPE end = ENUMUNDEF, std::string file_ord = "");
535  void Save(std::string file, const AnnotationService * annotation = NULL);
537  bool & isParallel() { return is_parallel; }
538  const bool & isParallel() const { return is_parallel; }
540  std::string GetName() const {return name;}
542  void Sort() { for (iterator it = Begin(); it != End(); ++it) it->Sort(); }
551  INMOST_DATA_REAL_TYPE Residual(Sparse::Vector &RHS, Sparse::Vector &SOL);
554  static void ZAXPBY(INMOST_DATA_REAL_TYPE alpha, const Sparse::Matrix& X, INMOST_DATA_REAL_TYPE beta, const Sparse::Matrix& Y, Sparse::Matrix& Z);
555  };
556 
557 #endif //defined(USE_SOLVER)
558 
559 #if defined(USE_SOLVER)
560 
563  {
564  public:
566  typedef HessianRows::iterator iterator;
567  typedef HessianRows::const_iterator const_iterator;
568  private:
569  INMOST_MPI_Comm comm;
570  HessianRows data;
571  std::string name;
572  bool is_parallel;
573  public:
579  HessianMatrix(std::string _name = "", INMOST_DATA_ENUM_TYPE start = 0, INMOST_DATA_ENUM_TYPE end = 0, INMOST_MPI_Comm _comm = INMOST_MPI_COMM_WORLD);
580  HessianMatrix(const HessianMatrix & other);
581  HessianMatrix & operator =(HessianMatrix const & other);
582  ~HessianMatrix();
584  HessianRow & operator [](INMOST_DATA_ENUM_TYPE i) {return data[i];}
586  const HessianRow & operator [](INMOST_DATA_ENUM_TYPE i) const {return data[i];}
588  INMOST_DATA_ENUM_TYPE Size() const { return static_cast<INMOST_DATA_ENUM_TYPE>(data.size()); }
589  bool Empty() const {return data.empty();}
590  iterator Begin() {return data.begin();}
591  iterator End() {return data.end();}
592  const_iterator Begin() const {return data.begin();}
593  const_iterator End() const {return data.end();}
595  void SetInterval(INMOST_DATA_ENUM_TYPE start, INMOST_DATA_ENUM_TYPE end) {data.set_interval_beg(start); data.set_interval_end(end);}
597  void GetInterval(INMOST_DATA_ENUM_TYPE & start, INMOST_DATA_ENUM_TYPE & end) const {start = data.get_interval_beg(); end = data.get_interval_end();}
598  void ShiftInterval(INMOST_DATA_ENUM_TYPE shift) {data.shift_interval(shift);}
600  INMOST_DATA_ENUM_TYPE GetFirstIndex() const {return data.get_interval_beg();}
602  INMOST_DATA_ENUM_TYPE GetLastIndex() const {return data.get_interval_end();}
604  INMOST_MPI_Comm GetCommunicator() const {return comm;}
605  void MoveRows(INMOST_DATA_ENUM_TYPE from, INMOST_DATA_ENUM_TYPE to, INMOST_DATA_ENUM_TYPE size); //for parallel
606  void Swap(HessianMatrix & other);
612  void MatVec(INMOST_DATA_REAL_TYPE alpha, const Matrix & U, INMOST_DATA_REAL_TYPE beta, Matrix & J) const;
614  void Clear() {for(HessianMatrix::iterator it = Begin(); it != End(); ++it) it->Clear(); data.clear();}
618  void Load(std::string file, INMOST_DATA_ENUM_TYPE beg = ENUMUNDEF, INMOST_DATA_ENUM_TYPE end = ENUMUNDEF);
621  void Save(std::string file, const AnnotationService * annotation = NULL);
623  bool & isParallel() { return is_parallel; }
624  const bool & isParallel() const { return is_parallel; }
626  std::string GetName() const {return name;}
627  };
628 
629 #endif //defined(USE_SOLVER)
630 
631 #if defined(USE_SOLVER) || defined(USE_AUTODIFF)
637  class RowMerger
638  {
639  //typedef robin_hood::unordered_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> container;
640  //typedef robin_hood::unordered_flat_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> container;
641  //typedef robin_hood::unordered_node_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> container;
642  //typedef std::unordered_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> container;
643  //typedef robin_hood::unordered_flat_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> container;
644  public:
645  const INMOST_DATA_ENUM_TYPE EOL = ENUMUNDEF-1;
646  //const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF; ///< Value not defined in linked list.
647  class iterator
648  {
649  private:
650  INMOST_DATA_ENUM_TYPE pos;
651  RowMerger * merger;
652  iterator(RowMerger* pmerger) : pos(pmerger->First), merger(pmerger) {}
653  iterator(INMOST_DATA_ENUM_TYPE pos, RowMerger* pmerger) : pos(pos), merger(pmerger) {}
654  public:
655  iterator(const iterator & other) : pos(other.pos), merger(other.merger) {}
656  ~iterator() {}
657  //INMOST_DATA_REAL_TYPE & operator *() {return merger->vals[merger->pos[pos]];}
658  //INMOST_DATA_REAL_TYPE operator *() const {return merger->vals[merger->pos[pos]];}
659  //INMOST_DATA_REAL_TYPE * operator ->() {return &merger->vals[merger->pos[pos]];}
660  //const INMOST_DATA_REAL_TYPE * operator ->() const {return &merger->vals[merger->pos[pos]];}
661  //iterator& operator ++() { pos = merger->next[merger->[pos]]; return *this; }
662  //iterator operator ++(int) { return iterator(merger->next[merger->[pos]], merger); }
663  INMOST_DATA_REAL_TYPE& operator *() { return merger->vals[merger->get_pos(pos)]; }
664  INMOST_DATA_REAL_TYPE operator *() const { return merger->vals[merger->get_pos(pos)]; }
665  INMOST_DATA_REAL_TYPE* operator ->() { return &merger->vals[merger->get_pos(pos)]; }
666  const INMOST_DATA_REAL_TYPE* operator ->() const { return &merger->vals[merger->get_pos(pos)]; }
667  iterator & operator ++(){ pos = merger->next[merger->get_pos(pos)]; return *this;}
668  iterator operator ++(int) { return iterator(merger->next[merger->get_pos(pos)], merger); }
669  iterator & operator = (const iterator & other) {merger = other.merger; pos = other.pos; return *this;}
670  bool operator ==(const iterator & other) const {return merger == other.merger && pos == other.pos;}
671  bool operator !=(const iterator & other) const {return merger != other.merger || pos != other.pos;}
672  bool operator < (const iterator & other) const {return merger == other.merger && pos < other.pos;}
673  bool operator <=(const iterator & other) const {return merger == other.merger && pos <= other.pos;}
674  bool operator > (const iterator & other) const {return merger == other.merger && pos > other.pos;}
675  bool operator >=(const iterator & other) const {return merger == other.merger && pos >= other.pos;}
676  friend class RowMerger;
677  };
678  //typedef container::iterator iterator;
679  private:
680  INMOST_DATA_ENUM_TYPE Nonzeros;
681  INMOST_DATA_ENUM_TYPE First;
682  //std::unordered_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> pos; //Position in vals and next array (huge array)
683  //typedef std::unordered_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> map_container;
684  typedef robin_hood::unordered_flat_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> map_container;
685  //typedef judyLArray<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> map_container;
686  //typedef tsl::hopscotch_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> map_container;
687  //typedef tsl::bhopscotch_map<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> map_container;
688  map_container pos; //Position in vals and next array (huge array)
689  //mutable void* judy_array;
690  std::vector<INMOST_DATA_REAL_TYPE> vals; //Values at the position (small array)
691  std::vector<INMOST_DATA_ENUM_TYPE> next; //Next nonzero position (small array)
692  //interval< INMOST_DATA_ENUM_TYPE, Row::entry > LinkedList; ///< Storage for linked list.
693  //container data;
694  INMOST_DATA_ENUM_TYPE get_pos(INMOST_DATA_ENUM_TYPE pos) const;
695  INMOST_DATA_ENUM_TYPE get_pos(INMOST_DATA_ENUM_TYPE pos);
696  void ins_pos(INMOST_DATA_ENUM_TYPE pos, INMOST_DATA_ENUM_TYPE k);
697  public:
704  //RowMerger(INMOST_DATA_ENUM_TYPE interval_begin, INMOST_DATA_ENUM_TYPE interval_end);
713  //void Resize(INMOST_DATA_ENUM_TYPE interval_begin, INMOST_DATA_ENUM_TYPE interval_end);
714  void Resize(INMOST_DATA_ENUM_TYPE size);
715 #if defined(USE_SOLVER)
719  RowMerger(const Matrix & A);
725  void Resize(const Matrix & A);
726 #endif //USE_SOLVER
728  void Clear();// { data.clear(); }
735  void PushRow(INMOST_DATA_REAL_TYPE coef, const Row & r);
740  void AddRow(INMOST_DATA_REAL_TYPE coef, const Row & r);
743  void Multiply(INMOST_DATA_REAL_TYPE coef);
750  void RetrieveRow(Row & r) const;
751  //INMOST_DATA_REAL_TYPE ScalarProd(RowMerger & other);
753  INMOST_DATA_ENUM_TYPE Size() const {return Nonzeros;}// { return static_cast<INMOST_DATA_ENUM_TYPE>(data.size()); }
755  bool Empty() const { return Nonzeros == 0; }
756  //bool Empty() const { return data.empty(); }
759  INMOST_DATA_REAL_TYPE& operator [] (INMOST_DATA_ENUM_TYPE pos) { return vals[get_pos(pos)]; }
764  INMOST_DATA_REAL_TYPE operator [] (INMOST_DATA_ENUM_TYPE pos) const { return vals[get_pos(pos)]; }
773  void Merge(Row & c, INMOST_DATA_REAL_TYPE alpha, const Row & a, INMOST_DATA_REAL_TYPE beta, const Row & b)
774  {
775  PushRow(alpha,a);
776  AddRow(beta,b);
777  RetrieveRow(c);
778  Clear();
779  }
781  iterator Begin() {return iterator(this);}
782  //iterator Begin() { return data.begin(); }
784  iterator End() {iterator ret(this); ret.pos = EOL; return ret;}
785  //iterator End() { return data.end(); }
786  };
787 #endif //defined(USE_SOLVER) || defined(USE_AUTODIFF)
788  } //namespace Sparse
789 } //namespace INMOST
790 
791 #endif //INMOST_SPARSE_INCLUDED
Abstract class for a matrix, used to abstract away all the data storage and access and provide common...
Definition: inmost_dense.h:647
This class can be used to annotate the matrix.
Definition: inmost_sparse.h:28
AnnotationService & operator=(AnnotationService const &other)
Assign annotations for the matrix.
Definition: inmost_sparse.h:40
~AnnotationService()
Destroy annotations for the matrix.
Definition: inmost_sparse.h:42
void GetInterval(INMOST_DATA_ENUM_TYPE &start, INMOST_DATA_ENUM_TYPE &end) const
Retrieve interval of the local matrix.
Definition: inmost_sparse.h:56
AnnotationService(INMOST_DATA_ENUM_TYPE start=0, INMOST_DATA_ENUM_TYPE end=0)
Create a new annotation for local matrix.
Definition: inmost_sparse.h:34
INMOST_DATA_ENUM_TYPE GetLastIndex() const
Get the last row index of the distributed matrix interval.
Definition: inmost_sparse.h:46
bool Empty() const
Check whether the interval of the local matrix was specified and non-empty.
Definition: inmost_sparse.h:48
void SetAnnotation(INMOST_DATA_ENUM_TYPE row, std::string str)
Specify the text to a certain row of the matrix.
Definition: inmost_sparse.h:66
std::string & GetAnnotation(INMOST_DATA_ENUM_TYPE row)
Retrieve the text corresponding to a certain row of the matrix.
Definition: inmost_sparse.h:59
void SetInterval(INMOST_DATA_ENUM_TYPE beg, INMOST_DATA_ENUM_TYPE end)
Specify interval of the local matrix.
Definition: inmost_sparse.h:52
const std::string & GetAnnotation(INMOST_DATA_ENUM_TYPE row) const
Retrieve the text corresponding to a certain row of the matrix without right of modification.
Definition: inmost_sparse.h:62
AnnotationService(const AnnotationService &other)
Copy annotations for the matrix.
Definition: inmost_sparse.h:37
INMOST_DATA_ENUM_TYPE GetFirstIndex() const
Get the first row index of the distributed matrix interval.
Definition: inmost_sparse.h:44
Class to store the distributed sparse hessian hyper matrix by compressed symmetric matrices.
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.
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.
HessianMatrix(std::string _name="", INMOST_DATA_ENUM_TYPE start=0, INMOST_DATA_ENUM_TYPE end=0, INMOST_MPI_Comm _comm=INMOST_MPI_COMM_WORLD)
Main constructor of the Matrix class.
void Save(std::string file, const AnnotationService *annotation=NULL)
Save the distributed matrix to a single data file in MTX format using parallel MPI I/O.
INMOST_DATA_ENUM_TYPE Size() const
Return the total number of rows in the matrix.
INMOST_MPI_Comm GetCommunicator() const
Get the communicator which the matrix is associated with.
INMOST_DATA_ENUM_TYPE GetLastIndex() const
Get the last row index of the distributed matrix interval.
HessianRow & operator[](INMOST_DATA_ENUM_TYPE i)
Return reference to i-th Row of the matrix.
void Load(std::string file, INMOST_DATA_ENUM_TYPE beg=ENUMUNDEF, INMOST_DATA_ENUM_TYPE end=ENUMUNDEF)
Load the matrix from a single data file in MTX format using the specified interval.
bool & isParallel()
Check that matrix is in parallel state.
void Clear()
Clear all data of the matrix.
INMOST_DATA_ENUM_TYPE GetFirstIndex() const
Get the first row index of the distributed matrix interval.
void MatVec(INMOST_DATA_REAL_TYPE alpha, const Matrix &U, INMOST_DATA_REAL_TYPE beta, Matrix &J) const
HyperMatrix-Matrix product of the form: J = alpha*H*U + beta * J.
std::string GetName() const
Get the matrix name specified in the main constructor.
Class to store the compressed symmetric matrix of a hessian row.
INMOST_DATA_REAL_TYPE & operator[](index i)
The operator [] used to fill the sparse matrix row, but not to access individual elements of the row.
void Clear()
Clear all data of the current row.
void Resize(INMOST_DATA_ENUM_TYPE size)
Resize row to specified size.
static void MergeSortedRows(INMOST_DATA_REAL_TYPE alpha, const HessianRow &left, INMOST_DATA_REAL_TYPE beta, const HessianRow &right, HessianRow &output)
output = alpha * left + beta *right
INMOST_DATA_REAL_TYPE operator[](index i) const
The operator [] used to access individual elements of the row.
INMOST_DATA_ENUM_TYPE Size() const
The size of the sparse row, i.e. the total number of nonzero elements.
void Zero()
Set the vector entries by zeroes.
struct INMOST::Sparse::HessianRow::hessian_index_s index
Entry of the sparse matrix row.
void RowVec(INMOST_DATA_REAL_TYPE alpha, const Row &rU, INMOST_DATA_REAL_TYPE beta, Row &rJ) const
Return the scalar product of the current sparse row by a dense Vector.
void Push(index ind, INMOST_DATA_REAL_TYPE val)
Push specified element into sparse row.
This class can be used for shared access to matrix with OpenMP.
INMOST_DATA_ENUM_TYPE GetLastIndex() const
Get the last row index of the distributed matrix interval.
INMOST_DATA_ENUM_TYPE GetFirstIndex() const
Get the first row index of the distributed matrix interval.
Class to store the distributed sparse matrix by compressed rows.
bool & isParallel()
Check that matrix is in parallel state.
INMOST_DATA_ENUM_TYPE GetFirstIndex() const
Get the first row index of the distributed matrix interval.
void MatVec(INMOST_DATA_REAL_TYPE alpha, Vector &x, INMOST_DATA_REAL_TYPE beta, Vector &y) const
Matrix-vector product of the form: y = alpha*A*x + beta * y.
INMOST_DATA_ENUM_TYPE Size() const
Return the total number of rows in the matrix.
void MatVecTranspose(INMOST_DATA_REAL_TYPE alpha, Vector &x, INMOST_DATA_REAL_TYPE beta, Vector &y) const
Matrix-vector product with transposed matrix of the form: y = alpha*A^T*x + beta * y.
INMOST_DATA_ENUM_TYPE Nonzeros()
Count number of nonzeros in matrix.
Row & operator[](INMOST_DATA_ENUM_TYPE i)
Return reference to i-th Row of the matrix.
static void ZAXPBY(INMOST_DATA_REAL_TYPE alpha, const Sparse::Matrix &X, INMOST_DATA_REAL_TYPE beta, const Sparse::Matrix &Y, Sparse::Matrix &Z)
ZAXPBY operation for sparse matrices Z = alpha * X + beta * Y.
INMOST_DATA_ENUM_TYPE GetLastIndex() const
Get the last row index of the distributed matrix interval.
void Save(std::string file, const AnnotationService *annotation=NULL)
Save the distributed matrix to a single data file in MTX format using parallel MPI I/O.
std::string GetName() const
Get the matrix name specified in the main constructor.
void Clear()
Clear all data of the matrix.
Matrix(std::string _name="", INMOST_DATA_ENUM_TYPE start=0, INMOST_DATA_ENUM_TYPE end=0, INMOST_MPI_Comm _comm=INMOST_MPI_COMM_WORLD)
Main constructor of the Matrix class.
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 Residual(Sparse::Vector &RHS, Sparse::Vector &SOL)
Calculate the real residual.
INMOST_MPI_Comm GetCommunicator() const
Get the communicator which the matrix is associated with.
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.
void Load(std::string file, INMOST_DATA_ENUM_TYPE beg=ENUMUNDEF, INMOST_DATA_ENUM_TYPE end=ENUMUNDEF, std::string file_ord="")
Load the matrix from a single data file in MTX format using the specified interval.
void Sort()
Sort rows.
This class may be used to sum multiple sparse rows.
iterator Begin()
Retrive iterator for the first element.
void Resize(const Matrix &A)
Resize linked list for new matrix, including non-local mapping.
void AddRow(INMOST_DATA_REAL_TYPE coef, const Row &r)
Add a row with a coefficient into non-empty linked list.
void Merge(Row &c, INMOST_DATA_REAL_TYPE alpha, const Row &a, INMOST_DATA_REAL_TYPE beta, const Row &b)
Operation of the form c = alpha a + beta b.
bool Empty() const
Check if linked list is empty.
iterator End()
Retrive iterator for the position beyond the last element.
INMOST_DATA_ENUM_TYPE Size() const
Get current number of nonzeros from linked list.
void RetrieveRow(Row &r) const
Place entries from linked list into row.
const INMOST_DATA_ENUM_TYPE EOL
End of linked list.
RowMerger()
Default constructor without size specified.
void Resize(INMOST_DATA_ENUM_TYPE size)
Resize linked list for new interval.
~RowMerger()
Constructor with size specified.
void Clear()
Clear linked list.
void Multiply(INMOST_DATA_REAL_TYPE coef)
Multiply all entries of linked list by a coefficient.
INMOST_DATA_REAL_TYPE & operator[](INMOST_DATA_ENUM_TYPE pos)
Retrive/add an entry from/to linked list.
RowMerger(const Matrix &A)
Constructor that gets sizes from the matrix, including non-local mapping.
void PushRow(INMOST_DATA_REAL_TYPE coef, const Row &r)
Add a row with a coefficient into empty linked list.
Class to store the sparse matrix row.
void MoveRow(Row &source)
An optimized assignment of the row, when the content of the source row may not be preserved.
void Sort()
Sort row.
bool Empty() const
Checks are there any nonzero entries in the row.
void Swap(Row &other)
Exchange all the data with another row.
INMOST_DATA_REAL_TYPE operator[](INMOST_DATA_ENUM_TYPE i) const
Finds and returns value with specified index.
INMOST_DATA_REAL_TYPE get_safe(INMOST_DATA_ENUM_TYPE i) const
Finds and returns value with specified index.
static __INLINE entry make_entry(INMOST_DATA_ENUM_TYPE ind, INMOST_DATA_REAL_TYPE val)
Assemble an entry of entry_s type.
Row()
Construct an empty row.
void Clear()
Clear all data of the current row.
Row(const Row &other)
Copy all data from another row.
void Pop()
Remove last element.
INMOST_DATA_REAL_TYPE & GetValue(INMOST_DATA_ENUM_TYPE k)
Retrieve a value corresponding to certain position in the array of pairs of index and value.
Entries::const_reverse_iterator const_reverse_iterator
Iterator over constant pairs of index and value running in backward direction.
Row & operator=(Row const &other)
Copy all data from another row.
void Print(double eps=-1, std::ostream &sout=std::cout) const
Output all entries of the row.
INMOST_DATA_ENUM_TYPE GetIndex(INMOST_DATA_ENUM_TYPE k) const
Retrieve an index corresponding to certain position in the array of pairs of index and value.
reverse_iterator rBegin()
An iterator pointing to the last position in the array of pairs of index and value.
Entries::iterator iterator
Iterator over pairs of index and value.
Row(entry *pbegin, entry *pend)
Construct a row from array of pairs of indices and values.
bool isSorted() const
Check whether the row is sorted.
INMOST_DATA_REAL_TYPE & operator[](INMOST_DATA_ENUM_TYPE i)
Finds and returns value with specified index.
void Resize(INMOST_DATA_ENUM_TYPE size)
Resize row to specified size.
static void MergeSortedRows(INMOST_DATA_REAL_TYPE alpha, const Row &left, INMOST_DATA_REAL_TYPE beta, const Row &right, Row &output)
Add up two rows.
const_iterator End() const
An iterator pointing behind the last position in the array of constant pairs of index and value.
struct INMOST::Sparse::Row::entry_s entry
Entry of the sparse matrix row.
iterator End()
An iterator pointing behind the last position in the array of pairs of index and value.
Entries::reverse_iterator reverse_iterator
Iterator over pairs of index and value running in backward direction.
INMOST_DATA_ENUM_TYPE Size() const
The size of the sparse row, i.e. the total number of nonzero elements.
INMOST_DATA_REAL_TYPE GetValue(INMOST_DATA_ENUM_TYPE k) const
Retrieve a value corresponding to certain position in the array of pairs of index and value.
Entries::const_iterator const_iterator
Iterator over constant pairs of index and value.
const_reverse_iterator rEnd() const
An iterator pointing before the first position in the array of constant pairs of index and value.
reverse_iterator rEnd()
An iterator pointing before the first position in the array of pairs of index and value.
INMOST_DATA_REAL_TYPE RowVec(Vector &x) const
Return the scalar product of the current sparse row by a dense Vector.
const_reverse_iterator rBegin() const
An iterator pointing to the last position in the array of constant pairs of index and value.
~Row()
Release all data.
iterator Begin()
Retrive interval of nonzeroes.
INMOST_DATA_ENUM_TYPE & GetIndex(INMOST_DATA_ENUM_TYPE k)
Retrieve an index corresponding to certain position in the array of pairs of index and value.
void Zero()
Set the vector entries by zeroes.
const_iterator Begin() const
An iterator pointing to the first position in the array of constant pairs of index and value.
void Push(INMOST_DATA_ENUM_TYPE ind, INMOST_DATA_REAL_TYPE val)
Push specified element into sparse row.
Distributed vector class.
Definition: inmost_sparse.h:75
bool Empty() const
Test is there any data in the vector.
void Save(std::string file)
Save the distributed vector to a single data file using parallel MPI I/O.
void SetInterval(INMOST_DATA_ENUM_TYPE start, INMOST_DATA_ENUM_TYPE end)
Set the start and the end of the distributed vector interval.
INMOST_DATA_ENUM_TYPE GetLastIndex() const
Get the last index of the distributed vector interval.
Vector(std::string _name="", INMOST_DATA_ENUM_TYPE start=0, INMOST_DATA_ENUM_TYPE end=0, INMOST_MPI_Comm _comm=INMOST_MPI_COMM_WORLD)
Main constructor of the Vector class.
void Clear()
Clear all data of the current vector.
const_iterator Begin() const
Iterator pointing to the first constant value of the vector.
void ShiftInterval(INMOST_DATA_ENUM_TYPE shift)
Move starting position of local indexes.
iterator Begin()
Iterator pointing to the first value of the vector.
Vector & operator=(Vector const &other)
Assignment operator.
const_iterator End() const
Iterator pointing behind the last constant value of the vector.
Entries::const_iterator const_iterator
Type for the iterator over vector of the constant values.
Definition: inmost_sparse.h:79
~Vector()
Delete data of the vector.
bool & isParallel()
Test whether the vector was assigned an extended range of values via OrderInfo class.
Entries::iterator iterator
Type for the iterator over vector of the values.
Definition: inmost_sparse.h:78
iterator End()
Iterator pointing behind the last value of the vector.
std::string GetName()
Get the vector name specified in the main constructor.
void Load(std::string file, INMOST_DATA_ENUM_TYPE mbeg=ENUMUNDEF, INMOST_DATA_ENUM_TYPE mend=ENUMUNDEF, std::string file_ord="")
Load the vector from a single data file using the specified interval.
INMOST_MPI_Comm GetCommunicator() const
Get the communicator which the vector is associated with.
Vector(const Vector &other)
Copy constructor.
void Swap(Vector &other)
Exchange all the data with another vector.
interval< INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE > Entries
Type for representation of the local array of values.
Definition: inmost_sparse.h:77
void GetInterval(INMOST_DATA_ENUM_TYPE &start, INMOST_DATA_ENUM_TYPE &end) const
Get the start and the end of the distributed vector interval.
INMOST_DATA_ENUM_TYPE GetFirstIndex() const
Get the first index of the distributed vector interval.
INMOST_DATA_REAL_TYPE & operator[](INMOST_DATA_ENUM_TYPE i)
Return reference to i-th element of the vector.
index first
the column number of the row element.
INMOST_DATA_REAL_TYPE second
the real value of the row element.
Entry of the sparse matrix row.
Entry of the sparse matrix row.
INMOST_DATA_REAL_TYPE second
the real value of the row element.
INMOST_DATA_ENUM_TYPE first
the column number of the row element.
bool operator<(const entry_s &other) const
Comparison operator that helps sorting entries.