Matrix_Symmetric.cxx
1 // Copyright (C) 2001-2011 Vivien Mallet
2 // Copyright (C) 2003-2011 Marc DuruflĂ©
3 //
4 // This file is part of the linear-algebra library Seldon,
5 // http://seldon.sourceforge.net/.
6 //
7 // Seldon is free software; you can redistribute it and/or modify it under the
8 // terms of the GNU Lesser General Public License as published by the Free
9 // Software Foundation; either version 2.1 of the License, or (at your option)
10 // any later version.
11 //
12 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 // more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with Seldon. If not, see http://www.gnu.org/licenses/.
19 
20 
21 #ifndef SELDON_FILE_MATRIX_SYMMETRIC_CXX
22 
23 #include "Matrix_Symmetric.hxx"
24 
25 namespace Seldon
26 {
27 
29 
34  template <class T, class Prop, class Storage, class Allocator>
36  ::Matrix_Symmetric(int i, int j): Matrix_Base<T, Allocator>(i, i)
37  {
38 
39 #ifdef SELDON_CHECK_MEMORY
40  try
41  {
42 #endif
43 
44  me_ = reinterpret_cast<pointer*>( calloc(i, sizeof(pointer)) );
45 
46 #ifdef SELDON_CHECK_MEMORY
47  }
48  catch (...)
49  {
50  this->m_ = 0;
51  this->n_ = 0;
52  me_ = NULL;
53  this->data_ = NULL;
54  }
55  if (me_ == NULL)
56  {
57  this->m_ = 0;
58  this->n_ = 0;
59  this->data_ = NULL;
60  }
61  if (me_ == NULL && i != 0)
62  throw NoMemory("Matrix_Symmetric::Matrix_Symmetric(int, int)",
63  string("Unable to allocate memory for a matrix of size ")
64  + to_str(static_cast<long int>(i)
65  * static_cast<long int>(i)
66  * static_cast<long int>(sizeof(T)))
67  + " bytes (" + to_str(i) + " x " + to_str(i)
68  + " elements).");
69 #endif
70 
71 #ifdef SELDON_CHECK_MEMORY
72  try
73  {
74 #endif
75 
76  this->data_ = Allocator::allocate(long(i) * long(i), this);
77 
78 #ifdef SELDON_CHECK_MEMORY
79  }
80  catch (...)
81  {
82  this->m_ = 0;
83  this->n_ = 0;
84  free(me_);
85  me_ = NULL;
86  this->data_ = NULL;
87  }
88  if (this->data_ == NULL)
89  {
90  this->m_ = 0;
91  this->n_ = 0;
92  free(me_);
93  me_ = NULL;
94  }
95  if (this->data_ == NULL && i != 0)
96  throw NoMemory("Matrix_Symmetric::Matrix_Symmetric(int, int)",
97  string("Unable to allocate memory for a matrix of size ")
98  + to_str(static_cast<long int>(i)
99  * static_cast<long int>(i)
100  * static_cast<long int>(sizeof(T)))
101  + " bytes (" + to_str(i) + " x " + to_str(i)
102  + " elements).");
103 #endif
104 
105  pointer ptr = this->data_;
106  long lgth = i;
107  for (int k = 0; k < i; k++, ptr += lgth)
108  me_[k] = ptr;
109  }
110 
111 
113  template <class T, class Prop, class Storage, class Allocator>
116  : Matrix_Base<T, Allocator>()
117  {
118  this->m_ = 0;
119  this->n_ = 0;
120  this->data_ = NULL;
121  this->me_ = NULL;
122 
123  this->Copy(A);
124  }
125 
126 
128 
132  template <class T, class Prop, class Storage, class Allocator>
134  {
135 
136 #ifdef SELDON_CHECK_MEMORY
137  try
138  {
139 #endif
140 
141  if (this->data_ != NULL)
142  {
143  Allocator::deallocate(this->data_, this->m_ * long(this->n_));
144  this->data_ = NULL;
145  }
146 
147 #ifdef SELDON_CHECK_MEMORY
148  }
149  catch (...)
150  {
151  this->data_ = NULL;
152  }
153 #endif
154 
155 #ifdef SELDON_CHECK_MEMORY
156  try
157  {
158 #endif
159 
160  if (me_ != NULL)
161  {
162  free(me_);
163  me_ = NULL;
164  }
165 
166 #ifdef SELDON_CHECK_MEMORY
167  }
168  catch (...)
169  {
170  this->m_ = 0;
171  this->n_ = 0;
172  me_ = NULL;
173  }
174 #endif
175 
176  this->m_ = 0;
177  this->n_ = 0;
178  }
179 
180 
181  /*********************
182  * MEMORY MANAGEMENT *
183  *********************/
184 
185 
187 
193  template <class T, class Prop, class Storage, class Allocator>
195  ::Reallocate(int i, int j)
196  {
197 
198  if (i != this->m_)
199  {
200  this->m_ = i;
201  this->n_ = i;
202 
203 #ifdef SELDON_CHECK_MEMORY
204  try
205  {
206 #endif
207 
208  me_ = reinterpret_cast<pointer*>( realloc(me_,
209  i * sizeof(pointer)) );
210 
211 #ifdef SELDON_CHECK_MEMORY
212  }
213  catch (...)
214  {
215  this->m_ = 0;
216  this->n_ = 0;
217  me_ = NULL;
218  this->data_ = NULL;
219  }
220  if (me_ == NULL)
221  {
222  this->m_ = 0;
223  this->n_ = 0;
224  this->data_ = NULL;
225  }
226  if (me_ == NULL && i != 0)
227  throw NoMemory("Matrix_Symmetric::Reallocate(int, int)",
228  string("Unable to reallocate memory")
229  + " for a matrix of size "
230  + to_str(static_cast<long int>(i)
231  * static_cast<long int>(i)
232  * static_cast<long int>(sizeof(T)))
233  + " bytes (" + to_str(i) + " x " + to_str(i)
234  + " elements).");
235 #endif
236 
237 #ifdef SELDON_CHECK_MEMORY
238  try
239  {
240 #endif
241 
242  this->data_ =
243  reinterpret_cast<pointer>(Allocator::reallocate(this->data_,
244  long(i)*long(i), this) );
245 
246 #ifdef SELDON_CHECK_MEMORY
247  }
248  catch (...)
249  {
250  this->m_ = 0;
251  this->n_ = 0;
252  free(me_);
253  me_ = NULL;
254  this->data_ = NULL;
255  }
256  if (this->data_ == NULL)
257  {
258  this->m_ = 0;
259  this->n_ = 0;
260  free(me_);
261  me_ = NULL;
262  }
263  if (this->data_ == NULL && i != 0)
264  throw NoMemory("Matrix_Symmetric::Reallocate(int, int)",
265  string("Unable to reallocate memory")
266  + " for a matrix of size "
267  + to_str(static_cast<long int>(i)
268  * static_cast<long int>(i)
269  * static_cast<long int>(sizeof(T)))
270  + " bytes (" + to_str(i) + " x " + to_str(i)
271  + " elements).");
272 #endif
273 
274  pointer ptr = this->data_;
275  long lgth = Storage::GetSecond(i, i);
276  for (int k = 0; k < Storage::GetFirst(i, i); k++, ptr += lgth)
277  me_[k] = ptr;
278  }
279  }
280 
281 
284 
298  template <class T, class Prop, class Storage, class Allocator>
300  ::SetData(int i, int j,
302  ::pointer data)
303  {
304 
305  this->Clear();
306 
307  this->m_ = i;
308  this->n_ = i;
309 
310 #ifdef SELDON_CHECK_MEMORY
311  try
312  {
313 #endif
314 
315  me_ = reinterpret_cast<pointer*>( calloc(i, sizeof(pointer)) );
316 
317 #ifdef SELDON_CHECK_MEMORY
318  }
319  catch (...)
320  {
321  this->m_ = 0;
322  this->n_ = 0;
323  me_ = NULL;
324  this->data_ = NULL;
325  return;
326  }
327  if (me_ == NULL)
328  {
329  this->m_ = 0;
330  this->n_ = 0;
331  this->data_ = NULL;
332  return;
333  }
334 #endif
335 
336  this->data_ = data;
337 
338  pointer ptr = this->data_;
339  long lgth = i;
340  for (int k = 0; k < i; k++, ptr += lgth)
341  me_[k] = ptr;
342  }
343 
344 
346 
351  template <class T, class Prop, class Storage, class Allocator>
353  {
354  this->m_ = 0;
355  this->n_ = 0;
356 
357 #ifdef SELDON_CHECK_MEMORY
358  try
359  {
360 #endif
361 
362  if (me_ != NULL)
363  {
364  free(me_);
365  me_ = NULL;
366  }
367 
368 #ifdef SELDON_CHECK_MEMORY
369  }
370  catch (...)
371  {
372  this->m_ = 0;
373  this->n_ = 0;
374  me_ = NULL;
375  }
376 #endif
377 
378  this->data_ = NULL;
379  }
380 
381 
382  /*********************
383  * MEMORY MANAGEMENT *
384  *********************/
385 
386 
388 
395  template <class T, class Prop, class Storage, class Allocator>
397  ::Resize(int i, int j)
398  {
399 
400  // Storing the old values of the matrix.
401  int iold = Storage::GetFirst(this->m_, this->n_);
402  int jold = Storage::GetSecond(this->m_, this->n_);
403  Vector<value_type, VectFull, Allocator> xold(this->GetDataSize());
404  for (long k = 0; k < this->GetDataSize(); k++)
405  xold(k) = this->data_[k];
406 
407  // Reallocation.
408  int inew = Storage::GetFirst(i, j);
409  int jnew = Storage::GetSecond(i, j);
410  this->Reallocate(i, j);
411 
412  // Filling the matrix with its old values.
413  int imin = min(iold, inew), jmin = min(jold, jnew);
414  for (int k = 0; k < imin; k++)
415  for (int l = 0; l < jmin; l++)
416  this->data_[k*long(jnew)+l] = xold(l+long(jold)*k);
417  }
418 
419 
420  /************************
421  * CONVENIENT FUNCTIONS *
422  ************************/
423 
424 
426 
430  template <class T, class Prop, class Storage, class Allocator>
432  {
433  Allocator::memoryset(this->data_, char(0),
434  this->GetDataSize() * sizeof(value_type));
435  }
436 
437 
439  template <class T, class Prop, class Storage, class Allocator>
441  {
442  T zero, one;
443  SetComplexZero(zero);
444  SetComplexOne(one);
445 
446  this->Fill(zero);
447 
448  for (int i = 0; i < min(this->m_, this->n_); i++)
449  this->Val(i, i) = one;
450  }
451 
452 
454 
458  template <class T, class Prop, class Storage, class Allocator>
460  {
461  for (long i = 0; i < this->GetDataSize(); i++)
462  SetComplexReal(i, this->data_[i]);
463  }
464 
465 
467 
470  template <class T, class Prop, class Storage, class Allocator>
471  template <class T0>
473  {
474  T x_;
475  SetComplexReal(x, x_);
476  for (long i = 0; i < this->GetDataSize(); i++)
477  this->data_[i] = x_;
478  }
479 
480 
482 
485  template <class T, class Prop, class Storage, class Allocator>
486  template <class T0>
489  {
490  this->Fill(x);
491 
492  return *this;
493  }
494 
495 
497 
500  template <class T, class Prop, class Storage, class Allocator>
502  {
503 #ifndef SELDON_WITHOUT_REINIT_RANDOM
504  srand(time(NULL));
505 #endif
506  for (long i = 0; i < this->GetDataSize(); i++)
507  SetComplexReal(rand(), this->data_[i]);
508  }
509 
510 
512 
517  template <class T, class Prop, class Storage, class Allocator>
519  {
520  for (int i = 0; i < this->m_; i++)
521  {
522  for (int j = 0; j < this->n_; j++)
523  cout << (*this)(i, j) << "\t";
524  cout << endl;
525  }
526  }
527 
528 
530 
541  template <class T, class Prop, class Storage, class Allocator>
543  ::Print(int a, int b, int m, int n) const
544  {
545  for (int i = a; i < min(this->m_, a + m); i++)
546  {
547  for (int j = b; j < min(this->n_, b + n); j++)
548  cout << (*this)(i, j) << "\t";
549  cout << endl;
550  }
551  }
552 
553 
555 
563  template <class T, class Prop, class Storage, class Allocator>
565  {
566  Print(0, 0, l, l);
567  }
568 
569 
570  /**************************
571  * INPUT/OUTPUT FUNCTIONS *
572  **************************/
573 
574 
576 
583  template <class T, class Prop, class Storage, class Allocator>
585  ::Write(string FileName) const
586  {
587  ofstream FileStream;
588  FileStream.open(FileName.c_str(), ofstream::binary);
589 
590 #ifdef SELDON_CHECK_IO
591  // Checks if the file was opened.
592  if (!FileStream.is_open())
593  throw IOError("Matrix_Symmetric::Write(string FileName)",
594  string("Unable to open file \"") + FileName + "\".");
595 #endif
596 
597  this->Write(FileStream);
598 
599  FileStream.close();
600  }
601 
602 
604 
611  template <class T, class Prop, class Storage, class Allocator>
613  ::Write(ostream& FileStream) const
614  {
615 
616 #ifdef SELDON_CHECK_IO
617  // Checks if the stream is ready.
618  if (!FileStream.good())
619  throw IOError("Matrix_Symmetric::Write(ofstream& FileStream)",
620  "Stream is not ready.");
621 #endif
622 
623  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
624  sizeof(int));
625  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
626  sizeof(int));
627 
628  FileStream.write(reinterpret_cast<char*>(this->data_),
629  long(this->m_) * long(this->n_) * sizeof(value_type));
630 
631 #ifdef SELDON_CHECK_IO
632  // Checks if data was written.
633  if (!FileStream.good())
634  throw IOError("Matrix_Symmetric::Write(ofstream& FileStream)",
635  string("Output operation failed.")
636  + string(" The output file may have been removed")
637  + " or there is no space left on device.");
638 #endif
639 
640  }
641 
642 
644 
651  template <class T, class Prop, class Storage, class Allocator>
653  ::WriteText(string FileName) const
654  {
655  ofstream FileStream;
656  FileStream.precision(cout.precision());
657  FileStream.flags(cout.flags());
658  FileStream.open(FileName.c_str());
659 
660 #ifdef SELDON_CHECK_IO
661  // Checks if the file was opened.
662  if (!FileStream.is_open())
663  throw IOError("Matrix_Symmetric::WriteText(string FileName)",
664  string("Unable to open file \"") + FileName + "\".");
665 #endif
666 
667  this->WriteText(FileStream);
668 
669  FileStream.close();
670  }
671 
672 
674 
681  template <class T, class Prop, class Storage, class Allocator>
683  ::WriteText(ostream& FileStream) const
684  {
685 
686 #ifdef SELDON_CHECK_IO
687  // Checks if the file is ready.
688  if (!FileStream.good())
689  throw IOError("Matrix_Symmetric::WriteText(ofstream& FileStream)",
690  "Stream is not ready.");
691 #endif
692 
693  int i, j;
694  for (i = 0; i < this->GetM(); i++)
695  {
696  for (j = 0; j < this->GetN(); j++)
697  FileStream << (*this)(i, j) << '\t';
698  FileStream << endl;
699  }
700 
701 #ifdef SELDON_CHECK_IO
702  // Checks if data was written.
703  if (!FileStream.good())
704  throw IOError("Matrix_Symmetric::WriteText(ofstream& FileStream)",
705  string("Output operation failed.")
706  + string(" The output file may have been removed")
707  + " or there is no space left on device.");
708 #endif
709 
710  }
711 
712 
714 
721  template <class T, class Prop, class Storage, class Allocator>
723  {
724  ifstream FileStream;
725  FileStream.open(FileName.c_str(), ifstream::binary);
726 
727 #ifdef SELDON_CHECK_IO
728  // Checks if the file was opened.
729  if (!FileStream.is_open())
730  throw IOError("Matrix_Symmetric::Read(string FileName)",
731  string("Unable to open file \"") + FileName + "\".");
732 #endif
733 
734  this->Read(FileStream);
735 
736  FileStream.close();
737  }
738 
739 
741 
748  template <class T, class Prop, class Storage, class Allocator>
750  ::Read(istream& FileStream)
751  {
752 
753 #ifdef SELDON_CHECK_IO
754  // Checks if the stream is ready.
755  if (!FileStream.good())
756  throw IOError("Matrix_Symmetric::Read(ifstream& FileStream)",
757  "Stream is not ready.");
758 #endif
759 
760  int new_m, new_n;
761  FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
762  FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
763  this->Reallocate(new_m, new_n);
764 
765  FileStream.read(reinterpret_cast<char*>(this->data_),
766  long(new_m) * long(new_n) * sizeof(value_type));
767 
768 #ifdef SELDON_CHECK_IO
769  // Checks if data was read.
770  if (!FileStream.good())
771  throw IOError("Matrix_Symmetric::Read(ifstream& FileStream)",
772  string("Input operation failed.")
773  + string(" The input file may have been removed")
774  + " or may not contain enough data.");
775 #endif
776 
777  }
778 
779 
781 
785  template <class T, class Prop, class Storage, class Allocator>
787  {
788  ifstream FileStream;
789  FileStream.open(FileName.c_str());
790 
791 #ifdef SELDON_CHECK_IO
792  // Checks if the file was opened.
793  if (!FileStream.is_open())
794  throw IOError("Matrix_Pointers::ReadText(string FileName)",
795  string("Unable to open file \"") + FileName + "\".");
796 #endif
797 
798  this->ReadText(FileStream);
799 
800  FileStream.close();
801  }
802 
803 
805 
809  template <class T, class Prop, class Storage, class Allocator>
811  ::ReadText(istream& FileStream)
812  {
813  // clears previous matrix
814  Clear();
815 
816 #ifdef SELDON_CHECK_IO
817  // Checks if the stream is ready.
818  if (!FileStream.good())
819  throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
820  "Stream is not ready.");
821 #endif
822 
823  // we read first line
824  string line;
825  getline(FileStream, line);
826 
827  if (FileStream.fail())
828  {
829  // empty file ?
830  return;
831  }
832 
833  // converting first line into a vector
834  istringstream line_stream(line);
835  Vector<T> first_row;
836  first_row.ReadText(line_stream);
837 
838  // and now the other rows
839  Vector<T> other_rows;
840  other_rows.ReadText(FileStream);
841 
842  // number of rows and columns
843  int n = first_row.GetM();
844  int m = 1 + other_rows.GetM()/n;
845 
846 #ifdef SELDON_CHECK_IO
847  // Checking number of elements
848  if (other_rows.GetM() != (m-1)*n)
849  throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
850  "The file should contain same number of columns.");
851 #endif
852 
853  this->Reallocate(m,n);
854  // filling matrix
855  for (int j = 0; j < n; j++)
856  this->Val(0, j) = first_row(j);
857 
858  long nb = 0;
859  for (int i = 1; i < m; i++)
860  {
861  for (int j = 0; j < i; j++)
862  nb++;
863 
864  for (int j = i; j < n; j++)
865  this->Val(i, j) = other_rows(nb++);
866  }
867  }
868 
869 
870 } // namespace Seldon.
871 
872 #define SELDON_FILE_MATRIX_SYMMETRIC_CXX
873 #endif
Seldon::Matrix_Symmetric::Resize
void Resize(int i, int j)
Reallocates memory to resize the matrix and keeps previous entries.
Definition: Matrix_Symmetric.cxx:397
Seldon::Matrix_Symmetric::Read
void Read(string FileName)
Reads the matrix from a file.
Definition: Matrix_Symmetric.cxx:722
Seldon::Matrix_Symmetric::ReadText
void ReadText(string FileName)
Reads the matrix from a file.
Definition: Matrix_Symmetric.cxx:786
Seldon::Matrix_Base
Base class for all matrices.
Definition: Matrix_Base.hxx:143
Seldon::Matrix_Symmetric::operator=
Matrix_Symmetric< T, Prop, Storage, Allocator > & operator=(const Matrix_Symmetric< T, Prop, Storage, Allocator > &A)
Duplicates a matrix (assignment operator).
Definition: Matrix_SymmetricInline.cxx:278
Seldon::Matrix_Symmetric::SetData
void SetData(int i, int j, pointer data)
Changes the size of the matrix and sets its data array (low level method).
Definition: Matrix_Symmetric.cxx:300
Seldon::Matrix_Symmetric::Print
void Print() const
Displays the matrix on the standard output.
Definition: Matrix_Symmetric.cxx:518
Seldon::to_str
std::string to_str(const T &input)
Converts most types to string.
Definition: CommonInline.cxx:137
Seldon::Matrix_Symmetric::Reallocate
void Reallocate(int i, int j)
Reallocates memory to resize the matrix.
Definition: Matrix_Symmetric.cxx:195
Seldon::Vector
Definition: SeldonHeader.hxx:207
Seldon::Matrix_Symmetric::Nullify
void Nullify()
Clears the matrix without releasing memory.
Definition: Matrix_Symmetric.cxx:352
Seldon::Matrix_Symmetric::Fill
void Fill()
Fills the matrix with 0, 1, 2, ...
Definition: Matrix_Symmetric.cxx:459
Seldon::Matrix_Symmetric::Write
void Write(string FileName) const
Writes the matrix in a file.
Definition: Matrix_Symmetric.cxx:585
Seldon::Matrix_Symmetric::Matrix_Symmetric
Matrix_Symmetric()
Default constructor.
Definition: Matrix_SymmetricInline.cxx:39
Seldon::Matrix_Symmetric::FillRand
void FillRand()
Fills a matrix randomly.
Definition: Matrix_Symmetric.cxx:501
Seldon::Matrix_Symmetric
Symmetric matrix stored in a full matrix.
Definition: Matrix_Symmetric.hxx:38
Seldon::Matrix_Symmetric::Zero
void Zero()
Sets all elements to zero.
Definition: Matrix_Symmetric.cxx:431
Seldon::Matrix_Symmetric::Clear
void Clear()
Clears the matrix.
Definition: Matrix_Symmetric.cxx:133
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::IOError
Definition: Errors.hxx:150
Seldon::NoMemory
Definition: Errors.hxx:90
Seldon::Matrix_Symmetric::WriteText
void WriteText(string FileName) const
Writes the matrix in a file.
Definition: Matrix_Symmetric.cxx:653
Seldon::Matrix_Symmetric::SetIdentity
void SetIdentity()
Sets the matrix to the identity.
Definition: Matrix_Symmetric.cxx:440
Seldon::SetComplexReal
void SetComplexReal(int n, std::complex< T > &number)
Sets a complex number to (n, 0).
Definition: CommonInline.cxx:234