Matrix_Hermitian.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_HERMITIAN_CXX
22 
23 #include "Matrix_Hermitian.hxx"
24 
25 namespace Seldon
26 {
27 
28 
30 
35  template <class T, class Prop, class Storage, class Allocator>
37  ::Matrix_Hermitian(int i, int j):
38  Matrix_Base<T, Allocator>(i, i)
39  {
40 
41 #ifdef SELDON_CHECK_MEMORY
42  try
43  {
44 #endif
45 
46  me_ = reinterpret_cast<pointer*>(calloc(i, sizeof(pointer)));
47 
48 #ifdef SELDON_CHECK_MEMORY
49  }
50  catch (...)
51  {
52  this->m_ = 0;
53  this->n_ = 0;
54  me_ = NULL;
55  this->data_ = NULL;
56  }
57  if (me_ == NULL)
58  {
59  this->m_ = 0;
60  this->n_ = 0;
61  this->data_ = NULL;
62  }
63  if ((me_ == NULL) && (i != 0))
64  throw NoMemory("Matrix_Hermitian::Matrix_Hermitian(int, int)",
65  string("Unable to allocate memory for a matrix of size ")
66  + to_str(static_cast<long int>(i)
67  * static_cast<long int>(i)
68  * static_cast<long int>(sizeof(T)))
69  + " bytes (" + to_str(i) + " x " + to_str(i)
70  + " elements).");
71 #endif
72 
73 #ifdef SELDON_CHECK_MEMORY
74  try
75  {
76 #endif
77 
78  this->data_ = Allocator::allocate(long(i) * long(i), this);
79 
80 #ifdef SELDON_CHECK_MEMORY
81  }
82  catch (...)
83  {
84  this->m_ = 0;
85  this->n_ = 0;
86  free(me_);
87  me_ = NULL;
88  this->data_ = NULL;
89  }
90  if (this->data_ == NULL)
91  {
92  this->m_ = 0;
93  this->n_ = 0;
94  free(me_);
95  me_ = NULL;
96  }
97  if (this->data_ == NULL && i != 0)
98  throw NoMemory("Matrix_Hermitian::Matrix_Hermitian(int, int)",
99  string("Unable to allocate memory for a matrix of size ")
100  + to_str(static_cast<long int>(i)
101  * static_cast<long int>(i)
102  * static_cast<long int>(sizeof(T)))
103  + " bytes (" + to_str(i) + " x " + to_str(i)
104  + " elements).");
105 #endif
106 
107  pointer ptr = this->data_;
108  long lgth = i;
109  for (int k = 0; k < i; k++, ptr += lgth)
110  me_[k] = ptr;
111  }
112 
113 
115  template <class T, class Prop, class Storage, class Allocator>
118  Matrix_Base<T, Allocator>()
119  {
120  this->m_ = 0;
121  this->n_ = 0;
122  this->data_ = NULL;
123  this->me_ = NULL;
124 
125  this->Copy(A);
126  }
127 
128 
129  /*********************
130  * MEMORY MANAGEMENT *
131  *********************/
132 
133 
135 
142  template <class T, class Prop, class Storage, class Allocator>
144  ::Resize(int i, int j)
145  {
146 
147  // Storing the old values of the matrix.
148  int iold = Storage::GetFirst(this->m_, this->n_);
149  int jold = Storage::GetSecond(this->m_, this->n_);
150  Vector<value_type, VectFull, Allocator> xold(this->GetDataSize());
151  for (long k = 0; k < this->GetDataSize(); k++)
152  xold(k) = this->data_[k];
153 
154  // Reallocation.
155  int inew = Storage::GetFirst(i, j);
156  int jnew = Storage::GetSecond(i, j);
157  this->Reallocate(i, j);
158 
159  // Filling the matrix with its old values.
160  int imin = min(iold, inew), jmin = min(jold, jnew);
161  for (int k = 0; k < imin; k++)
162  for (int l = 0; l < jmin; l++)
163  this->data_[long(k)*jnew+l] = xold(long(l)+long(jold)*k);
164  }
165 
166 
168 
172  template <class T, class Prop, class Storage, class Allocator>
174  {
175 #ifdef SELDON_CHECK_MEMORY
176  try
177  {
178 #endif
179 
180  if (this->data_ != NULL)
181  {
182  Allocator::deallocate(this->data_, long(this->m_) * this->n_);
183  this->data_ = NULL;
184  }
185 
186 #ifdef SELDON_CHECK_MEMORY
187  }
188  catch (...)
189  {
190  this->data_ = NULL;
191  }
192 #endif
193 
194 #ifdef SELDON_CHECK_MEMORY
195  try
196  {
197 #endif
198 
199  if (me_ != NULL)
200  {
201  free(me_);
202  me_ = NULL;
203  }
204 
205 #ifdef SELDON_CHECK_MEMORY
206  }
207  catch (...)
208  {
209  this->m_ = 0;
210  this->n_ = 0;
211  me_ = NULL;
212  }
213 #endif
214 
215  this->m_ = 0;
216  this->n_ = 0;
217  }
218 
219 
221 
227  template <class T, class Prop, class Storage, class Allocator>
229  ::Reallocate(int i, int j)
230  {
231 
232  if (i != this->m_)
233  {
234  this->m_ = i;
235  this->n_ = i;
236 
237 #ifdef SELDON_CHECK_MEMORY
238  try
239  {
240 #endif
241 
242  me_ = reinterpret_cast<pointer*>( realloc(me_,
243  i * sizeof(pointer)) );
244 
245 #ifdef SELDON_CHECK_MEMORY
246  }
247  catch (...)
248  {
249  this->m_ = 0;
250  this->n_ = 0;
251  me_ = NULL;
252  this->data_ = NULL;
253  }
254  if (me_ == NULL)
255  {
256  this->m_ = 0;
257  this->n_ = 0;
258  this->data_ = NULL;
259  }
260  if (me_ == NULL && i != 0)
261  throw NoMemory("Matrix_Hermitian::Reallocate(int, int)",
262  string("Unable to reallocate memory")
263  + " for a matrix of size "
264  + to_str(static_cast<long int>(i)
265  * static_cast<long int>(i)
266  * static_cast<long int>(sizeof(T)))
267  + " bytes (" + to_str(i) + " x " + to_str(i)
268  + " elements).");
269 #endif
270 
271 #ifdef SELDON_CHECK_MEMORY
272  try
273  {
274 #endif
275 
276  this->data_ =
277  reinterpret_cast<pointer>(Allocator::reallocate(this->data_,
278  long(i) * i, this));
279 
280 #ifdef SELDON_CHECK_MEMORY
281  }
282  catch (...)
283  {
284  this->m_ = 0;
285  this->n_ = 0;
286  free(me_);
287  me_ = NULL;
288  this->data_ = NULL;
289  }
290  if (this->data_ == NULL)
291  {
292  this->m_ = 0;
293  this->n_ = 0;
294  free(me_);
295  me_ = NULL;
296  }
297  if (this->data_ == NULL && i != 0)
298  throw NoMemory("Matrix_Hermitian::Reallocate(int, int)",
299  string("Unable to reallocate memory")
300  + " for a matrix of size "
301  + to_str(static_cast<long int>(i)
302  * static_cast<long int>(i)
303  * static_cast<long int>(sizeof(T)))
304  + " bytes (" + to_str(i) + " x " + to_str(i)
305  + " elements).");
306 #endif
307 
308  pointer ptr = this->data_;
309  long lgth = Storage::GetSecond(i, i);
310  for (int k = 0; k < Storage::GetFirst(i, i); k++, ptr += lgth)
311  me_[k] = ptr;
312  }
313  }
314 
315 
318 
332  template <class T, class Prop, class Storage, class Allocator>
334  ::SetData(int i, int j,
336  ::pointer data)
337  {
338  this->Clear();
339 
340  this->m_ = i;
341  this->n_ = i;
342 
343 #ifdef SELDON_CHECK_MEMORY
344  try
345  {
346 #endif
347 
348  me_ = reinterpret_cast<pointer*>(calloc(i, sizeof(pointer)));
349 
350 #ifdef SELDON_CHECK_MEMORY
351  }
352  catch (...)
353  {
354  this->m_ = 0;
355  this->n_ = 0;
356  me_ = NULL;
357  this->data_ = NULL;
358  return;
359  }
360  if (me_ == NULL)
361  {
362  this->m_ = 0;
363  this->n_ = 0;
364  this->data_ = NULL;
365  return;
366  }
367 #endif
368 
369  this->data_ = data;
370 
371  pointer ptr = this->data_;
372  long lgth = i;
373  for (int k = 0; k < i; k++, ptr += lgth)
374  me_[k] = ptr;
375  }
376 
377 
379 
384  template <class T, class Prop, class Storage, class Allocator>
386  {
387  this->m_ = 0;
388  this->n_ = 0;
389 
390 #ifdef SELDON_CHECK_MEMORY
391  try
392  {
393 #endif
394 
395  if (me_ != NULL)
396  {
397  free(me_);
398  me_ = NULL;
399  }
400 
401 #ifdef SELDON_CHECK_MEMORY
402  }
403  catch (...)
404  {
405  this->m_ = 0;
406  this->n_ = 0;
407  me_ = NULL;
408  }
409 #endif
410 
411  this->data_ = NULL;
412  }
413 
414 
415  /************************
416  * CONVENIENT FUNCTIONS *
417  ************************/
418 
419 
421 
425  template <class T, class Prop, class Storage, class Allocator>
427  {
428  Allocator::memoryset(this->data_, char(0),
429  this->GetDataSize() * sizeof(value_type));
430  }
431 
432 
434 
438  template <class T, class Prop, class Storage, class Allocator>
440  {
441  T one, zero;
442  SetComplexZero(zero);
443  SetComplexOne(one);
444 
445  this->Fill(zero);
446 
447  for (int i = 0; i < min(this->m_, this->n_); i++)
448  this->Val(i, i) = one;
449  }
450 
451 
453 
457  template <class T, class Prop, class Storage, class Allocator>
459  {
460  for (long i = 0; i < this->GetDataSize(); i++)
461  SetComplexReal(i, this->data_[i]);
462  }
463 
464 
466 
471  template <class T, class Prop, class Storage, class Allocator>
472  template <class T0>
474  {
475  T x_;
476  SetComplexReal(x, x_);
477  for (long i = 0; i < this->GetDataSize(); i++)
478  this->data_[i] = x_;
479  }
480 
481 
483 
488  template <class T, class Prop, class Storage, class Allocator>
489  template <class T0>
492  {
493  this->Fill(x);
494 
495  return *this;
496  }
497 
498 
500 
503  template <class T, class Prop, class Storage, class Allocator>
505  {
506 #ifndef SELDON_WITHOUT_REINIT_RANDOM
507  srand(time(NULL));
508 #endif
509  for (long i = 0; i < this->GetDataSize(); i++)
510  SetComplexReal(rand(), this->data_[i]);
511  }
512 
513 
515 
520  template <class T, class Prop, class Storage, class Allocator>
522  {
523  for (int i = 0; i < this->m_; i++)
524  {
525  for (int j = 0; j < this->n_; j++)
526  cout << (*this)(i, j) << "\t";
527  cout << endl;
528  }
529  }
530 
531 
533 
544  template <class T, class Prop, class Storage, class Allocator>
546  ::Print(int a, int b, int m, int n) const
547  {
548  for (int i = a; i < min(this->m_, a+m); i++)
549  {
550  for (int j = b; j < min(this->n_, b+n); j++)
551  cout << (*this)(i, j) << "\t";
552  cout << endl;
553  }
554  }
555 
556 
558 
566  template <class T, class Prop, class Storage, class Allocator>
568  {
569  Print(0, 0, l, l);
570  }
571 
572 
573  /**************************
574  * INPUT/OUTPUT FUNCTIONS *
575  **************************/
576 
577 
579 
586  template <class T, class Prop, class Storage, class Allocator>
588  ::Write(string FileName) const
589  {
590  ofstream FileStream;
591  FileStream.open(FileName.c_str(), ofstream::binary);
592 
593 #ifdef SELDON_CHECK_IO
594  // Checks if the file was opened.
595  if (!FileStream.is_open())
596  throw IOError("Matrix_Hermitian::Write(string FileName)",
597  string("Unable to open file \"") + FileName + "\".");
598 #endif
599 
600  this->Write(FileStream);
601 
602  FileStream.close();
603  }
604 
605 
607 
614  template <class T, class Prop, class Storage, class Allocator>
616  ::Write(ostream& FileStream) const
617  {
618 
619 #ifdef SELDON_CHECK_IO
620  // Checks if the stream is ready.
621  if (!FileStream.good())
622  throw IOError("Matrix_Hermitian::Write(ofstream& FileStream)",
623  "Stream is not ready.");
624 #endif
625 
626  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
627  sizeof(int));
628  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
629  sizeof(int));
630 
631  FileStream.write(reinterpret_cast<char*>(this->data_),
632  long(this->m_) * long(this->n_) * sizeof(value_type));
633 
634 #ifdef SELDON_CHECK_IO
635  // Checks if data was written.
636  if (!FileStream.good())
637  throw IOError("Matrix_Hermitian::Write(ofstream& FileStream)",
638  string("Output operation failed.")
639  + string(" The output file may have been removed")
640  + " or there is no space left on device.");
641 #endif
642 
643  }
644 
645 
647 
654  template <class T, class Prop, class Storage, class Allocator>
656  ::WriteText(string FileName) const
657  {
658  ofstream FileStream;
659  FileStream.precision(cout.precision());
660  FileStream.flags(cout.flags());
661  FileStream.open(FileName.c_str());
662 
663 #ifdef SELDON_CHECK_IO
664  // Checks if the file was opened.
665  if (!FileStream.is_open())
666  throw IOError("Matrix_Hermitian::WriteText(string FileName)",
667  string("Unable to open file \"") + FileName + "\".");
668 #endif
669 
670  this->WriteText(FileStream);
671 
672  FileStream.close();
673  }
674 
675 
677 
684  template <class T, class Prop, class Storage, class Allocator>
686  ::WriteText(ostream& FileStream) const
687  {
688 
689 #ifdef SELDON_CHECK_IO
690  // Checks if the file is ready.
691  if (!FileStream.good())
692  throw IOError("Matrix_Hermitian::WriteText(ofstream& FileStream)",
693  "Stream is not ready.");
694 #endif
695 
696  int i, j;
697  for (i = 0; i < this->GetM(); i++)
698  {
699  for (j = 0; j < this->GetN(); j++)
700  FileStream << (*this)(i, j) << '\t';
701  FileStream << endl;
702  }
703 
704 #ifdef SELDON_CHECK_IO
705  // Checks if data was written.
706  if (!FileStream.good())
707  throw IOError("Matrix_Hermitian::WriteText(ofstream& FileStream)",
708  string("Output operation failed.")
709  + string(" The output file may have been removed")
710  + " or there is no space left on device.");
711 #endif
712 
713  }
714 
715 
717 
724  template <class T, class Prop, class Storage, class Allocator>
726  {
727  ifstream FileStream;
728  FileStream.open(FileName.c_str(), ifstream::binary);
729 
730 #ifdef SELDON_CHECK_IO
731  // Checks if the file was opened.
732  if (!FileStream.is_open())
733  throw IOError("Matrix_Hermitian::Read(string FileName)",
734  string("Unable to open file \"") + FileName + "\".");
735 #endif
736 
737  this->Read(FileStream);
738 
739  FileStream.close();
740  }
741 
742 
744 
751  template <class T, class Prop, class Storage, class Allocator>
753  ::Read(istream& FileStream)
754  {
755 
756 #ifdef SELDON_CHECK_IO
757  // Checks if the stream is ready.
758  if (!FileStream.good())
759  throw IOError("Matrix_Hermitian::Read(ifstream& FileStream)",
760  "Stream is not ready.");
761 #endif
762 
763  int new_m, new_n;
764  FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
765  FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
766  this->Reallocate(new_m, new_n);
767 
768  FileStream.read(reinterpret_cast<char*>(this->data_),
769  long(new_m) * long(new_n) * sizeof(value_type));
770 
771 #ifdef SELDON_CHECK_IO
772  // Checks if data was read.
773  if (!FileStream.good())
774  throw IOError("Matrix_Hermitian::Read(ifstream& FileStream)",
775  string("Input operation failed.")
776  + string(" The input file may have been removed")
777  + " or may not contain enough data.");
778 #endif
779 
780  }
781 
782 
784 
788  template <class T, class Prop, class Storage, class Allocator>
790  {
791  ifstream FileStream;
792  FileStream.open(FileName.c_str());
793 
794 #ifdef SELDON_CHECK_IO
795  // Checks if the file was opened.
796  if (!FileStream.is_open())
797  throw IOError("Matrix_Pointers::ReadText(string FileName)",
798  string("Unable to open file \"") + FileName + "\".");
799 #endif
800 
801  this->ReadText(FileStream);
802 
803  FileStream.close();
804  }
805 
806 
808 
812  template <class T, class Prop, class Storage, class Allocator>
814  ::ReadText(istream& FileStream)
815  {
816  // clears previous matrix
817  Clear();
818 
819 #ifdef SELDON_CHECK_IO
820  // Checks if the stream is ready.
821  if (!FileStream.good())
822  throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
823  "Stream is not ready.");
824 #endif
825 
826  // we read first line
827  string line;
828  getline(FileStream, line);
829 
830  if (FileStream.fail())
831  {
832  // empty file ?
833  return;
834  }
835 
836  // converting first line into a vector
837  istringstream line_stream(line);
838  Vector<T> first_row;
839  first_row.ReadText(line_stream);
840 
841  // and now the other rows
842  Vector<T> other_rows;
843  other_rows.ReadText(FileStream);
844 
845  // number of rows and columns
846  int n = first_row.GetM();
847  int m = 1 + other_rows.GetM()/n;
848 
849 #ifdef SELDON_CHECK_IO
850  // Checking number of elements
851  if (other_rows.GetM() != (m-1)*n)
852  throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
853  "The file should contain same number of columns.");
854 #endif
855 
856  this->Reallocate(m,n);
857  // filling matrix
858  for (int j = 0; j < n; j++)
859  this->Val(0, j) = first_row(j);
860 
861  long nb = 0;
862  for (int i = 1; i < m; i++)
863  {
864  for (int j = 0; j < i; j++)
865  nb++;
866 
867  for (int j = i; j < n; j++)
868  this->Val(i, j) = other_rows(nb++);
869  }
870  }
871 
872 
873 } // namespace Seldon.
874 
875 #define SELDON_FILE_MATRIX_HERMITIAN_CXX
876 #endif
Seldon::Matrix_Hermitian::WriteText
void WriteText(string FileName) const
Writes the matrix in a file.
Definition: Matrix_Hermitian.cxx:656
Seldon::Matrix_Hermitian::Nullify
void Nullify()
Clears the matrix without releasing memory.
Definition: Matrix_Hermitian.cxx:385
Seldon::Matrix_Hermitian::ReadText
void ReadText(string FileName)
Reads the matrix from a file.
Definition: Matrix_Hermitian.cxx:789
Seldon::Matrix_Base
Base class for all matrices.
Definition: Matrix_Base.hxx:143
Seldon::Matrix_Hermitian::operator=
Matrix_Hermitian< T, Prop, Storage, Allocator > & operator=(const Matrix_Hermitian< T, Prop, Storage, Allocator > &A)
Duplicates a matrix (assignement operator).
Definition: Matrix_HermitianInline.cxx:266
Seldon::to_str
std::string to_str(const T &input)
Converts most types to string.
Definition: CommonInline.cxx:137
Seldon::Vector
Definition: SeldonHeader.hxx:207
Seldon::Matrix_Hermitian::Reallocate
void Reallocate(int i, int j)
Reallocates memory to resize the matrix.
Definition: Matrix_Hermitian.cxx:229
Seldon::Matrix_Hermitian
Hermitian matrix stored in a full matrix.
Definition: Matrix_Hermitian.hxx:38
Seldon::Matrix_Hermitian::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_Hermitian.cxx:334
Seldon::Matrix_Hermitian::Read
void Read(string FileName)
Reads the matrix from a file.
Definition: Matrix_Hermitian.cxx:725
Seldon::Matrix_Hermitian::Clear
void Clear()
Clears the matrix.
Definition: Matrix_Hermitian.cxx:173
Seldon::Matrix_Hermitian::FillRand
void FillRand()
Fills the matrix randomly.
Definition: Matrix_Hermitian.cxx:504
Seldon::Matrix_Hermitian::Zero
void Zero()
Sets all elements to zero.
Definition: Matrix_Hermitian.cxx:426
Seldon::Matrix_Hermitian::Write
void Write(string FileName) const
Writes the matrix in a file.
Definition: Matrix_Hermitian.cxx:588
Seldon::Matrix_Hermitian::Print
void Print() const
Displays the matrix on the standard output.
Definition: Matrix_Hermitian.cxx:521
Seldon::Matrix_Hermitian::Fill
void Fill()
Fills the matrix with 0, 1, 2, ...
Definition: Matrix_Hermitian.cxx:458
Seldon::Matrix_Hermitian::SetIdentity
void SetIdentity()
Sets the matrix to the identity.
Definition: Matrix_Hermitian.cxx:439
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::IOError
Definition: Errors.hxx:150
Seldon::NoMemory
Definition: Errors.hxx:90
Seldon::Matrix_Hermitian::Resize
void Resize(int i, int j)
Reallocates memory to resize the matrix and keeps previous entries.
Definition: Matrix_Hermitian.cxx:144
Seldon::SetComplexReal
void SetComplexReal(int n, std::complex< T > &number)
Sets a complex number to (n, 0).
Definition: CommonInline.cxx:234
Seldon::Matrix_Hermitian::Matrix_Hermitian
Matrix_Hermitian()
Default constructor.
Definition: Matrix_HermitianInline.cxx:39