Matrix_SymPacked.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_SYMPACKED_CXX
22 
23 #include "Matrix_SymPacked.hxx"
24 
25 namespace Seldon
26 {
27 
28 
30 
35  template <class T, class Prop, class Storage, class Allocator>
37  ::Matrix_SymPacked(int i, int j): Matrix_Base<T, Allocator>(i, i)
38  {
39 
40 #ifdef SELDON_CHECK_MEMORY
41  try
42  {
43 #endif
44 
45  this->data_ = Allocator::allocate((i * (i + 1)) / 2, this);
46 
47 #ifdef SELDON_CHECK_MEMORY
48  }
49  catch (...)
50  {
51  this->m_ = 0;
52  this->n_ = 0;
53  this->data_ = NULL;
54  return;
55  }
56  if (this->data_ == NULL)
57  {
58  this->m_ = 0;
59  this->n_ = 0;
60  return;
61  }
62 #endif
63 
64  }
65 
66 
68  template <class T, class Prop, class Storage, class Allocator>
71  : Matrix_Base<T, Allocator>()
72  {
73  this->m_ = 0;
74  this->n_ = 0;
75  this->data_ = NULL;
76 
77  this->Copy(A);
78  }
79 
80 
82 
86  template <class T, class Prop, class Storage, class Allocator>
88  {
89 #ifdef SELDON_CHECK_MEMORY
90  try
91  {
92 #endif
93 
94  if (this->data_ != NULL)
95  {
96  Allocator::deallocate(this->data_,
97  (this->m_ * (this->m_ + 1)) / 2);
98  this->data_ = NULL;
99  }
100 
101 #ifdef SELDON_CHECK_MEMORY
102  }
103  catch (...)
104  {
105  this->m_ = 0;
106  this->n_ = 0;
107  this->data_ = NULL;
108  }
109 #endif
110 
111  this->m_ = 0;
112  this->n_ = 0;
113  }
114 
115 
116  /*********************
117  * MEMORY MANAGEMENT *
118  *********************/
119 
120 
122 
128  template <class T, class Prop, class Storage, class Allocator>
130  int j)
131  {
132 
133  if (i != this->m_)
134  {
135  this->m_ = i;
136  this->n_ = i;
137 
138 #ifdef SELDON_CHECK_MEMORY
139  try
140  {
141 #endif
142 
143  this->data_ =
144  reinterpret_cast<pointer>(Allocator::
145  reallocate(this->data_,
146  (i * (i + 1)) / 2, this));
147 
148 #ifdef SELDON_CHECK_MEMORY
149  }
150  catch (...)
151  {
152  this->m_ = 0;
153  this->n_ = 0;
154  this->data_ = NULL;
155  throw NoMemory("Matrix_SymPacked::Reallocate(int, int)",
156  "Unable to reallocate memory for data_.");
157  }
158  if (this->data_ == NULL)
159  {
160  this->m_ = 0;
161  this->n_ = 0;
162  throw NoMemory("Matrix_SymPacked::Reallocate(int, int)",
163  "Unable to reallocate memory for data_.");
164  }
165 #endif
166 
167  }
168  }
169 
170 
173 
187  template <class T, class Prop, class Storage, class Allocator>
189  ::SetData(int i, int j,
191  ::pointer data)
192  {
193  this->Clear();
194 
195  this->m_ = i;
196  this->n_ = i;
197 
198  this->data_ = data;
199  }
200 
201 
203 
207  template <class T, class Prop, class Storage, class Allocator>
209  {
210  this->data_ = NULL;
211  this->m_ = 0;
212  this->n_ = 0;
213  }
214 
215 
216  /************************
217  * CONVENIENT FUNCTIONS *
218  ************************/
219 
220 
222 
226  template <class T, class Prop, class Storage, class Allocator>
228  {
229  Allocator::memoryset(this->data_, char(0),
230  this->GetDataSize() * sizeof(value_type));
231  }
232 
233 
235  template <class T, class Prop, class Storage, class Allocator>
237  {
238  T one, zero;
239  SetComplexOne(one);
240  SetComplexZero(zero);
241 
242  this->Fill(zero);
243 
244  for (int i = 0; i < min(this->m_, this->n_); i++)
245  (*this)(i, i) = one;
246  }
247 
248 
250 
254  template <class T, class Prop, class Storage, class Allocator>
256  {
257  for (int i = 0; i < this->GetDataSize(); i++)
258  SetComplexReal(i, this->data_[i]);
259  }
260 
261 
263 
266  template <class T, class Prop, class Storage, class Allocator>
267  template <class T0>
269  {
270  T x_;
271  SetComplexReal(x, x_);
272  for (int i = 0; i < this->GetDataSize(); i++)
273  this->data_[i] = x_;
274  }
275 
276 
278 
281  template <class T, class Prop, class Storage, class Allocator>
282  template <class T0>
285  {
286  this->Fill(x);
287 
288  return *this;
289  }
290 
291 
293 
296  template <class T, class Prop, class Storage, class Allocator>
298  {
299 #ifndef SELDON_WITHOUT_REINIT_RANDOM
300  srand(time(NULL));
301 #endif
302  for (int i = 0; i < this->GetDataSize(); i++)
303  SetComplexReal(rand(), this->data_[i]);
304  }
305 
306 
308 
313  template <class T, class Prop, class Storage, class Allocator>
315  {
316  for (int i = 0; i < this->m_; i++)
317  {
318  for (int j = 0; j < this->n_; j++)
319  cout << (*this)(i, j) << "\t";
320  cout << endl;
321  }
322  }
323 
324 
326 
337  template <class T, class Prop, class Storage, class Allocator>
339  ::Print(int a, int b, int m, int n) const
340  {
341  for (int i = a; i < min(this->m_, a + m); i++)
342  {
343  for (int j = b; j < min(this->n_, b + n); j++)
344  cout << (*this)(i, j) << "\t";
345  cout << endl;
346  }
347  }
348 
349 
351 
359  template <class T, class Prop, class Storage, class Allocator>
361  {
362  Print(0, 0, l, l);
363  }
364 
365 
366  /**************************
367  * INPUT/OUTPUT FUNCTIONS *
368  **************************/
369 
370 
372 
379  template <class T, class Prop, class Storage, class Allocator>
381  ::Write(string FileName) const
382  {
383  ofstream FileStream;
384  FileStream.open(FileName.c_str(), ofstream::binary);
385 
386 #ifdef SELDON_CHECK_IO
387  // Checks if the file was opened.
388  if (!FileStream.is_open())
389  throw IOError("Matrix_SymPacked::Write(string FileName)",
390  string("Unable to open file \"") + FileName + "\".");
391 #endif
392 
393  this->Write(FileStream);
394 
395  FileStream.close();
396  }
397 
398 
400 
407  template <class T, class Prop, class Storage, class Allocator>
409  ::Write(ostream& FileStream) const
410  {
411 
412 #ifdef SELDON_CHECK_IO
413  // Checks if the file is ready.
414  if (!FileStream.good())
415  throw IOError("Matrix_SymPacked::Write(ostream& FileStream)",
416  "The stream is not ready.");
417 #endif
418 
419  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
420  sizeof(int));
421  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
422  sizeof(int));
423 
424  FileStream.write(reinterpret_cast<char*>(this->data_),
425  this->GetDataSize() * sizeof(value_type));
426 
427 #ifdef SELDON_CHECK_IO
428  // Checks if data was written.
429  if (!FileStream.good())
430  throw IOError("Matrix_SymPacked::Write(ostream& FileStream)",
431  "Output operation failed.");
432 #endif
433 
434  }
435 
436 
438 
445  template <class T, class Prop, class Storage, class Allocator>
447  ::WriteText(string FileName) const
448  {
449  ofstream FileStream;
450  FileStream.precision(cout.precision());
451  FileStream.flags(cout.flags());
452  FileStream.open(FileName.c_str());
453 
454 #ifdef SELDON_CHECK_IO
455  // Checks if the file was opened.
456  if (!FileStream.is_open())
457  throw IOError("Matrix_SymPacked::WriteText(string FileName)",
458  string("Unable to open file \"") + FileName + "\".");
459 #endif
460 
461  this->WriteText(FileStream);
462 
463  FileStream.close();
464  }
465 
466 
468 
475  template <class T, class Prop, class Storage, class Allocator>
477  ::WriteText(ostream& FileStream) const
478  {
479 
480 #ifdef SELDON_CHECK_IO
481  // Checks if the stream is ready.
482  if (!FileStream.good())
483  throw IOError("Matrix_SymPacked::WriteText(ostream& FileStream)",
484  "The stream is not ready.");
485 #endif
486 
487  int i, j;
488  for (i = 0; i < this->GetM(); i++)
489  {
490  for (j = 0; j < this->GetN(); j++)
491  FileStream << (*this)(i, j) << '\t';
492  FileStream << endl;
493  }
494 
495 #ifdef SELDON_CHECK_IO
496  // Checks if data was written.
497  if (!FileStream.good())
498  throw IOError("Matrix_SymPacked::WriteText(ostream& FileStream)",
499  "Output operation failed.");
500 #endif
501 
502  }
503 
504 
506 
513  template <class T, class Prop, class Storage, class Allocator>
515  {
516  ifstream FileStream;
517  FileStream.open(FileName.c_str(), ifstream::binary);
518 
519 #ifdef SELDON_CHECK_IO
520  // Checks if the file was opened.
521  if (!FileStream.good())
522  throw IOError("Matrix_SymPacked::Read(string FileName)",
523  string("Unable to open file \"") + FileName + "\".");
524 #endif
525 
526  this->Read(FileStream);
527 
528  FileStream.close();
529  }
530 
531 
533 
540  template <class T, class Prop, class Storage, class Allocator>
542  ::Read(istream& FileStream)
543  {
544 
545 #ifdef SELDON_CHECK_IO
546  // Checks if the stream is ready.
547  if (!FileStream.good())
548  throw IOError("Matrix_SymPacked::Read(istream& FileStream)",
549  "The stream is not ready.");
550 #endif
551 
552  int new_m, new_n;
553  FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
554  FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
555  this->Reallocate(new_m, new_n);
556 
557  FileStream.read(reinterpret_cast<char*>(this->data_),
558  this->GetDataSize() * sizeof(value_type));
559 
560 #ifdef SELDON_CHECK_IO
561  // Checks if data was read.
562  if (!FileStream.good())
563  throw IOError("Matrix_SymPacked::Read(istream& FileStream)",
564  "Input operation failed.");
565 #endif
566 
567  }
568 
569 
571 
575  template <class T, class Prop, class Storage, class Allocator>
577  ::ReadText(string FileName)
578  {
579  ifstream FileStream;
580  FileStream.open(FileName.c_str());
581 
582 #ifdef SELDON_CHECK_IO
583  // Checks if the file was opened.
584  if (!FileStream.is_open())
585  throw IOError("Matrix_Pointers::ReadText(string FileName)",
586  string("Unable to open file \"") + FileName + "\".");
587 #endif
588 
589  this->ReadText(FileStream);
590 
591  FileStream.close();
592  }
593 
594 
596 
600  template <class T, class Prop, class Storage, class Allocator>
602  ::ReadText(istream& FileStream)
603  {
604  // Clears the matrix.
605  Clear();
606 
607 #ifdef SELDON_CHECK_IO
608  // Checks if the stream is ready.
609  if (!FileStream.good())
610  throw IOError("Matrix_SymPacked::ReadText(istream& FileStream)",
611  "The stream is not ready.");
612 #endif
613 
614  // Reads the first line.
615  string line;
616  getline(FileStream, line);
617  if (FileStream.fail())
618  // Is the file empty?
619  return;
620 
621  // Converts the first line into a vector.
622  istringstream line_stream(line);
623  Vector<T> first_row;
624  first_row.ReadText(line_stream);
625 
626  // Now reads all other rows, and puts them in a single vector.
627  Vector<T> other_row;
628  other_row.ReadText(FileStream);
629 
630  // Number of rows and columns.
631  int n = first_row.GetM();
632  int m = 1 + other_row.GetM() / n;
633 
634 #ifdef SELDON_CHECK_IO
635  // Checks that enough elements were read.
636  if (other_row.GetM() != (m - 1) * n)
637  throw IOError("Matrix_SymPacked::ReadText(istream& FileStream)",
638  "Not all rows have the same number of columns.");
639 #endif
640 
641  this->Reallocate(m,n);
642 
643  // Fills the matrix.
644  for (int j = 0; j < n; j++)
645  this->Val(0, j) = first_row(j);
646  int k = 0;
647  for (int i = 1; i < m; i++)
648  {
649  k += i;
650  for (int j = i; j < n; j++)
651  this->Val(i, j) = other_row(k++);
652  }
653  }
654 
655 
657  // MATRIX<COLSYMPACKED> //
659 
660 
661  /*****************
662  * OTHER METHODS *
663  *****************/
664 
665 
667 
674  template <class T, class Prop, class Allocator>
676  {
677 
678  // Storing the old values of the matrix.
679  long nold = this->GetDataSize();
681  for (long k = 0; k < nold; k++)
682  xold(k) = this->data_[k];
683 
684  // Reallocation.
685  this->Reallocate(i,j);
686 
687  // Filling the matrix with its old values.
688  long nmin = min(nold, this->GetDataSize());
689  for (long k = 0; k < nmin; k++)
690  this->data_[k] = xold(k);
691  }
692 
693 
695  // MATRIX<ROWSYMPACKED> //
697 
698 
699  /*****************
700  * OTHER METHODS *
701  *****************/
702 
703 
705 
712  template <class T, class Prop, class Allocator>
714  {
715 
716  // Storing the old values of the matrix.
717  long nold = this->GetDataSize(), iold = this->m_;
719  for (long k = 0; k < nold; k++)
720  xold(k) = this->data_[k];
721 
722  // Reallocation.
723  this->Reallocate(i,j);
724 
725  // Filling the matrix with its old values.
726  long imin = min(iold, long(i));
727  nold = 0;
728  long n = 0;
729  for (long k = 0; k < imin; k++)
730  {
731  for (long l = k; l < imin; l++)
732  this->data_[n+l-k] = xold(nold+l-k);
733 
734  n += i - k;
735  nold += iold - k;
736  }
737  }
738 
739 
740 } // namespace Seldon.
741 
742 #define SELDON_FILE_MATRIX_SYMPACKED_CXX
743 #endif
Seldon::Matrix_SymPacked::Clear
void Clear()
Clears the matrix.
Definition: Matrix_SymPacked.cxx:87
Seldon::Matrix_Base
Base class for all matrices.
Definition: Matrix_Base.hxx:143
Seldon::Matrix_SymPacked::Nullify
void Nullify()
Clears the matrix without releasing memory.
Definition: Matrix_SymPacked.cxx:208
Seldon::Matrix_SymPacked::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_SymPacked.cxx:189
Seldon::Vector< T >
Seldon::Matrix_SymPacked
Symmetric packed matrix class.
Definition: Matrix_SymPacked.hxx:37
Seldon::Matrix_SymPacked::WriteText
void WriteText(string FileName) const
Writes the matrix in a file.
Definition: Matrix_SymPacked.cxx:447
Seldon::Matrix
Definition: SeldonHeader.hxx:226
Seldon::Matrix_SymPacked::ReadText
void ReadText(string FileName)
Reads the matrix from a file.
Definition: Matrix_SymPacked.cxx:577
Seldon::Matrix_SymPacked::FillRand
void FillRand()
Fills the matrix randomly.
Definition: Matrix_SymPacked.cxx:297
Seldon::Matrix_SymPacked::Matrix_SymPacked
Matrix_SymPacked()
Default constructor.
Definition: Matrix_SymPackedInline.cxx:39
Seldon::Matrix_SymPacked::Fill
void Fill()
Fills the matrix with 0, 1, 2, ...
Definition: Matrix_SymPacked.cxx:255
Seldon::Vector< T, VectFull, Allocator >
Full vector class.
Definition: Vector.hxx:88
Seldon::Matrix_SymPacked::Print
void Print() const
Displays the matrix on the standard output.
Definition: Matrix_SymPacked.cxx:314
Seldon::Matrix_SymPacked::operator=
Matrix_SymPacked< T, Prop, Storage, Allocator > & operator=(const Matrix_SymPacked< T, Prop, Storage, Allocator > &A)
Duplicates a matrix (assignment operator).
Definition: Matrix_SymPackedInline.cxx:276
Seldon::Matrix_SymPacked::SetIdentity
void SetIdentity()
Sets the matrix to the identity.
Definition: Matrix_SymPacked.cxx:236
Seldon::Matrix_SymPacked::Zero
void Zero()
Sets all elements to zero.
Definition: Matrix_SymPacked.cxx:227
Seldon::Matrix_SymPacked::Read
void Read(string FileName)
Reads the matrix from a file.
Definition: Matrix_SymPacked.cxx:514
Seldon::Matrix_SymPacked::Write
void Write(string FileName) const
Writes the matrix in a file.
Definition: Matrix_SymPacked.cxx:381
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::IOError
Definition: Errors.hxx:150
Seldon::NoMemory
Definition: Errors.hxx:90
Seldon::SetComplexReal
void SetComplexReal(int n, std::complex< T > &number)
Sets a complex number to (n, 0).
Definition: CommonInline.cxx:234
Seldon::Matrix_SymPacked::Reallocate
void Reallocate(int i, int j)
Reallocates memory to resize the matrix.
Definition: Matrix_SymPacked.cxx:129