00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 namespace Seldon
00062 {
00063
00064
00066
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
00079
00080
00082
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
00234
00235
00237
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
00288
00289
00291
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
00323
00324
00326
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
00478
00479
00481
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
00534
00535
00537
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
00590
00591
00593
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
00605
00606
00608
00609
00610
00612 template<class T>
00613 void GenRot(T& a_in, T& b_in, T& c_, T& s_)
00614 {
00615
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
00703
00704
00706
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
00755
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
00887
00888
00890
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
00913
00914
00915 }
00916
00917
00918 #endif