00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SELDON_FILE_FUNCTIONS_MATVECT_CXX
00021 #define SELDON_FILE_FUNCTIONS_MATVECT_CXX
00022
00023
00024 #include "Functions_MatVect.hxx"
00025
00026
00027
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 namespace Seldon
00056 {
00057
00058
00060
00061
00062
00064
00072 template <class T0, class Prop0, class Storage0, class Allocator0,
00073 class T1, class Storage1, class Allocator1,
00074 class T2, class Storage2, class Allocator2>
00075 void Mlt(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
00076 const Vector<T1, Storage1, Allocator1>& X,
00077 Vector<T2, Storage2, Allocator2>& Y)
00078 {
00079 Y.Fill(T2(0));
00080 MltAdd(T2(1), M, X, T2(0), Y);
00081 }
00082
00083
00085
00096 template <class T1, class Prop1, class Storage1, class Allocator1,
00097 class T2, class Storage2, class Allocator2,
00098 class T3, class Storage3, class Allocator3>
00099 void Mlt(const T3& alpha,
00100 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
00101 const Vector<T2, Storage2, Allocator2>& X,
00102 Vector<T3, Storage3, Allocator3>& Y)
00103 {
00104 Y.Fill(T2(0));
00105 MltAdd(alpha, M, X, T3(0), Y);
00106 }
00107
00108
00110
00120 template <class T1, class Prop1, class Storage1, class Allocator1,
00121 class T2, class Storage2, class Allocator2,
00122 class T3, class Storage3, class Allocator3>
00123 void Mlt(const SeldonTranspose& Trans,
00124 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
00125 const Vector<T2, Storage2, Allocator2>& X,
00126 Vector<T3, Storage3, Allocator3>& Y)
00127 {
00128 Y.Fill(T2(0));
00129 MltAdd(T2(1), Trans, M, X, T3(0), Y);
00130 }
00131
00132
00133
00135
00136
00138
00139
00140
00141
00142
00143
00144 template <class T0,
00145 class T1, class Prop1, class Allocator1,
00146 class T2, class Allocator2,
00147 class T3,
00148 class T4, class Allocator4>
00149 void MltAdd(const T0 alpha,
00150 const Matrix<T1, Prop1, PETScMPIAIJ, Allocator1>& M,
00151 const Vector<T2, PETScSeq, Allocator2>& X,
00152 const T3 beta, Vector<T4, PETScSeq, Allocator4>& Y)
00153 {
00154 #ifdef SELDON_CHECK_DIMENSIONS
00155 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00156 #endif
00157 if (beta == T3(0))
00158 if (alpha == T0(0))
00159 {
00160 Y.Fill(T4(0));
00161 return;
00162 }
00163 else
00164 {
00165 MatMult(M.GetPetscMatrix(), X.GetPetscVector(), Y.GetPetscVector());
00166 if (alpha != T0(1))
00167 VecScale(Y.GetPetscVector(), alpha);
00168 return;
00169 }
00170 if (alpha == T0(1))
00171 {
00172 if (beta != T3(1))
00173 VecScale(Y.GetPetscVector(), beta);
00174 MatMultAdd(M.GetPetscMatrix(), X.GetPetscVector(),
00175 Y.GetPetscVector(),Y.GetPetscVector());
00176 return;
00177 }
00178 Vector<T2, PETScSeq, Allocator2> tmp;
00179 tmp.Copy(Y);
00180 MatMult(M.GetPetscMatrix(), X.GetPetscVector(), tmp.GetPetscVector());
00181 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
00182 return;
00183 }
00184
00185
00186 template <class T0,
00187 class T1, class Prop1, class Allocator1,
00188 class T2, class Allocator2,
00189 class T3,
00190 class T4, class Allocator4>
00191 void MltAdd(const T0 alpha,
00192 const Matrix<T1, Prop1, PETScMPIAIJ, Allocator1>& M,
00193 const Vector<T2, PETScPar, Allocator2>& X,
00194 const T3 beta, Vector<T4, PETScPar, Allocator4>& Y)
00195 {
00196 #ifdef SELDON_CHECK_DIMENSIONS
00197 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00198 #endif
00199 if (beta == T3(0))
00200 if (alpha == T0(0))
00201 {
00202 Y.Fill(T4(0));
00203 return;
00204 }
00205 else
00206 {
00207 MatMult(M.GetPetscMatrix(), X.GetPetscVector(), Y.GetPetscVector());
00208 if (alpha != T0(1))
00209 VecScale(Y.GetPetscVector(), alpha);
00210 return;
00211 }
00212 if (alpha == T0(1))
00213 {
00214 if (beta != T3(1))
00215 VecScale(Y.GetPetscVector(), beta);
00216 MatMultAdd(M.GetPetscMatrix(), X.GetPetscVector(),
00217 Y.GetPetscVector(),Y.GetPetscVector());
00218 return;
00219 }
00220 Vector<T2, PETScPar, Allocator2> tmp;
00221 tmp.Copy(Y);
00222 MatMult(M.GetPetscMatrix(), X.GetPetscVector(), tmp.GetPetscVector());
00223 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
00224 return;
00225 }
00226
00227
00228 template <class T0,
00229 class T1, class Prop1, class Allocator1,
00230 class T2, class Allocator2,
00231 class T3,
00232 class T4, class Allocator4>
00233 void MltAdd(const T0 alpha,
00234 const Matrix<T1, Prop1, PETScMPIAIJ, Allocator1>& M,
00235 const Vector<T2, VectFull, Allocator2>& X,
00236 const T3 beta, Vector<T4, PETScSeq, Allocator4>& Y)
00237 {
00238 #ifdef SELDON_CHECK_DIMENSIONS
00239 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00240 #endif
00241
00242 Vector<T4, PETScSeq, Allocator4> X_Petsc;
00243 X_Petsc.Reallocate(X.GetM());
00244 for (int i = 0; i < X.GetM(); i++)
00245 X_Petsc.SetBuffer(i, X(i));
00246 X_Petsc.Flush();
00247
00248 if (beta == T3(0))
00249 if (alpha == T0(0))
00250 {
00251 Y.Fill(T4(0));
00252 return;
00253 }
00254 else
00255 {
00256 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
00257 Y.GetPetscVector());
00258 if (alpha != T0(1))
00259 VecScale(Y.GetPetscVector(), alpha);
00260 return;
00261 }
00262 if (alpha == T0(1))
00263 {
00264 if (beta != T3(1))
00265 VecScale(Y.GetPetscVector(), beta);
00266 MatMultAdd(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
00267 Y.GetPetscVector(),Y.GetPetscVector());
00268 return;
00269 }
00270 Vector<T2, PETScSeq, Allocator2> tmp;
00271 tmp.Copy(Y);
00272 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
00273 tmp.GetPetscVector());
00274 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
00275 return;
00276 }
00277
00278
00279 template <class T0,
00280 class T1, class Prop1, class Allocator1,
00281 class T2, class Allocator2,
00282 class T3,
00283 class T4, class Allocator4>
00284 void MltAdd(const T0 alpha,
00285 const Matrix<T1, Prop1, PETScMPIAIJ, Allocator1>& M,
00286 const Vector<T2, VectFull, Allocator2>& X,
00287 const T3 beta, Vector<T4, PETScPar, Allocator4>& Y)
00288 {
00289 #ifdef SELDON_CHECK_DIMENSIONS
00290 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00291 #endif
00292
00293 Vector<T4, PETScPar, Allocator4> X_Petsc;
00294 X_Petsc.SetCommunicator(M.GetCommunicator());
00295 X_Petsc.Reallocate(X.GetM());
00296 for (int i = 0; i < X.GetM(); i++)
00297 X_Petsc.SetBuffer(i, X(i));
00298 X_Petsc.Flush();
00299
00300 if (beta == T3(0))
00301 if (alpha == T0(0))
00302 {
00303 Y.Fill(T4(0));
00304 return;
00305 }
00306 else
00307 {
00308 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
00309 Y.GetPetscVector());
00310 if (alpha != T0(1))
00311 VecScale(Y.GetPetscVector(), alpha);
00312 return;
00313 }
00314 if (alpha == T0(1))
00315 {
00316 if (beta != T3(1))
00317 VecScale(Y.GetPetscVector(), beta);
00318 MatMultAdd(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
00319 Y.GetPetscVector(),Y.GetPetscVector());
00320 return;
00321 }
00322 Vector<T2, PETScPar, Allocator2> tmp;
00323 tmp.Copy(Y);
00324 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
00325 tmp.GetPetscVector());
00326 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
00327 return;
00328 }
00329
00330
00331 template <class T0,
00332 class T1, class Prop1, class Allocator1,
00333 class T2, class Allocator2,
00334 class T3,
00335 class T4, class Allocator4>
00336 void MltAdd(const T0 alpha,
00337 const Matrix<T1, Prop1, PETScMPIDense, Allocator1>& M,
00338 const Vector<T2, VectFull, Allocator2>& X,
00339 const T3 beta, Vector<T4, PETScPar, Allocator4>& Y)
00340 {
00341 #ifdef SELDON_CHECK_DIMENSIONS
00342 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00343 #endif
00344
00345 Vector<T4, PETScPar, Allocator4> X_Petsc;
00346 X_Petsc.SetCommunicator(M.GetCommunicator());
00347 X_Petsc.Reallocate(X.GetM());
00348 for (int i = 0; i < X.GetM(); i++)
00349 X_Petsc.SetBuffer(i, X(i));
00350 X_Petsc.Flush();
00351
00352 if (beta == T3(0))
00353 if (alpha == T0(0))
00354 {
00355 Y.Fill(T4(0));
00356 return;
00357 }
00358 else
00359 {
00360 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
00361 Y.GetPetscVector());
00362 if (alpha != T0(1))
00363 VecScale(Y.GetPetscVector(), alpha);
00364 return;
00365 }
00366 if (alpha == T0(1))
00367 {
00368 if (beta != T3(1))
00369 VecScale(Y.GetPetscVector(), beta);
00370 MatMultAdd(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
00371 Y.GetPetscVector(),Y.GetPetscVector());
00372 return;
00373 }
00374 Vector<T2, PETScPar, Allocator2> tmp;
00375 tmp.Copy(Y);
00376 tmp.SetCommunicator(M.GetCommunicator());
00377 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
00378 tmp.GetPetscVector());
00379 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
00380 return;
00381 }
00382
00383
00384
00385
00386
00387
00388 template <class T0,
00389 class T1, class Prop1, class Allocator1,
00390 class T2, class Storage2, class Allocator2,
00391 class T3,
00392 class T4, class Storage4, class Allocator4>
00393 void MltAdd(const T0 alpha,
00394 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
00395 const Vector<T2, Storage2, Allocator2>& X,
00396 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00397 {
00398 int ma = M.GetM();
00399
00400 #ifdef SELDON_CHECK_DIMENSIONS
00401 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00402 #endif
00403
00404 Mlt(beta, Y);
00405
00406 T4 zero(0);
00407 T4 temp;
00408
00409 int* ptr = M.GetPtr();
00410 int* ind = M.GetInd();
00411 typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
00412 data = M.GetData();
00413
00414 for (int i = 0; i < ma; i++)
00415 {
00416 temp = zero;
00417 for (int j = ptr[i]; j < ptr[i+1]; j++)
00418 temp += data[j] * X(ind[j]);
00419 Y(i) += alpha * temp;
00420 }
00421 }
00422
00423
00424 template <class T0,
00425 class T1, class Prop1, class Allocator1,
00426 class T2, class Storage2, class Allocator2,
00427 class T3,
00428 class T4, class Allocator4>
00429 void MltAdd(const T0 alpha,
00430 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
00431 const Vector<T2, Storage2, Allocator2>& X,
00432 const T3 beta, Vector<T4, Collection, Allocator4>& Y)
00433 {
00434 int ma = M.GetM();
00435
00436 #ifdef SELDON_CHECK_DIMENSIONS
00437 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00438 #endif
00439
00440 Mlt(beta, Y);
00441
00442 typename T4::value_type zero(0);
00443 typename T4::value_type temp;
00444
00445 int* ptr = M.GetPtr();
00446 int* ind = M.GetInd();
00447 typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
00448 data = M.GetData();
00449
00450 for (int i = 0; i < ma; i++)
00451 {
00452 temp = zero;
00453 for (int j = ptr[i]; j < ptr[i+1]; j++)
00454 temp += data[j] * X(ind[j]);
00455 Y(i) += alpha * temp;
00456 }
00457 }
00458
00459
00460
00461
00462
00463 template <class T0,
00464 class T1, class Prop1, class Allocator1,
00465 class T2, class Storage2, class Allocator2,
00466 class T3,
00467 class T4, class Storage4, class Allocator4>
00468 void MltAdd(const T0 alpha,
00469 const Matrix<T1, Prop1, RowComplexSparse, Allocator1>& M,
00470 const Vector<T2, Storage2, Allocator2>& X,
00471 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00472 {
00473 int i, j;
00474
00475 int ma = M.GetM();
00476
00477 #ifdef SELDON_CHECK_DIMENSIONS
00478 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00479 #endif
00480
00481 Mlt(beta, Y);
00482
00483 complex<T1> zero(0);
00484 complex<T1> temp;
00485
00486 int* real_ptr = M.GetRealPtr();
00487 int* imag_ptr = M.GetImagPtr();
00488 int* real_ind = M.GetRealInd();
00489 int* imag_ind = M.GetImagInd();
00490 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00491 real_data = M.GetRealData();
00492 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00493 imag_data = M.GetImagData();
00494
00495 for (i = 0; i < ma; i++)
00496 {
00497 temp = zero;
00498 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00499 temp += real_data[j] * X(real_ind[j]);
00500 Y(i) += alpha * temp;
00501 }
00502
00503 for (i = 0; i < ma; i++)
00504 {
00505 temp = zero;
00506 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00507 temp += complex<T1>(T1(0), imag_data[j]) * X(imag_ind[j]);
00508 Y(i) += alpha * temp;
00509 }
00510 }
00511
00512
00513
00514
00515
00516 template <class T0,
00517 class T1, class Prop1, class Allocator1,
00518 class T2, class Storage2, class Allocator2,
00519 class T3,
00520 class T4, class Storage4, class Allocator4>
00521 void MltAdd(const T0 alpha,
00522 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
00523 const Vector<T2, Storage2, Allocator2>& X,
00524 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00525 {
00526 int ma = M.GetM();
00527
00528 #ifdef SELDON_CHECK_DIMENSIONS
00529 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00530 #endif
00531
00532 Mlt(beta, Y);
00533
00534 int i, j;
00535 T4 zero(0);
00536 T4 temp;
00537
00538 int* ptr = M.GetPtr();
00539 int* ind = M.GetInd();
00540 typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
00541 data = M.GetData();
00542
00543 for (i = 0; i < ma; i++)
00544 {
00545 temp = zero;
00546 for (j = ptr[i]; j < ptr[i + 1]; j++)
00547 temp += data[j] * X(ind[j]);
00548 Y(i) += alpha * temp;
00549 }
00550 for (i = 0; i < ma-1; i++)
00551 for (j = ptr[i]; j < ptr[i + 1]; j++)
00552 if (ind[j] != i)
00553 Y(ind[j]) += alpha * data[j] * X(i);
00554 }
00555
00556
00557 template <class T0,
00558 class T1, class Prop1, class Allocator1,
00559 class T2, class Allocator2,
00560 class T3,
00561 class T4, class Allocator4>
00562 void MltAdd(const T0 alpha,
00563 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
00564 const Vector<T2, Collection, Allocator2>& X,
00565 const T3 beta, Vector<T4, Collection, Allocator4>& Y)
00566 {
00567 int ma = M.GetM();
00568
00569 #ifdef SELDON_CHECK_DIMENSIONS
00570 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00571 #endif
00572
00573 Mlt(beta, Y);
00574
00575 int i, j;
00576 typename T4::value_type zero(0);
00577 typename T4::value_type temp;
00578
00579 int* ptr = M.GetPtr();
00580 int* ind = M.GetInd();
00581 typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
00582 data = M.GetData();
00583
00584 for (i = 0; i < ma; i++)
00585 {
00586 temp = zero;
00587 for (j = ptr[i]; j < ptr[i + 1]; j++)
00588 temp += data[j] * X(ind[j]);
00589 Y(i) += alpha * temp;
00590 }
00591 for (i = 0; i < ma-1; i++)
00592 for (j = ptr[i]; j < ptr[i + 1]; j++)
00593 if (ind[j] != i)
00594 Y(ind[j]) += alpha * data[j] * X(i);
00595 }
00596
00597
00598 template <class T0,
00599 class T1, class Prop1, class Allocator1,
00600 class T2, class Storage2, class Allocator2,
00601 class T3,
00602 class T4, class Allocator4>
00603 void MltAdd(const T0 alpha,
00604 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
00605 const Vector<T2, Storage2, Allocator2>& X,
00606 const T3 beta, Vector<T4, Collection, Allocator4>& Y)
00607 {
00608 int ma = M.GetM();
00609
00610 #ifdef SELDON_CHECK_DIMENSIONS
00611 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00612 #endif
00613
00614 Mlt(beta, Y);
00615
00616 int i, j;
00617 typename T4::value_type zero(0);
00618 typename T4::value_type temp;
00619
00620 int* ptr = M.GetPtr();
00621 int* ind = M.GetInd();
00622 typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
00623 data = M.GetData();
00624
00625 for (i = 0; i < ma; i++)
00626 {
00627 temp = zero;
00628 for (j = ptr[i]; j < ptr[i + 1]; j++)
00629 temp += data[j] * X(ind[j]);
00630 Y(i) += alpha * temp;
00631 }
00632 for (i = 0; i < ma-1; i++)
00633 for (j = ptr[i]; j < ptr[i + 1]; j++)
00634 if (ind[j] != i)
00635 Y(ind[j]) += alpha * data[j] * X(i);
00636 }
00637
00638
00639
00640
00641
00642 template <class T0,
00643 class T1, class Prop1, class Allocator1,
00644 class T2, class Storage2, class Allocator2,
00645 class T3,
00646 class T4, class Storage4, class Allocator4>
00647 void MltAdd(const T0 alpha,
00648 const Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& M,
00649 const Vector<T2, Storage2, Allocator2>& X,
00650 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00651 {
00652 int ma = M.GetM();
00653
00654 #ifdef SELDON_CHECK_DIMENSIONS
00655 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00656 #endif
00657
00658 Mlt(beta, Y);
00659
00660 int i, j;
00661 complex<T1> zero(0);
00662 complex<T1> temp;
00663
00664 int* real_ptr = M.GetRealPtr();
00665 int* imag_ptr = M.GetImagPtr();
00666 int* real_ind = M.GetRealInd();
00667 int* imag_ind = M.GetImagInd();
00668 typename Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>::pointer
00669 real_data = M.GetRealData();
00670 typename Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>::pointer
00671 imag_data = M.GetImagData();
00672
00673 for (i = 0; i<ma; i++)
00674 {
00675 temp = zero;
00676 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00677 temp += real_data[j] * X(real_ind[j]);
00678 Y(i) += alpha * temp;
00679 }
00680 for (i = 0; i<ma-1; i++)
00681 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00682 if (real_ind[j] != i)
00683 Y(real_ind[j]) += alpha * real_data[j] * X(i);
00684
00685 for (i = 0; i < ma; i++)
00686 {
00687 temp = zero;
00688 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00689 temp += complex<T1>(T1(0), imag_data[j]) * X(imag_ind[j]);
00690 Y(i) += alpha * temp;
00691 }
00692 for (i = 0; i<ma-1; i++)
00693 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00694 if (imag_ind[j] != i)
00695 Y(imag_ind[j]) += alpha * complex<T1>(T1(0), imag_data[j]) * X(i);
00696 }
00697
00698
00699
00700
00701
00702
00703 template <class T0,
00704 class T1, class Prop1, class Allocator1,
00705 class T2, class Storage2, class Allocator2,
00706 class T3,
00707 class T4, class Storage4, class Allocator4>
00708 void MltAdd(const T0 alpha,
00709 const class_SeldonNoTrans& Trans,
00710 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
00711 const Vector<T2, Storage2, Allocator2>& X,
00712 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00713 {
00714 MltAdd(alpha, M, X, beta, Y);
00715 }
00716
00717
00718
00719 template <class T0,
00720 class T1, class Prop1, class Allocator1,
00721 class T2, class Storage2, class Allocator2,
00722 class T3,
00723 class T4, class Storage4, class Allocator4>
00724 void MltAdd(const T0 alpha,
00725 const class_SeldonTrans& Trans,
00726 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
00727 const Vector<T2, Storage2, Allocator2>& X,
00728 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00729 {
00730 int i, j;
00731
00732 int ma = M.GetM();
00733
00734 #ifdef SELDON_CHECK_DIMENSIONS
00735 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonTrans, M, X, beta, Y)");
00736 #endif
00737
00738 Mlt(beta, Y);
00739
00740 int* ptr = M.GetPtr();
00741 int* ind = M.GetInd();
00742 typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
00743 data = M.GetData();
00744
00745 for (i = 0; i < ma; i++)
00746 for (j = ptr[i]; j < ptr[i + 1]; j++)
00747 Y(ind[j]) += alpha * data[j] * X(i);
00748 }
00749
00750
00751
00752 template <class T0,
00753 class T1, class Prop1, class Allocator1,
00754 class T2, class Storage2, class Allocator2,
00755 class T3,
00756 class T4, class Storage4, class Allocator4>
00757 void MltAdd(const T0 alpha,
00758 const class_SeldonConjTrans& Trans,
00759 const Matrix<complex<T1>, Prop1, RowSparse, Allocator1>& M,
00760 const Vector<T2, Storage2, Allocator2>& X,
00761 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00762 {
00763 int i, j;
00764
00765 int ma = M.GetM();
00766
00767 #ifdef SELDON_CHECK_DIMENSIONS
00768 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
00769 #endif
00770
00771 Mlt(beta, Y);
00772
00773 int* ptr = M.GetPtr();
00774 int* ind = M.GetInd();
00775 typename Matrix<complex<T1>, Prop1, RowSparse, Allocator1>::pointer
00776 data = M.GetData();
00777
00778 for (i = 0; i < ma; i++)
00779 for (j = ptr[i]; j < ptr[i + 1]; j++)
00780 Y(ind[j]) += alpha * conj(data[j]) * X(i);
00781 }
00782
00783
00784
00785
00786
00787
00788 template <class T0,
00789 class T1, class Prop1, class Allocator1,
00790 class T2, class Storage2, class Allocator2,
00791 class T3,
00792 class T4, class Storage4, class Allocator4>
00793 void MltAdd(const T0 alpha,
00794 const class_SeldonNoTrans& Trans,
00795 const Matrix<T1, Prop1, RowComplexSparse, Allocator1>& M,
00796 const Vector<T2, Storage2, Allocator2>& X,
00797 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00798 {
00799 MltAdd(alpha, M, X, beta, Y);
00800 }
00801
00802
00803
00804 template <class T0,
00805 class T1, class Prop1, class Allocator1,
00806 class T2, class Storage2, class Allocator2,
00807 class T3,
00808 class T4, class Storage4, class Allocator4>
00809 void MltAdd(const T0 alpha,
00810 const class_SeldonTrans& Trans,
00811 const Matrix<T1, Prop1, RowComplexSparse, Allocator1>& M,
00812 const Vector<T2, Storage2, Allocator2>& X,
00813 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00814 {
00815 int i, j;
00816
00817 int ma = M.GetM();
00818
00819 #ifdef SELDON_CHECK_DIMENSIONS
00820 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonTrans, M, X, beta, Y)");
00821 #endif
00822
00823 Mlt(beta, Y);
00824
00825 int* real_ptr = M.GetRealPtr();
00826 int* imag_ptr = M.GetImagPtr();
00827 int* real_ind = M.GetRealInd();
00828 int* imag_ind = M.GetImagInd();
00829 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00830 real_data = M.GetRealData();
00831 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00832 imag_data = M.GetImagData();
00833
00834 for (i = 0; i < ma; i++)
00835 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00836 Y(real_ind[j]) += alpha * real_data[j] * X(i);
00837
00838 for (i = 0; i < ma; i++)
00839 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00840 Y(imag_ind[j]) += alpha * complex<T1>(T1(0), imag_data[j]) * X(i);
00841 }
00842
00843
00844
00845 template <class T0,
00846 class T1, class Prop1, class Allocator1,
00847 class T2, class Storage2, class Allocator2,
00848 class T3,
00849 class T4, class Storage4, class Allocator4>
00850 void MltAdd(const T0 alpha,
00851 const class_SeldonConjTrans& Trans,
00852 const Matrix<T1, Prop1, RowComplexSparse, Allocator1>& M,
00853 const Vector<T2, Storage2, Allocator2>& X,
00854 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00855 {
00856 int i, j;
00857
00858 int ma = M.GetM();
00859
00860 #ifdef SELDON_CHECK_DIMENSIONS
00861 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
00862 #endif
00863
00864 Mlt(beta, Y);
00865
00866 int* real_ptr = M.GetRealPtr();
00867 int* imag_ptr = M.GetImagPtr();
00868 int* real_ind = M.GetRealInd();
00869 int* imag_ind = M.GetImagInd();
00870 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00871 real_data = M.GetRealData();
00872 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00873 imag_data = M.GetImagData();
00874
00875 for (i = 0; i < ma; i++)
00876 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00877 Y(real_ind[j]) += alpha * real_data[j] * X(i);
00878
00879 for (i = 0; i < ma; i++)
00880 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00881 Y(imag_ind[j]) += alpha * complex<T1>(T1(0), - imag_data[j]) * X(i);
00882 }
00883
00884
00885
00886
00887
00888
00889 template <class T0,
00890 class T1, class Prop1, class Allocator1,
00891 class T2, class Storage2, class Allocator2,
00892 class T3,
00893 class T4, class Storage4, class Allocator4>
00894 void MltAdd(const T0 alpha,
00895 const class_SeldonNoTrans& Trans,
00896 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
00897 const Vector<T2, Storage2, Allocator2>& X,
00898 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00899 {
00900 MltAdd(alpha, M, X, beta, Y);
00901 }
00902
00903
00904
00905 template <class T0,
00906 class T1, class Prop1, class Allocator1,
00907 class T2, class Storage2, class Allocator2,
00908 class T3,
00909 class T4, class Storage4, class Allocator4>
00910 void MltAdd(const T0 alpha,
00911 const class_SeldonTrans& Trans,
00912 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
00913 const Vector<T2, Storage2, Allocator2>& X,
00914 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00915 {
00916 MltAdd(alpha, M, X, beta, Y);
00917 }
00918
00919
00920
00921 template <class T0,
00922 class T1, class Prop1, class Allocator1,
00923 class T2, class Storage2, class Allocator2,
00924 class T3,
00925 class T4, class Storage4, class Allocator4>
00926 void MltAdd(const T0 alpha,
00927 const class_SeldonConjTrans& Trans,
00928 const Matrix<complex<T1>, Prop1, RowSymSparse, Allocator1>& M,
00929 const Vector<T2, Storage2, Allocator2>& X,
00930 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00931 {
00932 int ma = M.GetM();
00933
00934 #ifdef SELDON_CHECK_DIMENSIONS
00935 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
00936 #endif
00937
00938 Mlt(beta, Y);
00939
00940 int i, j;
00941 complex<T1> zero(0);
00942 complex<T1> temp;
00943
00944 int* ptr = M.GetPtr();
00945 int* ind = M.GetInd();
00946 typename Matrix<complex<T1>, Prop1, RowSymSparse, Allocator1>::pointer
00947 data = M.GetData();
00948
00949 for (i = 0; i < ma; i++)
00950 {
00951 temp = zero;
00952 for (j = ptr[i]; j < ptr[i + 1]; j++)
00953 temp += conj(data[j]) * X(ind[j]);
00954 Y(i) += temp;
00955 }
00956 for (i = 0; i < ma - 1; i++)
00957 for (j = ptr[i]; j < ptr[i + 1]; j++)
00958 if (ind[j] != i)
00959 Y(ind[j]) += conj(data[j]) * X(i);
00960 }
00961
00962
00963
00964
00965
00966
00967 template <class T0,
00968 class T1, class Prop1, class Allocator1,
00969 class T2, class Storage2, class Allocator2,
00970 class T3,
00971 class T4, class Storage4, class Allocator4>
00972 void MltAdd(const T0 alpha,
00973 const class_SeldonNoTrans& Trans,
00974 const Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& M,
00975 const Vector<T2, Storage2, Allocator2>& X,
00976 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00977 {
00978 MltAdd(alpha, M, X, beta, Y);
00979 }
00980
00981
00982
00983 template <class T0,
00984 class T1, class Prop1, class Allocator1,
00985 class T2, class Storage2, class Allocator2,
00986 class T3,
00987 class T4, class Storage4, class Allocator4>
00988 void MltAdd(const T0 alpha,
00989 const class_SeldonTrans& Trans,
00990 const Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& M,
00991 const Vector<T2, Storage2, Allocator2>& X,
00992 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00993 {
00994 MltAdd(alpha, M, X, beta, Y);
00995 }
00996
00997
00998
00999 template <class T0,
01000 class T1, class Prop1, class Allocator1,
01001 class T2, class Storage2, class Allocator2,
01002 class T3,
01003 class T4, class Storage4, class Allocator4>
01004 void MltAdd(const T0 alpha,
01005 const class_SeldonConjTrans& Trans,
01006 const Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& M,
01007 const Vector<T2, Storage2, Allocator2>& X,
01008 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
01009 {
01010 int ma = M.GetM();
01011
01012 #ifdef SELDON_CHECK_DIMENSIONS
01013 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
01014 #endif
01015
01016 Mlt(beta, Y);
01017
01018 int i, j;
01019 complex<T1> zero(0);
01020 complex<T1> temp;
01021
01022 int* real_ptr = M.GetRealPtr();
01023 int* imag_ptr = M.GetImagPtr();
01024 int* real_ind = M.GetRealInd();
01025 int* imag_ind = M.GetImagInd();
01026 typename Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>::pointer
01027 real_data = M.GetRealData();
01028 typename Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>::pointer
01029 imag_data = M.GetImagData();
01030
01031 for (i = 0; i < ma; i++)
01032 {
01033 temp = zero;
01034 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
01035 temp += real_data[j] * X(real_ind[j]);
01036 Y(i) += temp;
01037 }
01038 for (i = 0; i < ma - 1; i++)
01039 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
01040 if (real_ind[j] != i)
01041 Y(real_ind[j]) += real_data[j] * X(i);
01042
01043 for (i = 0; i < ma; i++)
01044 {
01045 temp = zero;
01046 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
01047 temp += complex<T1>(T1(0), - imag_data[j]) * X(imag_ind[j]);
01048 Y(i) += temp;
01049 }
01050 for (i = 0; i < ma - 1; i++)
01051 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
01052 if (imag_ind[j] != i)
01053 Y(imag_ind[j]) += complex<T1>(T1(0), - imag_data[j]) * X(i);
01054 }
01055
01056
01057
01059
01060
01062
01063
01064
01079 template <class T0,
01080 class T1, class Prop1, class Storage1, class Allocator1,
01081 class T2, class Storage2, class Allocator2,
01082 class T3,
01083 class T4, class Storage4, class Allocator4>
01084 void MltAdd(const T0 alpha,
01085 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
01086 const Vector<T2, Storage2, Allocator2>& X,
01087 const T3 beta,
01088 Vector<T4, Storage4, Allocator4>& Y)
01089 {
01090 int ma = M.GetM();
01091 int na = M.GetN();
01092
01093 #ifdef SELDON_CHECK_DIMENSIONS
01094 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
01095 #endif
01096
01097 Mlt(beta, Y);
01098
01099 T4 zero(0);
01100 T4 temp;
01101 T4 alpha_(alpha);
01102
01103 for (int i = 0; i < ma; i++)
01104 {
01105 temp = zero;
01106 for (int j = 0; j < na; j++)
01107 temp += M(i, j) * X(j);
01108 Y(i) += alpha_ * temp;
01109 }
01110 }
01111
01112
01127 template <class T0,
01128 class T1, class Prop1, class Storage1, class Allocator1,
01129 class T2, class Storage2, class Allocator2,
01130 class T3,
01131 class T4, class Allocator4>
01132 void MltAdd(const T0 alpha,
01133 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
01134 const Vector<T2, Storage2, Allocator2>& X,
01135 const T3 beta,
01136 Vector<T4, Collection, Allocator4>& Y)
01137 {
01138 int ma = M.GetM();
01139 int na = M.GetN();
01140
01141 #ifdef SELDON_CHECK_DIMENSIONS
01142 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
01143 #endif
01144
01145 Mlt(beta, Y);
01146
01147 typename T4::value_type zero(0);
01148 typename T4::value_type temp;
01149 typename T4::value_type alpha_(alpha);
01150
01151 for (int i = 0; i < ma; i++)
01152 {
01153 temp = zero;
01154 for (int j = 0; j < na; j++)
01155 temp += M(i, j) * X(j);
01156 Y(i) += alpha_ * temp;
01157 }
01158 }
01159
01160
01175 template <class T0,
01176 class T1, class Prop1, class Allocator1,
01177 class T2, class Allocator2,
01178 class T3,
01179 class T4, class Allocator4>
01180 void MltAdd(const T0 alpha,
01181 const Matrix<T1, Prop1, RowMajorCollection, Allocator1>& M,
01182 const Vector<T2, Collection, Allocator2>& X,
01183 const T3 beta,
01184 Vector<T4, Collection, Allocator4>& Y)
01185 {
01186 int ma = M.GetMmatrix();
01187 int na = M.GetNmatrix();
01188
01189 #ifdef SELDON_CHECK_DIMENSIONS
01190 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
01191 #endif
01192 typedef typename T4::value_type value_type;
01193
01194 Mlt(value_type(beta), Y);
01195
01196 for (int i = 0; i < ma; i++)
01197 for (int j = 0; j < na; j++)
01198 MltAdd(alpha, M.GetMatrix(i, j), X.GetVector(j), value_type(1.),
01199 Y.GetVector(i));
01200 }
01201
01202
01217 template <class T0,
01218 class T1, class Prop1, class Allocator1,
01219 class T2, class Allocator2,
01220 class T3,
01221 class T4, class Allocator4>
01222 void MltAdd(const T0 alpha,
01223 const Matrix<T1, Prop1, ColMajorCollection, Allocator1>& M,
01224 const Vector<T2, Collection, Allocator2>& X,
01225 const T3 beta,
01226 Vector<T4, Collection, Allocator4>& Y)
01227 {
01228 int ma = M.GetMmatrix();
01229 int na = M.GetNmatrix();
01230
01231 #ifdef SELDON_CHECK_DIMENSIONS
01232 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
01233 #endif
01234 typedef typename T4::value_type value_type;
01235
01236 Mlt(value_type(beta), Y);
01237
01238 for (int i = 0; i < ma; i++)
01239 for (int j = 0; j < na; j++)
01240 MltAdd(alpha, M.GetMatrix(i, j), X.GetVector(j), value_type(1.),
01241 Y.GetVector(i));
01242 }
01243
01244
01264 template <class T0,
01265 class T1, class Prop1, class Storage1, class Allocator1,
01266 class T2, class Storage2, class Allocator2,
01267 class T3,
01268 class T4, class Storage4, class Allocator4>
01269 void MltAdd(const T0 alpha,
01270 const SeldonTranspose& Trans,
01271 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
01272 const Vector<T2, Storage2, Allocator2>& X,
01273 const T3 beta,
01274 Vector<T4, Storage4, Allocator4>& Y)
01275 {
01276 if (Trans.NoTrans())
01277 {
01278 MltAdd(alpha, M, X, beta, Y);
01279 return;
01280 }
01281 else if (Trans.ConjTrans())
01282 throw WrongArgument("MltAdd(alpha, trans, M, X, beta, Y)",
01283 "Complex conjugation not supported.");
01284
01285 int ma = M.GetM();
01286 int na = M.GetN();
01287
01288 #ifdef SELDON_CHECK_DIMENSIONS
01289 CheckDim(Trans, M, X, Y, "MltAdd(alpha, trans, M, X, beta, Y)");
01290 #endif
01291
01292 if (beta == T3(0))
01293 Y.Fill(T4(0));
01294 else
01295 Mlt(beta, Y);
01296
01297 T4 zero(0);
01298 T4 temp;
01299 T4 alpha_(alpha);
01300
01301 for (int i = 0; i < na; i++)
01302 {
01303 temp = zero;
01304 for (int j = 0; j < ma; j++)
01305 temp += M(j, i) * X(j);
01306 Y(i) += alpha_ * temp;
01307 }
01308 }
01309
01310
01311
01313
01314
01316
01317
01318
01319
01320
01321 template <class T0, class Prop0, class Storage0, class Allocator0,
01322 class T1, class Storage1, class Allocator1>
01323 inline void Gauss(Matrix<T0, Prop0, Storage0, Allocator0>& M,
01324 Vector<T1, Storage1, Allocator1>& X)
01325 {
01326 int i, j, k;
01327 T1 r, S;
01328
01329 int ma = M.GetM();
01330 int na = M.GetN();
01331
01332 #ifdef SELDON_CHECK_DIMENSIONS
01333 if (na != ma)
01334 throw WrongDim("Gauss(M, X)",
01335 "The matrix must be squared.");
01336
01337 CheckDim(M, X, "Gauss(M, X)");
01338 #endif
01339
01340 for (k = 0; k < ma - 1; k++)
01341 for (i = k + 1; i < ma; i++)
01342 {
01343 r = M(i, k) / M(k, k);
01344 for (j = k + 1; j < ma; j++)
01345 M(i, j) -= r * M(k, j);
01346 X(i) -= r *= X(k);
01347 }
01348
01349 X(ma - 1) = X(ma - 1) / M(ma - 1, ma - 1);
01350 for (k = ma - 2; k > -1; k--)
01351 {
01352 S = X(k);
01353 for (j = k + 1; j < ma; j++)
01354 S -= M(k, j) * X(j);
01355 X(k) = S / M(k, k);
01356 }
01357 }
01358
01359
01360
01362
01363
01365
01366
01367
01368
01369 template <class T0, class Prop0, class Storage0, class Allocator0,
01370 class T1, class Storage1, class Allocator1,
01371 class T2, class Storage2, class Allocator2>
01372 inline void GaussSeidel(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01373 const Vector<T1, Storage1, Allocator1>& X,
01374 Vector<T2, Storage2, Allocator2>& Y,
01375 int iter)
01376 {
01377 int i, j, k;
01378 T1 temp;
01379
01380 int ma = M.GetM();
01381 int na = M.GetN();
01382
01383 #ifdef SELDON_CHECK_DIMENSIONS
01384 if (na != ma)
01385 throw WrongDim("GaussSeidel(M, X, Y, iter)",
01386 "The matrix must be squared.");
01387
01388 CheckDim(M, X, Y, "GaussSeidel(M, X, Y, iter)");
01389 #endif
01390
01391 for (i = 0; i < iter; i++)
01392 for (j = 0; j < na; j++)
01393 {
01394 temp = 0;
01395 for (k = 0; k < j; k++)
01396 temp -= M(j, k) * Y(k);
01397 for (k = j + 1; k < na; k++)
01398 temp -= M(j, k) * Y(k);
01399 Y(j) = (X(j) + temp) / M(j, j);
01400 }
01401 }
01402
01403
01404
01406
01407
01409
01410
01411
01412
01413 template <class T0, class Prop0, class Storage0, class Allocator0,
01414 class T1, class Storage1, class Allocator1,
01415 class T2, class Storage2, class Allocator2,
01416 class T3>
01417 inline void SOR(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01418 const Vector<T1, Storage1, Allocator1>& X,
01419 Vector<T2, Storage2, Allocator2>& Y,
01420 T3 omega,
01421 int iter)
01422 {
01423 int i, j, k;
01424 T1 temp;
01425
01426 int ma = M.GetM();
01427 int na = M.GetN();
01428
01429 #ifdef SELDON_CHECK_DIMENSIONS
01430 if (na != ma)
01431 throw WrongDim("SOR(M, X, Y, omega, iter)",
01432 "The matrix must be squared.");
01433
01434 CheckDim(M, X, Y, "SOR(M, X, Y, omega, iter)");
01435 #endif
01436
01437 for (i = 0; i < iter; i++)
01438 for (j = 0; j < na; j++)
01439 {
01440 temp = 0;
01441 for (k = 0; k < j; k++)
01442 temp -= M(j, k) * Y(k);
01443 for (k = j + 1; k < na; k++)
01444 temp -= M(j, k) * Y(k);
01445 Y(j) = (T3(1) - omega) * Y(j) + omega * (X(j) + temp) / M(j, j);
01446 }
01447 }
01448
01449
01450
01452
01453
01454
01456
01457
01458
01460
01472 template <class T0, class Prop0, class Storage0, class Allocator0,
01473 class T1, class Storage1, class Allocator1>
01474 void SolveLU(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01475 Vector<T1, Storage1, Allocator1>& Y)
01476 {
01477 int i, k;
01478 T1 temp;
01479
01480 int ma = M.GetM();
01481
01482 #ifdef SELDON_CHECK_DIMENSIONS
01483 int na = M.GetN();
01484 if (na != ma)
01485 throw WrongDim("SolveLU(M, Y)",
01486 "The matrix must be squared.");
01487
01488 CheckDim(M, Y, "SolveLU(M, Y)");
01489 #endif
01490
01491
01492 for (i = 0; i < ma; i++)
01493 {
01494 temp = 0;
01495 for (k = 0; k < i; k++)
01496 temp += M(i, k) * Y(k);
01497 Y(i) = (Y(i) - temp) / M(i, i);
01498 }
01499
01500 for (i = ma - 2; i > -1; i--)
01501 {
01502 temp = 0;
01503 for (k = i + 1; k < ma; k++)
01504 temp += M(i, k) * Y(k);
01505 Y(i) -= temp;
01506 }
01507 }
01508
01509
01510
01512
01513
01515
01516
01517
01519
01526 template <class T0, class Prop0, class Storage0, class Allocator0,
01527 class T1, class Storage1, class Allocator1>
01528 void GetAndSolveLU(Matrix<T0, Prop0, Storage0, Allocator0>& M,
01529 Vector<T1, Storage1, Allocator1>& Y)
01530 {
01531 #ifdef SELDON_WITH_LAPACK
01532 Vector<int> P;
01533 GetLU(M, P);
01534 SolveLU(M, P, Y);
01535 #else
01536 GetLU(M);
01537 SolveLU(M, Y);
01538 #endif
01539 }
01540
01541
01542
01544
01545
01547
01548
01549
01551
01560 template <class T0, class Prop0, class Storage0, class Allocator0,
01561 class T1, class Storage1, class Allocator1,
01562 class T2, class Storage2, class Allocator2>
01563 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01564 const Vector<T1, Storage1, Allocator1>& X,
01565 const Vector<T2, Storage2, Allocator2>& Y,
01566 string function)
01567 {
01568 if (X.GetLength() != M.GetN() || Y.GetLength() != M.GetM())
01569 throw WrongDim(function, string("Operation M X + Y -> Y not permitted:")
01570 + string("\n M (") + to_str(&M) + string(") is a ")
01571 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01572 + string(" matrix;\n X (") + to_str(&X)
01573 + string(") is vector of length ")
01574 + to_str(X.GetLength()) + string(";\n Y (")
01575 + to_str(&Y) + string(") is vector of length ")
01576 + to_str(Y.GetLength()) + string("."));
01577 }
01578
01579
01581
01590 template <class T0, class Prop0, class Allocator0,
01591 class T1, class Allocator1,
01592 class T2, class Allocator2>
01593 void CheckDim(const Matrix<T0, Prop0, RowMajorCollection, Allocator0>& M,
01594 const Vector<T1, Collection, Allocator1>& X,
01595 const Vector<T2, Collection, Allocator2>& Y,
01596 string function)
01597 {
01598 if (X.GetNvector() != M.GetNmatrix() || Y.GetNvector() != M.GetMmatrix())
01599 throw WrongDim(function, string("Operation M X + Y -> Y not permitted:")
01600 + string("\n M (") + to_str(&M) + string(") is a ")
01601 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01602 + string(" matrix;\n X (") + to_str(&X)
01603 + string(") is vector of length ")
01604 + to_str(X.GetNvector()) + string(";\n Y (")
01605 + to_str(&Y) + string(") is vector of length ")
01606 + to_str(Y.GetNvector()) + string("."));
01607 }
01608
01609
01611
01620 template <class T0, class Prop0, class Allocator0,
01621 class T1, class Allocator1,
01622 class T2, class Allocator2>
01623 void CheckDim(const Matrix<T0, Prop0, ColMajorCollection, Allocator0>& M,
01624 const Vector<T1, Collection, Allocator1>& X,
01625 const Vector<T2, Collection, Allocator2>& Y,
01626 string function)
01627 {
01628 if (X.GetNvector() != M.GetNmatrix() || Y.GetNvector() != M.GetMmatrix())
01629 throw WrongDim(function, string("Operation M X + Y -> Y not permitted:")
01630 + string("\n M (") + to_str(&M) + string(") is a ")
01631 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01632 + string(" matrix;\n X (") + to_str(&X)
01633 + string(") is vector of length ")
01634 + to_str(X.GetNvector()) + string(";\n Y (")
01635 + to_str(&Y) + string(") is vector of length ")
01636 + to_str(Y.GetNvector()) + string("."));
01637 }
01638
01639
01641
01650 template <class T0, class Prop0, class Storage0, class Allocator0,
01651 class T1, class Allocator1,
01652 class T2, class Storage2, class Allocator2>
01653 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01654 const Vector<T1, Collection, Allocator1>& X,
01655 const Vector<T2, Storage2, Allocator2>& Y,
01656 string function)
01657 {
01658 if (X.GetLength() != M.GetN() || Y.GetLength() != M.GetM())
01659 throw WrongDim(function, string("Operation M X + Y -> Y not permitted:")
01660 + string("\n M (") + to_str(&M) + string(") is a ")
01661 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01662 + string(" matrix;\n X (") + to_str(&X)
01663 + string(") is vector of length ")
01664 + to_str(X.GetLength()) + string(";\n Y (")
01665 + to_str(&Y) + string(") is vector of length ")
01666 + to_str(Y.GetLength()) + string("."));
01667 }
01668
01669
01671
01683 template <class T0, class Prop0, class Storage0, class Allocator0,
01684 class T1, class Storage1, class Allocator1,
01685 class T2, class Storage2, class Allocator2>
01686 void CheckDim(const SeldonTranspose& trans,
01687 const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01688 const Vector<T1, Storage1, Allocator1>& X,
01689 const Vector<T2, Storage2, Allocator2>& Y,
01690 string function, string op)
01691 {
01692 if (op == "M X + Y -> Y")
01693 if (trans.Trans())
01694 op = string("Operation M' X + Y -> Y not permitted:");
01695 else if (trans.ConjTrans())
01696 op = string("Operation M* X + Y -> Y not permitted:");
01697 else
01698 op = string("Operation M X + Y -> Y not permitted:");
01699 else
01700 op = string("Operation ") + op + string(" not permitted:");
01701 if (X.GetLength() != M.GetN(trans) || Y.GetLength() != M.GetM(trans))
01702 throw WrongDim(function, op + string("\n M (") + to_str(&M)
01703 + string(") is a ") + to_str(M.GetM()) + string(" x ")
01704 + to_str(M.GetN()) + string(" matrix;\n X (")
01705 + to_str(&X) + string(") is vector of length ")
01706 + to_str(X.GetLength()) + string(";\n Y (")
01707 + to_str(&Y) + string(") is vector of length ")
01708 + to_str(Y.GetLength()) + string("."));
01709 }
01710
01711
01713
01722 template <class T0, class Prop0, class Storage0, class Allocator0,
01723 class T1, class Storage1, class Allocator1>
01724 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01725 const Vector<T1, Storage1, Allocator1>& X,
01726 string function, string op)
01727 {
01728 if (X.GetLength() != M.GetN())
01729 throw WrongDim(function, string("Operation ") + op + " not permitted:"
01730 + string("\n M (") + to_str(&M) + string(") is a ")
01731 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01732 + string(" matrix;\n X (") + to_str(&X)
01733 + string(") is vector of length ")
01734 + to_str(X.GetLength()) + string("."));
01735 }
01736
01737
01738
01740
01741
01742 }
01743
01744
01745 #endif