vector/Vector.cxx

00001 // Copyright (C) 2001-2009 Vivien Mallet
00002 // Copyright (C) 2003-2009 Marc Duruflé
00003 //
00004 // This file is part of the linear-algebra library Seldon,
00005 // http://seldon.sourceforge.net/.
00006 //
00007 // Seldon is free software; you can redistribute it and/or modify it under the
00008 // terms of the GNU Lesser General Public License as published by the Free
00009 // Software Foundation; either version 2.1 of the License, or (at your option)
00010 // any later version.
00011 //
00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00015 // more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public License
00018 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00019 
00020 
00021 #ifndef SELDON_FILE_VECTOR_CXX
00022 
00023 #include "Vector.hxx"
00024 
00025 namespace Seldon
00026 {
00027 
00028 
00030   // C_VECTOR_BASE //
00032 
00033 
00034   /****************
00035    * CONSTRUCTORS *
00036    ****************/
00037 
00038 
00040 
00043   template <class T, class Allocator>
00044   inline Vector_Base<T, Allocator>::Vector_Base()
00045   {
00046     m_ = 0;
00047     data_ = NULL;
00048   }
00049 
00050 
00052 
00056   template <class T, class Allocator>
00057   inline Vector_Base<T, Allocator>::Vector_Base(int i)
00058   {
00059     m_ = i;
00060     data_ = NULL;
00061   }
00062 
00063 
00065 
00069   template <class T, class Allocator>
00070   inline Vector_Base<T, Allocator>::
00071   Vector_Base(const Vector_Base<T, Allocator>& A)
00072   {
00073     m_ = A.GetM();
00074     data_ = NULL;
00075   }
00076 
00077 
00078   /**************
00079    * DESTRUCTOR *
00080    **************/
00081 
00082 
00084   template <class T, class Allocator>
00085   inline Vector_Base<T, Allocator>::~Vector_Base()
00086   {
00087 
00088 #ifdef SELDON_CHECK_MEMORY
00089     try
00090       {
00091 #endif
00092 
00093         if (data_ != NULL)
00094           {
00095             vect_allocator_.deallocate(data_, m_);
00096             m_ = 0;
00097             data_ = NULL;
00098           }
00099 
00100 #ifdef SELDON_CHECK_MEMORY
00101       }
00102     catch (...)
00103       {
00104         m_ = 0;
00105         data_ = NULL;
00106       }
00107 #endif
00108 
00109   }
00110 
00111 
00112   /*******************
00113    * BASIC FUNCTIONS *
00114    *******************/
00115 
00116 
00118 
00121   template <class T, class Allocator>
00122   int Vector_Base<T, Allocator>::GetM() const
00123   {
00124     return m_;
00125   }
00126 
00127 
00129 
00132   template <class T, class Allocator>
00133   int Vector_Base<T, Allocator>::GetLength() const
00134   {
00135     return m_;
00136   }
00137 
00138 
00140 
00143   template <class T, class Allocator>
00144   int Vector_Base<T, Allocator>::GetSize() const
00145   {
00146     return m_;
00147   }
00148 
00149 
00151 
00154   template <class T, class Allocator>
00155   typename Vector_Base<T, Allocator>::pointer
00156   Vector_Base<T, Allocator>::GetData() const
00157   {
00158     return data_;
00159   }
00160 
00161 
00163 
00166   template <class T, class Allocator>
00167   typename Vector_Base<T, Allocator>::const_pointer
00168   Vector_Base<T, Allocator>::GetDataConst() const
00169   {
00170     return reinterpret_cast<typename Vector_Base<T,
00171       Allocator>::const_pointer>(data_);
00172   }
00173 
00174 
00176 
00179   template <class T, class Allocator>
00180   void* Vector_Base<T, Allocator>::GetDataVoid() const
00181   {
00182     return reinterpret_cast<void*>(data_);
00183   }
00184 
00185 
00187 
00190   template <class T, class Allocator>
00191   const void* Vector_Base<T, Allocator>::GetDataConstVoid() const
00192   {
00193     return reinterpret_cast<const void*>(data_);
00194   }
00195 
00196 
00198   // VECTOR<VECT_FULL> //
00200 
00201 
00202   /****************
00203    * CONSTRUCTORS *
00204    ****************/
00205 
00206 
00208 
00211   template <class T, class Allocator>
00212   Vector<T, VectFull, Allocator>::Vector():
00213     Vector_Base<T, Allocator>()
00214   {
00215   }
00216 
00217 
00219 
00222   template <class T, class Allocator>
00223   Vector<T, VectFull, Allocator>::Vector(int i):
00224     Vector_Base<T, Allocator>(i)
00225   {
00226 
00227 #ifdef SELDON_CHECK_MEMORY
00228     try
00229       {
00230 #endif
00231 
00232         this->data_ = this->vect_allocator_.allocate(i, this);
00233 
00234 #ifdef SELDON_CHECK_MEMORY
00235       }
00236     catch (...)
00237       {
00238         this->m_ = 0;
00239         this->data_ = NULL;
00240       }
00241     if (this->data_ == NULL)
00242       this->m_ = 0;
00243     if (this->data_ == NULL && i != 0)
00244       throw NoMemory("Vector<VectFull>::Vector(int)",
00245                      string("Unable to allocate memory for a vector of size ")
00246                      + to_str(i*sizeof(T)) + " bytes ("
00247                      + to_str(i) + " elements).");
00248 #endif
00249 
00250   }
00251 
00252 
00254 
00264   template <class T, class Allocator>
00265   Vector<T, VectFull, Allocator>
00266   ::Vector(int i, typename Vector<T, VectFull, Allocator>::pointer data):
00267     Vector_Base<T, Allocator>()
00268   {
00269     SetData(i, data);
00270   }
00271 
00272 
00274 
00277   template <class T, class Allocator>
00278   Vector<T, VectFull, Allocator>::
00279   Vector(const Vector<T, VectFull, Allocator>& V):
00280     Vector_Base<T, Allocator>(V)
00281   {
00282 
00283 #ifdef SELDON_CHECK_MEMORY
00284     try
00285       {
00286 #endif
00287 
00288         this->data_ = this->vect_allocator_.allocate(V.GetM(), this);
00289 
00290 #ifdef SELDON_CHECK_MEMORY
00291       }
00292     catch (...)
00293       {
00294         this->m_ = 0;
00295         this->data_ = NULL;
00296       }
00297     if (this->data_ == NULL)
00298       this->m_ = 0;
00299     if (this->data_ == NULL && V.GetM() != 0)
00300       throw NoMemory("Vector<VectFull>::Vector(Vector<VectFull>&)",
00301                      string("Unable to allocate memory for a vector of size ")
00302                      + to_str(V.GetM()*sizeof(T)) + " bytes ("
00303                      + to_str(V.GetM()) + " elements).");
00304 #endif
00305 
00306     this->vect_allocator_.memorycpy(this->data_, V.GetData(), V.GetM());
00307 
00308   }
00309 
00310 
00311   /**************
00312    * DESTRUCTOR *
00313    **************/
00314 
00315 
00317   template <class T, class Allocator>
00318   Vector<T, VectFull, Allocator>::~Vector()
00319   {
00320   }
00321 
00322 
00323   /*********************
00324    * MEMORY MANAGEMENT *
00325    *********************/
00326 
00327 
00329 
00333   template <class T, class Allocator>
00334   inline void Vector<T, VectFull, Allocator>::Clear()
00335   {
00336     this->~Vector();
00337   }
00338 
00339 
00341 
00347   template <class T, class Allocator>
00348   inline void Vector<T, VectFull, Allocator>::Reallocate(int i)
00349   {
00350 
00351     if (i != this->m_)
00352       {
00353 
00354         this->m_ = i;
00355 
00356 #ifdef SELDON_CHECK_MEMORY
00357         try
00358           {
00359 #endif
00360 
00361             this->data_ =
00362               reinterpret_cast<pointer>(this->vect_allocator_
00363                                         .reallocate(this->data_, i, this));
00364 
00365 #ifdef SELDON_CHECK_MEMORY
00366           }
00367         catch (...)
00368           {
00369             this->m_ = 0;
00370             this->data_ = NULL;
00371             return;
00372           }
00373         if (this->data_ == NULL)
00374           {
00375             this->m_ = 0;
00376             return;
00377           }
00378 #endif
00379 
00380       }
00381   }
00382 
00383 
00385 
00389   template <class T, class Allocator>
00390   inline void Vector<T, VectFull, Allocator>::Resize(int n)
00391   {
00392 
00393     if (n == this->m_)
00394       return;
00395 
00396     Vector<T, VectFull, Allocator> X_new(n);
00397     for (int i = 0; i < min(this->m_, n); i++)
00398       X_new(i) = this->data_[i];
00399 
00400     SetData(n, X_new.GetData());
00401     X_new.Nullify();
00402   }
00403 
00404 
00420   template <class T, class Allocator>
00421   inline void Vector<T, VectFull, Allocator>
00422   ::SetData(int i, typename Vector<T, VectFull, Allocator>::pointer data)
00423   {
00424     this->Clear();
00425 
00426     this->m_ = i;
00427 
00428     this->data_ = data;
00429   }
00430 
00431 
00433 
00445   template <class T, class Allocator>
00446   template <class Allocator0>
00447   inline void Vector<T, VectFull, Allocator>
00448   ::SetData(const Vector<T, VectFull, Allocator0>& V)
00449   {
00450     SetData(V.GetLength(), V.GetData());
00451   }
00452 
00453 
00455 
00460   template <class T, class Allocator>
00461   void Vector<T, VectFull, Allocator>::Nullify()
00462   {
00463     this->m_ = 0;
00464     this->data_ = NULL;
00465   }
00466 
00467 
00468   /**********************************
00469    * ELEMENT ACCESS AND AFFECTATION *
00470    **********************************/
00471 
00472 
00474 
00478   template <class T, class Allocator>
00479   inline typename Vector<T, VectFull, Allocator>::reference
00480   Vector<T, VectFull, Allocator>::operator() (int i)
00481   {
00482 
00483 #ifdef SELDON_CHECK_BOUNDS
00484     if (i < 0 || i >= this->m_)
00485       throw WrongIndex("Vector<VectFull>::operator()",
00486                        string("Index should be in [0, ") + to_str(this->m_-1)
00487                        + "], but is equal to " + to_str(i) + ".");
00488 #endif
00489 
00490     return this->data_[i];
00491   }
00492 
00493 
00495 
00499   template <class T, class Allocator>
00500   inline typename Vector<T, VectFull, Allocator>::reference
00501   Vector<T, VectFull, Allocator>::Get(int i)
00502   {
00503 
00504 #ifdef SELDON_CHECK_BOUNDS
00505     if (i < 0 || i >= this->m_)
00506       throw WrongIndex("Vector<VectFull>::Get(int)",
00507                        string("Index should be in [0, ") + to_str(this->m_-1)
00508                        + "], but is equal to " + to_str(i) + ".");
00509 #endif
00510 
00511     return this->data_[i];
00512   }
00513 
00514 
00516 
00520   template <class T, class Allocator>
00521   inline typename Vector<T, VectFull, Allocator>::const_reference
00522   Vector<T, VectFull, Allocator>::operator() (int i) const
00523   {
00524 
00525 #ifdef SELDON_CHECK_BOUNDS
00526     if (i < 0 || i >= this->m_)
00527       throw WrongIndex("Vector<VectFull>::operator() const",
00528                        string("Index should be in [0, ") + to_str(this->m_-1)
00529                        + "], but is equal to " + to_str(i) + ".");
00530 #endif
00531 
00532     return this->data_[i];
00533   }
00534 
00535 
00537 
00541   template <class T, class Allocator>
00542   inline typename Vector<T, VectFull, Allocator>::const_reference
00543   Vector<T, VectFull, Allocator>::Get(int i) const
00544   {
00545 
00546 #ifdef SELDON_CHECK_BOUNDS
00547     if (i < 0 || i >= this->m_)
00548       throw WrongIndex("Vector<VectFull>::Get(int) const",
00549                        string("Index should be in [0, ") + to_str(this->m_-1)
00550                        + "], but is equal to " + to_str(i) + ".");
00551 #endif
00552 
00553     return this->data_[i];
00554   }
00555 
00556 
00558 
00563   template <class T, class Allocator>
00564   inline Vector<T, VectFull, Allocator>& Vector<T, VectFull, Allocator>
00565   ::operator= (const Vector<T, VectFull, Allocator>& X)
00566   {
00567     this->Copy(X);
00568 
00569     return *this;
00570   }
00571 
00572 
00574 
00579   template <class T, class Allocator>
00580   inline void Vector<T, VectFull, Allocator>
00581   ::Copy(const Vector<T, VectFull, Allocator>& X)
00582   {
00583     this->Reallocate(X.GetLength());
00584 
00585     this->vect_allocator_.memorycpy(this->data_, X.GetData(), this->m_);
00586   }
00587 
00588 
00590 
00595   template <class T, class Allocator>
00596   inline Vector<T, VectFull, Allocator>
00597   Vector<T, VectFull, Allocator>::Copy() const
00598   {
00599     return Vector<T, VectFull, Allocator>(*this);
00600   }
00601 
00602 
00604 
00607   template <class T, class Allocator> template<class T0>
00608   inline Vector<T, VectFull, Allocator>& Vector<T, VectFull, Allocator>
00609   ::operator*= (const T0& alpha)
00610   {
00611     for (int i = 0; i < this->m_; i++)
00612       this->data_[i] *= alpha;
00613 
00614     return *this;
00615   }
00616 
00617 
00619 
00624   template <class T, class Allocator>
00625   inline void Vector<T, VectFull, Allocator>::Append(const T& x)
00626   {
00627     int i = this->GetLength();
00628     this->Reallocate(i + 1);
00629     this->data_[i] = x;
00630   }
00631 
00632 
00634 
00637   template <class T, class Allocator> template<class T0>
00638   inline void Vector<T, VectFull, Allocator>::PushBack(const T0& x)
00639   {
00640     Resize(this->m_+1);
00641     this->data_[this->m_-1] = x;
00642   }
00643 
00644 
00646 
00649   template <class T, class Allocator> template<class Allocator0>
00650   inline void Vector<T, VectFull, Allocator>
00651   ::PushBack(const Vector<T, VectFull, Allocator0>& X)
00652   {
00653     int Nold = this->m_;
00654     Resize(this->m_ + X.GetM());
00655     for (int i = 0; i < X.GetM(); i++)
00656       this->data_[Nold+i] = X(i);
00657   }
00658 
00659 
00660   /*******************
00661    * BASIC FUNCTIONS *
00662    *******************/
00663 
00664 
00666 
00669   template <class T, class Allocator>
00670   int Vector<T, VectFull, Allocator>::GetDataSize()
00671   {
00672     return this->m_;
00673   }
00674 
00675 
00676   /************************
00677    * CONVENIENT FUNCTIONS *
00678    ************************/
00679 
00680 
00682 
00686   template <class T, class Allocator>
00687   void Vector<T, VectFull, Allocator>::Zero()
00688   {
00689     this->vect_allocator_.memoryset(this->data_, char(0),
00690                                     this->GetDataSize() * sizeof(value_type));
00691   }
00692 
00693 
00695   template <class T, class Allocator>
00696   void Vector<T, VectFull, Allocator>::Fill()
00697   {
00698     for (int i = 0; i < this->m_; i++)
00699       this->data_[i] = i;
00700   }
00701 
00702 
00704 
00707   template <class T, class Allocator>
00708   template <class T0>
00709   void Vector<T, VectFull, Allocator>::Fill(const T0& x)
00710   {
00711     for (int i = 0; i < this->m_; i++)
00712       this->data_[i] = x;
00713   }
00714 
00715 
00717 
00720   template <class T, class Allocator>
00721   template <class T0>
00722   Vector<T, VectFull, Allocator>&
00723   Vector<T, VectFull, Allocator>::operator= (const T0& x)
00724   {
00725     this->Fill(x);
00726 
00727     return *this;
00728   }
00729 
00730 
00732 
00735   template <class T, class Allocator>
00736   void Vector<T, VectFull, Allocator>::FillRand()
00737   {
00738     srand(time(NULL));
00739     for (int i = 0; i < this->m_; i++)
00740       this->data_[i] = rand();
00741   }
00742 
00743 
00745   template <class T, class Allocator>
00746   void Vector<T, VectFull, Allocator>::Print() const
00747   {
00748     for (int i = 0; i < this->GetLength(); i++)
00749       cout << (*this)(i) << "\t";
00750     cout << endl;
00751   }
00752 
00753 
00754   /*********
00755    * NORMS *
00756    *********/
00757 
00758 
00760 
00763   template <class T, class Allocator>
00764   typename Vector<T, VectFull, Allocator>::value_type
00765   Vector<T, VectFull, Allocator>::GetNormInf() const
00766   {
00767     value_type res = value_type(0);
00768     for (int i = 0; i < this->GetLength(); i++)
00769       {
00770         res = max(res, this->data_[i]);
00771         res = max(res, T(-this->data_[i]));
00772       }
00773 
00774     return res;
00775   }
00776 
00777 
00779 
00782   template <class T, class Allocator>
00783   int Vector<T, VectFull, Allocator>::GetNormInfIndex() const
00784   {
00785 
00786 #ifdef SELDON_CHECK_DIMENSIONS
00787     if (this->GetLength() == 0)
00788       throw WrongDim("Vector<VectFull>::GetNormInfIndex()",
00789                      "Vector is null.");
00790 #endif
00791 
00792     value_type res = value_type(0), temp;
00793     int j = 0;
00794     for (int i = 0; i < this->GetLength(); i++)
00795       {
00796         temp = res;
00797         res = max(res, this->data_[i]);
00798         res = max(res, T(-this->data_[i]));
00799         if (temp != res) j = i;
00800       }
00801 
00802     return j;
00803   }
00804 
00805 
00806   /**************************
00807    * OUTPUT/INPUT FUNCTIONS *
00808    **************************/
00809 
00810 
00812 
00818   template <class T, class Allocator>
00819   void Vector<T, VectFull, Allocator>
00820   ::Write(string FileName, bool with_size) const
00821   {
00822     ofstream FileStream;
00823     FileStream.open(FileName.c_str(), ofstream::binary);
00824 
00825 #ifdef SELDON_CHECK_IO
00826     // Checks if the file was opened.
00827     if (!FileStream.is_open())
00828       throw IOError("Vector<VectFull>::Write(string FileName, "
00829                     "bool with_size)",
00830                     string("Unable to open file \"") + FileName + "\".");
00831 #endif
00832 
00833     this->Write(FileStream, with_size);
00834 
00835     FileStream.close();
00836   }
00837 
00838 
00840 
00846   template <class T, class Allocator>
00847   void Vector<T, VectFull, Allocator>
00848   ::Write(ostream& FileStream, bool with_size) const
00849   {
00850 
00851 #ifdef SELDON_CHECK_IO
00852     // Checks if the stream is ready.
00853     if (!FileStream.good())
00854       throw IOError("Vector<VectFull>::Write(ostream& FileStream, "
00855                     "bool with_size)",
00856                     "The stream is not ready.");
00857 #endif
00858 
00859     if (with_size)
00860       FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00861                        sizeof(int));
00862 
00863     FileStream.write(reinterpret_cast<char*>(this->data_),
00864                      this->m_ * sizeof(value_type));
00865 
00866 #ifdef SELDON_CHECK_IO
00867     // Checks if data was written.
00868     if (!FileStream.good())
00869       throw IOError("Vector<VectFull>::Write(ostream& FileStream, "
00870                     "bool with_size)",
00871                     "Output operation failed.");
00872 #endif
00873 
00874   }
00875 
00876 
00878 
00883   template <class T, class Allocator>
00884   void Vector<T, VectFull, Allocator>::WriteText(string FileName) const
00885   {
00886     ofstream FileStream;
00887     FileStream.precision(cout.precision());
00888     FileStream.flags(cout.flags());
00889     FileStream.open(FileName.c_str());
00890 
00891 #ifdef SELDON_CHECK_IO
00892     // Checks if the file was opened.
00893     if (!FileStream.is_open())
00894       throw IOError("Vector<VectFull>::WriteText(string FileName)",
00895                     string("Unable to open file \"") + FileName + "\".");
00896 #endif
00897 
00898     this->WriteText(FileStream);
00899 
00900     FileStream.close();
00901   }
00902 
00903 
00905 
00910   template <class T, class Allocator>
00911   void Vector<T, VectFull, Allocator>::WriteText(ostream& FileStream) const
00912   {
00913 
00914 #ifdef SELDON_CHECK_IO
00915     // Checks if the stream is ready.
00916     if (!FileStream.good())
00917       throw IOError("Vector<VectFull>::WriteText(ostream& FileStream)",
00918                     "The stream is not ready.");
00919 #endif
00920 
00921     if (this->GetLength() != 0)
00922       FileStream << (*this)(0);
00923 
00924     for (int i = 1; i < this->GetLength(); i++)
00925       FileStream << "\t" << (*this)(i);
00926 
00927 #ifdef SELDON_CHECK_IO
00928     // Checks if data was written.
00929     if (!FileStream.good())
00930       throw IOError("Vector<VectFull>::WriteText(ostream& FileStream)",
00931                     "Output operation failed.");
00932 #endif
00933 
00934   }
00935 
00936 
00937 #ifdef SELDON_WITH_HDF5
00938 
00939 
00945   template <class T, class Allocator>
00946   void Vector<T, VectFull, Allocator>::WriteHDF5(string FileName,
00947                                                  string group_name,
00948                                                  string dataset_name) const
00949   {
00950     hid_t file_id = H5Fopen(FileName.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
00951 
00952 #ifdef SELDON_CHECK_IO
00953     // Checks if the file was opened.
00954     if (!file_id)
00955       throw IOError("Vector<VectFull>::WriteHDF5(string FileName)",
00956                     string("Unable to open file \"") + FileName + "\".");
00957 #endif
00958 
00959     hid_t dataset_id, dataspace_id, group_id;
00960     herr_t status;
00961 
00962     T x(0);
00963     hid_t datatype = GetH5Type(x);
00964 
00965     if (!H5Lexists(file_id, group_name.c_str(), H5P_DEFAULT))
00966       group_id = H5Gcreate(file_id, group_name.c_str(), 0);
00967     group_id = H5Gopen(file_id, group_name.c_str());
00968 
00969     if (!H5Lexists(group_id, dataset_name.c_str(), H5P_DEFAULT))
00970       {
00971         // Create the initial dataspace.
00972         hsize_t dim[1] = {0};
00973         hsize_t maxdims[1] = {H5S_UNLIMITED};
00974         dataspace_id = H5Screate_simple(1, dim, maxdims);
00975 
00976         // Define chunking parameters to allow extension of the dataspace.
00977         hid_t cparms = H5Pcreate(H5P_DATASET_CREATE);
00978         hsize_t chunk_dims[1] = {this->GetLength()};
00979         status = H5Pset_chunk(cparms, 1, chunk_dims);
00980 
00981         // Create the dataset.
00982         hid_t filetype = H5Tvlen_create(datatype);
00983         dataset_id = H5Dcreate(group_id, dataset_name.c_str(),
00984                                filetype, dataspace_id, cparms);
00985       }
00986 
00987     // Opens the dataset, and extend it to store a new vector.
00988     dataset_id = H5Dopen(group_id, dataset_name.c_str());
00989     dataspace_id = H5Dget_space(dataset_id);
00990     hsize_t dims_out[1];
00991     status  = H5Sget_simple_extent_dims(dataspace_id, dims_out, NULL);
00992     hsize_t new_dim[1]= {dims_out[0] + 1};
00993     status = H5Dextend(dataset_id, new_dim);
00994 
00995     // Selects the last memory part of the dataset, to store the vector.
00996     hsize_t offset[1] = {dims_out[0]};
00997     hsize_t dim2[1] = {1};
00998     dataspace_id = H5Dget_space(dataset_id);
00999     status = H5Sselect_hyperslab(dataspace_id, H5S_SELECT_SET,
01000                                  offset, NULL,
01001                                  dim2, NULL);
01002 
01003     // Defines memory space.
01004     hid_t dataspace = H5Screate_simple(1, dim2, NULL);
01005 
01006     // Writes the data to the memory hyperslab selected.
01007     hid_t memtype = H5Tvlen_create(datatype);
01008     hvl_t wdata[1];
01009     wdata[0].len = this->GetLength();
01010     wdata[0].p = this->GetDataVoid();
01011     status = H5Dwrite(dataset_id, memtype, dataspace,
01012                       dataspace_id, H5P_DEFAULT, wdata);
01013 
01014     // Closes the dataset, group and file.
01015     status = H5Dclose(dataset_id);
01016     status = H5Gclose(group_id);
01017     status = H5Fclose(file_id);
01018   }
01019 #endif
01020 
01021 
01023 
01031   template <class T, class Allocator>
01032   void Vector<T, VectFull, Allocator>
01033   ::Read(string FileName, bool with_size)
01034   {
01035     ifstream FileStream;
01036     FileStream.open(FileName.c_str(), ifstream::binary);
01037 
01038 #ifdef SELDON_CHECK_IO
01039     // Checks if the file was opened.
01040     if (!FileStream.is_open())
01041       throw IOError("Vector<VectFull>::Read(string FileName, bool with_size)",
01042                     string("Unable to open file \"") + FileName + "\".");
01043 #endif
01044 
01045     this->Read(FileStream, with_size);
01046 
01047     FileStream.close();
01048   }
01049 
01050 
01052 
01060   template <class T, class Allocator>
01061   void Vector<T, VectFull, Allocator>
01062   ::Read(istream& FileStream, bool with_size)
01063   {
01064 
01065 #ifdef SELDON_CHECK_IO
01066     // Checks if the stream is ready.
01067     if (!FileStream.good())
01068       throw IOError("Vector<VectFull>::Read(istream& FileStream, "
01069                     "bool with_size)",
01070                     "The stream is not ready.");
01071 #endif
01072 
01073     if (with_size)
01074       {
01075         int new_size;
01076         FileStream.read(reinterpret_cast<char*>(&new_size), sizeof(int));
01077         this->Reallocate(new_size);
01078       }
01079 
01080     FileStream.read(reinterpret_cast<char*>(this->data_),
01081                     this->GetLength() * sizeof(value_type));
01082 
01083 #ifdef SELDON_CHECK_IO
01084     // Checks if data was read.
01085     if (!FileStream.good())
01086       throw IOError("Vector<VectFull>::Read(istream& FileStream, "
01087                     "bool with_size)",
01088                     "Output operation failed.");
01089 #endif
01090 
01091   }
01092 
01093 
01095 
01100   template <class T, class Allocator>
01101   void Vector<T, VectFull, Allocator>::ReadText(string FileName)
01102   {
01103     ifstream FileStream;
01104     FileStream.open(FileName.c_str());
01105 
01106 #ifdef SELDON_CHECK_IO
01107     // Checks if the file was opened.
01108     if (!FileStream.is_open())
01109       throw IOError("Vector<VectFull>::ReadText(string FileName)",
01110                     string("Unable to open file \"") + FileName + "\".");
01111 #endif
01112 
01113     this->ReadText(FileStream);
01114 
01115     FileStream.close();
01116   }
01117 
01118 
01120 
01125   template <class T, class Allocator>
01126   void Vector<T, VectFull, Allocator>::ReadText(istream& FileStream)
01127   {
01128     // Previous values of the vector are cleared.
01129     Clear();
01130 
01131 #ifdef SELDON_CHECK_IO
01132     // Checks if the stream is ready.
01133     if (!FileStream.good())
01134       throw IOError("Vector<VectFull>::ReadText(istream& FileStream)",
01135                     "The stream is not ready.");
01136 #endif
01137 
01138     T entry;
01139     int number_element = 0;
01140     while (!FileStream.eof())
01141       {
01142         // Reads a new entry.
01143         FileStream >> entry;
01144 
01145         if (FileStream.fail())
01146           break;
01147         else
01148           {
01149             number_element++;
01150 
01151             // If needed, resizes the vector. Its size is already doubled so
01152             // that the vector should be resized a limited number of times.
01153             if (number_element > this->m_)
01154               this->Resize(2 * number_element);
01155 
01156             this->data_[number_element - 1] = entry;
01157           }
01158       }
01159 
01160     // Resizes to the actual size.
01161     if (number_element > 0)
01162       this->Resize(number_element);
01163     else
01164       this->Clear();
01165   }
01166 
01167 
01169 
01174   template <class T, class Storage, class Allocator>
01175   ostream& operator << (ostream& out,
01176                         const Vector<T, Storage, Allocator>& V)
01177   {
01178     for (int i = 0; i < V.GetLength() - 1; i++)
01179       out << V(i) << '\t';
01180     if (V.GetLength() != 0)
01181       out << V(V.GetLength() - 1);
01182 
01183     return out;
01184   }
01185 
01186 
01187 } // namespace Seldon.
01188 
01189 #define SELDON_FILE_VECTOR_CXX
01190 #endif