Vector.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_VECTOR_CXX
22 
23 #include "Vector.hxx"
24 
25 namespace Seldon
26 {
27 
29 
33  template <class T, class Allocator>
35  {
36  ResizeVector(n);
37  }
38 
39 
41 
45  template <class T, class Allocator>
47  {
48  // function implemented in the aim that explicit specialization
49  // of Resize can call ResizeVector
50  if (n == this->m_)
51  return;
52 
54  for (size_t i = 0; i < min(this->m_, n); i++)
55  X_new(i) = this->data_[i];
56 
57  SetData(n, X_new.GetData());
58  X_new.Nullify();
59  }
60 
61 
62  /*********
63  * NORMS *
64  *********/
65 
66 
68 
71  template <class T, class Allocator>
72  typename ClassComplexType<T>::Treal
74  {
75  typename ClassComplexType<T>::Treal res(0);
76  for (size_t i = 0; i < this->GetLength(); i++)
77  res = max(res, ComplexAbs(this->data_[i]));
78 
79  return res;
80  }
81 
82 
84 
87  template <class T, class Allocator>
89  {
90 
91 #ifdef SELDON_CHECK_DIMENSIONS
92  if (this->GetLength() == 0)
93  throw WrongDim("Vector<VectFull>::GetNormInfIndex()",
94  "Vector is null.");
95 #endif
96 
97  typename ClassComplexType<T>::Treal res(0), temp;
98  long j = 0;
99  for (size_t i = 0; i < this->GetLength(); i++)
100  {
101  temp = res;
102  res = max(res, ComplexAbs(this->data_[i]));
103  if (temp != res) j = i;
104  }
105 
106  return j;
107  }
108 
109 
110  /**************************
111  * OUTPUT/INPUT FUNCTIONS *
112  **************************/
113 
114 
116 
122  template <class T, class Allocator>
124  ::Write(string FileName, bool with_size) const
125  {
126  ofstream FileStream;
127  FileStream.open(FileName.c_str(), ofstream::binary);
128 
129 #ifdef SELDON_CHECK_IO
130  // Checks if the file was opened.
131  if (!FileStream.is_open())
132  throw IOError("Vector<VectFull>::Write(string FileName, "
133  "bool with_size)",
134  string("Unable to open file \"") + FileName + "\".");
135 #endif
136 
137  this->Write(FileStream, with_size);
138 
139  FileStream.close();
140  }
141 
142 
144 
150  template <class T, class Allocator>
152  ::Write(ostream& FileStream, bool with_size) const
153  {
154 
155 #ifdef SELDON_CHECK_IO
156  // Checks if the stream is ready.
157  if (!FileStream.good())
158  throw IOError("Vector<VectFull>::Write(ostream& FileStream, "
159  "bool with_size)",
160  "The stream is not ready.");
161 #endif
162  int n = this->m_;
163  if (with_size)
164  FileStream.write(reinterpret_cast<char*>(&n),
165  sizeof(int));
166 
167  FileStream.write(reinterpret_cast<char*>(this->data_),
168  this->m_ * sizeof(value_type));
169 
170 #ifdef SELDON_CHECK_IO
171  // Checks if data was written.
172  if (!FileStream.good())
173  throw IOError("Vector<VectFull>::Write(ostream& FileStream, "
174  "bool with_size)",
175  "Output operation failed.");
176 #endif
177 
178  }
179 
180 
182 
187  template <class T, class Allocator>
188  void Vector<T, VectFull, Allocator>::WriteText(string FileName) const
189  {
190  ofstream FileStream;
191  FileStream.precision(cout.precision());
192  FileStream.flags(cout.flags());
193  FileStream.open(FileName.c_str());
194 
195 #ifdef SELDON_CHECK_IO
196  // Checks if the file was opened.
197  if (!FileStream.is_open())
198  throw IOError("Vector<VectFull>::WriteText(string FileName)",
199  string("Unable to open file \"") + FileName + "\".");
200 #endif
201 
202  this->WriteText(FileStream);
203 
204  // end of line to finish the file
205  FileStream << endl;
206 
207  FileStream.close();
208  }
209 
210 
212 
217  template <class T, class Allocator>
218  void Vector<T, VectFull, Allocator>::WriteText(ostream& FileStream) const
219  {
220 
221 #ifdef SELDON_CHECK_IO
222  // Checks if the stream is ready.
223  if (!FileStream.good())
224  throw IOError("Vector<VectFull>::WriteText(ostream& FileStream)",
225  "The stream is not ready.");
226 #endif
227 
228  if (this->GetLength() != 0)
229  FileStream << (*this)(0);
230 
231  for (size_t i = 1; i < this->GetLength(); i++)
232  FileStream << "\t" << (*this)(i);
233 
234 #ifdef SELDON_CHECK_IO
235  // Checks if data was written.
236  if (!FileStream.good())
237  throw IOError("Vector<VectFull>::WriteText(ostream& FileStream)",
238  "Output operation failed.");
239 #endif
240 
241  }
242 
243 
244 #ifdef SELDON_WITH_HDF5
245 
252  template <class T, class Allocator>
253  void Vector<T, VectFull, Allocator>::WriteHDF5(string FileName,
254  string group_name,
255  string dataset_name) const
256  {
257  hid_t file_id = H5Fopen(FileName.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
258 
259 #ifdef SELDON_CHECK_IO
260  // Checks if the file was opened.
261  if (!file_id)
262  throw IOError("Vector<VectFull>::WriteHDF5(string FileName)",
263  string("Unable to open file \"") + FileName + "\".");
264 #endif
265 
266  hid_t dataset_id, dataspace_id, group_id;
267  herr_t status;
268 
269  T x;
270  SetComplexZero(x);
271  hid_t datatype = GetH5Type(x);
272 
273  if (!H5Lexists(file_id, group_name.c_str(), H5P_DEFAULT))
274  group_id = H5Gcreate(file_id, group_name.c_str(), 0);
275  group_id = H5Gopen(file_id, group_name.c_str());
276 
277  if (!H5Lexists(group_id, dataset_name.c_str(), H5P_DEFAULT))
278  {
279  // Create the initial dataspace.
280  hsize_t dim[1] = {0};
281  hsize_t maxdims[1] = {H5S_UNLIMITED};
282  dataspace_id = H5Screate_simple(1, dim, maxdims);
283 
284  // Define chunking parameters to allow extension of the dataspace.
285  hid_t cparms = H5Pcreate(H5P_DATASET_CREATE);
286  hsize_t chunk_dims[1] = {this->GetLength()};
287  status = H5Pset_chunk(cparms, 1, chunk_dims);
288 
289  // Create the dataset.
290  hid_t filetype = H5Tvlen_create(datatype);
291  dataset_id = H5Dcreate(group_id, dataset_name.c_str(),
292  filetype, dataspace_id, cparms);
293  }
294 
295  // Opens the dataset, and extend it to store a new vector.
296  dataset_id = H5Dopen(group_id, dataset_name.c_str());
297  dataspace_id = H5Dget_space(dataset_id);
298  hsize_t dims_out[1];
299  status = H5Sget_simple_extent_dims(dataspace_id, dims_out, NULL);
300  hsize_t new_dim[1]= {dims_out[0] + 1};
301  status = H5Dextend(dataset_id, new_dim);
302 
303  // Selects the last memory part of the dataset, to store the vector.
304  hsize_t offset[1] = {dims_out[0]};
305  hsize_t dim2[1] = {1};
306  dataspace_id = H5Dget_space(dataset_id);
307  status = H5Sselect_hyperslab(dataspace_id, H5S_SELECT_SET,
308  offset, NULL,
309  dim2, NULL);
310 
311  // Defines memory space.
312  hid_t dataspace = H5Screate_simple(1, dim2, NULL);
313 
314  // Writes the data to the memory hyperslab selected.
315  hid_t memtype = H5Tvlen_create(datatype);
316  hvl_t wdata[1];
317  wdata[0].len = this->GetLength();
318  wdata[0].p = this->GetDataVoid();
319  status = H5Dwrite(dataset_id, memtype, dataspace,
320  dataspace_id, H5P_DEFAULT, wdata);
321 
322  // Closes the dataset, group and file.
323  status = H5Dclose(dataset_id);
324  status = H5Gclose(group_id);
325  status = H5Fclose(file_id);
326  }
327 #endif
328 
329 
331 
339  template <class T, class Allocator>
341  ::Read(string FileName, bool with_size)
342  {
343  ifstream FileStream;
344  FileStream.open(FileName.c_str(), ifstream::binary);
345 
346 #ifdef SELDON_CHECK_IO
347  // Checks if the file was opened.
348  if (!FileStream.is_open())
349  throw IOError("Vector<VectFull>::Read(string FileName, bool with_size)",
350  string("Unable to open file \"") + FileName + "\".");
351 #endif
352 
353  this->Read(FileStream, with_size);
354 
355  FileStream.close();
356  }
357 
358 
360 
368  template <class T, class Allocator>
370  ::Read(istream& FileStream, bool with_size)
371  {
372 
373 #ifdef SELDON_CHECK_IO
374  // Checks if the stream is ready.
375  if (!FileStream.good())
376  throw IOError("Vector<VectFull>::Read(istream& FileStream, "
377  "bool with_size)",
378  "The stream is not ready.");
379 #endif
380 
381  if (with_size)
382  {
383  int new_size;
384  FileStream.read(reinterpret_cast<char*>(&new_size), sizeof(int));
385  this->Reallocate(new_size);
386  }
387 
388  FileStream.read(reinterpret_cast<char*>(this->data_),
389  this->GetLength() * sizeof(value_type));
390 
391 #ifdef SELDON_CHECK_IO
392  // Checks if data was read.
393  if (!FileStream.good())
394  throw IOError("Vector<VectFull>::Read(istream& FileStream, "
395  "bool with_size)",
396  "Output operation failed.");
397 #endif
398 
399  }
400 
401 
403 
408  template <class T, class Allocator>
410  {
411  ifstream FileStream;
412  FileStream.open(FileName.c_str());
413 
414 #ifdef SELDON_CHECK_IO
415  // Checks if the file was opened.
416  if (!FileStream.is_open())
417  throw IOError("Vector<VectFull>::ReadText(string FileName)",
418  string("Unable to open file \"") + FileName + "\".");
419 #endif
420 
421  this->ReadText(FileStream);
422 
423  FileStream.close();
424  }
425 
426 
428 
433  template <class T, class Allocator>
435  {
436  // Previous values of the vector are cleared.
437  Clear();
438 
439 #ifdef SELDON_CHECK_IO
440  // Checks if the stream is ready.
441  if (!FileStream.good())
442  throw IOError("Vector<VectFull>::ReadText(istream& FileStream)",
443  "The stream is not ready.");
444 #endif
445 
446  T entry;
447  size_t number_element = 0;
448  while (!FileStream.eof())
449  {
450  // Reads a new entry.
451  FileStream >> entry;
452  if (FileStream.fail())
453  break;
454  else
455  {
456  number_element++;
457 
458  // If needed, resizes the vector. Its size is already doubled so
459  // that the vector should be resized a limited number of times.
460  if (number_element > this->m_)
461  this->Resize(2 * number_element);
462 
463  this->data_[number_element - 1] = entry;
464  }
465  }
466 
467  // Resizes to the actual size.
468  if (number_element > 0)
469  this->Resize(number_element);
470  else
471  this->Clear();
472  }
473 
474 
476 
481  template <class T, class Storage, class Allocator>
482  ostream& operator << (ostream& out,
484  {
485  if (V.GetLength() >= 1)
486  for (size_t i = 0; i < V.GetLength() - 1; i++)
487  out << V(i) << '\t';
488 
489  if (V.GetLength() != 0)
490  out << V(V.GetLength() - 1);
491 
492  return out;
493  }
494 
495 
496 } // namespace Seldon.
497 
498 #define SELDON_FILE_VECTOR_CXX
499 #endif
Seldon::Vector
Definition: SeldonHeader.hxx:207
Seldon::Vector< T, VectFull, Allocator >::Nullify
void Nullify()
Clears the vector without releasing memory.
Definition: VectorInline.cxx:476
Seldon::Vector< T, VectFull, Allocator >::Read
void Read(string FileName, bool with_size=true)
Sets the vector from a file.
Definition: Vector.cxx:341
Seldon::Vector< T, VectFull, Allocator >
Full vector class.
Definition: Vector.hxx:88
Seldon::WrongDim
Definition: Errors.hxx:102
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::operator<<
ostream & operator<<(ostream &out, const Array< T, N, Allocator > &A)
operator<< overloaded for a 3D array.
Definition: Array.cxx:1617
Seldon::IOError
Definition: Errors.hxx:150
Seldon::ComplexAbs
T ComplexAbs(const T &val)
returns absolute value of val
Definition: CommonInline.cxx:309
Seldon::Vector_Base::GetData
pointer GetData() const
Returns a pointer to data_ (stored data).
Definition: VectorInline.cxx:177