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
00022
00023
00024
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 namespace Seldon
00050 {
00051
00052
00054
00055
00056
00058
00066 template <class T0, class Prop0, class Storage0, class Allocator0,
00067 class T1, class Storage1, class Allocator1,
00068 class T2, class Storage2, class Allocator2>
00069 void Mlt(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
00070 const Vector<T1, Storage1, Allocator1>& X,
00071 Vector<T2, Storage2, Allocator2>& Y)
00072 {
00073 Y.Fill(T2(0));
00074 MltAdd(T2(1), M, X, T2(0), Y);
00075 }
00076
00077
00079
00090 template <class T1, class Prop1, class Storage1, class Allocator1,
00091 class T2, class Storage2, class Allocator2,
00092 class T3, class Storage3, class Allocator3>
00093 void Mlt(const T3& alpha,
00094 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
00095 const Vector<T2, Storage2, Allocator2>& X,
00096 Vector<T3, Storage3, Allocator3>& Y)
00097 {
00098 Y.Fill(T2(0));
00099 MltAdd(alpha, M, X, T3(0), Y);
00100 }
00101
00102
00104
00114 template <class T1, class Prop1, class Storage1, class Allocator1,
00115 class T2, class Storage2, class Allocator2,
00116 class T3, class Storage3, class Allocator3>
00117 void Mlt(const SeldonTranspose& Trans,
00118 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
00119 const Vector<T2, Storage2, Allocator2>& X,
00120 Vector<T3, Storage3, Allocator3>& Y)
00121 {
00122 Y.Fill(T2(0));
00123 MltAdd(T2(1), Trans, M, X, T3(0), Y);
00124 }
00125
00126
00127
00129
00130
00131
00133
00134
00135
00136
00137
00138
00139 template <class T0,
00140 class T1, class Prop1, class Allocator1,
00141 class T2, class Storage2, class Allocator2,
00142 class T3,
00143 class T4, class Storage4, class Allocator4>
00144 void MltAdd(const T0 alpha,
00145 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
00146 const Vector<T2, Storage2, Allocator2>& X,
00147 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00148 {
00149 int ma = M.GetM();
00150
00151 #ifdef SELDON_CHECK_DIMENSIONS
00152 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00153 #endif
00154
00155 Mlt(beta, Y);
00156
00157 T4 zero(0);
00158 T4 temp;
00159
00160 int* ptr = M.GetPtr();
00161 int* ind = M.GetInd();
00162 typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
00163 data = M.GetData();
00164
00165 for (int i = 0; i < ma; i++)
00166 {
00167 temp = zero;
00168 for (int j = ptr[i]; j < ptr[i+1]; j++)
00169 temp += data[j] * X(ind[j]);
00170 Y(i) += alpha * temp;
00171 }
00172 }
00173
00174
00175
00176
00177
00178 template <class T0,
00179 class T1, class Prop1, class Allocator1,
00180 class T2, class Storage2, class Allocator2,
00181 class T3,
00182 class T4, class Storage4, class Allocator4>
00183 void MltAdd(const T0 alpha,
00184 const Matrix<T1, Prop1, RowComplexSparse, Allocator1>& M,
00185 const Vector<T2, Storage2, Allocator2>& X,
00186 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00187 {
00188 int i, j;
00189
00190 int ma = M.GetM();
00191
00192 #ifdef SELDON_CHECK_DIMENSIONS
00193 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00194 #endif
00195
00196 Mlt(beta, Y);
00197
00198 complex<T1> zero(0);
00199 complex<T1> temp;
00200
00201 int* real_ptr = M.GetRealPtr();
00202 int* imag_ptr = M.GetImagPtr();
00203 int* real_ind = M.GetRealInd();
00204 int* imag_ind = M.GetImagInd();
00205 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00206 real_data = M.GetRealData();
00207 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00208 imag_data = M.GetImagData();
00209
00210 for (i = 0; i < ma; i++)
00211 {
00212 temp = zero;
00213 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00214 temp += real_data[j] * X(real_ind[j]);
00215 Y(i) += alpha * temp;
00216 }
00217
00218 for (i = 0; i < ma; i++)
00219 {
00220 temp = zero;
00221 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00222 temp += complex<T1>(T1(0), imag_data[j]) * X(imag_ind[j]);
00223 Y(i) += alpha * temp;
00224 }
00225 }
00226
00227
00228
00229
00230
00231 template <class T0,
00232 class T1, class Prop1, class Allocator1,
00233 class T2, class Storage2, class Allocator2,
00234 class T3,
00235 class T4, class Storage4, class Allocator4>
00236 void MltAdd(const T0 alpha,
00237 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
00238 const Vector<T2, Storage2, Allocator2>& X,
00239 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00240 {
00241 int ma = M.GetM();
00242
00243 #ifdef SELDON_CHECK_DIMENSIONS
00244 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00245 #endif
00246
00247 Mlt(beta, Y);
00248
00249 int i, j;
00250 T4 zero(0);
00251 T4 temp;
00252
00253 int* ptr = M.GetPtr();
00254 int* ind = M.GetInd();
00255 typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
00256 data = M.GetData();
00257
00258 for (i = 0; i < ma; i++)
00259 {
00260 temp = zero;
00261 for (j = ptr[i]; j < ptr[i + 1]; j++)
00262 temp += data[j] * X(ind[j]);
00263 Y(i) += alpha * temp;
00264 }
00265 for (i = 0; i < ma-1; i++)
00266 for (j = ptr[i]; j < ptr[i + 1]; j++)
00267 if (ind[j] != i)
00268 Y(ind[j]) += alpha * data[j] * X(i);
00269 }
00270
00271
00272
00273
00274
00275 template <class T0,
00276 class T1, class Prop1, class Allocator1,
00277 class T2, class Storage2, class Allocator2,
00278 class T3,
00279 class T4, class Storage4, class Allocator4>
00280 void MltAdd(const T0 alpha,
00281 const Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& M,
00282 const Vector<T2, Storage2, Allocator2>& X,
00283 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00284 {
00285 int ma = M.GetM();
00286
00287 #ifdef SELDON_CHECK_DIMENSIONS
00288 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00289 #endif
00290
00291 Mlt(beta, Y);
00292
00293 int i, j;
00294 complex<T1> zero(0);
00295 complex<T1> temp;
00296
00297 int* real_ptr = M.GetRealPtr();
00298 int* imag_ptr = M.GetImagPtr();
00299 int* real_ind = M.GetRealInd();
00300 int* imag_ind = M.GetImagInd();
00301 typename Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>::pointer
00302 real_data = M.GetRealData();
00303 typename Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>::pointer
00304 imag_data = M.GetImagData();
00305
00306 for (i = 0; i<ma; i++)
00307 {
00308 temp = zero;
00309 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00310 temp += real_data[j] * X(real_ind[j]);
00311 Y(i) += alpha * temp;
00312 }
00313 for (i = 0; i<ma-1; i++)
00314 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00315 if (real_ind[j] != i)
00316 Y(real_ind[j]) += alpha * real_data[j] * X(i);
00317
00318 for (i = 0; i < ma; i++)
00319 {
00320 temp = zero;
00321 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00322 temp += complex<T1>(T1(0), imag_data[j]) * X(imag_ind[j]);
00323 Y(i) += alpha * temp;
00324 }
00325 for (i = 0; i<ma-1; i++)
00326 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00327 if (imag_ind[j] != i)
00328 Y(imag_ind[j]) += alpha * complex<T1>(T1(0), imag_data[j]) * X(i);
00329 }
00330
00331
00332
00333
00334
00335
00336 template <class T0,
00337 class T1, class Prop1, class Allocator1,
00338 class T2, class Storage2, class Allocator2,
00339 class T3,
00340 class T4, class Storage4, class Allocator4>
00341 void MltAdd(const T0 alpha,
00342 const class_SeldonNoTrans& Trans,
00343 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
00344 const Vector<T2, Storage2, Allocator2>& X,
00345 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00346 {
00347 MltAdd(alpha, M, X, beta, Y);
00348 }
00349
00350
00351
00352 template <class T0,
00353 class T1, class Prop1, class Allocator1,
00354 class T2, class Storage2, class Allocator2,
00355 class T3,
00356 class T4, class Storage4, class Allocator4>
00357 void MltAdd(const T0 alpha,
00358 const class_SeldonTrans& Trans,
00359 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
00360 const Vector<T2, Storage2, Allocator2>& X,
00361 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00362 {
00363 int i, j;
00364
00365 int ma = M.GetM();
00366
00367 #ifdef SELDON_CHECK_DIMENSIONS
00368 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonTrans, M, X, beta, Y)");
00369 #endif
00370
00371 Mlt(beta, Y);
00372
00373 int* ptr = M.GetPtr();
00374 int* ind = M.GetInd();
00375 typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
00376 data = M.GetData();
00377
00378 for (i = 0; i < ma; i++)
00379 for (j = ptr[i]; j < ptr[i + 1]; j++)
00380 Y(ind[j]) += alpha * data[j] * X(i);
00381 }
00382
00383
00384
00385 template <class T0,
00386 class T1, class Prop1, class Allocator1,
00387 class T2, class Storage2, class Allocator2,
00388 class T3,
00389 class T4, class Storage4, class Allocator4>
00390 void MltAdd(const T0 alpha,
00391 const class_SeldonConjTrans& Trans,
00392 const Matrix<complex<T1>, Prop1, RowSparse, Allocator1>& M,
00393 const Vector<T2, Storage2, Allocator2>& X,
00394 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00395 {
00396 int i, j;
00397
00398 int ma = M.GetM();
00399
00400 #ifdef SELDON_CHECK_DIMENSIONS
00401 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
00402 #endif
00403
00404 Mlt(beta, Y);
00405
00406 int* ptr = M.GetPtr();
00407 int* ind = M.GetInd();
00408 typename Matrix<complex<T1>, Prop1, RowSparse, Allocator1>::pointer
00409 data = M.GetData();
00410
00411 for (i = 0; i < ma; i++)
00412 for (j = ptr[i]; j < ptr[i + 1]; j++)
00413 Y(ind[j]) += alpha * conj(data[j]) * X(i);
00414 }
00415
00416
00417
00418
00419
00420
00421 template <class T0,
00422 class T1, class Prop1, class Allocator1,
00423 class T2, class Storage2, class Allocator2,
00424 class T3,
00425 class T4, class Storage4, class Allocator4>
00426 void MltAdd(const T0 alpha,
00427 const class_SeldonNoTrans& Trans,
00428 const Matrix<T1, Prop1, RowComplexSparse, Allocator1>& M,
00429 const Vector<T2, Storage2, Allocator2>& X,
00430 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00431 {
00432 MltAdd(alpha, M, X, beta, Y);
00433 }
00434
00435
00436
00437 template <class T0,
00438 class T1, class Prop1, class Allocator1,
00439 class T2, class Storage2, class Allocator2,
00440 class T3,
00441 class T4, class Storage4, class Allocator4>
00442 void MltAdd(const T0 alpha,
00443 const class_SeldonTrans& Trans,
00444 const Matrix<T1, Prop1, RowComplexSparse, Allocator1>& M,
00445 const Vector<T2, Storage2, Allocator2>& X,
00446 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00447 {
00448 int i, j;
00449
00450 int ma = M.GetM();
00451
00452 #ifdef SELDON_CHECK_DIMENSIONS
00453 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonTrans, M, X, beta, Y)");
00454 #endif
00455
00456 Mlt(beta, Y);
00457
00458 int* real_ptr = M.GetRealPtr();
00459 int* imag_ptr = M.GetImagPtr();
00460 int* real_ind = M.GetRealInd();
00461 int* imag_ind = M.GetImagInd();
00462 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00463 real_data = M.GetRealData();
00464 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00465 imag_data = M.GetImagData();
00466
00467 for (i = 0; i < ma; i++)
00468 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00469 Y(real_ind[j]) += alpha * real_data[j] * X(i);
00470
00471 for (i = 0; i < ma; i++)
00472 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00473 Y(imag_ind[j]) += alpha * complex<T1>(T1(0), imag_data[j]) * X(i);
00474 }
00475
00476
00477
00478 template <class T0,
00479 class T1, class Prop1, class Allocator1,
00480 class T2, class Storage2, class Allocator2,
00481 class T3,
00482 class T4, class Storage4, class Allocator4>
00483 void MltAdd(const T0 alpha,
00484 const class_SeldonConjTrans& Trans,
00485 const Matrix<T1, Prop1, RowComplexSparse, Allocator1>& M,
00486 const Vector<T2, Storage2, Allocator2>& X,
00487 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00488 {
00489 int i, j;
00490
00491 int ma = M.GetM();
00492
00493 #ifdef SELDON_CHECK_DIMENSIONS
00494 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
00495 #endif
00496
00497 Mlt(beta, Y);
00498
00499 int* real_ptr = M.GetRealPtr();
00500 int* imag_ptr = M.GetImagPtr();
00501 int* real_ind = M.GetRealInd();
00502 int* imag_ind = M.GetImagInd();
00503 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00504 real_data = M.GetRealData();
00505 typename Matrix<T1, Prop1, RowComplexSparse, Allocator1>::pointer
00506 imag_data = M.GetImagData();
00507
00508 for (i = 0; i < ma; i++)
00509 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00510 Y(real_ind[j]) += alpha * real_data[j] * X(i);
00511
00512 for (i = 0; i < ma; i++)
00513 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00514 Y(imag_ind[j]) += alpha * complex<T1>(T1(0), - imag_data[j]) * X(i);
00515 }
00516
00517
00518
00519
00520
00521
00522 template <class T0,
00523 class T1, class Prop1, class Allocator1,
00524 class T2, class Storage2, class Allocator2,
00525 class T3,
00526 class T4, class Storage4, class Allocator4>
00527 void MltAdd(const T0 alpha,
00528 const class_SeldonNoTrans& Trans,
00529 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
00530 const Vector<T2, Storage2, Allocator2>& X,
00531 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00532 {
00533 MltAdd(alpha, M, X, beta, Y);
00534 }
00535
00536
00537
00538 template <class T0,
00539 class T1, class Prop1, class Allocator1,
00540 class T2, class Storage2, class Allocator2,
00541 class T3,
00542 class T4, class Storage4, class Allocator4>
00543 void MltAdd(const T0 alpha,
00544 const class_SeldonTrans& Trans,
00545 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
00546 const Vector<T2, Storage2, Allocator2>& X,
00547 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00548 {
00549 MltAdd(alpha, M, X, beta, Y);
00550 }
00551
00552
00553
00554 template <class T0,
00555 class T1, class Prop1, class Allocator1,
00556 class T2, class Storage2, class Allocator2,
00557 class T3,
00558 class T4, class Storage4, class Allocator4>
00559 void MltAdd(const T0 alpha,
00560 const class_SeldonConjTrans& Trans,
00561 const Matrix<complex<T1>, Prop1, RowSymSparse, Allocator1>& M,
00562 const Vector<T2, Storage2, Allocator2>& X,
00563 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00564 {
00565 int ma = M.GetM();
00566
00567 #ifdef SELDON_CHECK_DIMENSIONS
00568 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
00569 #endif
00570
00571 Mlt(beta, Y);
00572
00573 int i, j;
00574 complex<T1> zero(0);
00575 complex<T1> temp;
00576
00577 int* ptr = M.GetPtr();
00578 int* ind = M.GetInd();
00579 typename Matrix<complex<T1>, Prop1, RowSymSparse, Allocator1>::pointer
00580 data = M.GetData();
00581
00582 for (i = 0; i < ma; i++)
00583 {
00584 temp = zero;
00585 for (j = ptr[i]; j < ptr[i + 1]; j++)
00586 temp += conj(data[j]) * X(ind[j]);
00587 Y(i) += temp;
00588 }
00589 for (i = 0; i < ma - 1; i++)
00590 for (j = ptr[i]; j < ptr[i + 1]; j++)
00591 if (ind[j] != i)
00592 Y(ind[j]) += conj(data[j]) * X(i);
00593 }
00594
00595
00596
00597
00598
00599
00600 template <class T0,
00601 class T1, class Prop1, class Allocator1,
00602 class T2, class Storage2, class Allocator2,
00603 class T3,
00604 class T4, class Storage4, class Allocator4>
00605 void MltAdd(const T0 alpha,
00606 const class_SeldonNoTrans& Trans,
00607 const Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& M,
00608 const Vector<T2, Storage2, Allocator2>& X,
00609 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00610 {
00611 MltAdd(alpha, M, X, beta, Y);
00612 }
00613
00614
00615
00616 template <class T0,
00617 class T1, class Prop1, class Allocator1,
00618 class T2, class Storage2, class Allocator2,
00619 class T3,
00620 class T4, class Storage4, class Allocator4>
00621 void MltAdd(const T0 alpha,
00622 const class_SeldonTrans& Trans,
00623 const Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& M,
00624 const Vector<T2, Storage2, Allocator2>& X,
00625 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00626 {
00627 MltAdd(alpha, M, X, beta, Y);
00628 }
00629
00630
00631
00632 template <class T0,
00633 class T1, class Prop1, class Allocator1,
00634 class T2, class Storage2, class Allocator2,
00635 class T3,
00636 class T4, class Storage4, class Allocator4>
00637 void MltAdd(const T0 alpha,
00638 const class_SeldonConjTrans& Trans,
00639 const Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& M,
00640 const Vector<T2, Storage2, Allocator2>& X,
00641 const T3 beta, Vector<T4, Storage4, Allocator4>& Y)
00642 {
00643 int ma = M.GetM();
00644
00645 #ifdef SELDON_CHECK_DIMENSIONS
00646 CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
00647 #endif
00648
00649 Mlt(beta, Y);
00650
00651 int i, j;
00652 complex<T1> zero(0);
00653 complex<T1> temp;
00654
00655 int* real_ptr = M.GetRealPtr();
00656 int* imag_ptr = M.GetImagPtr();
00657 int* real_ind = M.GetRealInd();
00658 int* imag_ind = M.GetImagInd();
00659 typename Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>::pointer
00660 real_data = M.GetRealData();
00661 typename Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>::pointer
00662 imag_data = M.GetImagData();
00663
00664 for (i = 0; i < ma; i++)
00665 {
00666 temp = zero;
00667 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00668 temp += real_data[j] * X(real_ind[j]);
00669 Y(i) += temp;
00670 }
00671 for (i = 0; i < ma - 1; i++)
00672 for (j = real_ptr[i]; j < real_ptr[i + 1]; j++)
00673 if (real_ind[j] != i)
00674 Y(real_ind[j]) += real_data[j] * X(i);
00675
00676 for (i = 0; i < ma; i++)
00677 {
00678 temp = zero;
00679 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00680 temp += complex<T1>(T1(0), - imag_data[j]) * X(imag_ind[j]);
00681 Y(i) += temp;
00682 }
00683 for (i = 0; i < ma - 1; i++)
00684 for (j = imag_ptr[i]; j < imag_ptr[i + 1]; j++)
00685 if (imag_ind[j] != i)
00686 Y(imag_ind[j]) += complex<T1>(T1(0), - imag_data[j]) * X(i);
00687 }
00688
00689
00690
00692
00693
00694
00696
00697
00698
00713 template <class T0,
00714 class T1, class Prop1, class Storage1, class Allocator1,
00715 class T2, class Storage2, class Allocator2,
00716 class T3,
00717 class T4, class Storage4, class Allocator4>
00718 void MltAdd(const T0 alpha,
00719 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
00720 const Vector<T2, Storage2, Allocator2>& X,
00721 const T3 beta,
00722 Vector<T4, Storage4, Allocator4>& Y)
00723 {
00724 int ma = M.GetM();
00725 int na = M.GetN();
00726
00727 #ifdef SELDON_CHECK_DIMENSIONS
00728 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00729 #endif
00730
00731 Mlt(beta, Y);
00732
00733 T4 zero(0);
00734 T4 temp;
00735 T4 alpha_(alpha);
00736
00737 for (int i = 0; i < ma; i++)
00738 {
00739 temp = zero;
00740 for (int j = 0; j < na; j++)
00741 temp += M(i, j) * X(j);
00742 Y(i) += alpha_ * temp;
00743 }
00744 }
00745
00746
00761 template <class T0,
00762 class T1, class Prop1, class Allocator1,
00763 class T2, class Allocator2,
00764 class T3,
00765 class T4, class Allocator4>
00766 void MltAdd(const T0 alpha,
00767 const Matrix<T1, Prop1, RowMajorCollection, Allocator1>& M,
00768 const Vector<T2, Collection, Allocator2>& X,
00769 const T3 beta,
00770 Vector<T4, Collection, Allocator4>& Y)
00771 {
00772 int ma = M.GetMmatrix();
00773 int na = M.GetNmatrix();
00774
00775 #ifdef SELDON_CHECK_DIMENSIONS
00776 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00777 #endif
00778 typedef typename T4::value_type value_type;
00779
00780 Mlt(value_type(beta), Y);
00781
00782 for (int i = 0; i < ma; i++)
00783 for (int j = 0; j < na; j++)
00784 MltAdd(alpha, M.GetMatrix(i, j), X.GetVector(j), value_type(1.),
00785 Y.GetVector(i));
00786 }
00787
00788
00803 template <class T0,
00804 class T1, class Prop1, class Allocator1,
00805 class T2, class Allocator2,
00806 class T3,
00807 class T4, class Allocator4>
00808 void MltAdd(const T0 alpha,
00809 const Matrix<T1, Prop1, ColMajorCollection, Allocator1>& M,
00810 const Vector<T2, Collection, Allocator2>& X,
00811 const T3 beta,
00812 Vector<T4, Collection, Allocator4>& Y)
00813 {
00814 int ma = M.GetMmatrix();
00815 int na = M.GetNmatrix();
00816
00817 #ifdef SELDON_CHECK_DIMENSIONS
00818 CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
00819 #endif
00820 typedef typename T4::value_type value_type;
00821
00822 Mlt(value_type(beta), Y);
00823
00824 for (int i = 0; i < ma; i++)
00825 for (int j = 0; j < na; j++)
00826 MltAdd(alpha, M.GetMatrix(i, j), X.GetVector(j), value_type(1.),
00827 Y.GetVector(i));
00828 }
00829
00830
00850 template <class T0,
00851 class T1, class Prop1, class Storage1, class Allocator1,
00852 class T2, class Storage2, class Allocator2,
00853 class T3,
00854 class T4, class Storage4, class Allocator4>
00855 void MltAdd(const T0 alpha,
00856 const SeldonTranspose& Trans,
00857 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
00858 const Vector<T2, Storage2, Allocator2>& X,
00859 const T3 beta,
00860 Vector<T4, Storage4, Allocator4>& Y)
00861 {
00862 if (Trans.NoTrans())
00863 {
00864 MltAdd(alpha, M, X, beta, Y);
00865 return;
00866 }
00867 else if (Trans.ConjTrans())
00868 throw WrongArgument("MltAdd(alpha, trans, M, X, beta, Y)",
00869 "Complex conjugation not supported.");
00870
00871 int ma = M.GetM();
00872 int na = M.GetN();
00873
00874 #ifdef SELDON_CHECK_DIMENSIONS
00875 CheckDim(Trans, M, X, Y, "MltAdd(alpha, trans, M, X, beta, Y)");
00876 #endif
00877
00878 if (beta == T3(0))
00879 Y.Fill(T4(0));
00880 else
00881 Mlt(beta, Y);
00882
00883 T4 zero(0);
00884 T4 temp;
00885 T4 alpha_(alpha);
00886
00887 for (int i = 0; i < na; i++)
00888 {
00889 temp = zero;
00890 for (int j = 0; j < ma; j++)
00891 temp += M(j, i) * X(j);
00892 Y(i) += alpha_ * temp;
00893 }
00894 }
00895
00896
00897
00899
00900
00902
00903
00904
00905
00906
00907 template <class T0, class Prop0, class Storage0, class Allocator0,
00908 class T1, class Storage1, class Allocator1>
00909 inline void Gauss(Matrix<T0, Prop0, Storage0, Allocator0>& M,
00910 Vector<T1, Storage1, Allocator1>& X)
00911 {
00912 int i, j, k;
00913 T1 r, S;
00914
00915 int ma = M.GetM();
00916 int na = M.GetN();
00917
00918 #ifdef SELDON_CHECK_DIMENSIONS
00919 if (na != ma)
00920 throw WrongDim("Gauss(M, X)",
00921 "The matrix must be squared.");
00922
00923 CheckDim(M, X, "Gauss(M, X)");
00924 #endif
00925
00926 for (k = 0; k < ma - 1; k++)
00927 for (i = k + 1; i < ma; i++)
00928 {
00929 r = M(i, k) / M(k, k);
00930 for (j = k + 1; j < ma; j++)
00931 M(i, j) -= r * M(k, j);
00932 X(i) -= r *= X(k);
00933 }
00934
00935 X(ma - 1) = X(ma - 1) / M(ma - 1, ma - 1);
00936 for (k = ma - 2; k > -1; k--)
00937 {
00938 S = X(k);
00939 for (j = k + 1; j < ma; j++)
00940 S -= M(k, j) * X(j);
00941 X(k) = S / M(k, k);
00942 }
00943 }
00944
00945
00946
00948
00949
00950
00952
00953
00954
00955
00956 template <class T0, class Prop0, class Storage0, class Allocator0,
00957 class T1, class Storage1, class Allocator1,
00958 class T2, class Storage2, class Allocator2>
00959 inline void GaussSeidel(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
00960 const Vector<T1, Storage1, Allocator1>& X,
00961 Vector<T2, Storage2, Allocator2>& Y,
00962 int iter)
00963 {
00964 int i, j, k;
00965 T1 temp;
00966
00967 int ma = M.GetM();
00968 int na = M.GetN();
00969
00970 #ifdef SELDON_CHECK_DIMENSIONS
00971 if (na != ma)
00972 throw WrongDim("GaussSeidel(M, X, Y, iter)",
00973 "The matrix must be squared.");
00974
00975 CheckDim(M, X, Y, "GaussSeidel(M, X, Y, iter)");
00976 #endif
00977
00978 for (i = 0; i < iter; i++)
00979 for (j = 0; j < na; j++)
00980 {
00981 temp = 0;
00982 for (k = 0; k < j; k++)
00983 temp -= M(j, k) * Y(k);
00984 for (k = j + 1; k < na; k++)
00985 temp -= M(j, k) * Y(k);
00986 Y(j) = (X(j) + temp) / M(j, j);
00987 }
00988 }
00989
00990
00991
00993
00994
00995
00997
00998
00999
01000
01001 template <class T0, class Prop0, class Storage0, class Allocator0,
01002 class T1, class Storage1, class Allocator1,
01003 class T2, class Storage2, class Allocator2,
01004 class T3>
01005 inline void SOR(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01006 const Vector<T1, Storage1, Allocator1>& X,
01007 Vector<T2, Storage2, Allocator2>& Y,
01008 T3 omega,
01009 int iter)
01010 {
01011 int i, j, k;
01012 T1 temp;
01013
01014 int ma = M.GetM();
01015 int na = M.GetN();
01016
01017 #ifdef SELDON_CHECK_DIMENSIONS
01018 if (na != ma)
01019 throw WrongDim("SOR(M, X, Y, omega, iter)",
01020 "The matrix must be squared.");
01021
01022 CheckDim(M, X, Y, "SOR(M, X, Y, omega, iter)");
01023 #endif
01024
01025 for (i = 0; i < iter; i++)
01026 for (j = 0; j < na; j++)
01027 {
01028 temp = 0;
01029 for (k = 0; k < j; k++)
01030 temp -= M(j, k) * Y(k);
01031 for (k = j + 1; k < na; k++)
01032 temp -= M(j, k) * Y(k);
01033 Y(j) = (T3(1) - omega) * Y(j) + omega * (X(j) + temp) / M(j, j);
01034 }
01035 }
01036
01037
01038
01040
01041
01042
01044
01045
01046
01048
01060 template <class T0, class Prop0, class Storage0, class Allocator0,
01061 class T1, class Storage1, class Allocator1>
01062 void SolveLU(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01063 Vector<T1, Storage1, Allocator1>& Y)
01064 {
01065 int i, k;
01066 T1 temp;
01067
01068 int ma = M.GetM();
01069
01070 #ifdef SELDON_CHECK_DIMENSIONS
01071 int na = M.GetN();
01072 if (na != ma)
01073 throw WrongDim("SolveLU(M, Y)",
01074 "The matrix must be squared.");
01075
01076 CheckDim(M, Y, "SolveLU(M, Y)");
01077 #endif
01078
01079
01080 for (i = 0; i < ma; i++)
01081 {
01082 temp = 0;
01083 for (k = 0; k < i; k++)
01084 temp += M(i, k) * Y(k);
01085 Y(i) = (Y(i) - temp) / M(i, i);
01086 }
01087
01088 for (i = ma - 2; i > -1; i--)
01089 {
01090 temp = 0;
01091 for (k = i + 1; k < ma; k++)
01092 temp += M(i, k) * Y(k);
01093 Y(i) -= temp;
01094 }
01095 }
01096
01097
01098
01100
01101
01103
01104
01105
01107
01114 template <class T0, class Prop0, class Storage0, class Allocator0,
01115 class T1, class Storage1, class Allocator1>
01116 void GetAndSolveLU(Matrix<T0, Prop0, Storage0, Allocator0>& M,
01117 Vector<T1, Storage1, Allocator1>& Y)
01118 {
01119 #ifdef SELDON_WITH_LAPACK
01120 Vector<int> P;
01121 GetLU(M, P);
01122 SolveLU(M, P, Y);
01123 #else
01124 GetLU(M);
01125 SolveLU(M, Y);
01126 #endif
01127 }
01128
01129
01130
01132
01133
01134
01136
01137
01138
01140
01149 template <class T0, class Prop0, class Storage0, class Allocator0,
01150 class T1, class Storage1, class Allocator1,
01151 class T2, class Storage2, class Allocator2>
01152 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01153 const Vector<T1, Storage1, Allocator1>& X,
01154 const Vector<T2, Storage2, Allocator2>& Y,
01155 string function = "")
01156 {
01157 if (X.GetLength() != M.GetN() || Y.GetLength() != M.GetM())
01158 throw WrongDim(function, string("Operation M X + Y -> Y not permitted:")
01159 + string("\n M (") + to_str(&M) + string(") is a ")
01160 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01161 + string(" matrix;\n X (") + to_str(&X)
01162 + string(") is vector of length ")
01163 + to_str(X.GetLength()) + string(";\n Y (")
01164 + to_str(&Y) + string(") is vector of length ")
01165 + to_str(Y.GetLength()) + string("."));
01166 }
01167
01168
01170
01179 template <class T0, class Prop0, class Allocator0,
01180 class T1, class Allocator1,
01181 class T2, class Allocator2>
01182 void CheckDim(const Matrix<T0, Prop0, RowMajorCollection, Allocator0>& M,
01183 const Vector<T1, Collection, Allocator1>& X,
01184 const Vector<T2, Collection, Allocator2>& Y,
01185 string function = "")
01186 {
01187 if (X.GetNvector() != M.GetNmatrix() || Y.GetNvector() != M.GetMmatrix())
01188 throw WrongDim(function, string("Operation M X + Y -> Y not permitted:")
01189 + string("\n M (") + to_str(&M) + string(") is a ")
01190 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01191 + string(" matrix;\n X (") + to_str(&X)
01192 + string(") is vector of length ")
01193 + to_str(X.GetNvector()) + string(";\n Y (")
01194 + to_str(&Y) + string(") is vector of length ")
01195 + to_str(Y.GetNvector()) + string("."));
01196 }
01197
01198
01200
01209 template <class T0, class Prop0, class Allocator0,
01210 class T1, class Allocator1,
01211 class T2, class Allocator2>
01212 void CheckDim(const Matrix<T0, Prop0, ColMajorCollection, Allocator0>& M,
01213 const Vector<T1, Collection, Allocator1>& X,
01214 const Vector<T2, Collection, Allocator2>& Y,
01215 string function = "")
01216 {
01217 if (X.GetNvector() != M.GetNmatrix() || Y.GetNvector() != M.GetMmatrix())
01218 throw WrongDim(function, string("Operation M X + Y -> Y not permitted:")
01219 + string("\n M (") + to_str(&M) + string(") is a ")
01220 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01221 + string(" matrix;\n X (") + to_str(&X)
01222 + string(") is vector of length ")
01223 + to_str(X.GetNvector()) + string(";\n Y (")
01224 + to_str(&Y) + string(") is vector of length ")
01225 + to_str(Y.GetNvector()) + string("."));
01226 }
01227
01228
01230
01239 template <class T0, class Prop0, class Storage0, class Allocator0,
01240 class T1, class Allocator1,
01241 class T2, class Storage2, class Allocator2>
01242 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01243 const Vector<T1, Collection, Allocator1>& X,
01244 const Vector<T2, Storage2, Allocator2>& Y,
01245 string function = "")
01246 {
01247 if (X.GetLength() != M.GetN() || Y.GetLength() != M.GetM())
01248 throw WrongDim(function, string("Operation M X + Y -> Y not permitted:")
01249 + string("\n M (") + to_str(&M) + string(") is a ")
01250 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01251 + string(" matrix;\n X (") + to_str(&X)
01252 + string(") is vector of length ")
01253 + to_str(X.GetLength()) + string(";\n Y (")
01254 + to_str(&Y) + string(") is vector of length ")
01255 + to_str(Y.GetLength()) + string("."));
01256 }
01257
01258
01260
01272 template <class T0, class Prop0, class Storage0, class Allocator0,
01273 class T1, class Storage1, class Allocator1,
01274 class T2, class Storage2, class Allocator2>
01275 void CheckDim(const SeldonTranspose& trans,
01276 const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01277 const Vector<T1, Storage1, Allocator1>& X,
01278 const Vector<T2, Storage2, Allocator2>& Y,
01279 string function = "", string op = "M X + Y -> Y")
01280 {
01281 if (op == "M X + Y -> Y")
01282 if (trans.Trans())
01283 op = string("Operation M' X + Y -> Y not permitted:");
01284 else if (trans.ConjTrans())
01285 op = string("Operation M* X + Y -> Y not permitted:");
01286 else
01287 op = string("Operation M X + Y -> Y not permitted:");
01288 else
01289 op = string("Operation ") + op + string(" not permitted:");
01290 if (X.GetLength() != M.GetN(trans) || Y.GetLength() != M.GetM(trans))
01291 throw WrongDim(function, op + string("\n M (") + to_str(&M)
01292 + string(") is a ") + to_str(M.GetM()) + string(" x ")
01293 + to_str(M.GetN()) + string(" matrix;\n X (")
01294 + to_str(&X) + string(") is vector of length ")
01295 + to_str(X.GetLength()) + string(";\n Y (")
01296 + to_str(&Y) + string(") is vector of length ")
01297 + to_str(Y.GetLength()) + string("."));
01298 }
01299
01300
01302
01311 template <class T0, class Prop0, class Storage0, class Allocator0,
01312 class T1, class Storage1, class Allocator1>
01313 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
01314 const Vector<T1, Storage1, Allocator1>& X,
01315 string function = "", string op = "M X")
01316 {
01317 if (X.GetLength() != M.GetN())
01318 throw WrongDim(function, string("Operation ") + op + " not permitted:"
01319 + string("\n M (") + to_str(&M) + string(") is a ")
01320 + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
01321 + string(" matrix;\n X (") + to_str(&X)
01322 + string(") is vector of length ")
01323 + to_str(X.GetLength()) + string("."));
01324 }
01325
01326
01327
01329
01330
01331 }
01332
01333 #define SELDON_FUNCTIONS_MATVECT_CXX
01334 #endif