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_MATRIX_CXX
00024 #define SELDON_FILE_FUNCTIONS_MATRIX_CXX
00025
00026
00027 #include "Functions_Matrix.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
00062
00063
00064 namespace Seldon
00065 {
00066
00067
00069
00070
00071
00073
00077 template <class T0,
00078 class T1, class Prop1, class Storage1, class Allocator1>
00079 void Mlt(const T0 alpha, Matrix<T1, Prop1, Storage1, Allocator1>& A)
00080 {
00081 T1 alpha_ = alpha;
00082
00083 typename Matrix<T1, Prop1, Storage1, Allocator1>::pointer
00084 data = A.GetData();
00085
00086 for (int i = 0; i < A.GetDataSize(); i++)
00087 data[i] = alpha_ * data[i];
00088 }
00089
00090
00092
00096 template <class T0,
00097 class T1, class Prop1, class Allocator1>
00098 void Mlt(const T0 alpha,
00099 Matrix<T1, Prop1, ColMajorCollection, Allocator1>& A)
00100 {
00101 typename T1::value_type alpha_ = alpha;
00102 for (int i = 0; i < A.GetMmatrix(); i++)
00103 for (int j = 0; j < A.GetNmatrix(); j++)
00104 Mlt(alpha, A.GetMatrix(i, j));
00105 }
00106
00107
00109
00113 template <class T0,
00114 class T1, class Prop1, class Allocator1>
00115 void Mlt(const T0 alpha,
00116 Matrix<T1, Prop1, RowMajorCollection, Allocator1>& A)
00117 {
00118 typename T1::value_type alpha_ = alpha;
00119 for (int i = 0; i < A.GetMmatrix(); i++)
00120 for (int j = 0; j < A.GetNmatrix(); j++)
00121 Mlt(alpha_, A.GetMatrix(i, j));
00122 }
00123
00124
00126
00130 template <class T0, class Allocator>
00131 void Mlt(const T0 alpha,
00132 Matrix<FloatDouble, General, DenseSparseCollection, Allocator>& A)
00133 {
00134 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator>
00135 ::float_dense_m m0;
00136 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator>
00137 ::float_sparse_m m1;
00138 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator>
00139 ::double_dense_m m2;
00140 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator>
00141 ::double_sparse_m m3;
00142
00143 for (int i = 0; i < A.GetMmatrix(); i++)
00144 for (int j = 0; j < A.GetNmatrix(); j++)
00145 {
00146 switch (A.GetType(i, j))
00147 {
00148 case 0:
00149 A.GetMatrix(i, j, m0);
00150 Mlt(float(alpha), m0);
00151 A.SetMatrix(i, j, m0);
00152 m0.Nullify();
00153 break;
00154 case 1:
00155 A.GetMatrix(i, j, m1);
00156 Mlt(float(alpha), m1);
00157 A.SetMatrix(i, j, m1);
00158 m1.Nullify();
00159 break;
00160 case 2:
00161 A.GetMatrix(i, j, m2);
00162 Mlt(double(alpha), m2);
00163 A.SetMatrix(i, j, m2);
00164 m2.Nullify();
00165 break;
00166 case 3:
00167 A.GetMatrix(i, j, m3);
00168 Mlt(double(alpha), m3);
00169 A.SetMatrix(i, j, m3);
00170 m3.Nullify();
00171 break;
00172 default:
00173 throw WrongArgument("Mlt(alpha, Matrix<FloatDouble, "
00174 "DenseSparseCollection)",
00175 "Underlying matrix (" + to_str(i) + " ,"
00176 + to_str(j) + " ) not defined.");
00177 }
00178 }
00179 }
00180
00181
00183
00191 template <class T0,
00192 class T1, class Prop1, class Storage1, class Allocator1,
00193 class T2, class Prop2, class Storage2, class Allocator2,
00194 class T3, class Prop3, class Storage3, class Allocator3>
00195 void Mlt(const T0 alpha,
00196 const Matrix<T1, Prop1, Storage1, Allocator1>& A,
00197 const Matrix<T2, Prop2, Storage2, Allocator2>& B,
00198 Matrix<T3, Prop3, Storage3, Allocator3>& C)
00199 {
00200 C.Fill(T3(0));
00201 MltAdd(alpha, A, B, T3(0), C);
00202 }
00203
00204
00206
00212 template <class T0, class Prop0, class Storage0, class Allocator0,
00213 class T1, class Prop1, class Storage1, class Allocator1,
00214 class T2, class Prop2, class Storage2, class Allocator2>
00215 void Mlt(const Matrix<T0, Prop0, Storage0, Allocator0>& A,
00216 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
00217 Matrix<T2, Prop2, Storage2, Allocator2>& C)
00218 {
00219 C.Fill(T2(0));
00220 MltAdd(T0(1), A, B, T2(0), C);
00221 }
00222
00223
00225
00233 template <class T0, class Prop0, class Allocator0,
00234 class T1, class Prop1, class Allocator1,
00235 class T2, class Prop2, class Allocator2>
00236 void Mlt(const Matrix<T0, Prop0, RowSparse, Allocator0>& A,
00237 const Matrix<T1, Prop1, RowSparse, Allocator1>& B,
00238 Matrix<T2, Prop2, RowSparse, Allocator2>& C)
00239 {
00240 #ifdef SELDON_CHECK_DIMENSIONS
00241 CheckDim(A, B, "Mlt(const Matrix<RowSparse>& A, const "
00242 "Matrix<RowSparse>& B, Matrix<RowSparse>& C)");
00243 #endif
00244
00245 int h, i, k, l, col;
00246 int Nnonzero, Nnonzero_row, Nnonzero_row_max;
00247 IVect column_index;
00248 Vector<T2> row_value;
00249 T1 value;
00250 int m = A.GetM();
00251
00252 int* c_ptr = NULL;
00253 int* c_ind = NULL;
00254 T2* c_data = NULL;
00255 C.Clear();
00256
00257 #ifdef SELDON_CHECK_MEMORY
00258 try
00259 {
00260 #endif
00261
00262 c_ptr = reinterpret_cast<int*>(calloc(m + 1, sizeof(int)));
00263
00264 #ifdef SELDON_CHECK_MEMORY
00265 }
00266 catch (...)
00267 {
00268 c_ptr = NULL;
00269 }
00270
00271 if (c_ptr == NULL)
00272 throw NoMemory("Mlt(const Matrix<RowSparse>& A, const "
00273 "Matrix<RowSparse>& B, Matrix<RowSparse>& C)",
00274 "Unable to allocate memory for an array of "
00275 + to_str(m + 1) + " integers.");
00276 #endif
00277
00278 c_ptr[0] = 0;
00279
00280
00281 Nnonzero = 0;
00282 for (i = 0; i < m; i++)
00283 {
00284 c_ptr[i + 1] = c_ptr[i];
00285
00286 if (A.GetPtr()[i + 1] != A.GetPtr()[i])
00287
00288
00289
00290
00291 {
00292
00293 Nnonzero_row_max = 0;
00294
00295 for (k = A.GetPtr()[i]; k < A.GetPtr()[i + 1]; k++)
00296 {
00297 col = A.GetInd()[k];
00298 Nnonzero_row_max += B.GetPtr()[col + 1] - B.GetPtr()[col];
00299 }
00300
00301 column_index.Reallocate(Nnonzero_row_max);
00302 row_value.Reallocate(Nnonzero_row_max);
00303 h = 0;
00304
00305 for (k = A.GetPtr()[i]; k < A.GetPtr()[i + 1]; k++)
00306 {
00307
00308
00309 col = A.GetInd()[k];
00310 value = A.GetData()[k];
00311
00312
00313 for (l = B.GetPtr()[col]; l < B.GetPtr()[col + 1]; l++)
00314 {
00315 column_index(h) = B.GetInd()[l];
00316 row_value(h) = value * B.GetData()[l];
00317 h++;
00318 }
00319 }
00320
00321 Nnonzero_row = column_index.GetLength();
00322 Assemble(Nnonzero_row, column_index, row_value);
00323
00324 #ifdef SELDON_CHECK_MEMORY
00325 try
00326 {
00327 #endif
00328
00329
00330
00331 c_ind = reinterpret_cast<int*>
00332 (realloc(reinterpret_cast<void*>(c_ind),
00333 (Nnonzero + Nnonzero_row) * sizeof(int)));
00334 c_data = reinterpret_cast<T2*>
00335 (C.GetAllocator().reallocate(c_data,
00336 Nnonzero + Nnonzero_row));
00337
00338 #ifdef SELDON_CHECK_MEMORY
00339 }
00340 catch (...)
00341 {
00342 c_ind = NULL;
00343 c_data = NULL;
00344 }
00345
00346 if ((c_ind == NULL || c_data == NULL)
00347 && Nnonzero + Nnonzero_row != 0)
00348 throw NoMemory("Mlt(const Matrix<RowSparse>& A, const "
00349 "Matrix<RowSparse>& B, Matrix<RowSparse>& C)",
00350 "Unable to allocate memory for an array of "
00351 + to_str(Nnonzero + Nnonzero_row) + " integers "
00352 "and for an array of "
00353 + to_str(sizeof(T2) * (Nnonzero + Nnonzero_row))
00354 + " bytes.");
00355 #endif
00356
00357 c_ptr[i + 1] += Nnonzero_row;
00358 for (h = 0; h < Nnonzero_row; h++)
00359 {
00360 c_ind[Nnonzero + h] = column_index(h);
00361 c_data[Nnonzero + h] = row_value(h);
00362 }
00363 Nnonzero += Nnonzero_row;
00364 }
00365 }
00366
00367 C.SetData(A.GetM(), B.GetN(), Nnonzero, c_data, c_ptr, c_ind);
00368 }
00369
00370
00372
00380 template <class T0, class Prop0, class Allocator0,
00381 class T1, class Prop1, class Allocator1,
00382 class T2, class Prop2, class Allocator2>
00383 void Mlt(const Matrix<T0, Prop0, RowMajor, Allocator0>& A,
00384 const Matrix<T1, Prop1, RowSparse, Allocator1>& B,
00385 Matrix<T2, Prop2, RowMajor, Allocator2>& C)
00386 {
00387 #ifdef SELDON_CHECK_DIMENSIONS
00388 CheckDim(A, B, "Mlt(const Matrix<RowMajor>& A, const "
00389 "Matrix<RowSparse>& B, Matrix<RowMajor>& C)");
00390 #endif
00391
00392 int m = A.GetM();
00393 int n = A.GetN();
00394
00395 C.Reallocate(A.GetM(), B.GetN());
00396 C.Fill(T2(0));
00397
00398 for (int i = 0; i < m; i++)
00399 {
00400 for (int k = 0; k < n; k++)
00401 {
00402
00403
00404 for (int l = B.GetPtr()[k]; l < B.GetPtr()[k + 1]; l++)
00405 C(i, B.GetInd()[l]) += A(i, k) * B.GetData()[l];
00406 }
00407 }
00408 }
00409
00410
00412
00420 template <class T0, class Prop0, class Allocator0,
00421 class T1, class Prop1, class Allocator1,
00422 class T2, class Prop2, class Allocator2>
00423 void MltNoTransTrans(const Matrix<T0, Prop0, RowMajor, Allocator0>& A,
00424 const Matrix<T1, Prop1, RowSparse, Allocator1>& B,
00425 Matrix<T2, Prop2, RowMajor, Allocator2>& C)
00426 {
00427 #ifdef SELDON_CHECK_DIMENSIONS
00428 CheckDim(SeldonNoTrans, A, SeldonTrans, B,
00429 "MltNoTransTrans(const Matrix<RowMajor>& A, const "
00430 "Matrix<RowSparse>& B, Matrix<RowMajor>& C)");
00431 #endif
00432
00433 int m = A.GetM();
00434 C.Reallocate(A.GetM(), B.GetM());
00435 C.Fill(T2(0));
00436 for (int i = 0; i < m; i++)
00437 {
00438 for (int j = 0; j < B.GetM(); j++)
00439 {
00440
00441
00442 for (int l = B.GetPtr()[j]; l < B.GetPtr()[j + 1]; l++)
00443 C(i, j) += A(i, B.GetInd()[l]) * B.GetData()[l];
00444 }
00445 }
00446 }
00447
00448
00450
00458 template <class T0, class Prop0, class Allocator0,
00459 class T1, class Prop1, class Allocator1,
00460 class T2, class Prop2, class Allocator2>
00461 void MltNoTransTrans(const Matrix<T0, Prop0, RowSparse, Allocator0>& A,
00462 const Matrix<T1, Prop1, RowSparse, Allocator1>& B,
00463 Matrix<T2, Prop2, RowSparse, Allocator2>& C)
00464 {
00465 #ifdef SELDON_CHECK_DIMENSIONS
00466 CheckDim(SeldonNoTrans, A, SeldonTrans, B,
00467 "MltNoTransTrans(const Matrix<RowSparse>& A, "
00468 "const Matrix<RowSparse>& B, Matrix<RowSparse>& C)");
00469 #endif
00470
00471 int h, i, k, col;
00472 int ib, kb;
00473 int Nnonzero_row;
00474 int Nnonzero;
00475
00476
00477
00478 Vector<int, VectFull, MallocAlloc<int> > column_index;
00479 Vector<T2, VectFull, MallocAlloc<T2> > row_value;
00480 T2 value = 0;
00481
00482 int m = A.GetM();
00483 int n = B.GetM();
00484
00485 int* c_ptr = NULL;
00486 int* c_ind = NULL;
00487 T2* c_data = NULL;
00488
00489 #ifdef SELDON_CHECK_MEMORY
00490 try
00491 {
00492 #endif
00493
00494 c_ptr = reinterpret_cast<int*>(calloc(m + 1, sizeof(int)));
00495
00496 #ifdef SELDON_CHECK_MEMORY
00497 }
00498 catch (...)
00499 {
00500 c_ptr = NULL;
00501 }
00502
00503 if (c_ptr == NULL)
00504 throw NoMemory("MltNoTransTrans(const Matrix<RowSparse>& A, "
00505 "const Matrix<RowSparse>& B, Matrix<RowSparse>& C)",
00506 "Unable to allocate memory for an array of "
00507 + to_str(m + 1) + " integers.");
00508 #endif
00509
00510 c_ptr[0] = 0;
00511
00512
00513 Nnonzero = 0;
00514
00515 for (i = 0; i < m; i++)
00516 {
00517 c_ptr[i + 1] = c_ptr[i];
00518
00519 if (A.GetPtr()[i + 1] != A.GetPtr()[i])
00520
00521
00522
00523
00524 {
00525
00526 for (k = A.GetPtr()[i]; k < A.GetPtr()[i + 1]; k++)
00527 {
00528 col = A.GetInd()[k];
00529
00530 for (ib = 0; ib < n; ib++)
00531 {
00532 for (kb = B.GetPtr()[ib]; kb < B.GetPtr()[ib + 1]; kb++)
00533 if (col == B.GetInd()[kb])
00534 value += A.GetData()[k] * B.GetData()[kb];
00535 if (value != T2(0))
00536 {
00537 row_value.Append(value);
00538 column_index.Append(ib);
00539 value = T2(0);
00540 }
00541 }
00542 }
00543
00544 Nnonzero_row = column_index.GetLength();
00545 Assemble(Nnonzero_row, column_index, row_value);
00546
00547 #ifdef SELDON_CHECK_MEMORY
00548 try
00549 {
00550 #endif
00551
00552
00553
00554 c_ind = reinterpret_cast<int*>
00555 (realloc(reinterpret_cast<void*>(c_ind),
00556 (Nnonzero + Nnonzero_row) * sizeof(int)));
00557 c_data = reinterpret_cast<T2*>
00558 (C.GetAllocator().reallocate(c_data,
00559 Nnonzero + Nnonzero_row));
00560
00561 #ifdef SELDON_CHECK_MEMORY
00562 }
00563 catch (...)
00564 {
00565 c_ind = NULL;
00566 c_data = NULL;
00567 }
00568
00569 if ((c_ind == NULL || c_data == NULL)
00570 && Nnonzero_row != 0)
00571 throw NoMemory("MltNoTransTrans(const Matrix<RowSparse>& A, "
00572 "const Matrix<RowSparse>& B, "
00573 "Matrix<RowSparse>& C)",
00574 "Unable to allocate memory for an array of "
00575 + to_str(Nnonzero + Nnonzero_row) + " integers "
00576 "and for an array of "
00577 + to_str(sizeof(T2) * (Nnonzero + Nnonzero_row))
00578 + " bytes.");
00579 #endif
00580
00581 c_ptr[i + 1] += Nnonzero_row;
00582 for (h = 0; h < Nnonzero_row; h++)
00583 {
00584 c_ind[Nnonzero + h] = column_index(h);
00585 c_data[Nnonzero + h] = row_value(h);
00586 }
00587 Nnonzero += Nnonzero_row;
00588 }
00589
00590 column_index.Clear();
00591 row_value.Clear();
00592 }
00593
00594 C.SetData(A.GetM(), B.GetM(), Nnonzero, c_data, c_ptr, c_ind);
00595 }
00596
00597
00598
00600
00601
00603
00604
00605
00607
00617 template <class T0,
00618 class T1, class Prop1, class Storage1, class Allocator1,
00619 class T2, class Prop2, class Storage2, class Allocator2,
00620 class T3,
00621 class T4, class Prop4, class Storage4, class Allocator4>
00622 void MltAdd(const T0 alpha,
00623 const Matrix<T1, Prop1, Storage1, Allocator1>& A,
00624 const Matrix<T2, Prop2, Storage2, Allocator2>& B,
00625 const T3 beta,
00626 Matrix<T4, Prop4, Storage4, Allocator4>& C)
00627 {
00628 int na = A.GetN();
00629 int mc = C.GetM();
00630 int nc = C.GetN();
00631
00632 #ifdef SELDON_CHECK_DIMENSIONS
00633 CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
00634 #endif
00635
00636 T4 temp;
00637 T4 alpha_(alpha);
00638 T4 beta_(beta);
00639
00640 if (beta_ != T4(0))
00641 for (int i = 0; i < Storage4::GetFirst(mc, nc); i++)
00642 for (int j = 0; j < Storage4::GetSecond(mc, nc); j++)
00643 C(Storage4::GetFirst(i, j), Storage4::GetSecond(i, j))
00644 *= beta_;
00645 else
00646 for (int i = 0; i < Storage4::GetFirst(mc, nc); i++)
00647 for (int j = 0; j < Storage4::GetSecond(mc, nc); j++)
00648 C(Storage4::GetFirst(i, j), Storage4::GetSecond(i, j)) = T4(0);
00649
00650 for (int i = 0; i < Storage4::GetFirst(mc, nc); i++)
00651 for (int j = 0; j < Storage4::GetSecond(mc, nc); j++)
00652 {
00653 temp = T4(0);
00654 for (int k = 0; k < na; k++)
00655 temp += A(Storage4::GetFirst(i, j), k)
00656 * B(k, Storage4::GetSecond(i, j));
00657 C(Storage4::GetFirst(i, j), Storage4::GetSecond(i, j))
00658 += alpha_ * temp;
00659 }
00660 }
00661
00662
00664
00678 template <class T0,
00679 class T1, class Prop1, class Storage1, class Allocator1,
00680 class T2, class Prop2, class Storage2, class Allocator2,
00681 class T3,
00682 class T4, class Prop4, class Storage4, class Allocator4>
00683 void MltAdd(const T0 alpha,
00684 const SeldonTranspose& TransA,
00685 const Matrix<T1, Prop1, Storage1, Allocator1>& A,
00686 const SeldonTranspose& TransB,
00687 const Matrix<T2, Prop2, Storage2, Allocator2>& B,
00688 const T3 beta,
00689 Matrix<T4, Prop4, Storage4, Allocator4>& C)
00690 {
00691 if (!TransA.NoTrans())
00692 throw WrongArgument("MltAdd(const T0 alpha, SeldonTranspose TransA, "
00693 "const Matrix<T1, Prop1, Storage1, Allocator1>& A"
00694 "SeldonTranspose TransB,"
00695 "const Matrix<T2, Prop2, Storage2, Allocator2>& B,"
00696 "const T3 beta,"
00697 "Matrix<T4, Prop4, Storage4, Allocator4>& C)",
00698 "'TransA' must be equal to 'SeldonNoTrans'.");
00699 if (!TransB.NoTrans() && !TransB.Trans())
00700 throw WrongArgument("MltAdd(const T0 alpha, SeldonTranspose TransA, "
00701 "const Matrix<T1, Prop1, Storage1, Allocator1>& A"
00702 "SeldonTranspose TransB,"
00703 "const Matrix<T2, Prop2, Storage2, Allocator2>& B,"
00704 "const T3 beta,"
00705 "Matrix<T4, Prop4, Storage4, Allocator4>& C)",
00706 "'TransB' must be equal to 'SeldonNoTrans' or "
00707 "'SeldonTrans'.");
00708
00709 if (!TransB.Trans())
00710 MltAdd(alpha, A, B, beta, C);
00711 else
00712 {
00713
00714 int na = A.GetN();
00715 int mc = C.GetM();
00716 int nc = C.GetN();
00717
00718 #ifdef SELDON_CHECK_DIMENSIONS
00719 CheckDim(SeldonNoTrans, A, SeldonTrans, B, C,
00720 "MltAdd(alpha, TransA, A, TransB, B, beta, C)");
00721 #endif
00722
00723 T4 temp;
00724 T4 alpha_(alpha);
00725 T4 beta_(beta);
00726
00727 if (beta_ != T4(0))
00728 for (int i = 0; i < Storage4::GetFirst(mc, nc); i++)
00729 for (int j = 0; j < Storage4::GetSecond(mc, nc); j++)
00730 C(Storage4::GetFirst(i, j), Storage4::GetSecond(i, j))
00731 *= beta_;
00732 else
00733 for (int i = 0; i < Storage4::GetFirst(mc, nc); i++)
00734 for (int j = 0; j < Storage4::GetSecond(mc, nc); j++)
00735 C(Storage4::GetFirst(i, j), Storage4::GetSecond(i, j)) = T4(0);
00736
00737 for (int i = 0; i < Storage4::GetFirst(mc, nc); i++)
00738 for (int j = 0; j < Storage4::GetSecond(mc, nc); j++)
00739 {
00740 temp = T4(0);
00741 for (int k = 0; k < na; k++)
00742 temp += A(Storage4::GetFirst(i, j), k)
00743 * B(Storage4::GetSecond(i, j), k);
00744 C(Storage4::GetFirst(i, j), Storage4::GetSecond(i, j))
00745 += alpha_ * temp;
00746 }
00747 }
00748 }
00749
00750
00752
00762 template <class T0,
00763 class T1, class Prop1, class Allocator1,
00764 class T2, class Allocator2,
00765 class T3,
00766 class T4, class Prop4, class Allocator4>
00767 void MltAdd(const T0 alpha,
00768 const Matrix<T1, Prop1, PETScMPIDense, Allocator1>& A,
00769 const Matrix<T2, General, RowMajor, Allocator2>& B,
00770 const T3 beta,
00771 Matrix<T4, Prop4, PETScMPIDense, Allocator4>& C)
00772 {
00773 int na = A.GetN();
00774 int mc = C.GetM();
00775 int nc = C.GetN();
00776
00777 #ifdef SELDON_CHECK_DIMENSIONS
00778 CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
00779 #endif
00780 T1 *local_a;
00781 MatGetArray(A.GetPetscMatrix(), &local_a);
00782 int nlocal_A;
00783 int mlocal_A;
00784 MatGetLocalSize(A.GetPetscMatrix(), &mlocal_A, &nlocal_A);
00785 Matrix<T1, Prop1, ColMajor, Allocator1> local_A;
00786 local_A.SetData(mlocal_A, na, local_a);
00787
00788 T4 *local_c;
00789 MatGetArray(C.GetPetscMatrix(), &local_c);
00790 int nlocal_C;
00791 int mlocal_C;
00792 MatGetLocalSize(C.GetPetscMatrix(), &mlocal_C, &nlocal_C);
00793 Matrix<T4, Prop4, ColMajor, Allocator4> local_C;
00794 local_C.SetData(mlocal_C, nc, local_c);
00795
00796 MltAdd(alpha, local_A, B, beta, local_C);
00797
00798 local_A.Nullify();
00799 MatRestoreArray(A.GetPetscMatrix(), &local_a);
00800 A.Flush();
00801
00802 local_C.Nullify();
00803 MatRestoreArray(C.GetPetscMatrix(), &local_c);
00804 C.Flush();
00805 }
00806
00807
00809
00819 template <class T0,
00820 class T1, class Prop1, class Allocator1,
00821 class T2, class Prop2, class Allocator2,
00822 class T3,
00823 class T4, class Prop4, class Allocator4>
00824 void MltAdd(const T0 alpha,
00825 const Matrix<T1, Prop1, RowMajorCollection, Allocator1>& A,
00826 const Matrix<T2, Prop2, RowMajorCollection, Allocator2>& B,
00827 const T3 beta,
00828 Matrix<T4, Prop4, RowMajorCollection, Allocator4>& C)
00829 {
00830 int na = A.GetNmatrix();
00831 int mc = C.GetMmatrix();
00832 int nc = C.GetNmatrix();
00833
00834 #ifdef SELDON_CHECK_DIMENSIONS
00835 CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
00836 #endif
00837
00838 typedef typename T4::value_type value_type;
00839
00840 Mlt(value_type(beta), C);
00841
00842 for (int i = 0; i < mc; i++ )
00843 for (int j = 0; j < nc; j++)
00844 for (int k = 0; k < na; k++)
00845 MltAdd(value_type(alpha), A.GetMatrix(i, k), B.GetMatrix(k, j),
00846 value_type(1), C.GetMatrix(i, j));
00847 }
00848
00849
00851
00861 template <class T0,
00862 class T1, class Prop1, class Allocator1,
00863 class T2, class Prop2, class Allocator2,
00864 class T3,
00865 class T4, class Prop4, class Allocator4>
00866 void MltAdd(const T0 alpha,
00867 const Matrix<T1, Prop1, ColMajorCollection, Allocator1>& A,
00868 const Matrix<T2, Prop2, ColMajorCollection, Allocator2>& B,
00869 const T3 beta,
00870 Matrix<T4, Prop4, ColMajorCollection, Allocator4>& C)
00871 {
00872 int na = A.GetNmatrix();
00873 int mc = C.GetMmatrix();
00874 int nc = C.GetNmatrix();
00875
00876 #ifdef SELDON_CHECK_DIMENSIONS
00877 CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
00878 #endif
00879
00880 typedef typename T4::value_type value_type;
00881
00882 Mlt(value_type(beta), C);
00883
00884 for (int i = 0; i < mc; i++ )
00885 for (int j = 0; j < nc; j++)
00886 for (int k = 0; k < na; k++)
00887 MltAdd(value_type(alpha), A.GetMatrix(i, k), B.GetMatrix(k, j),
00888 value_type(1), C.GetMatrix(i, j));
00889 }
00890
00891
00892 template <class T0,
00893 class T1, class Allocator1,
00894 class T2, class Allocator2,
00895 class T3,
00896 class T4, class Allocator4>
00897 void MltAdd(const T0 alpha,
00898 const Matrix<T1, General, RowMajor, Allocator1>& A,
00899 const Matrix<T2, General, RowMajor, Allocator2>& B,
00900 const T3 beta,
00901 Matrix<T4, General, RowSparse, Allocator4>& C)
00902 {
00903 throw Undefined("void MltAdd(const T0 alpha,"
00904 "const Matrix<T1, General, RowMajor, Allocator1>& A,"
00905 "const Matrix<T2, General, RowMajor, Allocator2>& B,"
00906 "const T3 beta,"
00907 "Matrix<T4, General, RowSparse, Allocator4>& C)");
00908 }
00909
00910
00911 template <class T0,
00912 class T1, class Allocator1,
00913 class T2, class Allocator2,
00914 class T3,
00915 class T4, class Allocator4>
00916 void MltAdd(const T0 alpha,
00917 const Matrix<T1, General, RowMajor, Allocator1>& A,
00918 const Matrix<T2, General, RowSparse, Allocator2>& B,
00919 const T3 beta,
00920 Matrix<T4, General, RowSparse, Allocator4>& C)
00921 {
00922 throw Undefined("void MltAdd(const T0 alpha,"
00923 "const Matrix<T1, General, RowMajor, Allocator1>& A,"
00924 "const Matrix<T2, General, RowSparse, Allocator2>& B,"
00925 "const T3 beta,"
00926 "Matrix<T4, General, RowSparse, Allocator4>& C)");
00927 }
00928
00929
00930 template <class T0,
00931 class T1, class Allocator1,
00932 class T2, class Allocator2,
00933 class T3,
00934 class T4, class Allocator4>
00935 void MltAdd(const T0 alpha,
00936 const Matrix<T1, General, RowSparse, Allocator1>& A,
00937 const Matrix<T2, General, RowMajor, Allocator2>& B,
00938 const T3 beta,
00939 Matrix<T4, General, RowSparse, Allocator4>& C)
00940 {
00941 throw Undefined("void MltAdd(const T0 alpha,"
00942 "const Matrix<T1, General, RowSparse, Allocator1>& A,"
00943 "const Matrix<T2, General, RowMajor, Allocator2>& B,"
00944 "const T3 beta,"
00945 "Matrix<T4, General, RowSparse, Allocator4>& C)");
00946 }
00947
00948
00949 template <class T0,
00950 class Allocator1,
00951 class Allocator2,
00952 class Allocator3,
00953 class T4, class Prop4, class Storage4, class Allocator4>
00954 void MltAdd_heterogeneous(const T0 alpha,
00955 const Matrix<FloatDouble, General,
00956 DenseSparseCollection, Allocator1>& A,
00957 const Matrix<FloatDouble, General,
00958 DenseSparseCollection, Allocator2>& B,
00959 Matrix<FloatDouble, General,
00960 DenseSparseCollection, Allocator3>& C,
00961 Matrix<T4, Prop4, Storage4, Allocator4>& mc,
00962 int i, int j)
00963 {
00964 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator1>
00965 ::float_dense_m m0a;
00966 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator1>
00967 ::float_sparse_m m1a;
00968 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator1>
00969 ::double_dense_m m2a;
00970 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator1>
00971 ::double_sparse_m m3a;
00972
00973 int na = A.GetNmatrix();
00974 for (int k = 0; k < na; k++)
00975 {
00976 switch (A.GetType(i, k))
00977 {
00978 case 0:
00979 A.GetMatrix(i, k, m0a);
00980 MltAdd_heterogeneous2(alpha, m0a, B, C, mc, j, k);
00981 m0a.Nullify();
00982 break;
00983 case 1:
00984 A.GetMatrix(i, k, m1a);
00985 MltAdd_heterogeneous2(alpha, m1a, B, C, mc, j, k);
00986 m1a.Nullify();
00987 break;
00988 case 2:
00989 A.GetMatrix(i, k, m2a);
00990 MltAdd_heterogeneous2(alpha, m2a, B, C, mc, j, k);
00991 m2a.Nullify();
00992 break;
00993 case 3:
00994 A.GetMatrix(i, k, m3a);
00995 MltAdd_heterogeneous2(alpha, m3a, B, C, mc, j, k);
00996 m3a.Nullify();
00997 break;
00998 default:
00999 throw WrongArgument("Matrix<FloatDouble, DenseSparseCollection>::"
01000 "MltAdd_heterogeneous(alpha, A, B, beta, C) ",
01001 "Underlying matrix A (" + to_str(i) + " ,"
01002 + to_str(k) + " ) not defined.");
01003 }
01004 }
01005 }
01006
01007
01008 template<class T0,
01009 class T1, class Prop1, class Storage1, class Allocator1,
01010 class Allocator2,
01011 class Allocator3,
01012 class T4, class Prop4, class Storage4, class Allocator4>
01013 void MltAdd_heterogeneous2(const T0 alpha,
01014 const Matrix<T1, Prop1,
01015 Storage1, Allocator1>& ma,
01016 const Matrix<FloatDouble, General,
01017 DenseSparseCollection, Allocator2>& B,
01018 Matrix<FloatDouble, General,
01019 DenseSparseCollection, Allocator3>& C,
01020 Matrix<T4, Prop4, Storage4, Allocator4>& mc,
01021 int j, int k)
01022 {
01023 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01024 ::float_dense_m m0b;
01025 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01026 ::float_sparse_m m1b;
01027 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01028 ::double_dense_m m2b;
01029 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01030 ::double_sparse_m m3b;
01031
01032 switch (B.GetType(k, j))
01033 {
01034 case 0:
01035 B.GetMatrix(k, j, m0b);
01036 MltAdd(alpha, ma, m0b, 1., mc);
01037 m0b.Nullify();
01038 break;
01039 case 1:
01040 B.GetMatrix(k, j, m1b);
01041 MltAdd(alpha, ma, m1b, 1., mc);
01042 m1b.Nullify();
01043 break;
01044 case 2:
01045 B.GetMatrix(k, j, m2b);
01046 MltAdd(alpha, ma, m2b, 1., mc);
01047 m2b.Nullify();
01048 break;
01049 case 3:
01050 B.GetMatrix(k, j, m3b);
01051 MltAdd(alpha, ma, m3b, 1., mc);
01052 m3b.Nullify();
01053 break;
01054 default:
01055 throw WrongArgument("Matrix<FloatDouble, DenseSparseCollection>"
01056 "::MltAdd_heterogeneous2(alpha, A, B, beta, C)",
01057 "Underlying matrix B (" + to_str(k) + " ,"
01058 + to_str(j) + " ) not defined.");
01059 }
01060 }
01061
01062
01063
01065
01069 template <class T0, class Allocator1, class Allocator2, class T3,
01070 class Allocator4>
01071 void MltAdd(const T0 alpha,
01072 const Matrix<FloatDouble, General, DenseSparseCollection,
01073 Allocator1>& A,
01074 const Matrix<FloatDouble, General, DenseSparseCollection,
01075 Allocator2>& B,
01076 const T3 beta,
01077 Matrix<FloatDouble, General, DenseSparseCollection,
01078 Allocator4>& C)
01079 {
01080 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator4>
01081 ::float_dense_m m0c;
01082 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator4>
01083 ::float_sparse_m m1c;
01084 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator4>
01085 ::double_dense_m m2c;
01086 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator4>
01087 ::double_sparse_m m3c;
01088
01089 Mlt(beta, C);
01090
01091 int mc = C.GetMmatrix();
01092 int nc = C.GetNmatrix();
01093 for (int i = 0; i < mc; i++ )
01094 for (int j = 0; j < nc; j++)
01095 {
01096 switch (C.GetType(i, j))
01097 {
01098 case 0:
01099 C.GetMatrix(i, j, m0c);
01100 MltAdd_heterogeneous(float(alpha), A, B, C, m0c, i, j);
01101 C.SetMatrix(i, j, m0c);
01102 m0c.Nullify();
01103 break;
01104 case 1:
01105 C.GetMatrix(i, j, m1c);
01106 MltAdd_heterogeneous(float(alpha), A, B, C, m1c, i, j);
01107 C.SetMatrix(i, j, m1c);
01108 m1c.Nullify();
01109 break;
01110 case 2:
01111 C.GetMatrix(i, j, m2c);
01112 MltAdd_heterogeneous(double(alpha), A, B, C, m2c, i, j);
01113 C.SetMatrix(i, j, m2c);
01114 m2c.Nullify();
01115 break;
01116 case 3:
01117 C.GetMatrix(i, j, m3c);
01118 MltAdd_heterogeneous(double(alpha), A, B, C, m3c, i, j);
01119 C.SetMatrix(i, j, m3c);
01120 m3c.Nullify();
01121 break;
01122 default:
01123 throw WrongArgument("Matrix<FloatDouble, DenseSparseCollection>"
01124 "::MltAdd(alpha, A, B, beta, C) ",
01125 "Underlying matrix C (" + to_str(i) + " ,"
01126 + to_str(j) + " ) not defined.");
01127 }
01128 }
01129 }
01130
01131
01133
01143 template <class T0,
01144 class T1, class Prop1, class Allocator1,
01145 class T2, class Prop2, class Allocator2,
01146 class T3,
01147 class T4, class Prop4, class Allocator4>
01148 void MltAdd(const T0 alpha,
01149 const Matrix<T1, Prop1, RowSparse, Allocator1>& A,
01150 const Matrix<T2, Prop2, RowSparse, Allocator2>& B,
01151 const T3 beta,
01152 Matrix<T4, Prop4, RowSparse, Allocator4>& C)
01153 {
01154 if (beta == T3(0))
01155 {
01156 if (alpha == T0(0))
01157 Mlt(alpha, C);
01158 else
01159 {
01160 Mlt(A, B, C);
01161 if (alpha != T0(1))
01162 Mlt(alpha, C);
01163 }
01164 }
01165 else
01166 {
01167 if (alpha == T0(0))
01168 Mlt(beta, C);
01169 else
01170 {
01171 Matrix<T4, Prop4, RowSparse, Allocator4> tmp;
01172 Mlt(A, B, tmp);
01173 if (beta != T0(1))
01174 Mlt(beta, C);
01175 Add(alpha, tmp, C);
01176 }
01177 }
01178 }
01179
01180
01182
01194 template <class T0,
01195 class T1, class Prop1, class Allocator1,
01196 class T2, class Prop2, class Allocator2,
01197 class T3,
01198 class T4, class Prop4, class Allocator4>
01199 void MltNoTransTransAdd(const T0 alpha,
01200 const Matrix<T1, Prop1, RowSparse, Allocator1>& A,
01201 const Matrix<T2, Prop2, RowSparse, Allocator2>& B,
01202 const T3 beta,
01203 Matrix<T4, Prop4, RowSparse, Allocator4>& C)
01204 {
01205 if (beta == T3(0))
01206 {
01207 if (alpha == T0(0))
01208 Mlt(alpha, C);
01209 else
01210 {
01211 MltNoTransTrans(A, B, C);
01212 if (alpha != T0(1))
01213 Mlt(alpha, C);
01214 }
01215 }
01216 else
01217 {
01218 if (alpha == T0(0))
01219 Mlt(beta, C);
01220 else
01221 {
01222 Matrix<T4, Prop4, RowSparse, Allocator4> tmp;
01223 MltNoTransTrans(A, B, tmp);
01224 if (beta != T0(1))
01225 Mlt(beta, C);
01226 Add(alpha, tmp, C);
01227 }
01228 }
01229 }
01230
01231
01233
01249 template <class T0,
01250 class T1, class Prop1, class Allocator1,
01251 class T2, class Prop2, class Allocator2,
01252 class T3,
01253 class T4, class Prop4, class Allocator4>
01254 void MltAdd(const T0 alpha,
01255 const SeldonTranspose& TransA,
01256 const Matrix<T1, Prop1, RowSparse, Allocator1>& A,
01257 const SeldonTranspose& TransB,
01258 const Matrix<T2, Prop2, RowSparse, Allocator2>& B,
01259 const T3 beta,
01260 Matrix<T4, Prop4, RowSparse, Allocator4>& C)
01261 {
01262 if (!TransA.NoTrans())
01263 throw WrongArgument("MltAdd(T0 alpha, SeldonTranspose TransA, "
01264 "const Matrix<RowSparse>& A, SeldonTranspose "
01265 "TransB, const Matrix<RowSparse>& B, T3 beta, "
01266 "Matrix<RowSparse>& C)",
01267 "'TransA' must be equal to 'SeldonNoTrans'.");
01268 if (!TransB.NoTrans() && !TransB.Trans())
01269 throw WrongArgument("MltAdd(T0 alpha, SeldonTranspose TransA, "
01270 "const Matrix<RowSparse>& A, SeldonTranspose "
01271 "TransB, const Matrix<RowSparse>& B, T3 beta, "
01272 "Matrix<RowSparse>& C)",
01273 "'TransB' must be equal to 'SeldonNoTrans' or "
01274 "'SeldonTrans'.");
01275
01276 if (TransB.Trans())
01277 MltNoTransTransAdd(alpha, A, B, beta, C);
01278 else
01279 MltAdd(alpha, A, B, beta, C);
01280 }
01281
01282
01292 template <class T0,
01293 class T1, class Prop1, class Allocator1,
01294 class T2, class Prop2, class Allocator2,
01295 class T3,
01296 class T4, class Prop4, class Allocator4>
01297 void MltAdd(const T0 alpha,
01298 const SeldonTranspose& TransA,
01299 const Matrix<T1, Prop1, RowMajor, Allocator1>& A,
01300 const SeldonTranspose& TransB,
01301 const Matrix<T2, Prop2, RowSparse, Allocator2>& B,
01302 const T3 beta,
01303 Matrix<T4, Prop4, RowMajor, Allocator4>& C)
01304 {
01305 if (!TransA.NoTrans())
01306 throw WrongArgument("MltAdd(T0 alpha, SeldonTranspose TransA, "
01307 "const Matrix<RowMajor>& A, SeldonTranspose "
01308 "TransB, const Matrix<RowSparse>& B, T3 beta, "
01309 "Matrix<RowSparse>& C)",
01310 "'TransA' must be equal to 'SeldonNoTrans'.");
01311 if (!TransB.NoTrans() && !TransB.Trans())
01312 throw WrongArgument("MltAdd(T0 alpha, SeldonTranspose TransA, "
01313 "const Matrix<RowMajor>& A, SeldonTranspose "
01314 "TransB, const Matrix<RowSparse>& B, T3 beta, "
01315 "Matrix<RowMajor>& C)",
01316 "'TransB' must be equal to 'SeldonNoTrans' or "
01317 "'SeldonTrans'.");
01318
01319 #ifdef SELDON_CHECK_DIMENSIONS
01320 CheckDim(SeldonNoTrans, A, SeldonTrans, B, C,
01321 "MltAdd(T0 alpha, const Matrix<RowMajor>& A, const "
01322 "Matrix<RowSparse>& B, T3 beta, Matrix<RowMajor>& C)");
01323 #endif
01324
01325 if (TransB.Trans())
01326 {
01327 int m = A.GetM();
01328 if (beta == 0)
01329 C.Fill(T2(0));
01330 else
01331 Mlt(beta, C);
01332 if (alpha != 0)
01333 for (int i = 0; i < m; i++)
01334 for (int j = 0; j < B.GetM(); j++)
01335 {
01336
01337
01338 for (int l = B.GetPtr()[j]; l < B.GetPtr()[j + 1]; l++)
01339 C(i, j) += alpha * A(i, B.GetInd()[l]) * B.GetData()[l];
01340 }
01341 }
01342 else
01343 MltAdd(alpha, A, B, beta, C);
01344 }
01345
01346
01347
01349
01350
01351
01353
01354
01355
01357
01364 template<class T0, class T1, class Prop1, class Storage1, class Allocator1,
01365 class T2, class Prop2, class Storage2, class Allocator2>
01366 void Add(const T0& alpha,
01367 const Matrix<T1, Prop1, Storage1, Allocator1>& A,
01368 Matrix<T2, Prop2, Storage2, Allocator2>& B)
01369 {
01370 int i, j;
01371 for (i = 0; i < A.GetM(); i++)
01372 for (j = 0; j < A.GetN(); j++)
01373 B(i, j) += alpha * A(i, j);
01374 }
01375
01376
01378
01385 template<class T0,
01386 class T1, class Prop1, class Allocator1,
01387 class T2, class Prop2, class Allocator2>
01388 void Add(const T0& alpha,
01389 const Matrix<T1, Prop1, RowMajorCollection, Allocator1>& A,
01390 Matrix<T2, Prop2, RowMajorCollection, Allocator2>& B)
01391 {
01392 int na = A.GetNmatrix();
01393 int ma = A.GetMmatrix();
01394
01395 typedef typename T2::value_type value_type;
01396
01397 for (int i = 0; i < ma; i++ )
01398 for (int j = 0; j < na; j++)
01399 Add(value_type(alpha), A.GetMatrix(i, j), B.GetMatrix(i, j));
01400 }
01401
01402
01404
01411 template<class T0,
01412 class T1, class Prop1, class Allocator1,
01413 class T2, class Prop2, class Allocator2>
01414 void Add(const T0& alpha,
01415 const Matrix<T1, Prop1, ColMajorCollection, Allocator1>& A,
01416 Matrix<T2, Prop2, ColMajorCollection, Allocator2>& B)
01417 {
01418 int na = A.GetNmatrix();
01419 int ma = A.GetMmatrix();
01420
01421 typedef typename T2::value_type value_type;
01422
01423 for (int i = 0; i < ma; i++ )
01424 for (int j = 0; j < na; j++)
01425 Add(value_type(alpha), A.GetMatrix(i, j), B.GetMatrix(i, j));
01426 }
01427
01428
01429 template <class T0,
01430 class T1, class Prop1, class Storage1, class Allocator1,
01431 class Allocator2>
01432 void Add_heterogeneous(const T0 alpha,
01433 const Matrix<T1, Prop1, Storage1, Allocator1 >& ma,
01434 Matrix<FloatDouble, General,
01435 DenseSparseCollection, Allocator2>& B,
01436 int i, int j)
01437 {
01438 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01439 ::float_dense_m m0b;
01440 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01441 ::float_sparse_m m1b;
01442 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01443 ::double_dense_m m2b;
01444 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01445 ::double_sparse_m m3b;
01446
01447 T0 alpha_ = alpha;
01448
01449 switch (B.GetType(i, j))
01450 {
01451 case 0:
01452 B.GetMatrix(i, j, m0b);
01453 Add(float(alpha_), ma, m0b);
01454 B.SetMatrix(i, j, m0b);
01455 m0b.Nullify();
01456 break;
01457 case 1:
01458 B.GetMatrix(i, j, m1b);
01459 Add(float(alpha_), ma, m1b);
01460 B.SetMatrix(i, j, m1b);
01461 m1b.Nullify();
01462 break;
01463 case 2:
01464 B.GetMatrix(i, j, m2b);
01465 Add(double(alpha_), ma, m2b);
01466 B.SetMatrix(i, j, m2b);
01467 m2b.Nullify();
01468 break;
01469 case 3:
01470 B.GetMatrix(i, j, m3b);
01471 Add(double(alpha_), ma, m3b);
01472 B.SetMatrix(i, j, m3b);
01473 m3b.Nullify();
01474 break;
01475 default:
01476 throw WrongArgument("Add_heterogeneous(alpha, Matrix<FloatDouble, "
01477 "DenseSparseCollection>, Matrix<FloatDouble,"
01478 "DenseSparseCollection> )",
01479 "Underlying matrix (" + to_str(i) + " ,"
01480 + to_str(j) + " ) not defined.");
01481 }
01482 }
01483
01484
01486
01490 template <class T0, class Allocator1, class Allocator2>
01491 void Add(const T0 alpha,
01492 const Matrix<FloatDouble, General,
01493 DenseSparseCollection, Allocator1>& A,
01494 Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>& B)
01495 {
01496 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01497 ::float_dense_m m0a;
01498 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01499 ::float_sparse_m m1a;
01500 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01501 ::double_dense_m m2a;
01502 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01503 ::double_sparse_m m3a;
01504
01505 T0 alpha_ = alpha;
01506
01507 for (int i = 0; i < B.GetMmatrix(); i++)
01508 for (int j = 0; j < B.GetNmatrix(); j++)
01509 {
01510 switch (B.GetType(i, j))
01511 {
01512 case 0:
01513 A.GetMatrix(i, j, m0a);
01514 Add_heterogeneous(float(alpha_), m0a, B, i, j);
01515 m0a.Nullify();
01516 break;
01517 case 1:
01518 A.GetMatrix(i, j, m1a);
01519 Add_heterogeneous(float(alpha_), m1a, B, i, j);
01520 m1a.Nullify();
01521 break;
01522 case 2:
01523 A.GetMatrix(i, j, m2a);
01524 Add_heterogeneous(double(alpha_), m2a, B, i, j);
01525 m2a.Nullify();
01526 break;
01527 case 3:
01528 A.GetMatrix(i, j, m3a);
01529 Add_heterogeneous(double(alpha_), m3a, B, i, j);
01530 m3a.Nullify();
01531 break;
01532 default:
01533 throw
01534 WrongArgument("Add(alpha, Matrix<FloatDouble, "
01535 "DenseSparseCollection>, Matrix<FloatDouble,"
01536 "DenseSparseCollection> )",
01537 "Underlying matrix (" + to_str(i) + " ,"
01538 + to_str(j) + " ) not defined.");
01539 }
01540 }
01541 }
01542
01543
01544 template<class T0, class T1, class Prop1, class Allocator1,
01545 class T2, class Prop2, class Allocator2>
01546 void Add(const T0& alpha,
01547 const Matrix<T1, Prop1, RowMajor, Allocator1>& A,
01548 Matrix<T2, Prop2, RowSparse, Allocator2>& B)
01549 {
01550 throw Undefined("void Add(const T0& alpha,"
01551 "const Matrix<T1, Prop1, RowMajor, Allocator1>& A,"
01552 "Matrix<T2, Prop2, RowSparse, Allocator2>& B)");
01553 }
01554
01555
01556 template<class T0, class T1, class Prop1, class Allocator1,
01557 class T2, class Prop2, class Allocator2>
01558 void Add(const T0& alpha,
01559 const Matrix<T1, Prop1, ColMajor, Allocator1>& A,
01560 Matrix<T2, Prop2, RowSparse, Allocator2>& B)
01561 {
01562 throw Undefined("void Add(const T0& alpha,"
01563 "const Matrix<T1, Prop1, RowMajor, Allocator1>& A,"
01564 "Matrix<T2, Prop2, RowSparse, Allocator2>& B)");
01565 }
01566
01567
01568 template<class T0, class T1, class Storage1, class Allocator1,
01569 class T2, class Storage2, class Allocator2>
01570 void Add(const T0& alpha,
01571 const Matrix<T1, Symmetric, Storage1, Allocator1>& A,
01572 Matrix<T2, Symmetric, Storage2, Allocator2>& B)
01573 {
01574 int i, j;
01575 for (i = 0; i < A.GetM(); i++)
01576 for (j = i; j < A.GetN(); j++)
01577 B(i, j) += alpha * A(i, j);
01578 }
01579
01580
01582
01589 template<class T0, class T1, class Prop1, class Allocator1,
01590 class T2, class Prop2, class Allocator2>
01591 void Add(const T0& alpha,
01592 const Matrix<T1, Prop1, RowSparse, Allocator1>& A,
01593 Matrix<T2, Prop2, RowSparse, Allocator2>& B)
01594 {
01595 #ifdef SELDON_CHECK_BOUNDS
01596 if (A.GetM() != B.GetM() || A.GetN() != B.GetN())
01597 throw WrongDim("Add(alpha, const Matrix<RowSparse>& A, "
01598 "Matrix<RowSparse>& B)",
01599 "Unable to add a " + to_str(A.GetM()) + " x "
01600 + to_str(A.GetN()) + " matrix with a "
01601 + to_str(B.GetM()) + " x " + to_str(B.GetN())
01602 + " matrix.");
01603 #endif
01604
01605 int i = 0;
01606 int j = 0;
01607 int k;
01608
01609 if (A.GetNonZeros() == B.GetNonZeros())
01610
01611 {
01612
01613
01614 for (i = 0; i < A.GetM(); i++)
01615 if (A.GetPtr()[i + 1] == B.GetPtr()[i + 1])
01616 {
01617 for (j = A.GetPtr()[i]; j < A.GetPtr()[i + 1]; j++)
01618 if (A.GetInd()[j] == B.GetInd()[j])
01619 B.GetData()[j] += alpha * A.GetData()[j];
01620 else
01621 break;
01622 if (j != A.GetPtr()[i + 1])
01623 break;
01624 }
01625 else
01626 break;
01627
01628 if (i == A.GetM())
01629 return;
01630 }
01631
01632
01633
01634
01635 for (k = A.GetPtr()[i]; k < j; k++)
01636 if (A.GetInd()[k] == B.GetInd()[k])
01637 B.GetData()[k] -= alpha * A.GetData()[k];
01638
01639
01640 int Nnonzero = A.GetPtr()[i];
01641
01642
01643
01644
01645 int* c_ptr = NULL;
01646 int* c_ind = NULL;
01647 T2* c_data = NULL;
01648
01649 #ifdef SELDON_CHECK_MEMORY
01650 try
01651 {
01652 #endif
01653
01654 c_ptr = reinterpret_cast<int*>(calloc(A.GetM() + 1, sizeof(int)));
01655
01656 #ifdef SELDON_CHECK_MEMORY
01657 }
01658 catch (...)
01659 {
01660 c_ptr = NULL;
01661 }
01662
01663 if (c_ptr == NULL)
01664 throw NoMemory("Add(alpha, const Matrix<RowSparse>& A, "
01665 "Matrix<RowSparse>& B)",
01666 "Unable to allocate memory for an array of "
01667 + to_str(A.GetM() + 1) + " integers.");
01668 #endif
01669
01670 #ifdef SELDON_CHECK_MEMORY
01671 try
01672 {
01673 #endif
01674
01675
01676 c_ind = reinterpret_cast<int*>
01677 (realloc(reinterpret_cast<void*>(c_ind), Nnonzero * sizeof(int)));
01678 c_data = reinterpret_cast<T2*>
01679 (B.GetAllocator().reallocate(c_data, Nnonzero));
01680
01681 #ifdef SELDON_CHECK_MEMORY
01682 }
01683 catch (...)
01684 {
01685 c_ind = NULL;
01686 c_data = NULL;
01687 }
01688
01689 if ((c_ind == NULL || c_data == NULL)
01690 && Nnonzero != 0)
01691 throw NoMemory("Add(alpha, const Matrix<RowSparse>& A, "
01692 "Matrix<RowSparse>& B)",
01693 "Unable to allocate memory for an array of "
01694 + to_str(Nnonzero) + " integers and for an array of "
01695 + to_str(sizeof(T2) * Nnonzero) + " bytes.");
01696 #endif
01697
01698
01699 for (k = 0; k < i + 1; k++)
01700 c_ptr[k] = B.GetPtr()[k];
01701
01702
01703 for (k = 0; k < Nnonzero; k++)
01704 {
01705 c_ind[k] = B.GetInd()[k];
01706 c_data[k] = B.GetData()[k];
01707 }
01708
01709 int Nnonzero_row_max;
01710 int Nnonzero_max;
01711 int ja, jb(0), ka, kb;
01712
01713 for (; i < A.GetM(); i++)
01714 {
01715 Nnonzero_row_max = A.GetPtr()[i + 1] - A.GetPtr()[i]
01716 + B.GetPtr()[i + 1] - B.GetPtr()[i];
01717
01718 Nnonzero_max = Nnonzero + Nnonzero_row_max;
01719
01720 #ifdef SELDON_CHECK_MEMORY
01721 try
01722 {
01723 #endif
01724
01725 c_ind = reinterpret_cast<int*>
01726 (realloc(reinterpret_cast<void*>(c_ind),
01727 Nnonzero_max * sizeof(int)));
01728 c_data = reinterpret_cast<T2*>
01729 (B.GetAllocator().reallocate(c_data, Nnonzero_max));
01730
01731 #ifdef SELDON_CHECK_MEMORY
01732 }
01733 catch (...)
01734 {
01735 c_ind = NULL;
01736 c_data = NULL;
01737 }
01738
01739 if ((c_ind == NULL || c_data == NULL)
01740 && Nnonzero_max != 0)
01741 throw NoMemory("Add(alpha, const Matrix<RowSparse>& A, "
01742 "Matrix<RowSparse>& B)",
01743 "Unable to allocate memory for an array of "
01744 + to_str(Nnonzero_max) + " integers and for an "
01745 "array of "
01746 + to_str(sizeof(T2) * Nnonzero_max) + " bytes.");
01747 #endif
01748
01749 kb = B.GetPtr()[i];
01750 if (kb < B.GetPtr()[i + 1])
01751 jb = B.GetInd()[kb];
01752 for (ka = A.GetPtr()[i]; ka < A.GetPtr()[i + 1]; ka++)
01753 {
01754 ja = A.GetInd()[ka];
01755 while (kb < B.GetPtr()[i + 1] && jb < ja)
01756
01757 {
01758 c_ind[Nnonzero] = jb;
01759 c_data[Nnonzero] = B.GetData()[kb];
01760 kb++;
01761 if (kb < B.GetPtr()[i + 1])
01762 jb = B.GetInd()[kb];
01763 Nnonzero++;
01764 }
01765
01766 if (kb < B.GetPtr()[i + 1] && ja == jb)
01767
01768 {
01769 c_ind[Nnonzero] = jb;
01770 c_data[Nnonzero] = B.GetData()[kb] + alpha * A.GetData()[ka];
01771 kb++;
01772 if (kb < B.GetPtr()[i + 1])
01773 jb = B.GetInd()[kb];
01774 }
01775 else
01776 {
01777 c_ind[Nnonzero] = ja;
01778 c_data[Nnonzero] = alpha * A.GetData()[ka];
01779 }
01780 Nnonzero++;
01781 }
01782
01783
01784 while (kb < B.GetPtr()[i + 1])
01785 {
01786 c_ind[Nnonzero] = jb;
01787 c_data[Nnonzero] = B.GetData()[kb];
01788 kb++;
01789 if (kb < B.GetPtr()[i + 1])
01790 jb = B.GetInd()[kb];
01791 Nnonzero++;
01792 }
01793
01794 c_ptr[i + 1] = Nnonzero;
01795 }
01796
01797 B.SetData(B.GetM(), B.GetN(), Nnonzero, c_data, c_ptr, c_ind);
01798 }
01799
01800
01801
01803
01804
01806
01807
01808
01810
01820 template <class T0, class Prop0, class Storage0, class Allocator0>
01821 void GetLU(Matrix<T0, Prop0, Storage0, Allocator0>& A)
01822 {
01823 int i, p, q, k;
01824 T0 temp;
01825
01826 int ma = A.GetM();
01827
01828 #ifdef SELDON_CHECK_BOUNDS
01829 int na = A.GetN();
01830 if (na != ma)
01831 throw WrongDim("GetLU(A)", "The matrix must be squared.");
01832 #endif
01833
01834 for (i = 0; i < ma; i++)
01835 {
01836 for (p = i; p < ma; p++)
01837 {
01838 temp = 0;
01839 for (k = 0; k < i; k++)
01840 temp += A(p, k) * A(k, i);
01841 A(p, i) -= temp;
01842 }
01843 for (q = i+1; q < ma; q++)
01844 {
01845 temp = 0;
01846 for (k = 0; k < i; k++)
01847 temp += A(i, k) * A(k, q);
01848 A(i, q) = (A(i,q ) - temp) / A(i, i);
01849 }
01850 }
01851 }
01852
01853
01854
01856
01857
01859
01860
01861
01863
01872 template <class T0, class Prop0, class Storage0, class Allocator0,
01873 class T1, class Prop1, class Storage1, class Allocator1,
01874 class T2, class Prop2, class Storage2, class Allocator2>
01875 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01876 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
01877 const Matrix<T2, Prop2, Storage2, Allocator2>& C,
01878 string function)
01879 {
01880 if (B.GetM() != A.GetN() || C.GetM() != A.GetM() || B.GetN() != C.GetN())
01881 throw WrongDim(function, string("Operation A B + C -> C not permitted:")
01882 + string("\n A (") + to_str(&A) + string(") is a ")
01883 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01884 + string(" matrix;\n B (") + to_str(&B)
01885 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01886 + to_str(B.GetN()) + string(" matrix;\n C (")
01887 + to_str(&C) + string(") is a ") + to_str(C.GetM())
01888 + string(" x ") + to_str(C.GetN()) + string(" matrix."));
01889 }
01890
01891
01893
01903 template <class T0, class Prop0, class Storage0, class Allocator0,
01904 class T1, class Prop1, class Storage1, class Allocator1,
01905 class T2, class Prop2, class Storage2, class Allocator2>
01906 void CheckDim(const SeldonSide& side,
01907 const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01908 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
01909 const Matrix<T2, Prop2, Storage2, Allocator2>& C,
01910 string function)
01911 {
01912 if ( SeldonSide(side).Left() &&
01913 (B.GetM() != A.GetN() || C.GetM() != A.GetM()
01914 || B.GetN() != C.GetN()) )
01915 throw WrongDim(function, string("Operation A B + C -> C not permitted:")
01916 + string("\n A (") + to_str(&A) + string(") is a ")
01917 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01918 + string(" matrix;\n B (") + to_str(&B)
01919 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01920 + to_str(B.GetN()) + string(" matrix;\n C (")
01921 + to_str(&C) + string(") is a ") + to_str(C.GetM())
01922 + string(" x ") + to_str(C.GetN()) + string(" matrix."));
01923 else if ( SeldonSide(side).Right() &&
01924 (B.GetN() != A.GetM() || C.GetM() != B.GetM()
01925 || A.GetN() != C.GetN()) )
01926 throw WrongDim(function, string("Operation B A + C -> C not permitted:")
01927 + string("\n A (") + to_str(&A) + string(") is a ")
01928 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01929 + string(" matrix;\n B (") + to_str(&B)
01930 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01931 + to_str(B.GetN()) + string(" matrix;\n C (")
01932 + to_str(&C) + string(") is a ") + to_str(C.GetM())
01933 + string(" x ") + to_str(C.GetN()) + string(" matrix."));
01934 }
01935
01936
01938
01948 template <class T0, class Prop0, class Storage0, class Allocator0,
01949 class T1, class Prop1, class Storage1, class Allocator1>
01950 void CheckDim(const SeldonTranspose& TransA,
01951 const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01952 const SeldonTranspose& TransB,
01953 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
01954 string function)
01955 {
01956 SeldonTranspose status_A(TransA);
01957 SeldonTranspose status_B(TransB);
01958 string op;
01959 if (status_A.Trans())
01960 op = string("A'");
01961 else if (status_A.ConjTrans())
01962 op = string("A*");
01963 else
01964 op = string("A");
01965 if (status_B.Trans())
01966 op += string(" B'");
01967 else if (status_B.ConjTrans())
01968 op += string(" B*");
01969 else
01970 op += string(" B");
01971 op = string("Operation ") + op + string(" not permitted:");
01972 if (B.GetM(status_B) != A.GetN(status_A))
01973 throw WrongDim(function, op
01974 + string("\n A (") + to_str(&A) + string(") is a ")
01975 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01976 + string(" matrix;\n B (") + to_str(&B)
01977 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01978 + to_str(B.GetN()) + string(" matrix."));
01979 }
01980
01981
01983
01994 template <class T0, class Prop0, class Storage0, class Allocator0,
01995 class T1, class Prop1, class Storage1, class Allocator1,
01996 class T2, class Prop2, class Storage2, class Allocator2>
01997 void CheckDim(const SeldonTranspose& TransA,
01998 const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01999 const SeldonTranspose& TransB,
02000 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
02001 const Matrix<T2, Prop2, Storage2, Allocator2>& C,
02002 string function)
02003 {
02004 string op;
02005 if (TransA.Trans())
02006 op = string("A'");
02007 else if (TransA.ConjTrans())
02008 op = string("A*");
02009 else
02010 op = string("A");
02011 if (TransB.Trans())
02012 op += string(" B' + C");
02013 else if (TransB.ConjTrans())
02014 op += string(" B* + C");
02015 else
02016 op += string(" B + C");
02017 op = string("Operation ") + op + string(" not permitted:");
02018 if (B.GetM(TransB) != A.GetN(TransA) || C.GetM() != A.GetM(TransA)
02019 || B.GetN(TransB) != C.GetN())
02020 throw WrongDim(function, op
02021 + string("\n A (") + to_str(&A) + string(") is a ")
02022 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
02023 + string(" matrix;\n B (") + to_str(&B)
02024 + string(") is a ") + to_str(B.GetM()) + string(" x ")
02025 + to_str(B.GetN()) + string(" matrix;\n C (")
02026 + to_str(&C) + string(") is a ") + to_str(C.GetM())
02027 + string(" x ") + to_str(C.GetN()) + string(" matrix."));
02028 }
02029
02030
02032
02040 template <class T0, class Prop0, class Storage0, class Allocator0,
02041 class T1, class Prop1, class Storage1, class Allocator1>
02042 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& A,
02043 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
02044 string function)
02045 {
02046 CheckDim(SeldonLeft, A, B, function);
02047 }
02048
02049
02051
02060 template <class T0, class Prop0, class Storage0, class Allocator0,
02061 class T1, class Prop1, class Storage1, class Allocator1>
02062 void CheckDim(const SeldonSide& side,
02063 const Matrix<T0, Prop0, Storage0, Allocator0>& A,
02064 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
02065 string function)
02066 {
02067 if (side.Left() && B.GetM() != A.GetN())
02068 throw WrongDim(function, string("Operation A B not permitted:")
02069 + string("\n A (") + to_str(&A) + string(") is a ")
02070 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
02071 + string(" matrix;\n B (") + to_str(&B)
02072 + string(") is a ") + to_str(B.GetM()) + string(" x ")
02073 + to_str(B.GetN()) + string(" matrix."));
02074 else if (side.Right() && B.GetN() != A.GetM())
02075 throw WrongDim(function, string("Operation B A not permitted:")
02076 + string("\n A (") + to_str(&A) + string(") is a ")
02077 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
02078 + string(" matrix;\n B (") + to_str(&B)
02079 + string(") is a ") + to_str(B.GetM()) + string(" x ")
02080 + to_str(B.GetN()) + string(" matrix."));
02081 }
02082
02083
02084
02086
02087
02089
02090
02091
02093
02097 template <class T, class Prop, class Storage, class Allocator>
02098 T MaxAbs(const Matrix<T, Prop, Storage, Allocator>& A)
02099 {
02100 T res(0);
02101 for (int i = 0; i < A.GetM(); i++)
02102 for (int j = 0; j < A.GetN(); j++)
02103 res = max(res, abs(A(i, j)) );
02104
02105 return res;
02106 }
02107
02108
02110
02114 template <class T, class Prop, class Storage, class Allocator>
02115 T Norm1(const Matrix<T, Prop, Storage, Allocator>& A)
02116 {
02117 T res(0), sum;
02118 for (int j = 0; j < A.GetN(); j++)
02119 {
02120 sum = T(0);
02121 for (int i = 0; i < A.GetM(); i++)
02122 sum += abs( A(i, j) );
02123
02124 res = max(res, sum);
02125 }
02126
02127 return res;
02128 }
02129
02130
02132
02136 template <class T, class Prop, class Storage, class Allocator>
02137 T NormInf(const Matrix<T, Prop, Storage, Allocator>& A)
02138 {
02139 T res(0), sum;
02140 for (int i = 0; i < A.GetM(); i++)
02141 {
02142 sum = T(0);
02143 for (int j = 0; j < A.GetN(); j++)
02144 sum += abs( A(i, j) );
02145
02146 res = max(res, sum);
02147 }
02148
02149 return res;
02150 }
02151
02152
02154
02158 template <class T, class Prop, class Storage, class Allocator>
02159 T MaxAbs(const Matrix<complex<T>, Prop, Storage, Allocator>& A)
02160 {
02161 T res(0);
02162 for (int i = 0; i < A.GetM(); i++)
02163 for (int j = 0; j < A.GetN(); j++)
02164 {
02165 res = max(res, abs(A(i, j)) );
02166 }
02167
02168 return res;
02169 }
02170
02171
02173
02177 template <class T, class Prop, class Storage, class Allocator>
02178 T Norm1(const Matrix<complex<T>, Prop, Storage, Allocator>& A)
02179 {
02180 T res(0), sum;
02181 for (int j = 0; j < A.GetN(); j++)
02182 {
02183 sum = T(0);
02184 for (int i = 0; i < A.GetM(); i++)
02185 sum += abs( A(i, j) );
02186
02187 res = max(res, sum);
02188 }
02189
02190 return res;
02191 }
02192
02193
02195
02199 template <class T, class Prop, class Storage, class Allocator>
02200 T NormInf(const Matrix<complex<T>, Prop, Storage, Allocator>& A)
02201 {
02202 T res(0), sum;
02203 for (int i = 0; i < A.GetM(); i++)
02204 {
02205 sum = T(0);
02206 for (int j = 0; j < A.GetN(); j++)
02207 sum += abs( A(i, j) );
02208
02209 res = max(res, sum);
02210 }
02211
02212 return res;
02213 }
02214
02215
02216
02218
02219
02221
02222
02223
02225 template<class T, class Prop, class Storage, class Allocator>
02226 void Transpose(Matrix<T, Prop, Storage, Allocator>& A)
02227 {
02228 int m = A.GetM();
02229 int n = A.GetN();
02230
02231 if (m == n)
02232 {
02233 T tmp;
02234 for (int i = 0; i < m; i++)
02235 for (int j = 0; j < i; j++)
02236 {
02237 tmp = A(i,j);
02238 A.Get(i,j) = A(j,i);
02239 A.Get(j,i) = tmp;
02240 }
02241 }
02242 else
02243 {
02244 Matrix<T, Prop, Storage, Allocator> B;
02245 B = A;
02246 A.Reallocate(n,m);
02247 for (int i = 0; i < m; i++)
02248 for (int j = 0; j < n; j++)
02249 A.Get(j,i) = B(i,j);
02250 }
02251 }
02252
02253
02255 template<class T, class Allocator>
02256 void Transpose(Matrix<T, General, RowSparse, Allocator>& A)
02257 {
02258 int m = A.GetM();
02259 int n = A.GetN();
02260 int nnz = A.GetDataSize();
02261 Vector<int, VectFull, CallocAlloc<int> > ptr_T(n+1), ptr;
02262 Vector<int, VectFull, CallocAlloc<int> > ind_T(nnz), ind;
02263 Vector<T, VectFull, Allocator> data_T(nnz), data;
02264
02265 ptr.SetData(m+1, A.GetPtr());
02266 ind.SetData(nnz, A.GetInd());
02267 data.SetData(nnz, A.GetData());
02268
02269 ptr_T.Zero();
02270 ind_T.Zero();
02271 data_T.Zero();
02272
02273
02274
02275 for (int i = 0; i < nnz; i++)
02276 ptr_T(ind(i) + 1)++;
02277
02278
02279 for (int j = 1; j < n + 1; j++)
02280 ptr_T(j) += ptr_T(j - 1);
02281
02282 Vector<int, VectFull, CallocAlloc<int> > row_ind(n+1);
02283 row_ind.Fill(0);
02284 for (int i = 0; i < m; i++)
02285 for (int jp = ptr(i); jp < ptr(i+1); jp++)
02286 {
02287 int j = ind(jp);
02288 int k = ptr_T(j) + row_ind(j);
02289 ++row_ind(j);
02290 data_T(k) = data(jp);
02291 ind_T(k) = i;
02292 }
02293
02294 A.SetData(n, m, data_T, ptr_T, ind_T);
02295
02296 data.Nullify();
02297 ptr.Nullify();
02298 ind.Nullify();
02299 }
02300
02301
02303 template<class T, class Prop, class Storage, class Allocator>
02304 void TransposeConj(Matrix<T, Prop, Storage, Allocator>& A)
02305 {
02306 int i, j;
02307
02308 int m = A.GetM();
02309 int n = A.GetN();
02310
02311 if (m == n)
02312 {
02313 T tmp;
02314 for (i = 0; i < m; i++)
02315 {
02316
02317 for (j = 0; j < i; j++)
02318 {
02319 tmp = A(i, j);
02320 A(i, j) = conj(A(j, i));
02321 A(j, i) = conj(tmp);
02322 }
02323
02324
02325 A(i, i) = conj(A(i, i));
02326 }
02327 }
02328 else
02329 {
02330 Matrix<T, Prop, Storage, Allocator> B;
02331 B = A;
02332 A.Reallocate(n, m);
02333 for (i = 0; i < m; i++)
02334 for (j = 0; j < n; j++)
02335 A(j, i) = conj(B(i, j));
02336 }
02337 }
02338
02339
02340
02342
02343
02345
02346
02347
02349 template<class T, class Prop, class Storage, class Allocator>
02350 bool IsSymmetricMatrix(const Matrix<T, Prop, Storage, Allocator>& A)
02351 {
02352 return false;
02353 }
02354
02355
02357 template<class T, class Storage, class Allocator>
02358 bool IsSymmetricMatrix(const Matrix<T, Symmetric, Storage, Allocator>& A)
02359 {
02360 return true;
02361 }
02362
02363
02364
02366
02367
02368 }
02369
02370
02371 #endif