vector/Vector2.cxx

00001 // Copyright (C) 2010, INRIA
00002 // Author(s): Marc Fragu, Vivien Mallet
00003 // Copyright (C) 2011, Vivien Mallet
00004 //
00005 // This file is part of the linear-algebra library Seldon,
00006 // http://seldon.sourceforge.net/.
00007 //
00008 // Seldon is free software; you can redistribute it and/or modify it under the
00009 // terms of the GNU Lesser General Public License as published by the Free
00010 // Software Foundation; either version 2.1 of the License, or (at your option)
00011 // any later version.
00012 //
00013 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00014 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00015 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00016 // more details.
00017 //
00018 // You should have received a copy of the GNU Lesser General Public License
00019 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00020 
00021 
00022 #ifndef SELDON_FILE_VECTOR_VECTOR2_CXX
00023 
00024 
00025 #include "Vector2.hxx"
00026 
00027 
00028 namespace Seldon
00029 {
00030 
00031 
00033   // VECTOR2 //
00035 
00036 
00037   /***************
00038    * CONSTRUCTOR *
00039    ***************/
00040 
00041 
00043 
00046   template <class T, class Allocator0, class Allocator1>
00047   Vector2<T, Allocator0, Allocator1>::Vector2()
00048   {
00049   }
00050 
00051 
00053 
00056   template <class T, class Allocator0, class Allocator1>
00057   Vector2<T, Allocator0, Allocator1>::Vector2(int length)
00058   {
00059     data_.Reallocate(length);
00060   }
00061 
00062 
00064 
00068   template <class T, class Allocator0, class Allocator1>
00069   Vector2<T, Allocator0, Allocator1>::Vector2(const Vector<int>& length)
00070   {
00071     data_.Clear();
00072     int m = length.GetSize();
00073     data_.Reallocate(m);
00074     for(int i = 0; i < m; i++)
00075       data_(i).Reallocate(length(i));
00076   }
00077 
00078 
00079   /**************
00080    * DESTRUCTOR *
00081    **************/
00082 
00083 
00085   template <class T, class Allocator0, class Allocator1>
00086   Vector2<T, Allocator0, Allocator1>::~Vector2()
00087   {
00088   }
00089 
00090 
00091   /*****************************
00092    * MANAGEMENT OF THE VECTORS *
00093    *****************************/
00094 
00095 
00097 
00100   template <class T, class Allocator0, class Allocator1>
00101   bool Vector2<T, Allocator0, Allocator1>::IsEmpty() const
00102   {
00103     for (int i = 0; i < GetLength(); i++)
00104       if (GetLength(i) > 0)
00105         return false;
00106     return true;
00107   }
00108 
00109 
00111 
00114   template <class T, class Allocator0, class Allocator1>
00115   int Vector2<T, Allocator0, Allocator1>::GetSize() const
00116   {
00117     return data_.GetSize();
00118   }
00119 
00120 
00122 
00125   template <class T, class Allocator0, class Allocator1>
00126   int Vector2<T, Allocator0, Allocator1>::GetLength() const
00127   {
00128     return data_.GetLength();
00129   }
00130 
00131 
00133 
00137   template <class T, class Allocator0, class Allocator1>
00138   int Vector2<T, Allocator0, Allocator1>::GetSize(int i) const
00139   {
00140     return data_(i).GetSize();
00141   }
00142 
00143 
00145 
00149   template <class T, class Allocator0, class Allocator1>
00150   int Vector2<T, Allocator0, Allocator1>::GetLength(int i) const
00151   {
00152     return data_(i).GetLength();
00153   }
00154 
00155 
00157 
00160   template <class T, class Allocator0, class Allocator1>
00161   int Vector2<T, Allocator0, Allocator1>::GetNelement() const
00162   {
00163     int total = 0;
00164     for (int i = 0; i < GetLength(); i++)
00165       total += GetLength(i);
00166     return total;
00167   }
00168 
00169 
00171 
00178   template <class T, class Allocator0, class Allocator1>
00179   int Vector2<T, Allocator0, Allocator1>::GetNelement(int beg, int end) const
00180   {
00181     if (beg > end)
00182       throw WrongArgument("Vector2::GetNelement(int beg, int end)",
00183                           "The lower bound of the range of inner vectors, ["
00184                           + to_str(beg) + ", " + to_str(end)
00185                           + "[, is strictly greater than its upper bound.");
00186     if (beg < 0 || end > GetLength())
00187       throw WrongArgument("Vector2::GetNelement(int beg, int end)",
00188                           "The inner-vector indexes should be in [0,"
00189                           + to_str(GetLength()) + "] but [" + to_str(beg)
00190                           + ", " + to_str(end) + "[ was provided.");
00191 
00192     int total = 0;
00193     for (int i = beg; i < end; i++)
00194       total += GetLength(i);
00195     return total;
00196   }
00197 
00198 
00200 
00203   template <class T, class Allocator0, class Allocator1>
00204   Vector<int> Vector2<T, Allocator0, Allocator1>::GetShape() const
00205   {
00206     Vector<int> shape(GetLength());
00207     for (int i = 0; i < GetLength(); i++)
00208       shape(i) = GetLength(i);
00209     return shape;
00210   }
00211 
00212 
00214 
00217   template <class T, class Allocator0, class Allocator1>
00218   void Vector2<T, Allocator0, Allocator1>::GetShape(Vector<int>& shape) const
00219   {
00220     shape.Reallocate(GetLength());
00221     for (int i = 0; i < GetLength(); i++)
00222       shape(i) = GetLength(i);
00223   }
00224 
00225 
00227 
00230   template <class T, class Allocator0, class Allocator1>
00231   void Vector2<T, Allocator0, Allocator1>::Reallocate(int M)
00232   {
00233     data_.Reallocate(M);
00234   }
00235 
00236 
00238 
00242   template <class T, class Allocator0, class Allocator1>
00243   void Vector2<T, Allocator0, Allocator1>::Reallocate(int i, int N)
00244   {
00245     data_(i).Reallocate(N);
00246   }
00247 
00248 
00250 
00254   template <class T, class Allocator0, class Allocator1>
00255   void Vector2<T, Allocator0, Allocator1>
00256   ::Reallocate(const Vector<int>& length)
00257   {
00258     int m = length.GetSize();
00259     data_.Reallocate(m);
00260     for(int i = 0; i < m; i++)
00261       data_(i).Reallocate(length(i));
00262   }
00263 
00264 
00266 
00271   template <class T, class Allocator0, class Allocator1>
00272   void Vector2<T, Allocator0, Allocator1>::Select(int beg, int end)
00273   {
00274     if (beg > end)
00275       throw WrongArgument("Vector2::SelectInnerVector(int beg, int end)",
00276                           "The lower bound of the range of inner vectors, ["
00277                           + to_str(beg) + ", " + to_str(end)
00278                           + "[, is strictly greater than its upper bound.");
00279     if (beg < 0 || end > GetLength())
00280       throw WrongArgument("Vector2::SelectInnerVector(int beg, int end)",
00281                           "The inner-vector indexes should be in [0,"
00282                           + to_str(GetLength()) + "] but [" + to_str(beg)
00283                           + ", " + to_str(end) + "[ was provided.");
00284 
00285     if (beg > 0)
00286       for (int i = 0; i < end - beg; i++)
00287         data_(i) = data_(beg + i);
00288     data_.Reallocate(end - beg);
00289   }
00290 
00291 
00293 
00297   template <class T, class Allocator0, class Allocator1>
00298   Vector<T, VectFull, Allocator0>
00299   Vector2<T, Allocator0, Allocator1>::Flatten() const
00300   {
00301     Vector<T, VectFull, Allocator0> data(GetNelement());
00302     int i, j, n(0);
00303     for (i = 0; i < GetLength(); i++)
00304       for (j = 0; j < GetLength(i); j++)
00305         data(n++) = data_(i)(j);
00306     return data;
00307   }
00308 
00309 
00311 
00315   template <class T, class Allocator0, class Allocator1>
00316   template <class Td, class Allocatord>
00317   void Vector2<T, Allocator0, Allocator1>
00318   ::Flatten(Vector<Td, VectFull, Allocatord>& data) const
00319   {
00320     data.Reallocate(GetNelement());
00321     int i, j, n(0);
00322     for (i = 0; i < GetLength(); i++)
00323       for (j = 0; j < GetLength(i); j++)
00324         data(n++) = data_(i)(j);
00325   }
00326 
00327 
00329 
00337   template <class T, class Allocator0, class Allocator1>
00338   template <class Td, class Allocatord>
00339   void Vector2<T, Allocator0, Allocator1>
00340   ::Flatten(int beg, int end, Vector<Td, VectFull, Allocatord>& data) const
00341   {
00342     if (beg > end)
00343       throw WrongArgument("Vector2::Flatten(int beg, int end, Vector& data)",
00344                           "The lower bound of the range of inner vectors, ["
00345                           + to_str(beg) + ", " + to_str(end)
00346                           + "[, is strictly greater than its upper bound.");
00347     if (beg < 0 || end > GetLength())
00348       throw WrongArgument("Vector2::Flatten(int beg, int end, Vector& data)",
00349                           "The inner-vector indexes should be in [0,"
00350                           + to_str(GetLength()) + "] but [" + to_str(beg)
00351                           + ", " + to_str(end) + "[ was provided.");
00352 
00353     data.Reallocate(GetNelement(beg, end));
00354     int i, j, n(0);
00355     for (i = beg; i < end; i++)
00356       for (j = 0; j < GetLength(i); j++)
00357         data(n++) = data_(i)(j);
00358   }
00359 
00360 
00362 
00366   template <class T, class Allocator0, class Allocator1>
00367   void Vector2<T, Allocator0, Allocator1>::PushBack(int i, const T& x)
00368   {
00369     data_(i).PushBack(x);
00370   }
00371 
00372 
00374 
00377   template <class T, class Allocator0, class Allocator1>
00378   void Vector2<T, Allocator0, Allocator1>
00379   ::PushBack(const Vector<T, VectFull, Allocator0>& X)
00380   {
00381     data_.PushBack(X);
00382   }
00383 
00384 
00386 
00390   template <class T, class Allocator0, class Allocator1>
00391   void Vector2<T, Allocator0, Allocator1>
00392   ::PushBack(const Vector<Vector<T, VectFull, Allocator0>,
00393              VectFull, Allocator1>& V)
00394   {
00395     for (int i = 0; i < V.GetLength(); i++)
00396       data_.PushBack(V(i));
00397   }
00398 
00399 
00401 
00405   template <class T, class Allocator0, class Allocator1>
00406   void Vector2<T, Allocator0, Allocator1>
00407   ::PushBack(const Vector2<T, Allocator0, Allocator1>& V)
00408   {
00409     PushBack(V.GetVector());
00410   }
00411 
00412 
00414   template <class T, class Allocator0, class Allocator1>
00415   void Vector2<T, Allocator0, Allocator1>::Clear()
00416   {
00417     data_.Clear();
00418   }
00419 
00420 
00422 
00425   template <class T, class Allocator0, class Allocator1>
00426   void Vector2<T, Allocator0, Allocator1>::Clear(int i)
00427   {
00428     data_(i).Clear();
00429   }
00430 
00431 
00433 
00436   template <class T, class Allocator0, class Allocator1>
00437   void Vector2<T, Allocator0, Allocator1>::Fill(const T& x)
00438   {
00439     for (int i = 0; i < data_.GetLength(); i++)
00440       data_(i).Fill(x);
00441   }
00442 
00443 
00445 
00448   template <class T, class Allocator0, class Allocator1>
00449   Vector<Vector<T, VectFull, Allocator0>, VectFull, Allocator1>&
00450   Vector2<T, Allocator0, Allocator1>::GetVector()
00451   {
00452     return data_;
00453   }
00454 
00455 
00457 
00460   template <class T, class Allocator0, class Allocator1>
00461   const Vector<Vector<T, VectFull, Allocator0>, VectFull, Allocator1>
00462   Vector2<T, Allocator0, Allocator1>::GetVector() const
00463   {
00464     return data_;
00465   }
00466 
00467 
00469 
00473   template <class T, class Allocator0, class Allocator1>
00474   Vector<T, VectFull, Allocator0>&
00475   Vector2<T, Allocator0, Allocator1>::GetVector(int i)
00476   {
00477     return data_(i);
00478   }
00479 
00480 
00482 
00486   template <class T, class Allocator0, class Allocator1>
00487   const Vector<T, VectFull, Allocator0>&
00488   Vector2<T, Allocator0, Allocator1>::GetVector(int i) const
00489   {
00490     return data_(i);
00491   }
00492 
00493 
00495 
00500   template <class T, class Allocator0, class Allocator1>
00501   void Vector2<T, Allocator0, Allocator1>
00502   ::Copy(const Vector2<T, Allocator0, Allocator1>& V)
00503   {
00504     Clear();
00505     Reallocate(V.GetLength());
00506     for (int i = 0; i < V.GetLength(); i++)
00507       data_(i) = V(i);
00508   }
00509 
00510 
00512 
00516   template <class T, class Allocator0, class Allocator1>
00517   Vector2<T, Allocator0, Allocator1>
00518   Vector2<T, Allocator0, Allocator1>::Copy() const
00519   {
00520     Vector2<T, Allocator0, Allocator1> output;
00521     output.Copy(*this);
00522     return output;
00523   }
00524 
00525 
00526   /*********************************
00527    * ELEMENT ACCESS AND ASSIGNMENT *
00528    *********************************/
00529 
00530 
00532 
00536   template <class T, class Allocator0, class Allocator1>
00537   const Vector<T, VectFull, Allocator0>&
00538   Vector2<T, Allocator0, Allocator1>::operator() (int i) const
00539   {
00540     return data_(i);
00541   }
00542 
00543 
00545 
00549   template <class T, class Allocator0, class Allocator1>
00550   Vector<T, VectFull, Allocator0>&
00551   Vector2<T, Allocator0, Allocator1>::operator() (int i)
00552   {
00553     return data_(i);
00554   }
00555 
00556 
00558 
00563   template <class T, class Allocator0, class Allocator1>
00564   typename Vector2<T, Allocator0, Allocator1>::const_reference
00565   Vector2<T, Allocator0, Allocator1>::operator() (int i, int j) const
00566   {
00567     return data_(i)(j);
00568   }
00569 
00570 
00572 
00577   template <class T, class Allocator0, class Allocator1>
00578   typename Vector2<T, Allocator0, Allocator1>::reference
00579   Vector2<T, Allocator0, Allocator1>::operator() (int i, int j)
00580   {
00581     return data_(i)(j);
00582   }
00583 
00584 
00585   /**********************
00586    * CONVENIENT METHODS *
00587    **********************/
00588 
00589 
00591 
00599   template <class T, class Allocator0, class Allocator1>
00600   template <class V2>
00601   bool Vector2<T, Allocator0, Allocator1>::HasSameShape(const V2& V) const
00602   {
00603     if (V.GetLength() != GetLength())
00604       return false;
00605     for (int i = 0; i < GetLength(); i++)
00606       if (V.GetLength(i) != GetLength(i))
00607         return false;
00608     return true;
00609   }
00610 
00611 
00613   template <class T, class Allocator0, class Allocator1>
00614   void Vector2<T, Allocator0, Allocator1>::Print() const
00615   {
00616     for (int i = 0; i < data_.GetLength(); i++)
00617       {
00618         cout << "Vector " << i << ": ";
00619         data_(i).Print();
00620       }
00621   }
00622 
00623 
00624   /**************************
00625    * INPUT/OUTPUT FUNCTIONS *
00626    **************************/
00627 
00628 
00630 
00638   template <class T, class Allocator0, class Allocator1>
00639   void Vector2<T, Allocator0, Allocator1>
00640   ::Write(string file_name, bool with_size) const
00641   {
00642     ofstream file_stream;
00643     file_stream.open(file_name.c_str());
00644 
00645 #ifdef SELDON_CHECK_IO
00646     // Checks if the file was opened.
00647     if (!file_stream.is_open())
00648       throw IOError("Vector2::Write(string file_name, bool with_size)",
00649                     string("Unable to open file \"") + file_name + "\".");
00650 #endif
00651 
00652     this->Write(file_stream, with_size);
00653 
00654     file_stream.close();
00655   }
00656 
00657 
00659 
00667   template <class T, class Allocator0, class Allocator1>
00668   void Vector2<T, Allocator0, Allocator1>
00669   ::Write(ostream& stream, bool with_size) const
00670   {
00671 
00672 #ifdef SELDON_CHECK_IO
00673     // Checks if the stream is ready.
00674     if (!stream.good())
00675       throw IOError("Vector2::Write(ostream& stream, bool with_size)",
00676                     "The stream is not ready.");
00677 #endif
00678 
00679     if (with_size)
00680       {
00681         int m = GetLength();
00682         stream.write(reinterpret_cast<char*>(const_cast<int*>(&m)),
00683                      sizeof(int));
00684       }
00685 
00686     for (int i = 0; i < GetLength(); i++)
00687       data_(i).Write(stream, with_size);
00688 
00689 #ifdef SELDON_CHECK_IO
00690     // Checks if data was written.
00691     if (!stream.good())
00692       throw IOError("Vector2::Write(ostream& stream, bool with_size)",
00693                     "Output operation failed.");
00694 #endif
00695 
00696   }
00697 
00698 
00700 
00710   template <class T, class Allocator0, class Allocator1>
00711   void Vector2<T, Allocator0, Allocator1>
00712   ::Read(string file_name, bool with_size)
00713   {
00714     ifstream file_stream;
00715     file_stream.open(file_name.c_str());
00716 
00717 #ifdef SELDON_CHECK_IO
00718     // Checks if the file was opened.
00719     if (!file_stream.is_open())
00720       throw IOError("Vector2::Read(string file_name, bool with_size)",
00721                     string("Unable to open file \"") + file_name + "\".");
00722 #endif
00723 
00724     this->Read(file_stream, with_size);
00725 
00726     file_stream.close();
00727   }
00728 
00729 
00731 
00741   template <class T, class Allocator0, class Allocator1>
00742   void Vector2<T, Allocator0, Allocator1>
00743   ::Read(istream& stream, bool with_size)
00744   {
00745 
00746 #ifdef SELDON_CHECK_IO
00747     // Checks if the stream is ready.
00748     if (!stream.good())
00749       throw IOError("Vector2::Read(istream& stream, bool with_size)",
00750                     "The stream is not ready.");
00751 #endif
00752 
00753     if (with_size)
00754       {
00755         int new_size;
00756         stream.read(reinterpret_cast<char*>(&new_size), sizeof(int));
00757         this->Reallocate(new_size);
00758       }
00759 
00760     for (int i = 0; i < GetLength(); i++)
00761       data_(i).Read(stream, with_size);
00762 
00763 #ifdef SELDON_CHECK_IO
00764     // Checks if data was read.
00765     if (!stream.good())
00766       throw IOError("Vector2::Read(istream& stream, bool with_size)",
00767                     "Output operation failed.");
00768 #endif
00769 
00770   }
00771 
00772 
00773 } // namespace Seldon.
00774 
00775 
00776 #define SELDON_FILE_VECTOR_VECTOR2_CXX
00777 #endif