computation/basic_functions/Functions_Vector.cxx

00001 // Copyright (C) 2003-2009 Marc Duruflé
00002 // Copyright (C) 2001-2009 Vivien Mallet
00003 // Copyright (C) 2010 INRIA
00004 // Author(s): Marc Fragu
00005 //
00006 // This file is part of the linear-algebra library Seldon,
00007 // http://seldon.sourceforge.net/.
00008 //
00009 // Seldon is free software; you can redistribute it and/or modify it under the
00010 // terms of the GNU Lesser General Public License as published by the Free
00011 // Software Foundation; either version 2.1 of the License, or (at your option)
00012 // any later version.
00013 //
00014 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00015 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00016 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00017 // more details.
00018 //
00019 // You should have received a copy of the GNU Lesser General Public License
00020 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00021 
00022 
00023 #ifndef SELDON_FILE_FUNCTIONS_VECTOR_CXX
00024 #define SELDON_FILE_FUNCTIONS_VECTOR_CXX
00025 
00026 
00027 #include "Functions_Vector.hxx"
00028 
00029 
00030 /*
00031   Functions defined in this file:
00032 
00033   alpha X -> X
00034   Mlt(alpha, X)
00035 
00036   alpha X + Y -> Y
00037   Add(alpha, X, Y)
00038 
00039   X -> Y
00040   Copy(X, Y)
00041 
00042   X <-> Y
00043   Swap(X, Y)
00044 
00045   X.Y
00046   DotProd(X, Y)
00047   DotProdConj(X, Y)
00048 
00049   ||X||
00050   Norm1(X)
00051   Norm2(X)
00052   GetMaxAbsIndex(X)
00053 
00054   Omega X
00055   GenRot(x, y, cos, sin)
00056   ApplyRot(x, y, cos, sin)
00057 
00058 */
00059 
00060 
00061 namespace Seldon
00062 {
00063 
00064 
00066   // MLT //
00067 
00068 
00069   template <class T0,
00070             class T1, class Storage1, class Allocator1>
00071   void Mlt(const T0 alpha, Vector<T1, Storage1, Allocator1>& X)
00072   {
00073     X *= alpha;
00074   }
00075 
00076 
00077   // MLT //
00079 
00080 
00082   // ADD //
00083 
00084 
00085   template <class T0,
00086             class T1, class Storage1, class Allocator1,
00087             class T2, class Storage2, class Allocator2>
00088   void Add(const T0 alpha,
00089            const Vector<T1, Storage1, Allocator1>& X,
00090            Vector<T2, Storage2, Allocator2>& Y)
00091   {
00092     if (alpha != T0(0))
00093       {
00094         T1 alpha_ = alpha;
00095 
00096         int ma = X.GetM();
00097 
00098 #ifdef SELDON_CHECK_DIMENSIONS
00099         CheckDim(X, Y, "Add(alpha, X, Y)");
00100 #endif
00101 
00102         for (int i = 0; i < ma; i++)
00103           Y(i) += alpha_ * X(i);
00104       }
00105   }
00106 
00107 
00108   template <class T0,
00109             class T1, class Allocator1,
00110             class T2, class Allocator2>
00111   void Add(const T0 alpha,
00112            const Vector<T1, PETScSeq, Allocator1>& X,
00113            Vector<T2, PETScSeq, Allocator2>& Y)
00114   {
00115     if (alpha != T0(0))
00116       {
00117         T1 alpha_ = alpha;
00118 
00119         int ma = X.GetM();
00120 
00121 #ifdef SELDON_CHECK_DIMENSIONS
00122         CheckDim(X, Y, "Add(alpha, X, Y)");
00123 #endif
00124 
00125         VecAXPY(Y.GetPetscVector(), alpha_, X.GetPetscVector());
00126       }
00127   }
00128 
00129 
00130   template <class T0,
00131             class T1, class Allocator1,
00132             class T2, class Allocator2>
00133   void Add(const T0 alpha,
00134            const Vector<T1, PETScPar, Allocator1>& X,
00135            Vector<T2, PETScPar, Allocator2>& Y)
00136   {
00137     if (alpha != T0(0))
00138       {
00139         T1 alpha_ = alpha;
00140 
00141         int ma = X.GetM();
00142 
00143 #ifdef SELDON_CHECK_DIMENSIONS
00144         CheckDim(X, Y, "Add(alpha, X, Y)");
00145 #endif
00146 
00147         VecAXPY(Y.GetPetscVector(), alpha_, X.GetPetscVector());
00148       }
00149   }
00150 
00151 
00152 
00153   template <class T0,
00154             class T1, class Allocator1,
00155             class T2, class Allocator2>
00156   void Add(const T0 alpha,
00157            const Vector<T1, VectSparse, Allocator1>& X,
00158            Vector<T2, VectSparse, Allocator2>& Y)
00159   {
00160     if (alpha != T0(0))
00161       {
00162         Vector<T1, VectSparse, Allocator1> Xalpha = X;
00163         Xalpha *= alpha;
00164         Y.AddInteractionRow(Xalpha.GetSize(),
00165                             Xalpha.GetIndex(), Xalpha.GetData(), true);
00166       }
00167   }
00168 
00169 
00170   template <class T0,
00171             class T1, class Allocator1,
00172             class T2, class Allocator2>
00173   void Add(const T0 alpha,
00174            const Vector<T1, Collection, Allocator1>& X,
00175            Vector<T2, Collection, Allocator2>& Y)
00176   {
00177 
00178 #ifdef SELDON_CHECK_DIMENSIONS
00179     CheckDim(X, Y, "Add(X, Y)", "X + Y");
00180 #endif
00181 
00182     for (int i = 0; i < X.GetNvector(); i++)
00183       Add(alpha, X.GetVector(i), Y.GetVector(i));
00184   }
00185 
00186 
00187   template <class T0,
00188             class T1, template <class U1> class Allocator1,
00189             class T2, template <class U2> class Allocator2>
00190   void Add(const T0 alpha,
00191            const
00192            Vector<FloatDouble, DenseSparseCollection, Allocator1<T1> >& X,
00193            Vector<FloatDouble, DenseSparseCollection, Allocator2<T2> >& Y)
00194   {
00195 
00196 #ifdef SELDON_CHECK_DIMENSIONS
00197     CheckDim(X, Y, "Add(X, Y)");
00198 #endif
00199 
00200     Add(alpha, X.GetFloatDense(), Y.GetFloatDense());
00201     Add(alpha, X.GetFloatSparse(), Y.GetFloatSparse());
00202     Add(alpha, X.GetDoubleDense(), Y.GetDoubleDense());
00203     Add(alpha, X.GetDoubleSparse(), Y.GetDoubleSparse());
00204   }
00205 
00206 
00207   template <class T0,
00208             class T1, template <class U1> class Allocator1,
00209             class T2, class Storage2, class Allocator2>
00210   void Add(const T0 alpha,
00211            const
00212            Vector<FloatDouble, DenseSparseCollection, Allocator1<T1> >& X,
00213            Vector<T2, Storage2, Allocator2>& Y)
00214   {
00215     if (alpha != T0(0))
00216       {
00217         double alpha_ = alpha;
00218 
00219         int ma = X.GetM();
00220 
00221 #ifdef SELDON_CHECK_DIMENSIONS
00222         CheckDim(X, Y, "Add(alpha, X, Y)");
00223 #endif
00224 
00225         for (int i = 0; i < ma; i++)
00226           Y(i) += alpha_ * X(i);
00227 
00228       }
00229   }
00230 
00231 
00232   // ADD //
00234 
00235 
00237   // COPY //
00238 
00239 
00240   template <class T1, class Storage1, class Allocator1,
00241             class T2, class Storage2, class Allocator2>
00242   void Copy(const Vector<T1, Storage1, Allocator1>& X,
00243             Vector<T2, Storage2, Allocator2>& Y)
00244   {
00245     Y.Copy(X);
00246   }
00247 
00248 
00249   template <class T1, class Allocator1,
00250             class T2, class Allocator2>
00251   void Copy(const Vector<T1, Collection, Allocator1>& X,
00252             Vector<T2, VectFull, Allocator2>& Y)
00253   {
00254     Y.Clear();
00255     for (int i = 0; i < X.GetNvector(); i++)
00256       Y.PushBack(X.GetVector(i));
00257   }
00258 
00259 
00260   template<class T, class Alloc1, class Alloc2>
00261   void Copy(const Vector<T, PETScPar, Alloc1>& A,
00262             Vector<T, VectFull, Alloc2>& B)
00263   {
00264     B.Reallocate(A.GetLocalM());
00265     T *local_data;
00266     VecGetArray(A.GetPetscVector(), &local_data);
00267     for (int i = 0; i < A.GetLocalM(); i++)
00268       B(i) = local_data[i];
00269     VecRestoreArray(A.GetPetscVector(), &local_data);
00270   }
00271 
00272 
00273   template<class T, class Alloc1, class Alloc2>
00274   void Copy(const Vector<T, VectFull, Alloc1>& A,
00275             Vector<T, PETScPar, Alloc2>& B)
00276   {
00277     T *local_data;
00278     VecGetArray(B.GetPetscVector(), &local_data);
00279     for (int i = 0; i < A.GetM(); i++)
00280       local_data[i] = A(i);
00281     VecRestoreArray(B.GetPetscVector(), &local_data);
00282   }
00283 
00284 
00285 
00286   // COPY //
00288 
00289 
00291   // SWAP //
00292 
00293 
00294   template <class T, class Storage, class Allocator>
00295   void Swap(Vector<T, Storage, Allocator>& X,
00296             Vector<T, Storage, Allocator>& Y)
00297   {
00298     int nx = X.GetM();
00299     T* data = X.GetData();
00300     X.Nullify();
00301     X.SetData(Y.GetM(), Y.GetData());
00302     Y.Nullify();
00303     Y.SetData(nx, data);
00304   }
00305 
00306 
00307   template <class T, class Allocator>
00308   void Swap(Vector<T, VectSparse, Allocator>& X,
00309             Vector<T, VectSparse, Allocator>& Y)
00310   {
00311     int nx = X.GetM();
00312     T* data = X.GetData();
00313     int* index = X.GetIndex();
00314     X.Nullify();
00315     X.SetData(Y.GetM(), Y.GetData(), Y.GetIndex());
00316     Y.Nullify();
00317     Y.SetData(nx, data, index);
00318   }
00319 
00320 
00321   // SWAP //
00323 
00324 
00326   // DOTPROD //
00327 
00328 
00330   template<class T1, class Storage1, class Allocator1,
00331            class T2, class Storage2, class Allocator2>
00332   T1 DotProd(const Vector<T1, Storage1, Allocator1>& X,
00333              const Vector<T2, Storage2, Allocator2>& Y)
00334   {
00335     T1 value;
00336     SetComplexZero(value);
00337 
00338 #ifdef SELDON_CHECK_DIMENSIONS
00339     CheckDim(X, Y, "DotProd(X, Y)");
00340 #endif
00341 
00342     for (int i = 0; i < X.GetM(); i++)
00343       value += X(i) * Y(i);
00344 
00345     return value;
00346   }
00347 
00348 
00350   template<class T1, class Allocator1,
00351            class T2, class Allocator2>
00352   typename T1::value_type DotProd(const Vector<T1, Collection, Allocator1>& X,
00353                                   const Vector<T2, Collection, Allocator2>& Y)
00354   {
00355     typename T1::value_type value(0);
00356 
00357 #ifdef SELDON_CHECK_DIMENSIONS
00358     CheckDim(X, Y, "DotProd(X, Y)", "<X, Y>");
00359 #endif
00360 
00361     for (int i = 0; i < X.GetNvector(); i++)
00362       value += DotProd(X.GetVector(i), Y.GetVector(i));
00363     return value;
00364   }
00365 
00366 
00368   template<class T1, template <class U1> class Allocator1,
00369            class T2, template <class U2> class Allocator2>
00370   double
00371   DotProd(const
00372           Vector<FloatDouble, DenseSparseCollection, Allocator1<T1> >& X,
00373           const
00374           Vector<FloatDouble, DenseSparseCollection, Allocator2<T2> >& Y)
00375   {
00376 
00377 #ifdef SELDON_CHECK_DIMENSIONS
00378     CheckDim(X, Y, "DotProd(X, Y)");
00379 #endif
00380 
00381     double value(0.);
00382     value += DotProd(X.GetFloatDense(), Y.GetFloatDense());
00383     value += DotProd(X.GetFloatSparse(), Y.GetFloatSparse());
00384     value += DotProd(X.GetDoubleDense(), Y.GetDoubleDense());
00385     value += DotProd(X.GetDoubleSparse(), Y.GetDoubleSparse());
00386     return value;
00387   }
00388 
00389 
00391   template<class T1, class Storage1, class Allocator1,
00392            class T2, class Storage2, class Allocator2>
00393   T1 DotProdConj(const Vector<T1, Storage1, Allocator1>& X,
00394                  const Vector<T2, Storage2, Allocator2>& Y)
00395   {
00396     return DotProd(X, Y);
00397   }
00398 
00399 
00401   template<class T1, class Storage1, class Allocator1,
00402            class T2, class Storage2, class Allocator2>
00403   complex<T1> DotProdConj(const Vector<complex<T1>, Storage1, Allocator1>& X,
00404                           const Vector<T2, Storage2, Allocator2>& Y)
00405   {
00406     complex<T1> value;
00407     SetComplexZero(value);
00408 
00409 #ifdef SELDON_CHECK_DIMENSIONS
00410     CheckDim(X, Y, "DotProdConj(X, Y)");
00411 #endif
00412 
00413     for (int i = 0; i < X.GetM(); i++)
00414       value += conj(X(i)) * Y(i);
00415 
00416     return value;
00417   }
00418 
00419 
00421   template<class T1, class Allocator1,
00422            class T2, class Allocator2>
00423   T1 DotProd(const Vector<T1, VectSparse, Allocator1>& X,
00424              const Vector<T2, VectSparse, Allocator2>& Y)
00425   {
00426     T1 value;
00427     SetComplexZero(value);
00428 
00429     int size_x = X.GetSize();
00430     int size_y = Y.GetSize();
00431     int kx = 0, ky = 0, pos_x;
00432     while (kx < size_x)
00433       {
00434         pos_x = X.Index(kx);
00435         while (ky < size_y && Y.Index(ky) < pos_x)
00436           ky++;
00437 
00438         if (ky < size_y && Y.Index(ky) == pos_x)
00439           value += X.Value(kx) * Y.Value(ky);
00440 
00441         kx++;
00442       }
00443 
00444     return value;
00445   }
00446 
00447 
00449   template<class T1, class Allocator1,
00450            class T2, class Allocator2>
00451   complex<T1>
00452   DotProdConj(const Vector<complex<T1>, VectSparse, Allocator1>& X,
00453               const Vector<T2, VectSparse, Allocator2>& Y)
00454   {
00455     complex<T1> value(0, 0);
00456 
00457     int size_x = X.GetSize();
00458     int size_y = Y.GetSize();
00459     int kx = 0, ky = 0, pos_x;
00460     while (kx < size_x)
00461       {
00462         pos_x = X.Index(kx);
00463         while (ky < size_y && Y.Index(ky) < pos_x)
00464           ky++;
00465 
00466         if (ky < size_y && Y.Index(ky) == pos_x)
00467           value += conj(X.Value(kx)) * Y.Value(ky);
00468 
00469         kx++;
00470       }
00471 
00472     return value;
00473   }
00474 
00475 
00476   // DOTPROD //
00478 
00479 
00481   // NORM1 //
00482 
00483 
00484   template<class T1, class Storage1, class Allocator1>
00485   T1 Norm1(const Vector<T1, Storage1, Allocator1>& X)
00486   {
00487     T1 value(0);
00488 
00489     for (int i = 0; i < X.GetM(); i++)
00490       value += abs(X(i));
00491 
00492     return value;
00493   }
00494 
00495 
00496   template<class T1, class Storage1, class Allocator1>
00497   T1 Norm1(const Vector<complex<T1>, Storage1, Allocator1>& X)
00498   {
00499     T1 value(0);
00500 
00501     for (int i = 0; i < X.GetM(); i++)
00502       value += abs(X(i));
00503 
00504     return value;
00505   }
00506 
00507 
00508   template<class T1, class Allocator1>
00509   T1 Norm1(const Vector<T1, VectSparse, Allocator1>& X)
00510   {
00511     T1 value(0);
00512 
00513     for (int i = 0; i < X.GetSize(); i++)
00514       value += abs(X.Value(i));
00515 
00516     return value;
00517   }
00518 
00519 
00520   template<class T1, class Allocator1>
00521   T1 Norm1(const Vector<complex<T1>, VectSparse, Allocator1>& X)
00522   {
00523     T1 value(0);
00524 
00525     for (int i = 0; i < X.GetSize(); i++)
00526       value += abs(X.Value(i));
00527 
00528     return value;
00529   }
00530 
00531 
00532   // NORM1 //
00534 
00535 
00537   // NORM2 //
00538 
00539 
00540   template<class T1, class Storage1, class Allocator1>
00541   T1 Norm2(const Vector<T1, Storage1, Allocator1>& X)
00542   {
00543     T1 value(0);
00544 
00545     for (int i = 0; i < X.GetM(); i++)
00546       value += X(i) * X(i);
00547 
00548     return sqrt(value);
00549   }
00550 
00551 
00552   template<class T1, class Storage1, class Allocator1>
00553   T1 Norm2(const Vector<complex<T1>, Storage1, Allocator1>& X)
00554   {
00555     T1 value(0);
00556 
00557     for (int i = 0; i < X.GetM(); i++)
00558       value += real(X(i) * conj(X(i)));
00559 
00560     return sqrt(value);
00561   }
00562 
00563 
00564   template<class T1, class Allocator1>
00565   T1 Norm2(const Vector<T1, VectSparse, Allocator1>& X)
00566   {
00567     T1 value(0);
00568 
00569     for (int i = 0; i < X.GetSize(); i++)
00570       value += X.Value(i) * X.Value(i);
00571 
00572     return sqrt(value);
00573   }
00574 
00575 
00576   template<class T1, class Allocator1>
00577   T1 Norm2(const Vector<complex<T1>, VectSparse, Allocator1>& X)
00578   {
00579     T1 value(0);
00580 
00581     for (int i = 0; i < X.GetSize(); i++)
00582       value += real(X.Value(i) * conj(X.Value(i)));
00583 
00584     return sqrt(value);
00585   }
00586 
00587 
00588   // NORM2 //
00590 
00591 
00593   // GETMAXABSINDEX //
00594 
00595 
00596   template<class T, class Storage, class Allocator>
00597   int GetMaxAbsIndex(const Vector<T, Storage, Allocator>& X)
00598   {
00599     return X.GetNormInfIndex();
00600   }
00601 
00602 
00603   // GETMAXABSINDEX //
00605 
00606 
00608   // APPLYROT //
00609 
00610 
00612   template<class T>
00613   void GenRot(T& a_in, T& b_in, T& c_, T& s_)
00614   {
00615     // Old BLAS version.
00616     T roe;
00617     if (abs(a_in) > abs(b_in))
00618       roe = a_in;
00619     else
00620       roe = b_in;
00621 
00622     T scal = abs(a_in) + abs(b_in);
00623     T r, z;
00624     if (scal != T(0))
00625       {
00626         T a_scl = a_in / scal;
00627         T b_scl = b_in / scal;
00628         r = scal * sqrt(a_scl * a_scl + b_scl * b_scl);
00629         if (roe < T(0))
00630           r *= T(-1);
00631 
00632         c_ = a_in / r;
00633         s_ = b_in / r;
00634         z = T(1);
00635         if (abs(a_in) > abs(b_in))
00636           z = s_;
00637         else if (abs(b_in) >= abs(a_in) && c_ != T(0))
00638           z = T(1) / c_;
00639       }
00640     else
00641       {
00642         c_ = T(1);
00643         s_ = T(0);
00644         r = T(0);
00645         z = T(0);
00646       }
00647     a_in = r;
00648     b_in = z;
00649   }
00650 
00651 
00653   template<class T>
00654   void GenRot(complex<T>& a_in, complex<T>& b_in, T& c_, complex<T>& s_)
00655   {
00656 
00657     T a = abs(a_in), b = abs(b_in);
00658     if (a == T(0))
00659       {
00660         c_ = T(0);
00661         s_ = complex<T>(1, 0);
00662         a_in = b_in;
00663       }
00664     else
00665       {
00666         T scale = a + b;
00667         T a_scal = abs(a_in / scale);
00668         T b_scal = abs(b_in / scale);
00669         T norm = sqrt(a_scal * a_scal + b_scal * b_scal) * scale;
00670 
00671         c_ = a / norm;
00672         complex<T> alpha = a_in / a;
00673         s_ = alpha * conj(b_in) / norm;
00674         a_in = alpha * norm;
00675       }
00676     b_in = complex<T>(0, 0);
00677   }
00678 
00679 
00681   template<class T>
00682   void ApplyRot(T& x, T& y, const T c_, const T s_)
00683   {
00684     T temp = c_ * x + s_ * y;
00685     y = c_ * y - s_ * x;
00686     x = temp;
00687   }
00688 
00689 
00691   template<class T>
00692   void ApplyRot(complex<T>& x, complex<T>& y,
00693                 const T& c_, const complex<T>& s_)
00694   {
00695     complex<T> temp = s_ * y + c_ * x;
00696     y = -conj(s_) * x + c_ * y;
00697     x = temp;
00698   }
00699 
00700 
00701   // APPLYROT //
00703 
00704 
00706   // CHECKDIM //
00707 
00708 
00710 
00720   template <class T0, class Storage0, class Allocator0,
00721             class T1, class Storage1, class Allocator1>
00722   void CheckDim(const Vector<T0, Storage0, Allocator0>& X,
00723                 const Vector<T1, Storage1, Allocator1>& Y,
00724                 string function, string op)
00725   {
00726     if (X.GetLength() != Y.GetLength())
00727       throw WrongDim(function, string("Operation ") + op
00728                      + string(" not permitted:")
00729                      + string("\n     X (") + to_str(&X) + string(") is a ")
00730                      + string("vector of length ") + to_str(X.GetLength())
00731                      + string(";\n     Y (") + to_str(&Y) + string(") is a ")
00732                      + string("vector of length ") + to_str(Y.GetLength())
00733                      + string("."));
00734   }
00735 
00736 
00738 
00748   template <class T0, class Allocator0,
00749             class T1, class Allocator1>
00750   void CheckDim(const Vector<T0, Vect_Sparse, Allocator0>& X,
00751                 const Vector<T1, Vect_Sparse, Allocator1>& Y,
00752                 string function, string op)
00753   {
00754     // The dimension of a Vector<Vect_Sparse> is infinite,
00755     // so no vector dimension checking has to be done.
00756   }
00757 
00758 
00760 
00770   template <class T0, class Allocator0,
00771             class T1, class Allocator1>
00772   void CheckDim(const Vector<T0, Collection, Allocator0>& X,
00773                 const Vector<T1, Collection, Allocator1>& Y,
00774                 string function, string op)
00775   {
00776     if (X.GetLength() != Y.GetLength())
00777       throw WrongDim(function, string("Operation ") + op
00778                      + string(" not permitted:")
00779                      + string("\n     X (") + to_str(&X) + string(") is a ")
00780                      + string("vector of length ") + to_str(X.GetLength())
00781                      + string(";\n     Y (") + to_str(&Y) + string(") is a ")
00782                      + string("vector of length ") + to_str(Y.GetLength())
00783                      + string("."));
00784 
00785     if (X.GetNvector() != Y.GetNvector())
00786       throw WrongDim(function, string("Operation ") + op
00787                      + string(" not permitted:")
00788                      + string("\n     X (") + to_str(&X) + string(") is a ")
00789                      + string("vector of length ") + to_str(X.GetNvector())
00790                      + string(";\n     Y (") + to_str(&Y) + string(") is a ")
00791                      + string("vector of length ") + to_str(Y.GetNvector())
00792                      + string("."));
00793   }
00794 
00795 
00797 
00807   template <class T0, class Allocator0, class Allocator00,
00808             class T1, class Allocator1, class Allocator11>
00809   void CheckDim(const Vector<Vector<T0, Vect_Sparse, Allocator0>,
00810                 Collection, Allocator00>& X,
00811                 const Vector<Vector<T1, Vect_Sparse, Allocator1>,
00812                 Collection, Allocator11>& Y,
00813                 string function, string op)
00814   {
00815     if (X.GetNvector() != Y.GetNvector())
00816       throw WrongDim(function, string("Operation ") + op
00817                      + string(" not permitted:")
00818                      + string("\n     X (") + to_str(&X) + string(") is a ")
00819                      + string("vector of length ") + to_str(X.GetNvector())
00820                      + string(";\n     Y (") + to_str(&Y) + string(") is a ")
00821                      + string("vector of length ") + to_str(Y.GetNvector())
00822                      + string("."));
00823   }
00824 
00825 
00827 
00837   template <class T0, class Allocator0,
00838             class T1, class Allocator1>
00839   void CheckDim(const Vector<T0, VectFull, Allocator0>& X,
00840                 Vector<T1, Collection, Allocator1>& Y,
00841                 string function, string op)
00842   {
00843     if (X.GetLength() != Y.GetM())
00844       throw WrongDim(function, string("Operation ") + op
00845                      + string(" not permitted:")
00846                      + string("\n     X (") + to_str(&X) + string(") is a ")
00847                      + string("vector of length ") + to_str(X.GetLength())
00848                      + string(";\n     Y (") + to_str(&Y) + string(") is a ")
00849                      + string("vector of length ") + to_str(Y.GetM())
00850                      + string("."));
00851   }
00852 
00853 
00855 
00865   template <class T0, template <class U0> class Allocator0,
00866             class T1, template <class U1> class Allocator1>
00867   void
00868   CheckDim(const
00869            Vector<FloatDouble, DenseSparseCollection, Allocator0<T0> >& X,
00870            const
00871            Vector<FloatDouble, DenseSparseCollection, Allocator1<T1> >& Y,
00872            string function, string op)
00873   {
00874     if (X.GetNvector() != Y.GetNvector())
00875       throw WrongDim(function, string("Operation ") + op
00876                      + string(" not permitted:")
00877                      + string("\n     X (") + to_str(&X) + string(") is a ")
00878                      + string("vector of length ") + to_str(X.GetNvector())
00879                      + string(";\n     Y (") + to_str(&Y) + string(") is a ")
00880                      + string("vector of length ") + to_str(Y.GetNvector())
00881                      + string("."));
00882   }
00883 
00884 
00885   // CHECKDIM //
00887 
00888 
00890   // CONJUGATE //
00891 
00892 
00894   template<class T, class Prop, class Allocator>
00895   void Conjugate(Vector<T, Prop, Allocator>& X)
00896   {
00897     for (int i = 0; i < X.GetM(); i++)
00898       X(i) = conj(X(i));
00899   }
00900 
00901 
00903   template<class T, class Allocator>
00904   void Conjugate(Vector<T, VectSparse, Allocator>& X)
00905   {
00906     for (int i = 0; i < X.GetSize(); i++)
00907       X.Value(i) = conj(X.Value(i));
00908   }
00909 
00910 
00911   // CONJUGATE //
00913 
00914 
00915 } // namespace Seldon.
00916 
00917 
00918 #endif