Matrix_Triangular.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_TRIANGULAR_CXX
22 
23 #include "Matrix_Triangular.hxx"
24 
25 namespace Seldon
26 {
27 
28 
30 
35  template <class T, class Prop, class Storage, class Allocator>
37  ::Matrix_Triangular(int i, int j): Matrix_Base<T, Allocator>(i, i)
38  {
39 
40 #ifdef SELDON_CHECK_MEMORY
41  try
42  {
43 #endif
44 
45  me_ = reinterpret_cast<pointer*>( calloc(i, sizeof(pointer)) );
46 
47 #ifdef SELDON_CHECK_MEMORY
48  }
49  catch (...)
50  {
51  this->m_ = 0;
52  this->n_ = 0;
53  me_ = NULL;
54  this->data_ = NULL;
55  }
56  if (me_ == NULL)
57  {
58  this->m_ = 0;
59  this->n_ = 0;
60  this->data_ = NULL;
61  }
62  if (me_ == NULL && i != 0)
63  throw NoMemory("Matrix_Triangular::Matrix_Triangular(int, int)",
64  string("Unable to allocate memory for a matrix of size ")
65  + to_str(static_cast<long int>(i)
66  * static_cast<long int>(i)
67  * static_cast<long int>(sizeof(T)))
68  + " bytes (" + to_str(i) + " x " + to_str(i)
69  + " elements).");
70 #endif
71 
72 #ifdef SELDON_CHECK_MEMORY
73  try
74  {
75 #endif
76 
77  this->data_ = Allocator::allocate(long(i) * long(i), this);
78 
79 #ifdef SELDON_CHECK_MEMORY
80  }
81  catch (...)
82  {
83  this->m_ = 0;
84  this->n_ = 0;
85  free(me_);
86  me_ = NULL;
87  this->data_ = NULL;
88  }
89  if (this->data_ == NULL)
90  {
91  this->m_ = 0;
92  this->n_ = 0;
93  free(me_);
94  me_ = NULL;
95  }
96  if (this->data_ == NULL && i != 0)
97  throw NoMemory("Matrix_Triangular::Matrix_Triangular(int, int)",
98  string("Unable to allocate memory for a matrix of size ")
99  + to_str(static_cast<long int>(i)
100  * static_cast<long int>(i)
101  * static_cast<long int>(sizeof(T)))
102  + " bytes (" + to_str(i) + " x " + to_str(i)
103  + " elements).");
104 #endif
105 
106  pointer ptr = this->data_;
107  long lgth = i;
108  for (int k = 0; k < i; k++, ptr += lgth)
109  me_[k] = ptr;
110  }
111 
112 
114  template <class T, class Prop, class Storage, class Allocator>
117  Storage, Allocator>& A)
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 
130 
134  template <class T, class Prop, class Storage, class Allocator>
136  {
137 #ifdef SELDON_CHECK_MEMORY
138  try
139  {
140 #endif
141 
142  if (this->data_ != NULL)
143  {
144  Allocator::deallocate(this->data_, long(this->m_) * long(this->n_));
145  this->data_ = NULL;
146  }
147 
148 #ifdef SELDON_CHECK_MEMORY
149  }
150  catch (...)
151  {
152  this->data_ = NULL;
153  }
154 #endif
155 
156 #ifdef SELDON_CHECK_MEMORY
157  try
158  {
159 #endif
160 
161  if (me_ != NULL)
162  {
163  free(me_);
164  me_ = NULL;
165  }
166 
167 #ifdef SELDON_CHECK_MEMORY
168  }
169  catch (...)
170  {
171  this->m_ = 0;
172  this->n_ = 0;
173  me_ = NULL;
174  }
175 #endif
176 
177  this->m_ = 0;
178  this->n_ = 0;
179  }
180 
181 
182  /*********************
183  * MEMORY MANAGEMENT *
184  *********************/
185 
186 
188 
194  template <class T, class Prop, class Storage, class Allocator>
196  ::Reallocate(int i, int j)
197  {
198 
199  if (i != this->m_)
200  {
201  this->m_ = i;
202  this->n_ = i;
203 
204 #ifdef SELDON_CHECK_MEMORY
205  try
206  {
207 #endif
208 
209  me_ = reinterpret_cast<pointer*>( realloc(me_,
210  i * sizeof(pointer)) );
211 
212 #ifdef SELDON_CHECK_MEMORY
213  }
214  catch (...)
215  {
216  this->m_ = 0;
217  this->n_ = 0;
218  me_ = NULL;
219  this->data_ = NULL;
220  }
221  if (me_ == NULL)
222  {
223  this->m_ = 0;
224  this->n_ = 0;
225  this->data_ = NULL;
226  }
227  if (me_ == NULL && i != 0)
228  throw NoMemory("Matrix_Triangular::Reallocate(int, int)",
229  string("Unable to reallocate memory")
230  + " for a matrix of size "
231  + to_str(static_cast<long int>(i)
232  * static_cast<long int>(i)
233  * static_cast<long int>(sizeof(T)))
234  + " bytes (" + to_str(i) + " x " + to_str(i)
235  + " elements).");
236 #endif
237 
238 #ifdef SELDON_CHECK_MEMORY
239  try
240  {
241 #endif
242 
243  this->data_ =
244  reinterpret_cast<pointer>(Allocator::reallocate(this->data_,
245  long(i)*long(i), this) );
246 
247 #ifdef SELDON_CHECK_MEMORY
248  }
249  catch (...)
250  {
251  this->m_ = 0;
252  this->n_ = 0;
253  free(me_);
254  me_ = NULL;
255  this->data_ = NULL;
256  }
257  if (this->data_ == NULL)
258  {
259  this->m_ = 0;
260  this->n_ = 0;
261  free(me_);
262  me_ = NULL;
263  }
264  if (this->data_ == NULL && i != 0)
265  throw NoMemory("Matrix_Triangular::Reallocate(int, int)",
266  string("Unable to reallocate memory")
267  + " for a matrix of size "
268  + to_str(static_cast<long int>(i)
269  * static_cast<long int>(i)
270  * static_cast<long int>(sizeof(T)))
271  + " bytes (" + to_str(i) + " x " + to_str(i)
272  + " elements).");
273 #endif
274 
275  pointer ptr = this->data_;
276  long lgth = Storage::GetSecond(i, i);
277  for (int k = 0; k < Storage::GetFirst(i, i); k++, ptr += lgth)
278  me_[k] = ptr;
279  }
280  }
281 
282 
285 
299  template <class T, class Prop, class Storage, class Allocator>
301  ::SetData(int i, int j,
303  ::pointer data)
304  {
305 
306  this->Clear();
307 
308  this->m_ = i;
309  this->n_ = i;
310 
311 #ifdef SELDON_CHECK_MEMORY
312  try
313  {
314 #endif
315 
316  me_ = reinterpret_cast<pointer*>( calloc(i, sizeof(pointer)) );
317 
318 #ifdef SELDON_CHECK_MEMORY
319  }
320  catch (...)
321  {
322  this->m_ = 0;
323  this->n_ = 0;
324  me_ = NULL;
325  this->data_ = NULL;
326  return;
327  }
328  if (me_ == NULL)
329  {
330  this->m_ = 0;
331  this->n_ = 0;
332  this->data_ = NULL;
333  return;
334  }
335 #endif
336 
337  this->data_ = data;
338 
339  pointer ptr = this->data_;
340  long lgth = i;
341  for (int k = 0; k < i; k++, ptr += lgth)
342  me_[k] = ptr;
343  }
344 
345 
347 
352  template <class T, class Prop, class Storage, class Allocator>
354  {
355  this->m_ = 0;
356  this->n_ = 0;
357 
358 #ifdef SELDON_CHECK_MEMORY
359  try
360  {
361 #endif
362 
363  if (me_ != NULL)
364  {
365  free(me_);
366  me_ = NULL;
367  }
368 
369 #ifdef SELDON_CHECK_MEMORY
370  }
371  catch (...)
372  {
373  this->m_ = 0;
374  this->n_ = 0;
375  me_ = NULL;
376  }
377 #endif
378 
379  this->data_ = NULL;
380  }
381 
382 
384 
391  template <class T, class Prop, class Storage, class Allocator>
393  ::Resize(int i, int j)
394  {
395 
396  if (i != this->m_)
397  {
398  // Storing the previous values of the matrix.
399  int iold = this->m_;
400  Vector<value_type, VectFull, Allocator> xold(this->GetDataSize());
401  for (long k = 0; k < this->GetDataSize(); k++)
402  xold(k) = this->data_[k];
403 
404  // Reallocation.
405  this->Reallocate(i, i);
406 
407  // Filling the matrix with its previous values.
408  int imin = min(iold, i);
409  for (int k = 0; k < imin; k++)
410  for (int l = 0; l < imin; l++)
411  this->data_[k*i + l] = xold(k*iold + l);
412  }
413  }
414 
415 
416  /************************
417  * CONVENIENT FUNCTIONS *
418  ************************/
419 
420 
422 
426  template <class T, class Prop, class Storage, class Allocator>
428  {
429  Allocator::memoryset(this->data_, char(0),
430  this->GetDataSize() * sizeof(value_type));
431  }
432 
433 
435  template <class T, class Prop, class Storage, class Allocator>
437  {
438  T zero, one;
439  SetComplexZero(zero);
440  SetComplexOne(one);
441 
442  this->Fill(zero);
443 
444  for (int i = 0; i < min(this->m_, this->n_); i++)
445  this->Val(i, i) = one;
446  }
447 
448 
450 
454  template <class T, class Prop, class Storage, class Allocator>
456  {
457  for (long i = 0; i < this->GetDataSize(); i++)
458  SetComplexReal(i, this->data_[i]);
459  }
460 
461 
463 
467  template <class T, class Prop, class Storage, class Allocator>
468  template <class T0>
470  {
471  T x_;
472  SetComplexReal(x, x_);
473  for (long i = 0; i < this->GetDataSize(); i++)
474  this->data_[i] = x_;
475  }
476 
477 
479 
483  template <class T, class Prop, class Storage, class Allocator>
484  template <class T0>
487  {
488  this->Fill(x);
489 
490  return *this;
491  }
492 
493 
495 
498  template <class T, class Prop, class Storage, class Allocator>
500  {
501 #ifndef SELDON_WITHOUT_REINIT_RANDOM
502  srand(time(NULL));
503 #endif
504  for (long i = 0; i < this->GetDataSize(); i++)
505  SetComplexReal(rand(), this->data_[i]);
506  }
507 
508 
510 
515  template <class T, class Prop, class Storage, class Allocator>
517  {
518  for (int i = 0; i < this->m_; i++)
519  {
520  for (int j = 0; j < this->n_; j++)
521  cout << (*this)(i, j) << "\t";
522  cout << endl;
523  }
524  }
525 
526 
528 
539  template <class T, class Prop, class Storage, class Allocator>
541  ::Print(int a, int b, int m, int n) const
542  {
543  for (int i = a; i < min(this->m_, a + m); i++)
544  {
545  for (int j = b; j < min(this->n_, b + n); j++)
546  cout << (*this)(i, j) << "\t";
547  cout << endl;
548  }
549  }
550 
551 
553 
561  template <class T, class Prop, class Storage, class Allocator>
563  {
564  Print(0, 0, l, l);
565  }
566 
567 
568  /**************************
569  * INPUT/OUTPUT FUNCTIONS *
570  **************************/
571 
572 
574 
581  template <class T, class Prop, class Storage, class Allocator>
583  ::Write(string FileName) const
584  {
585  ofstream FileStream;
586  FileStream.open(FileName.c_str(), ofstream::binary);
587 
588 #ifdef SELDON_CHECK_IO
589  // Checks if the file was opened.
590  if (!FileStream.is_open())
591  throw IOError("Matrix_Triangular::Write(string FileName)",
592  string("Unable to open file \"") + FileName + "\".");
593 #endif
594 
595  this->Write(FileStream);
596 
597  FileStream.close();
598  }
599 
600 
602 
609  template <class T, class Prop, class Storage, class Allocator>
611  ::Write(ostream& FileStream) const
612  {
613 
614 #ifdef SELDON_CHECK_IO
615  // Checks if the stream is ready.
616  if (!FileStream.good())
617  throw IOError("Matrix_Triangular::Write(ofstream& FileStream)",
618  "Stream is not ready.");
619 #endif
620 
621  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
622  sizeof(int));
623  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
624  sizeof(int));
625 
626  FileStream.write(reinterpret_cast<char*>(this->data_),
627  this->m_ * this->n_ * sizeof(value_type));
628 
629 #ifdef SELDON_CHECK_IO
630  // Checks if data was written.
631  if (!FileStream.good())
632  throw IOError("Matrix_Triangular::Write(ofstream& FileStream)",
633  string("Output operation failed.")
634  + string(" The output file may have been removed")
635  + " or there is no space left on device.");
636 #endif
637 
638  }
639 
640 
642 
649  template <class T, class Prop, class Storage, class Allocator>
651  ::WriteText(string FileName) const
652  {
653  ofstream FileStream;
654  FileStream.precision(cout.precision());
655  FileStream.flags(cout.flags());
656  FileStream.open(FileName.c_str());
657 
658 #ifdef SELDON_CHECK_IO
659  // Checks if the file was opened.
660  if (!FileStream.is_open())
661  throw IOError("Matrix_Triangular::WriteText(string FileName)",
662  string("Unable to open file \"") + FileName + "\".");
663 #endif
664 
665  this->WriteText(FileStream);
666 
667  FileStream.close();
668  }
669 
670 
672 
679  template <class T, class Prop, class Storage, class Allocator>
681  ::WriteText(ostream& FileStream) const
682  {
683 
684 #ifdef SELDON_CHECK_IO
685  // Checks if the file is ready.
686  if (!FileStream.good())
687  throw IOError("Matrix_Triangular::WriteText(ofstream& FileStream)",
688  "Stream is not ready.");
689 #endif
690 
691  int i, j;
692  for (i = 0; i < this->GetM(); i++)
693  {
694  for (j = 0; j < this->GetN(); j++)
695  FileStream << (*this)(i, j) << '\t';
696  FileStream << endl;
697  }
698 
699 #ifdef SELDON_CHECK_IO
700  // Checks if data was written.
701  if (!FileStream.good())
702  throw IOError("Matrix_Triangular::WriteText(ofstream& FileStream)",
703  string("Output operation failed.")
704  + string(" The output file may have been removed")
705  + " or there is no space left on device.");
706 #endif
707 
708  }
709 
710 
712 
719  template <class T, class Prop, class Storage, class Allocator>
721  {
722  ifstream FileStream;
723  FileStream.open(FileName.c_str(), ifstream::binary);
724 
725 #ifdef SELDON_CHECK_IO
726  // Checks if the file was opened.
727  if (!FileStream.is_open())
728  throw IOError("Matrix_Triangular::Read(string FileName)",
729  string("Unable to open file \"") + FileName + "\".");
730 #endif
731 
732  this->Read(FileStream);
733 
734  FileStream.close();
735  }
736 
737 
739 
746  template <class T, class Prop, class Storage, class Allocator>
748  ::Read(istream& FileStream)
749  {
750 
751 #ifdef SELDON_CHECK_IO
752  // Checks if the stream is ready.
753  if (!FileStream.good())
754  throw IOError("Matrix_Triangular::Read(ifstream& FileStream)",
755  "Stream is not ready.");
756 #endif
757 
758  int new_m, new_n;
759  FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
760  FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
761  this->Reallocate(new_m, new_n);
762 
763  FileStream.read(reinterpret_cast<char*>(this->data_),
764  long(new_m) * long(new_n) * sizeof(value_type));
765 
766 #ifdef SELDON_CHECK_IO
767  // Checks if data was read.
768  if (!FileStream.good())
769  throw IOError("Matrix_Triangular::Read(ifstream& FileStream)",
770  string("Input operation failed.")
771  + string(" The input file may have been removed")
772  + " or may not contain enough data.");
773 #endif
774 
775  }
776 
777 
779 
783  template <class T, class Prop, class Storage, class Allocator>
785  {
786  ifstream FileStream;
787  FileStream.open(FileName.c_str());
788 
789 #ifdef SELDON_CHECK_IO
790  // Checks if the file was opened.
791  if (!FileStream.is_open())
792  throw IOError("Matrix_Pointers::ReadText(string FileName)",
793  string("Unable to open file \"") + FileName + "\".");
794 #endif
795 
796  this->ReadText(FileStream);
797 
798  FileStream.close();
799  }
800 
801 
803 
807  template <class T, class Prop, class Storage, class Allocator>
809  ::ReadText(istream& FileStream)
810  {
811  // clears previous matrix
812  Clear();
813 
814 #ifdef SELDON_CHECK_IO
815  // Checks if the stream is ready.
816  if (!FileStream.good())
817  throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
818  "Stream is not ready.");
819 #endif
820 
821  // we read first line
822  string line;
823  getline(FileStream, line);
824 
825  if (FileStream.fail())
826  {
827  // empty file ?
828  return;
829  }
830 
831  // converting first line into a vector
832  istringstream line_stream(line);
833  Vector<T> first_row;
834  first_row.ReadText(line_stream);
835 
836  // and now the other rows
837  Vector<T> other_rows;
838  other_rows.ReadText(FileStream);
839 
840  // number of rows and columns
841  int n = first_row.GetM();
842  int m = 1 + other_rows.GetM()/n;
843 
844 #ifdef SELDON_CHECK_IO
845  // Checking number of elements
846  if (other_rows.GetM() != (m-1)*n)
847  throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
848  "The file should contain same number of columns.");
849 #endif
850 
851  this->Reallocate(m,n);
852  // filling matrix
853  if (Storage::UpLo())
854  for (int j = 0; j < n; j++)
855  this->Val(0, j) = first_row(j);
856  else
857  this->Val(0, 0) = first_row(0);
858 
859  long nb = 0;
860  if (Storage::UpLo())
861  for (int i = 1; i < m; i++)
862  {
863  for (int j = 0; j < i; j++)
864  nb++;
865 
866  for (int j = i; j < n; j++)
867  this->Val(i, j) = other_rows(nb++);
868  }
869  else
870  for (int i = 1; i < m; i++)
871  {
872  for (int j = 0; j <= i; j++)
873  this->Val(i, j) = other_rows(nb++);
874 
875  for (int j = i+1; j < n; j++)
876  nb++;
877  }
878  }
879 
880 
881 } // namespace Seldon.
882 
883 #define SELDON_FILE_MATRIX_TRIANGULAR_CXX
884 #endif
Seldon::Matrix_Triangular::Nullify
void Nullify()
Clears the matrix without releasing memory.
Definition: Matrix_Triangular.cxx:353
Seldon::Matrix_Base
Base class for all matrices.
Definition: Matrix_Base.hxx:143
Seldon::Matrix_Triangular::Read
void Read(string FileName)
Reads the matrix from a file.
Definition: Matrix_Triangular.cxx:720
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_Triangular::Matrix_Triangular
Matrix_Triangular()
Default constructor.
Definition: Matrix_TriangularInline.cxx:39
Seldon::Matrix_Triangular::ReadText
void ReadText(string FileName)
Reads the matrix from a file.
Definition: Matrix_Triangular.cxx:784
Seldon::Matrix_Triangular::Write
void Write(string FileName) const
Writes the matrix in a file.
Definition: Matrix_Triangular.cxx:583
Seldon::Matrix_Triangular::WriteText
void WriteText(string FileName) const
Writes the matrix in a file.
Definition: Matrix_Triangular.cxx:651
Seldon::Matrix_Triangular::Clear
void Clear()
Clears the matrix.
Definition: Matrix_Triangular.cxx:135
Seldon::Matrix_Triangular::Print
void Print() const
Displays the matrix on the standard output.
Definition: Matrix_Triangular.cxx:516
Seldon::Matrix_Triangular::Zero
void Zero()
Sets all elements to zero.
Definition: Matrix_Triangular.cxx:427
Seldon::Matrix_Triangular::Resize
void Resize(int i, int j)
Reallocates memory to resize the matrix and keeps previous entries.
Definition: Matrix_Triangular.cxx:393
Seldon::Matrix_Triangular::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_Triangular.cxx:301
Seldon::Matrix_Triangular::Fill
void Fill()
Fills the matrix with 0, 1, 2, ...
Definition: Matrix_Triangular.cxx:455
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::IOError
Definition: Errors.hxx:150
Seldon::Matrix_Triangular::operator=
Matrix_Triangular< T, Prop, Storage, Allocator > & operator=(const Matrix_Triangular< T, Prop, Storage, Allocator > &A)
Duplicates a matrix (assignment operator).
Definition: Matrix_TriangularInline.cxx:259
Seldon::NoMemory
Definition: Errors.hxx:90
Seldon::Matrix_Triangular::SetIdentity
void SetIdentity()
Sets the matrix to the identity.
Definition: Matrix_Triangular.cxx:436
Seldon::SetComplexReal
void SetComplexReal(int n, std::complex< T > &number)
Sets a complex number to (n, 0).
Definition: CommonInline.cxx:234
Seldon::Matrix_Triangular::Reallocate
void Reallocate(int i, int j)
Reallocates memory to resize the matrix.
Definition: Matrix_Triangular.cxx:196
Seldon::Matrix_Triangular::FillRand
void FillRand()
Fills the matrix randomly.
Definition: Matrix_Triangular.cxx:499
Seldon::Matrix_Triangular
Triangular matrix stored in a full matrix.
Definition: Matrix_Triangular.hxx:38