00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef SELDON_FILE_SPARSE_VECTOR_CXX
00022
00023 #include "SparseVector.hxx"
00024
00025 namespace Seldon
00026 {
00027
00028
00029
00030
00031
00032
00033
00035
00038 template <class T, class Allocator>
00039 Vector<T, VectSparse, Allocator>::Vector() throw():
00040 Vector<T, VectFull, Allocator>()
00041 {
00042 index_ = NULL;
00043 }
00044
00045
00047
00050 template <class T, class Allocator>
00051 Vector<T, VectSparse, Allocator>::Vector(int i):
00052 Vector<T, VectFull, Allocator>(i)
00053 {
00054
00055 #ifdef SELDON_CHECK_MEMORY
00056 try
00057 {
00058 #endif
00059
00060 this->index_ = index_allocator_.allocate(i, this);
00061
00062 #ifdef SELDON_CHECK_MEMORY
00063 }
00064 catch (...)
00065 {
00066 this->m_ = 0;
00067 this->index_ = NULL;
00068 this->data_ = NULL;
00069 }
00070
00071 if (this->index_ == NULL)
00072 {
00073 this->m_ = 0;
00074 this->data_ = NULL;
00075 }
00076
00077 if (this->data_ == NULL && i != 0)
00078 throw NoMemory("Vector<VectSparse>::Vector(int)",
00079 string("Unable to allocate memory for a vector of size ")
00080 + to_str(i * sizeof(T)) + " bytes ("
00081 + to_str(i) + " elements).");
00082 #endif
00083
00084 }
00085
00086
00088
00091 template <class T, class Allocator>
00092 Vector<T, VectSparse, Allocator>::
00093 Vector(const Vector<T, VectSparse, Allocator>& V) :
00094 Vector<T, VectFull, Allocator>()
00095 {
00096 this->index_ = NULL;
00097 Copy(V);
00098 }
00099
00100
00101
00102
00103
00104
00105
00107 template <class T, class Allocator>
00108 Vector<T, VectSparse, Allocator>::~Vector()
00109 {
00110
00111 #ifdef SELDON_CHECK_MEMORY
00112 try
00113 {
00114 #endif
00115 if (this->data_ != NULL)
00116 {
00117 this->vect_allocator_.deallocate(this->data_, this->m_);
00118 this->data_ = NULL;
00119 }
00120
00121 if (index_ != NULL)
00122 {
00123 index_allocator_.deallocate(index_, this->m_);
00124 index_ = NULL;
00125 }
00126
00127 this->m_ = 0;
00128
00129 #ifdef SELDON_CHECK_MEMORY
00130 }
00131 catch (...)
00132 {
00133 this->data_ = NULL;
00134 index_ = NULL;
00135 this->m_ = 0;
00136 return;
00137 }
00138 #endif
00139
00140 }
00141
00142
00143
00144
00145
00146
00147
00149
00153 template <class T, class Allocator>
00154 inline void Vector<T, VectSparse, Allocator>::Clear()
00155 {
00156 this->~Vector();
00157 }
00158
00159
00161
00167 template <class T, class Allocator>
00168 inline void Vector<T, VectSparse, Allocator>::Reallocate(int i)
00169 {
00170
00171 if (i != this->m_)
00172 {
00173
00174 this->m_ = i;
00175
00176 #ifdef SELDON_CHECK_MEMORY
00177 try
00178 {
00179 #endif
00180
00181 this->data_ =
00182 reinterpret_cast<pointer>(this->vect_allocator_
00183 .reallocate(this->data_, i, this));
00184
00185 index_
00186 = reinterpret_cast<int*>(this->index_allocator_
00187 .reallocate(index_, i, this));
00188
00189 #ifdef SELDON_CHECK_MEMORY
00190 }
00191 catch (...)
00192 {
00193 this->m_ = 0;
00194 this->data_ = NULL;
00195 this->index_ = NULL;
00196 return;
00197 }
00198 if (this->data_ == NULL)
00199 {
00200 this->m_ = 0;
00201 this->index_ = NULL;
00202 return;
00203 }
00204 #endif
00205
00206 }
00207 }
00208
00209
00211
00216 template <class T, class Allocator>
00217 inline void Vector<T, VectSparse, Allocator>::Resize(int n)
00218 {
00219
00220 if (n == this->m_)
00221 return;
00222
00223 Vector<T, VectFull, Allocator> new_value(n);
00224 Vector<int> new_index(n);
00225 int Nmin = min(this->m_, n);
00226 for (int i = 0; i < Nmin; i++)
00227 {
00228 new_value(i) = this->data_[i];
00229 new_index(i) = index_[i];
00230 }
00231
00232 SetData(new_value, new_index);
00233 }
00234
00235
00252 template <class T, class Allocator>
00253 inline void Vector<T, VectSparse, Allocator>
00254 ::SetData(int i, T* data, int* index)
00255 {
00256 this->Clear();
00257
00258 this->m_ = i;
00259
00260 this->data_ = data;
00261 this->index_ = index;
00262 }
00263
00264
00276 template <class T, class Allocator>
00277 template<class Allocator2>
00278 void Vector<T, VectSparse, Allocator>
00279 ::SetData(Vector<T, VectFull, Allocator2>& data, Vector<int>& index)
00280 {
00281
00282 #ifdef SELDON_CHECK_BOUNDS
00283 if (data.GetM() != index.GetM())
00284 throw WrongDim("Vector<VectSparse>::SetData ",
00285 string("The data vector and the index vector should")
00286 + " have the same size.\n Size of the data vector: "
00287 + to_str(data.GetM()) + "\n Size of index vector: "
00288 + to_str(index.GetM()));
00289 #endif
00290
00291 SetData(data.GetM(), data.GetData(), index.GetData());
00292 data.Nullify();
00293 index.Nullify();
00294 }
00295
00296
00308 template <class T, class Allocator>
00309 template<class Allocator2>
00310 void Vector<T, VectSparse, Allocator>
00311 ::SetData(const Vector<T, VectSparse, Allocator2>& V)
00312 {
00313 SetData(V.GetM(), V.GetData(), V.GetIndex());
00314 }
00315
00316
00318
00323 template <class T, class Allocator>
00324 void Vector<T, VectSparse, Allocator>::Nullify()
00325 {
00326 this->m_ = 0;
00327 this->data_ = NULL;
00328 this->index_ = NULL;
00329 }
00330
00331
00332
00333
00334
00335
00336
00338
00342 template <class T, class Allocator>
00343 inline typename Vector<T, VectSparse, Allocator>::reference
00344 Vector<T, VectSparse, Allocator>::Value(int i)
00345 {
00346
00347 #ifdef SELDON_CHECK_BOUNDS
00348 if (i < 0 || i >= this->m_)
00349 throw WrongIndex("Vector<VectSparse>::Value(int)",
00350 string("Index should be in [0, ") + to_str(this->m_-1)
00351 + "], but is equal to " + to_str(i) + ".");
00352 #endif
00353
00354 return this->data_[i];
00355 }
00356
00357
00359
00363 template <class T, class Allocator>
00364 inline typename Vector<T, VectSparse, Allocator>::const_reference
00365 Vector<T, VectSparse, Allocator>::Value(int i) const
00366 {
00367
00368 #ifdef SELDON_CHECK_BOUNDS
00369 if (i < 0 || i >= this->m_)
00370 throw WrongIndex("Vector<VectSparse>::Value(int)",
00371 string("Index should be in [0, ") + to_str(this->m_-1)
00372 + "], but is equal to " + to_str(i) + ".");
00373 #endif
00374
00375 return this->data_[i];
00376 }
00377
00378
00380
00384 template <class T, class Allocator>
00385 inline int& Vector<T, VectSparse, Allocator>::Index(int i)
00386 {
00387
00388 #ifdef SELDON_CHECK_BOUNDS
00389 if (i < 0 || i >= this->m_)
00390 throw WrongIndex("Vector<VectSparse>::Index(int)",
00391 string("Index should be in [0, ") + to_str(this->m_-1)
00392 + "], but is equal to " + to_str(i) + ".");
00393 #endif
00394
00395 return this->index_[i];
00396 }
00397
00398
00400
00404 template <class T, class Allocator>
00405 inline int Vector<T, VectSparse, Allocator>::Index(int i) const
00406 {
00407
00408 #ifdef SELDON_CHECK_BOUNDS
00409 if (i < 0 || i >= this->m_)
00410 throw WrongIndex("Vector<VectSparse>::Index(int)",
00411 string("Index should be in [0, ") + to_str(this->m_-1)
00412 + "], but is equal to " + to_str(i) + ".");
00413 #endif
00414
00415 return this->index_[i];
00416 }
00417
00418
00420
00424 template <class T, class Allocator>
00425 inline typename Vector<T, VectSparse, Allocator>::reference
00426 Vector<T, VectSparse, Allocator>::operator() (int i)
00427 {
00428 int k = 0;
00429
00430 while (k < this->m_ && index_[k] < i)
00431 k++;
00432
00433 if (k >= this->m_ || index_[k] != i)
00434
00435 AddInteraction(i, T(0));
00436
00437 return this->data_[k];
00438 }
00439
00440
00442
00446 template <class T, class Allocator>
00447 inline typename Vector<T, VectSparse, Allocator>::value_type
00448 Vector<T, VectSparse, Allocator>::operator() (int i) const
00449 {
00450 int k = 0;
00451
00452 while (k < this->m_ && index_[k] < i)
00453 k++;
00454
00455 if (k >= this->m_ || index_[k] != i)
00456
00457 return T(0);
00458
00459 return this->data_[k];
00460 }
00461
00462
00464
00468 template <class T, class Allocator>
00469 inline typename Vector<T, VectSparse, Allocator>::reference
00470 Vector<T, VectSparse, Allocator>::Val(int i)
00471 {
00472 return (*this)(i);
00473 }
00474
00475
00477
00483 template <class T, class Allocator>
00484 inline typename Vector<T, VectSparse, Allocator>::const_reference
00485 Vector<T, VectSparse, Allocator>::Val(int i) const
00486 {
00487 int k = 0;
00488
00489 while (k < this->m_ && index_[k] < i)
00490 k++;
00491
00492 if (k >= this->m_ || index_[k] != i)
00493
00494 throw WrongArgument("Vector<VectSparse>::Val(int)",
00495 "No reference to element " + to_str(i)
00496 + " can be returned: it is a zero entry.");
00497
00498 return this->data_[k];
00499 }
00500
00501
00503
00508 template <class T, class Allocator>
00509 inline Vector<T, VectSparse, Allocator>& Vector<T, VectSparse, Allocator>
00510 ::operator= (const Vector<T, VectSparse, Allocator>& X)
00511 {
00512 this->Copy(X);
00513
00514 return *this;
00515 }
00516
00517
00519
00524 template <class T, class Allocator>
00525 inline void Vector<T, VectSparse, Allocator>
00526 ::Copy(const Vector<T, VectSparse, Allocator>& X)
00527 {
00528 this->Reallocate(X.GetLength());
00529
00530 this->vect_allocator_.memorycpy(this->data_, X.GetData(), this->m_);
00531 this->index_allocator_.memorycpy(this->index_, X.GetIndex(), this->m_);
00532 }
00533
00534
00535
00536
00537
00538
00539
00545 template <class T, class Allocator>
00546 int* Vector<T, VectSparse, Allocator>::GetIndex() const
00547 {
00548 return this->index_;
00549 }
00550
00551
00552
00553
00554
00555
00556
00558
00561 template <class T, class Allocator>
00562 template <class T0>
00563 Vector<T, VectSparse, Allocator>&
00564 Vector<T, VectSparse, Allocator>::operator= (const T0& x)
00565 {
00566 this->Fill(x);
00567
00568 return *this;
00569 }
00570
00571
00573 template <class T, class Allocator>
00574 void Vector<T, VectSparse, Allocator>::Print() const
00575 {
00576 for (int i = 0; i < this->GetLength(); i++)
00577 cout << (Index(i) + 1) << ' ' << Value(i) << '\n';
00578 }
00579
00580
00582
00586 template <class T, class Allocator>
00587 void Vector<T, VectSparse, Allocator>::Assemble()
00588 {
00589 int new_size = this->m_;
00590 Vector<T, VectFull, Allocator> values(new_size);
00591 Vector<int> index(new_size);
00592 for (int i = 0; i < new_size; i++)
00593 {
00594 values(i) = this->data_[i];
00595 index(i) = index_[i];
00596 }
00597
00598 Seldon::Assemble(new_size, index, values);
00599 index.Resize(new_size);
00600 values.Resize(new_size);
00601 SetData(values, index);
00602 }
00603
00604
00606
00610 template <class T, class Allocator> template<class T0>
00611 void Vector<T, VectSparse, Allocator>::RemoveSmallEntry(const T0& epsilon)
00612 {
00613 int new_size = this->m_;
00614 Vector<T, VectFull, Allocator> values(new_size);
00615 Vector<int> index(new_size);
00616 new_size = 0;
00617 for (int i = 0; i < this->m_; i++)
00618 if (abs(this->data_[i]) > epsilon)
00619 {
00620 values(new_size) = this->data_[i];
00621 index(new_size) = index_[i];
00622 new_size++;
00623 }
00624
00625 index.Resize(new_size);
00626 values.Resize(new_size);
00627 SetData(values, index);
00628 }
00629
00630
00632
00637 template <class T, class Allocator> inline
00638 void Vector<T, VectSparse, Allocator>::AddInteraction(int i, const T& val)
00639 {
00640
00641 int pos = 0;
00642 while (pos < this->m_ && index_[pos] < i)
00643 pos++;
00644
00645
00646 if (pos < this->m_ && index_[pos] == i)
00647 {
00648 this->data_[pos] += val;
00649 return;
00650 }
00651
00652 int k;
00653
00654
00655 Vector<T, VectFull, Allocator> new_val(this->m_ + 1);
00656 Vector<int> new_ind(this->m_ + 1);
00657 for (k = 0; k < pos; k++)
00658 {
00659 new_ind(k) = index_[k];
00660 new_val(k) = this->data_[k];
00661 }
00662
00663
00664 new_ind(pos) = i;
00665 new_val(pos) = val;
00666
00667
00668 for (k = pos + 1; k <= this->m_; k++)
00669 {
00670 new_ind(k) = index_[k - 1];
00671 new_val(k) = this->data_[k - 1];
00672 }
00673
00674 SetData(new_val, new_ind);
00675 }
00676
00677
00679
00688 template <class T, class Allocator> inline
00689 void Vector<T, VectSparse, Allocator>::
00690 AddInteractionRow(int n, int* index, T* value, bool already_sorted)
00691 {
00692 Vector<int> ind;
00693 Vector<T, VectFull, Allocator> val;
00694 ind.SetData(n, index);
00695 val.SetData(n, value);
00696 AddInteractionRow(n, ind, val, already_sorted);
00697 ind.Nullify();
00698 val.Nullify();
00699 }
00700
00701
00703
00712 template <class T, class Allocator>
00713 template<class Allocator0>
00714 void Vector<T, VectSparse, Allocator>::
00715 AddInteractionRow(int n, Vector<int> index,
00716 Vector<T, VectFull, Allocator0> value,
00717 bool already_sorted)
00718 {
00719 if (!already_sorted)
00720
00721 Seldon::Assemble(n, index, value);
00722
00723
00724
00725
00726 int Nnew = 0;
00727 Vector<bool> new_index(n);
00728 new_index.Fill(true);
00729 int k = 0;
00730 for (int j = 0; j < n; j++)
00731 {
00732 while (k < this->m_ && index_[k] < index(j))
00733 k++;
00734
00735 if (k < this->m_ && index(j) == index_[k])
00736 {
00737 new_index(j) = false;
00738 this->data_[k] += value(j);
00739 }
00740 else
00741 Nnew++;
00742 }
00743
00744 if (Nnew > 0)
00745 {
00746
00747 Vector<T> new_val(this->m_ + Nnew);
00748 Vector<int> new_ind(this->m_ + Nnew);
00749 int nb = 0;
00750 k = 0;
00751 for (int j = 0; j < n; j++)
00752 if (new_index(j))
00753 {
00754 while (k < this->m_ && index_[k] < index(j))
00755 {
00756 new_ind(nb) = index_[k];
00757 new_val(nb) = this->data_[k];
00758 k++;
00759 nb++;
00760 }
00761
00762
00763 new_ind(nb) = index(j);
00764 new_val(nb) = value(j);
00765 nb++;
00766 }
00767
00768
00769 while (k < this->m_)
00770 {
00771 new_ind(nb) = index_[k];
00772 new_val(nb) = this->data_[k];
00773 k++;
00774 nb++;
00775 }
00776
00777 SetData(new_val, new_ind);
00778 }
00779 }
00780
00781
00782
00783
00784
00785
00786
00788
00793 template <class T, class Allocator>
00794 void Vector<T, VectSparse, Allocator>::Write(string FileName) const
00795 {
00796 ofstream FileStream;
00797 FileStream.open(FileName.c_str());
00798
00799 #ifdef SELDON_CHECK_IO
00800
00801 if (!FileStream.is_open())
00802 throw IOError("Vector<VectSparse>::Write(string FileName)",
00803 string("Unable to open file \"") + FileName + "\".");
00804 #endif
00805
00806 this->Write(FileStream);
00807
00808 FileStream.close();
00809 }
00810
00811
00813
00818 template <class T, class Allocator>
00819 void Vector<T, VectSparse, Allocator>::Write(ostream& stream) const
00820 {
00821
00822 #ifdef SELDON_CHECK_IO
00823
00824 if (!stream.good())
00825 throw IOError("Vector<VectSparse>::Write(ostream& stream)",
00826 "Stream is not ready.");
00827 #endif
00828
00829 stream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00830 sizeof(int));
00831
00832 stream.write(reinterpret_cast<char*>(this->index_),
00833 this->m_ * sizeof(int));
00834
00835 stream.write(reinterpret_cast<char*>(this->data_),
00836 this->m_ * sizeof(value_type));
00837
00838 #ifdef SELDON_CHECK_IO
00839
00840 if (!stream.good())
00841 throw IOError("Vector<VectSparse>::Write(ostream& stream)",
00842 "Output operation failed.");
00843 #endif
00844
00845 }
00846
00847
00849
00854 template <class T, class Allocator>
00855 void Vector<T, VectSparse, Allocator>::WriteText(string FileName) const
00856 {
00857 ofstream FileStream;
00858 FileStream.precision(cout.precision());
00859 FileStream.flags(cout.flags());
00860 FileStream.open(FileName.c_str());
00861
00862 #ifdef SELDON_CHECK_IO
00863
00864 if (!FileStream.is_open())
00865 throw IOError("Vector<VectSparse>::WriteText(string FileName)",
00866 string("Unable to open file \"") + FileName + "\".");
00867 #endif
00868
00869 this->WriteText(FileStream);
00870
00871 FileStream.close();
00872 }
00873
00874
00876
00881 template <class T, class Allocator>
00882 void Vector<T, VectSparse, Allocator>::WriteText(ostream& stream) const
00883 {
00884
00885 #ifdef SELDON_CHECK_IO
00886
00887 if (!stream.good())
00888 throw IOError("Vector<VectSparse>::WriteText(ostream& stream)",
00889 "Stream is not ready.");
00890 #endif
00891
00892
00893 for (int i = 0; i < this->m_ - 1; i++)
00894 stream << (Index(i) + 1) << " " << Value(i) << '\n';
00895
00896
00897
00898 if (this->m_ > 0)
00899 stream << (Index(this->m_ - 1) + 1) << " " << Value(this->m_ - 1);
00900
00901 #ifdef SELDON_CHECK_IO
00902
00903 if (!stream.good())
00904 throw IOError("Vector<VectSparse>::WriteText(ostream& stream)",
00905 "Output operation failed.");
00906 #endif
00907
00908 }
00909
00910
00912
00916 template <class T, class Allocator>
00917 void Vector<T, VectSparse, Allocator>::Read(string FileName)
00918 {
00919 ifstream FileStream;
00920 FileStream.open(FileName.c_str());
00921
00922 #ifdef SELDON_CHECK_IO
00923
00924 if (!FileStream.is_open())
00925 throw IOError("Vector<VectSparse>::Read(string FileName)",
00926 string("Unable to open file \"") + FileName + "\".");
00927 #endif
00928
00929 this->Read(FileStream);
00930
00931 FileStream.close();
00932 }
00933
00934
00936
00940 template <class T, class Allocator>
00941 void Vector<T, VectSparse, Allocator>::Read(istream& stream)
00942 {
00943
00944 #ifdef SELDON_CHECK_IO
00945
00946 if (!stream.good())
00947 throw IOError("Vector<VectSparse>::Read(istream& stream)",
00948 "Stream is not ready.");
00949 #endif
00950
00951 int m;
00952 stream.read(reinterpret_cast<char*>(&m), sizeof(int));
00953 this->Reallocate(m);
00954
00955 stream.read(reinterpret_cast<char*>(this->index_), m * sizeof(int));
00956
00957 stream.read(reinterpret_cast<char*>(this->data_),
00958 m * sizeof(value_type));
00959
00960 #ifdef SELDON_CHECK_IO
00961
00962 if (!stream.good())
00963 throw IOError("Vector<VectSparse>::Read(istream& stream)",
00964 "Output operation failed.");
00965 #endif
00966
00967 }
00968
00969
00971
00975 template <class T, class Allocator>
00976 void Vector<T, VectSparse, Allocator>::ReadText(string FileName)
00977 {
00978 ifstream FileStream;
00979 FileStream.open(FileName.c_str());
00980
00981 #ifdef SELDON_CHECK_IO
00982
00983 if (!FileStream.is_open())
00984 throw IOError("Vector<VectSparse>::ReadText(string FileName)",
00985 string("Unable to open file \"") + FileName + "\".");
00986 #endif
00987
00988 this->ReadText(FileStream);
00989
00990 FileStream.close();
00991 }
00992
00993
00995
00999 template <class T, class Allocator>
01000 void Vector<T, VectSparse, Allocator>::ReadText(istream& stream)
01001 {
01002 Clear();
01003
01004 #ifdef SELDON_CHECK_IO
01005
01006 if (!stream.good())
01007 throw IOError("Vector<VectSparse>::ReadText(istream& stream)",
01008 "Stream is not ready.");
01009 #endif
01010
01011 Vector<T, VectFull, Allocator> values;
01012 Vector<int> index;
01013 T entry;
01014 int ind = 0;
01015 int nb_elt = 0;
01016 while (!stream.eof())
01017 {
01018
01019 stream >> ind >> entry;
01020
01021 if (stream.fail())
01022 break;
01023 else
01024 {
01025 #ifdef SELDON_CHECK_IO
01026 if (ind < 1)
01027 throw IOError(string("Vector<VectSparse>::ReadText") +
01028 "(istream& stream)",
01029 string("Index should be greater ")
01030 + "than 0 but is equal to " + to_str(ind) + ".");
01031 #endif
01032
01033 nb_elt++;
01034 ind--;
01035
01036
01037 if (nb_elt > values.GetM())
01038 {
01039 values.Resize(2 * nb_elt);
01040 index.Resize(2 * nb_elt);
01041 }
01042
01043 values(nb_elt - 1) = entry;
01044 index(nb_elt - 1) = ind;
01045 }
01046 }
01047
01048 if (nb_elt > 0)
01049 {
01050
01051 this->Reallocate(nb_elt);
01052 for (int i = 0; i < nb_elt; i++)
01053 {
01054 Index(i) = index(i);
01055 Value(i) = values(i);
01056 }
01057 }
01058 }
01059
01060
01062
01067 template <class T, class Allocator>
01068 ostream& operator << (ostream& out,
01069 const Vector<T, VectSparse, Allocator>& V)
01070 {
01071 for (int i = 0; i < V.GetLength(); i++)
01072 out << (V.Index(i) + 1) << ' ' << V.Value(i) << '\n';
01073
01074 return out;
01075 }
01076
01077
01078 }
01079
01080 #define SELDON_FILE_SPARSE_VECTOR_CXX
01081 #endif