VectorCollection.cxx
1 // Copyright (C) 2010, INRIA
2 // Author(s): Marc Fragu, Vivien Mallet
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_VECTOR_VECTORCOLLECTION_CXX
22 
23 
24 #include "VectorCollection.hxx"
25 
26 
27 namespace Seldon
28 {
29 
30 
32  // VECTORCOLLECTION //
34 
35 
36  /**************
37  * DESTRUCTOR *
38  **************/
39 
40 
42 
45  template <class T, class Allocator >
47  {
48  for (int i = 0; i < Nvector_; i++)
49  vector_(i).Nullify();
50  label_map_.clear();
51  label_vector_.clear();
52  }
53 
54 
56 
59  template <class T, class Allocator >
61  {
62  for (int i = 0; i < Nvector_; i++)
63  vector_(i).Nullify();
64  vector_.Clear();
65  length_sum_.Clear();
66  length_.Clear();
67  Nvector_ = 0;
68  this->m_ = 0;
69  label_map_.clear();
70  label_vector_.clear();
71  }
72 
73 
75 
80  template <class T, class Allocator >
82  {
83  Clear();
84  vector_type v;
85  v.Reallocate(i);
86  AddVector(v);
87  v.Nullify();
88  }
89 
90 
92 
95  template <class T, class Allocator >
97  {
98  for (int i = 0; i < Nvector_; i++)
99  vector_(i).Clear();
100  vector_.Clear();
101  length_sum_.Clear();
102  length_.Clear();
103  Nvector_ = 0;
104  this->m_ = 0;
105  label_map_.clear();
106  label_vector_.clear();
107  }
108 
109 
110  /**********************
111  * VECTORS MANAGEMENT *
112  **********************/
113 
114 
116 
120  template <class T, class Allocator >
122  ::GetVectorIndex(string name) const
123  {
124  map<string,int>::const_iterator label_iterator = label_map_.find(name);
125  if (label_iterator == label_map_.end())
126  throw WrongArgument("VectorCollection::GetVectorIndex(string name)",
127  "Unknown vector name: \"" + name + "\".");
128  return label_iterator->second;
129  }
130 
131 
138  template <class T, class Allocator >
140  {
141  map<string,int>::const_iterator label_iterator = label_map_.find(name);
142  if (label_iterator == label_map_.end())
143  throw WrongArgument("VectorCollection::GetIndex(string name)",
144  string("Unknown vector name: \"") + name + "\".");
145  return (label_iterator->second == 0) ?
146  0 : length_sum_(label_iterator->second - 1);
147  }
148 
149 
151 
155  template <class T, class Allocator >
156  typename
159  {
160  map<string,int>::const_iterator label_iterator;
161  label_iterator = label_map_.find(name);
162  if (label_iterator == label_map_.end())
163  throw WrongArgument("VectorCollection::SetVector(string name)",
164  string("Unknown vector name: \"") + name + "\".");
165  return GetVector(label_iterator->second);
166  }
167 
168 
170 
174  template <class T, class Allocator >
177  {
178  map<string,int>::iterator label_iterator;
179  label_iterator = label_map_.find(name);
180  if (label_iterator == label_map_.end())
181  throw WrongArgument("VectorCollection::SetVector(string name)",
182  string("Unknown vector name: \"") + name + "\".");
183  return GetVector(label_iterator->second);
184  }
185 
186 
187  /*********************************
188  * ELEMENT ACCESS AND ASSIGNMENT *
189  *********************************/
190 
191 
193 
197  template <class T, class Allocator >
200  {
201 #ifdef SELDON_CHECK_BOUNDS
202  if (i < 0 || i >= this->m_)
203  throw WrongIndex("VectorCollection::operator()",
204  string("Index should be in [0, ")
205  + to_str(this->m_ - 1)
206  + "], but is equal to " + to_str(i) + ".");
207 #endif
208 
209  int j = 0;
210  while (i >= length_sum_(j))
211  j++;
212  return (j == 0) ? vector_(j)(i) : vector_(j)(i - length_sum_(j - 1));
213  }
214 
215 
217 
221  template <class T, class Allocator >
224  {
225 #ifdef SELDON_CHECK_BOUNDS
226  if (i < 0 || i >= this->m_)
227  throw WrongIndex("VectorCollection::operator()",
228  string("Index should be in [0, ")
229  + to_str(this->m_ - 1)
230  + "], but is equal to " + to_str(i) + ".");
231 #endif
232 
233  int j = 0;
234  while (i >= length_sum_(j))
235  j++;
236  return (j == 0) ? vector_(j)(i) : vector_(j)(i - length_sum_(j - 1));
237  }
238 
239 
241 
246  template <class T, class Allocator >
250  {
251  this->Copy(X);
252  return *this;
253  }
254 
255 
257 
262  template <class T, class Allocator >
265  {
266  Clear();
267  for (int i = 0; i < X.GetNvector(); i++)
268  AddVector(X.GetVector(i));
269  label_map_.insert(X.label_map_.begin(), X.label_map_.end());
270  label_vector_.assign(X.label_vector_.begin(), X.label_vector_.end());
271  }
272 
273 
275 
280  template <class T, class Allocator >
281  template <class T0, class Allocator0>
284  {
285 #ifdef SELDON_CHECK_BOUNDS
286  if (this->m_ != X.GetM())
287  throw WrongIndex("VectorCollection::Copy(X)",
288  string("The size of X should be equal to ")
289  + to_str(this->m_ - 1)
290  + ", but is equal to " + to_str(X.GetM()) + ".");
291 #endif
292 
293  for (int i = 0; i < X.GetM(); i++)
294  (*this)(i) = X(i);
295  }
296 
297 
299 
302  template <class T, class Allocator >
303  template <class T0, class Storage0, class Allocator0>
306  Storage0, Allocator0>& vector)
307  {
308  Nvector_++;
309  length_.PushBack(0);
310  length_sum_.PushBack(this->m_);
311 
312  // Resizes 'vector_'.
313  collection_type new_vector(Nvector_);
314  for (int i = 0; i < Nvector_ - 1; i++)
315  {
316  new_vector(i).SetData(vector_(i));
317  vector_(i).Nullify();
318  }
319  vector_.Clear();
320  vector_.SetData(new_vector);
321  new_vector.Nullify();
322 
323  // Adds the new vector.
324  SetVector(Nvector_ - 1, vector);
325  }
326 
327 
329 
333  template <class T, class Allocator >
334  template <class T0, class Storage0, class Allocator0>
337  Storage0, Allocator0>& vector,
338  string name)
339  {
340  AddVector(vector);
341  SetName(Nvector_ - 1, name);
342  }
343 
344 
346 
350  template <class T, class Allocator >
351  template <class T0, class Storage0, class Allocator0>
353  ::SetVector(int i, const Vector<T0,
354  Storage0, Allocator0>& vector)
355  {
356  int size_difference;
357  size_difference = vector.GetM() - vector_(i).GetM();
358  this->m_ += size_difference;
359  length_(i) = vector.GetM();
360  for (int k = i; k < Nvector_; k++)
361  length_sum_(k) += size_difference;
362 
363  vector_(i).Nullify();
364  vector_(i).SetData(vector);
365  }
366 
367 
369 
374  template <class T, class Allocator >
375  template <class T0, class Storage0, class Allocator0>
378  string name)
379  {
380  SetVector(i, vector);
381  SetName(i, name);
382  }
383 
384 
386 
390  template <class T, class Allocator >
391  template <class T0, class Storage0, class Allocator0>
393  ::SetVector(string name, const Vector<T0,
394  Storage0, Allocator0>& vector)
395  {
396  map<string,int>::iterator label_iterator;
397  label_iterator = label_map_.find(name);
398  if (label_iterator == label_map_.end())
399  throw WrongArgument("VectorCollection::SetVector(string name, Vector)",
400  string("Unknown vector name: \"") + name + "\".");
401  SetVector(label_iterator->second, vector);
402  }
403 
404 
406 
410  template <class T, class Allocator >
412  ::SetName(int i, string name)
413  {
414 
415 #ifdef SELDON_CHECK_BOUNDS
416  if (i < 0 || i >= Nvector_)
417  throw WrongIndex("VectorCollection::SetName(int i, string name)",
418  string("Index should be in [0, ")
419  + to_str(Nvector_ - 1)
420  + "], but is equal to " + to_str(i) + ".");
421 #endif
422 
423  if (i >= int(label_vector_.size()))
424  label_vector_.resize(Nvector_, "");
425 
426  if (label_vector_[i] != "")
427  label_map_.erase(label_vector_[i]);
428 
429  label_vector_[i] = name;
430  label_map_[name] = i;
431  }
432 
433 
435 
439  template <class T, class Allocator >
442  {
443  Clear();
444  for (int i = 0; i < X.GetNvector(); i++)
445  AddVector(X.GetVector(i));
446  label_map_.insert(X.label_map_.begin(), X.label_map_.end());
447  label_vector_.assign(X.label_vector_.begin(), X.label_vector_.end());
448  }
449 
450 
452  template <class T, class Allocator >
454  {
455  for (int i = 0; i < Nvector_; i++)
456  vector_(i).Nullify();
457  for (int i = 0; i < Nvector_; i++)
458  length_(i) = length_sum_(i) = 0;
459  }
460 
461 
463  // CONVENIENT METHOD //
465 
466 
468 
471  template <class T, class Allocator>
472  template <class T0>
474  {
475  for (int i = 0; i < Nvector_; i++)
476  vector_(i).Fill(x);
477  }
478 
479 
481  template <class T, class Allocator >
483  {
484  for (int i = 0; i < GetNvector(); i++)
485  {
486  if (i < int(label_vector_.size()) && label_vector_[i] != "")
487  cout << label_vector_[i] << ":" << endl;
488  else
489  cout << "(noname):" << endl;
490  vector_(i).Print();
491  }
492  cout << endl;
493  }
494 
495 
497 
503  template <class T, class Allocator >
505  ::Write(string FileName, bool with_size) const
506  {
507  ofstream FileStream;
508  FileStream.open(FileName.c_str(), ofstream::binary);
509 
510 #ifdef SELDON_CHECK_IO
511  // Checks if the file was opened.
512  if (!FileStream.is_open())
513  throw IOError("Vector<Collection>::Write(string FileName)",
514  string("Unable to open file \"") + FileName + "\".");
515 #endif
516 
517  this->Write(FileStream, with_size);
518 
519  FileStream.close();
520  }
521 
522 
524 
530  template <class T, class Allocator >
532  ::Write(ostream& FileStream, bool with_size) const
533  {
534 
535 #ifdef SELDON_CHECK_IO
536  // Checks if the stream is ready.
537  if (!FileStream.good())
538  throw IOError("Vector<Collection>::Write(ostream& FileStream)",
539  "The stream is not ready.");
540 #endif
541  if (with_size)
542  FileStream
543  .write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
544  sizeof(int));
545 
546  for (int i = 0; i < GetNvector(); i++)
547  vector_(i).Write(FileStream, false);
548 
549 #ifdef SELDON_CHECK_IO
550  // Checks if data was written.
551  if (!FileStream.good())
552  throw IOError("Vector<Collection>::Write(ostream& FileStream)",
553  "Output operation failed.");
554 #endif
555  }
556 
557 
559 
564  template <class T, class Allocator >
566  ::WriteText(string FileName) const
567  {
568  ofstream FileStream;
569  FileStream.precision(cout.precision());
570  FileStream.flags(cout.flags());
571  FileStream.open(FileName.c_str());
572 
573 #ifdef SELDON_CHECK_IO
574  // Checks if the file was opened.
575  if (!FileStream.is_open())
576  throw IOError("Vector<Collection>::WriteText(string FileName)",
577  string("Unable to open file \"") + FileName + "\".");
578 #endif
579 
580  this->WriteText(FileStream);
581 
582  FileStream.close();
583  }
584 
585 
587 
592  template <class T, class Allocator >
594  ::WriteText(ostream& FileStream) const
595  {
596 
597 #ifdef SELDON_CHECK_IO
598  // Checks if the stream is ready.
599  if (!FileStream.good())
600  throw IOError("Vector<Collection>::Write(ostream& FileStream)",
601  "The stream is not ready.");
602 #endif
603 
604  for (int i = 0; i < GetNvector(); i++)
605  vector_(i).WriteText(FileStream);
606 
607 #ifdef SELDON_CHECK_IO
608  // Checks if data was written.
609  if (!FileStream.good())
610  throw IOError("Vector<Collection>::Write(ostream& FileStream)",
611  "Output operation failed.");
612 #endif
613  }
614 
615 
617 
622  template <class T, class Allocator >
624  {
625  ifstream FileStream;
626  FileStream.open(FileName.c_str(), ifstream::binary);
627 
628 #ifdef SELDON_CHECK_IO
629  // Checks if the file was opened.
630  if (!FileStream.is_open())
631  throw IOError("Vector<Collection>::Read(string FileName)",
632  string("Unable to open file \"") + FileName + "\".");
633 #endif
634 
635  Vector<int> length;
636  length.Read(FileStream);
637 
638  this->Read(FileStream, length);
639 
640  FileStream.close();
641  }
642 
643 
645 
650  template <class T, class Allocator >
652  ::Read(string FileName, Vector<int, VectFull, MallocAlloc<int> >& length)
653  {
654  ifstream FileStream;
655  FileStream.open(FileName.c_str(), ifstream::binary);
656 
657 #ifdef SELDON_CHECK_IO
658  // Checks if the file was opened.
659  if (!FileStream.is_open())
660  throw IOError("Vector<Collection>::Read(string FileName)",
661  string("Unable to open file \"") + FileName + "\".");
662 #endif
663 
664  this->Read(FileStream, length);
665 
666  FileStream.close();
667  }
668 
669 
671 
676  template <class T, class Allocator >
678  ::Read(istream& FileStream,
679  Vector<int, VectFull, MallocAlloc<int> >& length)
680  {
681 
682 #ifdef SELDON_CHECK_IO
683  // Checks if the stream is ready.
684  if (!FileStream.good())
685  throw IOError("Vector<Collection>::Read(istream& FileStream)",
686  "The stream is not ready.");
687 #endif
688 
689  T working_vector;
690  working_vector.Read(FileStream);
691 
693  int Nvector;
694 
695  Clear();
696  Nvector = length.GetSize();
697  length_sum.Reallocate(Nvector);
698  length_sum(0) = length(0);
699  for (int i = 1; i < Nvector; i++)
700  length_sum(i) = length_sum(i - 1) + length(i);
701 
702  T U, V;
703  U.SetData(length(0), &working_vector.GetData()[0]);
704  V.Copy(U);
705  AddVector(V);
706  U.Nullify();
707  V.Nullify();
708  for (int i = 1; i < Nvector; i++)
709  {
710  U.SetData(length(i), &working_vector.GetData()[length_sum(i - 1)]);
711  V.Copy(U);
712  AddVector(V);
713  U.Nullify();
714  V.Nullify();
715  }
716 
717 #ifdef SELDON_CHECK_IO
718  // Checks if data was read.
719  if (!FileStream.good())
720  throw IOError("Vector<Collection>::Read(istream& FileStream)",
721  "Input operation failed.");
722 #endif
723 
724  }
725 
726 
728 
733  template <class T, class Allocator>
734  ostream& operator <<
735  (ostream& out, const Vector<T, Collection, Allocator>& V)
736  {
737  for (int i = 0; i < V.GetNvector() - 1; i++)
738  out << V.GetVector(i) << '\t';
739  if (V.GetNvector() != 0)
740  out << V.GetVector(V.GetNvector() - 1);
741  return out;
742  }
743 
744 
745 } // namespace Seldon.
746 
747 
748 #define SELDON_FILE_VECTOR_VECTORCOLLECTION_CXX
749 #endif
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::Vector< T, Collection, Allocator >::label_vector_
vector< string > label_vector_
Names associated with the inner vectors.
Definition: VectorCollection.hxx:76
Seldon::Vector< T, Collection, Allocator >::GetVector
collection_reference GetVector()
Returns the list of vectors.
Definition: VectorCollectionInline.cxx:149
Seldon::MallocAlloc
Definition: Allocator.hxx:32
Seldon::WrongIndex
Definition: Errors.hxx:114
Seldon::Vector< T, Collection, Allocator >::GetNvector
int GetNvector() const
Returns the number of aggregated vectors.
Definition: VectorCollectionInline.cxx:113
Seldon::VectFull
Definition: StorageInline.cxx:74
Seldon::WrongArgument
Definition: Errors.hxx:76
Seldon::Vector< T, Collection, Allocator >
Structure for distributed vectors.
Definition: VectorCollection.hxx:38
Seldon::Vector< T, Collection, Allocator >::label_map_
map< string, int > label_map_
Indexes of the inner vectors that have a name.
Definition: VectorCollection.hxx:74
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::IOError
Definition: Errors.hxx:150
Seldon::AddVector
void AddVector(const T0 &alpha, const Vector< T1, Storage1, Allocator1 > &X, Vector< T2, Storage2, Allocator2 > &Y)
Adds two vectors Y = Y + alpha X.
Definition: Functions_Vector.cxx:94