Matrix_ArraySparse.cxx
1 // Copyright (C) 2003-2011 Marc DuruflĂ©
2 //
3 // This file is part of the linear-algebra library Seldon,
4 // http://seldon.sourceforge.net/.
5 //
6 // Seldon is free software; you can redistribute it and/or modify it under the
7 // terms of the GNU Lesser General Public License as published by the Free
8 // Software Foundation; either version 2.1 of the License, or (at your option)
9 // any later version.
10 //
11 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
14 // more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with Seldon. If not, see http://www.gnu.org/licenses/.
18 
19 
20 #ifndef SELDON_FILE_MATRIX_ARRAY_SPARSE_CXX
21 
22 #include "Matrix_ArraySparse.hxx"
23 
24 namespace Seldon
25 {
26 
27 
28  /*********************
29  * MEMORY MANAGEMENT *
30  *********************/
31 
32 
34 
40  template <class T, class Prop, class Storage, class Allocator>
42  Reallocate(int i, int j)
43  {
44  // Clears previous entries.
45  Clear();
46 
47  this->m_ = i;
48  this->n_ = j;
49 
50  int n = Storage::GetFirst(i, j);
51  val_.Reallocate(n);
52  }
53 
54 
56 
62  template <class T, class Prop, class Storage, class Allocator>
64  {
65  int n = Storage::GetFirst(this->m_, this->n_);
66  int new_n = Storage::GetFirst(i, j);
67  if (n != new_n)
68  {
71 
72  new_val.Reallocate(new_n);
73 
74  for (int k = 0 ; k < min(n, new_n) ; k++)
75  Swap(new_val(k), this->val_(k));
76 
77  val_.SetData(new_n, new_val.GetData());
78  new_val.Nullify();
79 
80  }
81 
82  this->m_ = i;
83  this->n_ = j;
84  }
85 
86 
87  /*******************
88  * BASIC FUNCTIONS *
89  *******************/
90 
91 
93 
96  template <class T, class Prop, class Storage, class Allocator>
98  const
99  {
100  long nnz = 0;
101  for (int i = 0; i < this->val_.GetM(); i++)
102  nnz += this->val_(i).GetM();
103 
104  return nnz;
105  }
106 
107 
109  template<class T, class Prop, class Storage, class Allocator>
111  {
112  size_t taille = sizeof(*this) + sizeof(pointer)*this->val_.GetM();
113  for (int i = 0; i < this->val_.GetM(); i++)
114  taille += this->val_(i).GetMemorySize();
115 
116  return taille;
117  }
118 
119 
120  /************************
121  * CONVENIENT FUNCTIONS *
122  ************************/
123 
124 
126 
131  template <class T, class Prop, class Storage, class Allocator>
133  {
134  if (Storage::GetFirst(1, 0) == 1)
135  for (int i = 0; i < this->m_; i++)
136  {
137  for (int j = 0; j < this->val_(i).GetM(); j++)
138  cout << (i+1) << " " << this->val_(i).Index(j)+1
139  << " " << this->val_(i).Value(j) << endl;
140  }
141  else
142  for (int i = 0; i < this->n_; i++)
143  {
144  for (int j = 0; j < this->val_(i).GetM(); j++)
145  cout << this->val_(i).Index(j)+1 << " " << i+1
146  << " " << this->val_(i).Value(j) << endl;
147  }
148  }
149 
150 
152 
158  template <class T, class Prop, class Storage, class Allocator>
160  {
161  for (int i = 0; i < val_.GetM(); i++)
162  val_(i).Assemble();
163  }
164 
165 
167 
170  template <class T, class Prop, class Storage, class Allocator>
171  template<class T0>
173  RemoveSmallEntry(const T0& epsilon)
174  {
175  for (int i = 0; i < val_.GetM(); i++)
176  val_(i).RemoveSmallEntry(epsilon);
177  }
178 
179 
181  template <class T, class Prop, class Storage, class Allocator>
183  {
184  T one; SetComplexOne(one);
185  this->n_ = this->m_;
186  for (int i = 0; i < this->m_; i++)
187  {
188  val_(i).Reallocate(1);
189  val_(i).Index(0) = i;
190  val_(i).Value(0) = one;
191  }
192  }
193 
194 
196  template <class T, class Prop, class Storage, class Allocator>
198  {
199  for (int i = 0; i < val_.GetM(); i++)
200  val_(i).Zero();
201  }
202 
203 
205  template <class T, class Prop, class Storage, class Allocator>
207  {
208  int value = 0;
209  for (int i = 0; i < val_.GetM(); i++)
210  for (int j = 0; j < val_(i).GetM(); j++)
211  {
212  SetComplexReal(value, val_(i).Value(j));
213  value++;
214  }
215  }
216 
217 
219  template <class T, class Prop, class Storage, class Allo> template<class T0>
221  {
222  for (int i = 0; i < val_.GetM(); i++)
223  val_(i).Fill(x);
224  }
225 
226 
228  template <class T, class Prop, class Storage, class Allocator>
229  template <class T0>
232  {
233  this->Fill(x);
234  }
235 
236 
238  template <class T, class Prop, class Storage, class Allocator>
240  {
241 #ifndef SELDON_WITHOUT_REINIT_RANDOM
242  srand(time(NULL));
243 #endif
244  for (int i = 0; i < val_.GetM(); i++)
245  val_(i).FillRand();
246  }
247 
248 
250 
257  template <class T, class Prop, class Storage, class Allocator>
259  Write(string FileName) const
260  {
261  ofstream FileStream;
262  FileStream.open(FileName.c_str(), ofstream::binary);
263 
264 #ifdef SELDON_CHECK_IO
265  // Checks if the file was opened.
266  if (!FileStream.is_open())
267  throw IOError("Matrix_ArraySparse::Write(string FileName)",
268  string("Unable to open file \"") + FileName + "\".");
269 #endif
270 
271  this->Write(FileStream);
272 
273  FileStream.close();
274  }
275 
276 
278 
285  template <class T, class Prop, class Storage, class Allocator>
287  Write(ostream& FileStream) const
288  {
289 
290 #ifdef SELDON_CHECK_IO
291  // Checks if the stream is ready.
292  if (!FileStream.good())
293  throw IOError("Matrix_ArraySparse::Write(ofstream& FileStream)",
294  "Stream is not ready.");
295 #endif
296 
297  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
298  sizeof(int));
299  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
300  sizeof(int));
301 
302  for (int i = 0; i < val_.GetM(); i++)
303  val_(i).Write(FileStream);
304  }
305 
306 
308 
312  template <class T, class Prop, class Storage, class Allocator>
314  WriteText(string FileName, bool cplx) const
315  {
316  ofstream FileStream; FileStream.precision(14);
317  FileStream.open(FileName.c_str());
318 
319  // changing precision
320  FileStream.precision(cout.precision());
321 
322 #ifdef SELDON_CHECK_IO
323  // Checks if the file was opened.
324  if (!FileStream.is_open())
325  throw IOError("Matrix_ArraySparse::Write(string FileName)",
326  string("Unable to open file \"") + FileName + "\".");
327 #endif
328 
329  this->WriteText(FileStream, cplx);
330 
331  FileStream.close();
332  }
333 
334 
336 
340  template <class T, class Prop, class Storage, class Allocator>
342  WriteText(ostream& FileStream, bool cplx) const
343  {
344 
345 #ifdef SELDON_CHECK_IO
346  // Checks if the stream is ready.
347  if (!FileStream.good())
348  throw IOError("Matrix_ArraySparse::Write(ofstream& FileStream)",
349  "Stream is not ready.");
350 #endif
351 
352  // conversion in coordinate format (1-index convention)
353  const Matrix<T, Prop, Storage, Allocator>& leaf_class =
354  static_cast<const Matrix<T, Prop, Storage, Allocator>& >(*this);
355 
356  T zero; int index = 1;
357  WriteCoordinateMatrix(leaf_class, FileStream, zero, index, cplx);
358  }
359 
360 
362 
369  template <class T, class Prop, class Storage, class Allocator>
371  Read(string FileName)
372  {
373  ifstream FileStream;
374  FileStream.open(FileName.c_str(), ifstream::binary);
375 
376 #ifdef SELDON_CHECK_IO
377  // Checks if the file was opened.
378  if (!FileStream.is_open())
379  throw IOError("Matrix_ArraySparse::Read(string FileName)",
380  string("Unable to open file \"") + FileName + "\".");
381 #endif
382 
383  this->Read(FileStream);
384 
385  FileStream.close();
386  }
387 
388 
390 
397  template <class T, class Prop, class Storage, class Allocator>
399  Read(istream& FileStream)
400  {
401 
402 #ifdef SELDON_CHECK_IO
403  // Checks if the stream is ready.
404  if (!FileStream.good())
405  throw IOError("Matrix_ArraySparse::Read(ofstream& FileStream)",
406  "Stream is not ready.");
407 #endif
408 
409  FileStream.read(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
410  sizeof(int));
411  FileStream.read(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
412  sizeof(int));
413 
414  val_.Reallocate(Storage::GetFirst(this->m_, this->n_));
415  for (int i = 0; i < val_.GetM(); i++)
416  val_(i).Read(FileStream);
417 
418 #ifdef SELDON_CHECK_IO
419  // Checks if data was read.
420  if (!FileStream.good())
421  throw IOError("Matrix_ArraySparse::Read(istream& FileStream)",
422  string("Input operation failed.")
423  + string(" The input file may have been removed")
424  + " or may not contain enough data.");
425 #endif
426 
427  }
428 
429 
431 
435  template <class T, class Prop, class Storage, class Allocator>
437  ReadText(string FileName, bool cplx)
438  {
439  ifstream FileStream;
440  FileStream.open(FileName.c_str());
441 
442 #ifdef SELDON_CHECK_IO
443  // Checks if the file was opened.
444  if (!FileStream.is_open())
445  throw IOError("Matrix_ArraySparse::ReadText(string FileName)",
446  string("Unable to open file \"") + FileName + "\".");
447 #endif
448 
449  this->ReadText(FileStream, cplx);
450 
451  FileStream.close();
452  }
453 
454 
456 
460  template <class T, class Prop, class Storage, class Allocator>
462  ReadText(istream& FileStream, bool cplx)
463  {
465  static_cast<Matrix<T, Prop, Storage, Allocator>& >(*this);
466 
467  T zero; int index = 1;
468  ReadCoordinateMatrix(leaf_class, FileStream, zero, index, -1, cplx);
469  }
470 
471 
473  // MATRIX<ARRAY_COLSPARSE> //
475 
476 
478 
484  template <class T, class Prop, class Allocator>
486  AddInteractionRow(int i, int nb, int* col_, T* value_,
487  bool already_sorted)
488  {
489  IVect col;
490  col.SetData(nb, col_);
491  Vector<T> val;
492  val.SetData(nb, value_);
493  AddInteractionRow(i, nb, col, val, already_sorted);
494  col.Nullify();
495  val.Nullify();
496  }
497 
498 
500 
506  template <class T, class Prop, class Allocator>
508  AddInteractionColumn(int i, int nb, int* row_, T* value_,
509  bool already_sorted)
510  {
511  IVect row;
512  row.SetData(nb, row_);
513  Vector<T> val;
514  val.SetData(nb, value_);
515  AddInteractionColumn(i, nb, row, val, already_sorted);
516  row.Nullify();
517  val.Nullify();
518  }
519 
520 
522 
528  template <class T, class Prop, class Allocator>
530  AddInteractionRow(int i, int nb, const Vector<int>& col,
531  const Vector<T>& val, bool already_sorted)
532  {
533  for (int j = 0; j < nb; j++)
534  this->val_(col(j)).AddInteraction(i, val(j));
535  }
536 
537 
539 
545  template <class T, class Prop, class Allocator>
547  AddInteractionColumn(int i, int nb, const Vector<int>& row,
548  const Vector<T>& val, bool already_sorted)
549  {
550  this->val_(i).AddInteractionRow(nb, row, val, already_sorted);
551  }
552 
553 
555  // MATRIX<ARRAY_ROWSPARSE> //
557 
558 
560 
566  template <class T, class Prop, class Allocator>
568  AddInteractionRow(int i, int nb, int* col_, T* value_,
569  bool already_sorted)
570  {
571  IVect col;
572  col.SetData(nb, col_);
573  Vector<T> val;
574  val.SetData(nb, value_);
575  AddInteractionRow(i, nb, col, val, already_sorted);
576  col.Nullify();
577  val.Nullify();
578  }
579 
580 
582 
588  template <class T, class Prop, class Allocator>
590  AddInteractionColumn(int i, int nb, int* row_, T* value_,
591  bool already_sorted)
592  {
593  IVect row;
594  row.SetData(nb, row_);
595  Vector<T> val;
596  val.SetData(nb, value_);
597  AddInteractionColumn(i, nb, row, val, already_sorted);
598  row.Nullify();
599  val.Nullify();
600  }
601 
602 
604 
610  template <class T, class Prop, class Allocator>
612  AddInteractionRow(int i, int nb, const Vector<int>& col,
613  const Vector<T>& val, bool already_sorted)
614  {
615  this->val_(i).AddInteractionRow(nb, col, val, already_sorted);
616  }
617 
618 
620 
626  template <class T, class Prop, class Allocator>
628  AddInteractionColumn(int i, int nb, const Vector<int>& row,
629  const Vector<T>& val, bool already_sorted)
630  {
631  for (int j = 0; j < nb; j++)
632  this->val_(row(j)).AddInteraction(i, val(j));
633  }
634 
635 
637  // MATRIX<ARRAY_COLSYMSPARSE> //
639 
640 
642 
648  template <class T, class Prop, class Allocator>
650  AddInteractionRow(int i, int nb, int* col_, T* value_,
651  bool already_sorted)
652  {
653  IVect col;
654  col.SetData(nb, col_);
655  Vector<T> val;
656  val.SetData(nb, value_);
657  AddInteractionRow(i, nb, col, val, already_sorted);
658  col.Nullify();
659  val.Nullify();
660  }
661 
662 
664 
670  template <class T, class Prop, class Allocator>
672  AddInteractionColumn(int i, int nb, int* row_, T* value_,
673  bool already_sorted)
674  {
675  IVect row;
676  row.SetData(nb, row_);
677  Vector<T> val;
678  val.SetData(nb, value_);
679  AddInteractionColumn(i, nb, row, val, already_sorted);
680  row.Nullify();
681  val.Nullify();
682  }
683 
684 
686 
692  template <class T, class Prop, class Allocator>
694  AddInteractionRow(int i, int nb, const Vector<int>& col,
695  const Vector<T>& val, bool already_sorted)
696  {
697  for (int j = 0; j < nb; j++)
698  if (i <= col(j))
699  this->val_(col(j)).AddInteraction(i, val(j));
700  }
701 
702 
704 
710  template <class T, class Prop, class Allocator>
712  AddInteractionColumn(int i, int nb, const Vector<int>& row,
713  const Vector<T>& val, bool already_sorted)
714  {
715  IVect new_row(nb);
716  Vector<T> new_val(nb);
717  nb = 0;
718  for (int j = 0; j < new_row.GetM(); j++)
719  if (row(j) <= i)
720  {
721  new_row(nb) = row(j);
722  new_val(nb) = val(j); nb++;
723  }
724 
725  this->val_(i).AddInteractionRow(nb, new_row, new_val, already_sorted);
726  }
727 
728 
730  // MATRIX<ARRAY_ROWSYMSPARSE> //
732 
733 
735 
741  template <class T, class Prop, class Allocator>
743  AddInteractionRow(int i, int nb, int* col_, T* value_,
744  bool already_sorted)
745  {
746  IVect col;
747  col.SetData(nb, col_);
748  Vector<T> val;
749  val.SetData(nb, value_);
750  AddInteractionRow(i, nb, col, val, already_sorted);
751  col.Nullify();
752  val.Nullify();
753  }
754 
755 
757 
763  template <class T, class Prop, class Allocator>
765  AddInteractionColumn(int i, int nb, int* row_, T* value_,
766  bool already_sorted)
767  {
768  IVect row;
769  row.SetData(nb, row_);
770  Vector<T> val;
771  val.SetData(nb, value_);
772  AddInteractionColumn(i, nb, row, val, already_sorted);
773  row.Nullify();
774  val.Nullify();
775  }
776 
777 
779 
785  template <class T, class Prop, class Allocator>
787  AddInteractionRow(int i, int nb, const Vector<int>& col,
788  const Vector<T>& val, bool already_sorted)
789  {
790  IVect new_col(nb);
791  Vector<T> new_val(nb);
792  nb = 0;
793  for (int j = 0; j < new_col.GetM(); j++)
794  if (i <= col(j))
795  {
796  new_col(nb) = col(j);
797  new_val(nb) = val(j); nb++;
798  }
799 
800  this->val_(i).AddInteractionRow(nb, new_col, new_val, already_sorted);
801  }
802 
803 
805 
811  template <class T, class Prop, class Allocator>
813  AddInteractionColumn(int i, int nb, const Vector<int>& row,
814  const Vector<T>& val, bool already_sorted)
815  {
816  for (int j = 0; j < nb; j++)
817  if (row(j) <= i)
818  this->val_(row(j)).AddInteraction(i, val(j));
819  }
820 
821 } // namespace Seldon
822 
823 #define SELDON_FILE_MATRIX_ARRAY_SPARSE_CXX
824 #endif
Seldon::Matrix_ArraySparse::Read
void Read(string FileName)
Reads the matrix from a file.
Definition: Matrix_ArraySparse.cxx:371
Seldon::Matrix_ArraySparse::Print
void Print() const
Displays the matrix on the standard output.
Definition: Matrix_ArraySparse.cxx:132
Seldon::Vector
Definition: SeldonHeader.hxx:207
Seldon::Matrix
Definition: SeldonHeader.hxx:226
Seldon::Matrix_ArraySparse::SetIdentity
void SetIdentity()
Matrix is initialized to the identity matrix.
Definition: Matrix_ArraySparse.cxx:182
Seldon::NewAlloc
Definition: Allocator.hxx:91
Seldon::Matrix_ArraySparse::GetMemorySize
size_t GetMemorySize() const
returns size of matrix in bytes
Definition: Matrix_ArraySparse.cxx:110
Seldon::VectFull
Definition: StorageInline.cxx:74
Seldon::Matrix_ArraySparse::RemoveSmallEntry
void RemoveSmallEntry(const T0 &epsilon)
Removes small coefficients from entries.
Definition: Matrix_ArraySparse.cxx:173
Seldon::Matrix_ArraySparse::Zero
void Zero()
Non-zero entries are set to 0 (but not removed).
Definition: Matrix_ArraySparse.cxx:197
Seldon::Matrix_ArraySparse::WriteText
void WriteText(string FileName, bool cplx=false) const
Writes the matrix in a file.
Definition: Matrix_ArraySparse.cxx:314
Seldon::Matrix_ArraySparse::Fill
void Fill()
Non-zero entries are filled with values 0, 1, 2, 3 ...
Definition: Matrix_ArraySparse.cxx:206
Seldon::Matrix_ArraySparse::Resize
void Resize(int i, int j)
Reallocates additional memory to resize the matrix.
Definition: Matrix_ArraySparse.cxx:63
Seldon::Matrix_ArraySparse::GetNonZeros
long GetNonZeros() const
Returns the number of non-zero entries.
Definition: Matrix_ArraySparse.cxx:97
Seldon::Matrix_ArraySparse::operator=
Matrix_ArraySparse< T, Prop, Storage, Allocator > & operator=(const T0 &x)
Non-zero entries are set to a given value x.
Definition: Matrix_ArraySparse.cxx:231
Seldon::Matrix_ArraySparse::FillRand
void FillRand()
Non-zero entries take a random value.
Definition: Matrix_ArraySparse.cxx:239
Seldon::Matrix_ArraySparse::ReadText
void ReadText(string FileName, bool cplx=false)
Reads the matrix from a file.
Definition: Matrix_ArraySparse.cxx:437
Seldon::Matrix_ArraySparse
Sparse Array-matrix class.
Definition: Matrix_ArraySparse.hxx:38
Seldon::Matrix_ArraySparse::Reallocate
void Reallocate(int i, int j)
Reallocates memory to resize the matrix.
Definition: Matrix_ArraySparse.cxx:42
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::IOError
Definition: Errors.hxx:150
Seldon::Swap
void Swap(Vector< T, Storage, Allocator > &X, Vector< T, Storage, Allocator > &Y)
Swaps X and Y without copying all elements.
Definition: Functions_Vector.cxx:348
Seldon::Matrix_ArraySparse::Write
void Write(string FileName) const
Writes the matrix in a file.
Definition: Matrix_ArraySparse.cxx:259
Seldon::SetComplexReal
void SetComplexReal(int n, std::complex< T > &number)
Sets a complex number to (n, 0).
Definition: CommonInline.cxx:234
Seldon::Matrix_ArraySparse::Assemble
void Assemble()
Assembles the matrix.
Definition: Matrix_ArraySparse.cxx:159