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
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
00056
00057
00058 namespace Seldon
00059 {
00060
00061
00063
00064
00065
00067
00071 template <class T0,
00072 class T1, class Prop1, class Storage1, class Allocator1>
00073 void Mlt(const T0 alpha,
00074 Matrix<T1, Prop1, Storage1, Allocator1>& A) throw()
00075 {
00076 T1 alpha_ = alpha;
00077
00078 typename Matrix<T1, Prop1, Storage1, Allocator1>::pointer
00079 data = A.GetData();
00080
00081 for (int i = 0; i < A.GetDataSize(); i++)
00082 data[i] = alpha_ * data[i];
00083 }
00084
00085
00087
00091 template <class T0,
00092 class T1, class Prop1, class Allocator1>
00093 void Mlt(const T0 alpha,
00094 Matrix<T1, Prop1, ColMajorCollection, Allocator1>& A)
00095 {
00096 typename T1::value_type alpha_ = alpha;
00097 for (int i = 0; i < A.GetMmatrix(); i++)
00098 for (int j = 0; j < A.GetNmatrix(); j++)
00099 Mlt(alpha, A.GetMatrix(i, j));
00100 }
00101
00102
00104
00108 template <class T0,
00109 class T1, class Prop1, class Allocator1>
00110 void Mlt(const T0 alpha,
00111 Matrix<T1, Prop1, RowMajorCollection, Allocator1>& A)
00112 {
00113 typename T1::value_type alpha_ = alpha;
00114 for (int i = 0; i < A.GetMmatrix(); i++)
00115 for (int j = 0; j < A.GetNmatrix(); j++)
00116 Mlt(alpha_, A.GetMatrix(i, j));
00117 }
00118
00119
00121
00125 template <class T0, class Allocator>
00126 void Mlt(const T0 alpha,
00127 Matrix<FloatDouble, General, DenseSparseCollection, Allocator>& A)
00128 {
00129 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator>
00130 ::float_dense_m m0;
00131 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator>
00132 ::float_sparse_m m1;
00133 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator>
00134 ::double_dense_m m2;
00135 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator>
00136 ::double_sparse_m m3;
00137
00138 for (int i = 0; i < A.GetMmatrix(); i++)
00139 for (int j = 0; j < A.GetNmatrix(); j++)
00140 {
00141 switch (A.GetType(i, j))
00142 {
00143 case 0:
00144 A.GetMatrix(i, j, m0);
00145 Mlt(float(alpha), m0);
00146 A.SetMatrix(i, j, m0);
00147 m0.Nullify();
00148 break;
00149 case 1:
00150 A.GetMatrix(i, j, m1);
00151 Mlt(float(alpha), m1);
00152 A.SetMatrix(i, j, m1);
00153 m1.Nullify();
00154 break;
00155 case 2:
00156 A.GetMatrix(i, j, m2);
00157 Mlt(double(alpha), m2);
00158 A.SetMatrix(i, j, m2);
00159 m2.Nullify();
00160 break;
00161 case 3:
00162 A.GetMatrix(i, j, m3);
00163 Mlt(double(alpha), m3);
00164 A.SetMatrix(i, j, m3);
00165 m3.Nullify();
00166 break;
00167 default:
00168 throw WrongArgument("Mlt(alpha, Matrix<FloatDouble, "
00169 "DenseSparseCollection)",
00170 "Underlying matrix (" + to_str(i) + " ,"
00171 + to_str(j) + " ) not defined.");
00172 }
00173 }
00174 }
00175
00176
00178
00186 template <class T0,
00187 class T1, class Prop1, class Storage1, class Allocator1,
00188 class T2, class Prop2, class Storage2, class Allocator2,
00189 class T3, class Prop3, class Storage3, class Allocator3>
00190 void Mlt(const T0 alpha,
00191 const Matrix<T1, Prop1, Storage1, Allocator1>& A,
00192 const Matrix<T2, Prop2, Storage2, Allocator2>& B,
00193 Matrix<T3, Prop3, Storage3, Allocator3>& C)
00194 {
00195 C.Fill(T3(0));
00196 MltAdd(alpha, A, B, T3(0), C);
00197 }
00198
00199
00201
00207 template <class T0, class Prop0, class Storage0, class Allocator0,
00208 class T1, class Prop1, class Storage1, class Allocator1,
00209 class T2, class Prop2, class Storage2, class Allocator2>
00210 void Mlt(const Matrix<T0, Prop0, Storage0, Allocator0>& A,
00211 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
00212 Matrix<T2, Prop2, Storage2, Allocator2>& C)
00213 {
00214 C.Fill(T2(0));
00215 MltAdd(T0(1), A, B, T2(0), C);
00216 }
00217
00218
00220
00228 template <class T0, class Prop0, class Allocator0,
00229 class T1, class Prop1, class Allocator1,
00230 class T2, class Prop2, class Allocator2>
00231 void Mlt(const Matrix<T0, Prop0, RowSparse, Allocator0>& A,
00232 const Matrix<T1, Prop1, RowSparse, Allocator1>& B,
00233 Matrix<T2, Prop2, RowSparse, Allocator2>& C)
00234 {
00235 #ifdef SELDON_CHECK_DIMENSIONS
00236 CheckDim(A, B, "Mlt(const Matrix<RowSparse>& A, const "
00237 "Matrix<RowSparse>& B, Matrix<RowSparse>& C)");
00238 #endif
00239
00240 int h, i, k, l, col;
00241 int Nnonzero, Nnonzero_row, Nnonzero_row_max;
00242 IVect column_index;
00243 Vector<T2> row_value;
00244 T1 value;
00245 int m = A.GetM();
00246
00247 int* c_ptr = NULL;
00248 int* c_ind = NULL;
00249 T2* c_data = NULL;
00250 C.Clear();
00251
00252 #ifdef SELDON_CHECK_MEMORY
00253 try
00254 {
00255 #endif
00256
00257 c_ptr = reinterpret_cast<int*>(calloc(m + 1, sizeof(int)));
00258
00259 #ifdef SELDON_CHECK_MEMORY
00260 }
00261 catch (...)
00262 {
00263 c_ptr = NULL;
00264 }
00265
00266 if (c_ptr == NULL)
00267 throw NoMemory("Mlt(const Matrix<RowSparse>& A, const "
00268 "Matrix<RowSparse>& B, Matrix<RowSparse>& C)",
00269 "Unable to allocate memory for an array of "
00270 + to_str(m + 1) + " integers.");
00271 #endif
00272
00273 c_ptr[0] = 0;
00274
00275
00276 Nnonzero = 0;
00277 for (i = 0; i < m; i++)
00278 {
00279 c_ptr[i + 1] = c_ptr[i];
00280
00281 if (A.GetPtr()[i + 1] != A.GetPtr()[i])
00282
00283
00284
00285
00286 {
00287
00288 Nnonzero_row_max = 0;
00289
00290 for (k = A.GetPtr()[i]; k < A.GetPtr()[i + 1]; k++)
00291 {
00292 col = A.GetInd()[k];
00293 Nnonzero_row_max += B.GetPtr()[col + 1] - B.GetPtr()[col];
00294 }
00295
00296 column_index.Reallocate(Nnonzero_row_max);
00297 row_value.Reallocate(Nnonzero_row_max);
00298 h = 0;
00299
00300 for (k = A.GetPtr()[i]; k < A.GetPtr()[i + 1]; k++)
00301 {
00302
00303
00304 col = A.GetInd()[k];
00305 value = A.GetData()[k];
00306
00307
00308 for (l = B.GetPtr()[col]; l < B.GetPtr()[col + 1]; l++)
00309 {
00310 column_index(h) = B.GetInd()[l];
00311 row_value(h) = value * B.GetData()[l];
00312 h++;
00313 }
00314 }
00315
00316 Nnonzero_row = column_index.GetLength();
00317 Assemble(Nnonzero_row, column_index, row_value);
00318
00319 #ifdef SELDON_CHECK_MEMORY
00320 try
00321 {
00322 #endif
00323
00324
00325
00326 c_ind = reinterpret_cast<int*>
00327 (realloc(reinterpret_cast<void*>(c_ind),
00328 (Nnonzero + Nnonzero_row) * sizeof(int)));
00329 c_data = reinterpret_cast<T2*>
00330 (C.GetAllocator().reallocate(c_data,
00331 Nnonzero + Nnonzero_row));
00332
00333 #ifdef SELDON_CHECK_MEMORY
00334 }
00335 catch (...)
00336 {
00337 c_ind = NULL;
00338 c_data = NULL;
00339 }
00340
00341 if ((c_ind == NULL || c_data == NULL)
00342 && Nnonzero + Nnonzero_row != 0)
00343 throw NoMemory("Mlt(const Matrix<RowSparse>& A, const "
00344 "Matrix<RowSparse>& B, Matrix<RowSparse>& C)",
00345 "Unable to allocate memory for an array of "
00346 + to_str(Nnonzero + Nnonzero_row) + " integers "
00347 "and for an array of "
00348 + to_str(sizeof(T2) * (Nnonzero + Nnonzero_row))
00349 + " bytes.");
00350 #endif
00351
00352 c_ptr[i + 1] += Nnonzero_row;
00353 for (h = 0; h < Nnonzero_row; h++)
00354 {
00355 c_ind[Nnonzero + h] = column_index(h);
00356 c_data[Nnonzero + h] = row_value(h);
00357 }
00358 Nnonzero += Nnonzero_row;
00359 }
00360 }
00361
00362 C.SetData(A.GetM(), B.GetN(), Nnonzero, c_data, c_ptr, c_ind);
00363 }
00364
00365
00367
00375 template <class T0, class Prop0, class Allocator0,
00376 class T1, class Prop1, class Allocator1,
00377 class T2, class Prop2, class Allocator2>
00378 void MltNoTransTrans(const Matrix<T0, Prop0, RowSparse, Allocator0>& A,
00379 const Matrix<T1, Prop1, RowSparse, Allocator1>& B,
00380 Matrix<T2, Prop2, RowSparse, Allocator2>& C)
00381 {
00382 #ifdef SELDON_CHECK_DIMENSIONS
00383 CheckDim(SeldonNoTrans, A, SeldonTrans, B,
00384 "MltNoTransTrans(const Matrix<RowSparse>& A, "
00385 "const Matrix<RowSparse>& B, Matrix<RowSparse>& C)");
00386 #endif
00387
00388 int h, i, k, col;
00389 int ib, kb;
00390 int Nnonzero_row;
00391 int Nnonzero;
00392
00393
00394
00395 Vector<int, VectFull, MallocAlloc<int> > column_index;
00396 Vector<T2, VectFull, MallocAlloc<T2> > row_value;
00397 T2 value = 0;
00398
00399 int m = A.GetM();
00400 int n = B.GetM();
00401
00402 int* c_ptr = NULL;
00403 int* c_ind = NULL;
00404 T2* c_data = NULL;
00405
00406 #ifdef SELDON_CHECK_MEMORY
00407 try
00408 {
00409 #endif
00410
00411 c_ptr = reinterpret_cast<int*>(calloc(m + 1, sizeof(int)));
00412
00413 #ifdef SELDON_CHECK_MEMORY
00414 }
00415 catch (...)
00416 {
00417 c_ptr = NULL;
00418 }
00419
00420 if (c_ptr == NULL)
00421 throw NoMemory("MltNoTransTrans(const Matrix<RowSparse>& A, "
00422 "const Matrix<RowSparse>& B, Matrix<RowSparse>& C)",
00423 "Unable to allocate memory for an array of "
00424 + to_str(m + 1) + " integers.");
00425 #endif
00426
00427 c_ptr[0] = 0;
00428
00429
00430 Nnonzero = 0;
00431
00432 for (i = 0; i < m; i++)
00433 {
00434 c_ptr[i + 1] = c_ptr[i];
00435
00436 if (A.GetPtr()[i + 1] != A.GetPtr()[i])
00437
00438
00439
00440
00441 {
00442
00443 for (k = A.GetPtr()[i]; k < A.GetPtr()[i + 1]; k++)
00444 {
00445 col = A.GetInd()[k];
00446
00447 for (ib = 0; ib < n; ib++)
00448 {
00449 for (kb = B.GetPtr()[ib]; kb < B.GetPtr()[ib + 1]; kb++)
00450 if (col == B.GetInd()[kb])
00451 value += A.GetData()[k] * B.GetData()[kb];
00452 if (value != T2(0))
00453 {
00454 row_value.Append(value);
00455 column_index.Append(ib);
00456 value = T2(0);
00457 }
00458 }
00459 }
00460
00461 Nnonzero_row = column_index.GetLength();
00462 Assemble(Nnonzero_row, column_index, row_value);
00463
00464 #ifdef SELDON_CHECK_MEMORY
00465 try
00466 {
00467 #endif
00468
00469
00470
00471 c_ind = reinterpret_cast<int*>
00472 (realloc(reinterpret_cast<void*>(c_ind),
00473 (Nnonzero + Nnonzero_row) * sizeof(int)));
00474 c_data = reinterpret_cast<T2*>
00475 (C.GetAllocator().reallocate(c_data,
00476 Nnonzero + Nnonzero_row));
00477
00478 #ifdef SELDON_CHECK_MEMORY
00479 }
00480 catch (...)
00481 {
00482 c_ind = NULL;
00483 c_data = NULL;
00484 }
00485
00486 if ((c_ind == NULL || c_data == NULL)
00487 && Nnonzero_row != 0)
00488 throw NoMemory("MltNoTransTrans(const Matrix<RowSparse>& A, "
00489 "const Matrix<RowSparse>& B, "
00490 "Matrix<RowSparse>& C)",
00491 "Unable to allocate memory for an array of "
00492 + to_str(Nnonzero + Nnonzero_row) + " integers "
00493 "and for an array of "
00494 + to_str(sizeof(T2) * (Nnonzero + Nnonzero_row))
00495 + " bytes.");
00496 #endif
00497
00498 c_ptr[i + 1] += Nnonzero_row;
00499 for (h = 0; h < Nnonzero_row; h++)
00500 {
00501 c_ind[Nnonzero + h] = column_index(h);
00502 c_data[Nnonzero + h] = row_value(h);
00503 }
00504 Nnonzero += Nnonzero_row;
00505 }
00506
00507 column_index.Clear();
00508 row_value.Clear();
00509 }
00510
00511 C.SetData(A.GetM(), B.GetM(), Nnonzero, c_data, c_ptr, c_ind);
00512 }
00513
00514
00515
00517
00518
00519
00521
00522
00523
00525
00535 template <class T0,
00536 class T1, class Prop1, class Storage1, class Allocator1,
00537 class T2, class Prop2, class Storage2, class Allocator2,
00538 class T3,
00539 class T4, class Prop4, class Storage4, class Allocator4>
00540 void MltAdd(const T0 alpha,
00541 const Matrix<T1, Prop1, Storage1, Allocator1>& A,
00542 const Matrix<T2, Prop2, Storage2, Allocator2>& B,
00543 const T3 beta,
00544 Matrix<T4, Prop4, Storage4, Allocator4>& C)
00545 {
00546 int na = A.GetN();
00547 int mc = C.GetM();
00548 int nc = C.GetN();
00549
00550 #ifdef SELDON_CHECK_DIMENSIONS
00551 CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
00552 #endif
00553
00554 T4 temp;
00555 T4 alpha_(alpha);
00556 T4 beta_(beta);
00557
00558 if (beta_ != T4(0))
00559 for (int i = 0; i < Storage4::GetFirst(mc, nc); i++)
00560 for (int j = 0; j < Storage4::GetSecond(mc, nc); j++)
00561 C(Storage4::GetFirst(i, j), Storage4::GetSecond(i, j))
00562 *= beta_;
00563 else
00564 for (int i = 0; i < Storage4::GetFirst(mc, nc); i++)
00565 for (int j = 0; j < Storage4::GetSecond(mc, nc); j++)
00566 C(Storage4::GetFirst(i, j), Storage4::GetSecond(i, j)) = T4(0);
00567
00568 for (int i = 0; i < Storage4::GetFirst(mc, nc); i++)
00569 for (int j = 0; j < Storage4::GetSecond(mc, nc); j++)
00570 {
00571 temp = T4(0);
00572 for (int k = 0; k < na; k++)
00573 temp += A(Storage4::GetFirst(i, j), k)
00574 * B(k, Storage4::GetSecond(i, j));
00575 C(Storage4::GetFirst(i, j), Storage4::GetSecond(i, j))
00576 += alpha_ * temp;
00577 }
00578 }
00579
00580
00582
00592 template <class T0,
00593 class T1, class Prop1, class Allocator1,
00594 class T2, class Prop2, class Allocator2,
00595 class T3,
00596 class T4, class Prop4, class Allocator4>
00597 void MltAdd(const T0 alpha,
00598 const Matrix<T1, Prop1, RowMajorCollection, Allocator1>& A,
00599 const Matrix<T2, Prop2, RowMajorCollection, Allocator2>& B,
00600 const T3 beta,
00601 Matrix<T4, Prop4, RowMajorCollection, Allocator4>& C)
00602 {
00603 int na = A.GetNmatrix();
00604 int mc = C.GetMmatrix();
00605 int nc = C.GetNmatrix();
00606
00607 #ifdef SELDON_CHECK_DIMENSIONS
00608 CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
00609 #endif
00610
00611 typedef typename T4::value_type value_type;
00612
00613 Mlt(value_type(beta), C);
00614
00615 for (int i = 0; i < mc; i++ )
00616 for (int j = 0; j < nc; j++)
00617 for (int k = 0; k < na; k++)
00618 MltAdd(value_type(alpha), A.GetMatrix(i, k), B.GetMatrix(k, j),
00619 value_type(1), C.GetMatrix(i, j));
00620 }
00621
00622
00624
00634 template <class T0,
00635 class T1, class Prop1, class Allocator1,
00636 class T2, class Prop2, class Allocator2,
00637 class T3,
00638 class T4, class Prop4, class Allocator4>
00639 void MltAdd(const T0 alpha,
00640 const Matrix<T1, Prop1, ColMajorCollection, Allocator1>& A,
00641 const Matrix<T2, Prop2, ColMajorCollection, Allocator2>& B,
00642 const T3 beta,
00643 Matrix<T4, Prop4, ColMajorCollection, Allocator4>& C)
00644 {
00645 int na = A.GetNmatrix();
00646 int mc = C.GetMmatrix();
00647 int nc = C.GetNmatrix();
00648
00649 #ifdef SELDON_CHECK_DIMENSIONS
00650 CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
00651 #endif
00652
00653 typedef typename T4::value_type value_type;
00654
00655 Mlt(value_type(beta), C);
00656
00657 for (int i = 0; i < mc; i++ )
00658 for (int j = 0; j < nc; j++)
00659 for (int k = 0; k < na; k++)
00660 MltAdd(value_type(alpha), A.GetMatrix(i, k), B.GetMatrix(k, j),
00661 value_type(1), C.GetMatrix(i, j));
00662 }
00663
00664
00665 template <class T0,
00666 class T1, class Allocator1,
00667 class T2, class Allocator2,
00668 class T3,
00669 class T4, class Allocator4>
00670 void MltAdd(const T0 alpha,
00671 const Matrix<T1, General, RowMajor, Allocator1>& A,
00672 const Matrix<T2, General, RowMajor, Allocator2>& B,
00673 const T3 beta,
00674 Matrix<T4, General, RowSparse, Allocator4>& C)
00675 {
00676 throw Undefined("void MltAdd(const T0 alpha,"
00677 "const Matrix<T1, General, RowMajor, Allocator1>& A,"
00678 "const Matrix<T2, General, RowMajor, Allocator2>& B,"
00679 "const T3 beta,"
00680 "Matrix<T4, General, RowSparse, Allocator4>& C)");
00681 }
00682
00683
00684 template <class T0,
00685 class T1, class Allocator1,
00686 class T2, class Allocator2,
00687 class T3,
00688 class T4, class Allocator4>
00689 void MltAdd(const T0 alpha,
00690 const Matrix<T1, General, RowMajor, Allocator1>& A,
00691 const Matrix<T2, General, RowSparse, Allocator2>& B,
00692 const T3 beta,
00693 Matrix<T4, General, RowSparse, Allocator4>& C)
00694 {
00695 throw Undefined("void MltAdd(const T0 alpha,"
00696 "const Matrix<T1, General, RowMajor, Allocator1>& A,"
00697 "const Matrix<T2, General, RowSparse, Allocator2>& B,"
00698 "const T3 beta,"
00699 "Matrix<T4, General, RowSparse, Allocator4>& C)");
00700 }
00701
00702
00703 template <class T0,
00704 class T1, class Allocator1,
00705 class T2, class Allocator2,
00706 class T3,
00707 class T4, class Allocator4>
00708 void MltAdd(const T0 alpha,
00709 const Matrix<T1, General, RowSparse, Allocator1>& A,
00710 const Matrix<T2, General, RowMajor, Allocator2>& B,
00711 const T3 beta,
00712 Matrix<T4, General, RowSparse, Allocator4>& C)
00713 {
00714 throw Undefined("void MltAdd(const T0 alpha,"
00715 "const Matrix<T1, General, RowSparse, Allocator1>& A,"
00716 "const Matrix<T2, General, RowMajor, Allocator2>& B,"
00717 "const T3 beta,"
00718 "Matrix<T4, General, RowSparse, Allocator4>& C)");
00719 }
00720
00721
00722 template <class T0,
00723 class Allocator1,
00724 class Allocator2,
00725 class Allocator3,
00726 class T4, class Prop4, class Storage4, class Allocator4>
00727 void MltAdd_heterogeneous(const T0 alpha,
00728 const Matrix<FloatDouble, General,
00729 DenseSparseCollection, Allocator1>& A,
00730 const Matrix<FloatDouble, General,
00731 DenseSparseCollection, Allocator2>& B,
00732 Matrix<FloatDouble, General,
00733 DenseSparseCollection, Allocator3>& C,
00734 Matrix<T4, Prop4, Storage4, Allocator4>& mc,
00735 int i, int j)
00736 {
00737 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator1>
00738 ::float_dense_m m0a;
00739 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator1>
00740 ::float_sparse_m m1a;
00741 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator1>
00742 ::double_dense_m m2a;
00743 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator1>
00744 ::double_sparse_m m3a;
00745
00746 int na = A.GetNmatrix();
00747 for (int k = 0; k < na; k++)
00748 {
00749 switch (A.GetType(i, k))
00750 {
00751 case 0:
00752 A.GetMatrix(i, k, m0a);
00753 MltAdd_heterogeneous2(alpha, m0a, B, C, mc, j, k);
00754 m0a.Nullify();
00755 break;
00756 case 1:
00757 A.GetMatrix(i, k, m1a);
00758 MltAdd_heterogeneous2(alpha, m1a, B, C, mc, j, k);
00759 m1a.Nullify();
00760 break;
00761 case 2:
00762 A.GetMatrix(i, k, m2a);
00763 MltAdd_heterogeneous2(alpha, m2a, B, C, mc, j, k);
00764 m2a.Nullify();
00765 break;
00766 case 3:
00767 A.GetMatrix(i, k, m3a);
00768 MltAdd_heterogeneous2(alpha, m3a, B, C, mc, j, k);
00769 m3a.Nullify();
00770 break;
00771 default:
00772 throw WrongArgument("Matrix<FloatDouble, DenseSparseCollection>::"
00773 "MltAdd_heterogeneous(alpha, A, B, beta, C) ",
00774 "Underlying matrix A (" + to_str(i) + " ,"
00775 + to_str(k) + " ) not defined.");
00776 }
00777 }
00778 }
00779
00780
00781 template<class T0,
00782 class T1, class Prop1, class Storage1, class Allocator1,
00783 class Allocator2,
00784 class Allocator3,
00785 class T4, class Prop4, class Storage4, class Allocator4>
00786 void MltAdd_heterogeneous2(const T0 alpha,
00787 const Matrix<T1, Prop1,
00788 Storage1, Allocator1>& ma,
00789 const Matrix<FloatDouble, General,
00790 DenseSparseCollection, Allocator2>& B,
00791 Matrix<FloatDouble, General,
00792 DenseSparseCollection, Allocator3>& C,
00793 Matrix<T4, Prop4, Storage4, Allocator4>& mc,
00794 int j, int k)
00795 {
00796 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
00797 ::float_dense_m m0b;
00798 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
00799 ::float_sparse_m m1b;
00800 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
00801 ::double_dense_m m2b;
00802 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
00803 ::double_sparse_m m3b;
00804
00805 switch (B.GetType(k, j))
00806 {
00807 case 0:
00808 B.GetMatrix(k, j, m0b);
00809 MltAdd(alpha, ma, m0b, 1., mc);
00810 m0b.Nullify();
00811 break;
00812 case 1:
00813 B.GetMatrix(k, j, m1b);
00814 MltAdd(alpha, ma, m1b, 1., mc);
00815 m1b.Nullify();
00816 break;
00817 case 2:
00818 B.GetMatrix(k, j, m2b);
00819 MltAdd(alpha, ma, m2b, 1., mc);
00820 m2b.Nullify();
00821 break;
00822 case 3:
00823 B.GetMatrix(k, j, m3b);
00824 MltAdd(alpha, ma, m3b, 1., mc);
00825 m3b.Nullify();
00826 break;
00827 default:
00828 throw WrongArgument("Matrix<FloatDouble, DenseSparseCollection>"
00829 "::MltAdd_heterogeneous2(alpha, A, B, beta, C)",
00830 "Underlying matrix B (" + to_str(k) + " ,"
00831 + to_str(j) + " ) not defined.");
00832 }
00833 }
00834
00835
00836
00838
00842 template <class T0, class Allocator1, class Allocator2, class T3,
00843 class Allocator4>
00844 void MltAdd(const T0 alpha,
00845 const Matrix<FloatDouble, General, DenseSparseCollection,
00846 Allocator1>& A,
00847 const Matrix<FloatDouble, General, DenseSparseCollection,
00848 Allocator2>& B,
00849 const T3 beta,
00850 Matrix<FloatDouble, General, DenseSparseCollection,
00851 Allocator4>& C)
00852 {
00853 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator4>
00854 ::float_dense_m m0c;
00855 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator4>
00856 ::float_sparse_m m1c;
00857 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator4>
00858 ::double_dense_m m2c;
00859 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator4>
00860 ::double_sparse_m m3c;
00861
00862 Mlt(beta, C);
00863
00864 int mc = C.GetMmatrix();
00865 int nc = C.GetNmatrix();
00866 for (int i = 0; i < mc; i++ )
00867 for (int j = 0; j < nc; j++)
00868 {
00869 switch (C.GetType(i, j))
00870 {
00871 case 0:
00872 C.GetMatrix(i, j, m0c);
00873 MltAdd_heterogeneous(float(alpha), A, B, C, m0c, i, j);
00874 C.SetMatrix(i, j, m0c);
00875 m0c.Nullify();
00876 break;
00877 case 1:
00878 C.GetMatrix(i, j, m1c);
00879 MltAdd_heterogeneous(float(alpha), A, B, C, m1c, i, j);
00880 C.SetMatrix(i, j, m1c);
00881 m1c.Nullify();
00882 break;
00883 case 2:
00884 C.GetMatrix(i, j, m2c);
00885 MltAdd_heterogeneous(double(alpha), A, B, C, m2c, i, j);
00886 C.SetMatrix(i, j, m2c);
00887 m2c.Nullify();
00888 break;
00889 case 3:
00890 C.GetMatrix(i, j, m3c);
00891 MltAdd_heterogeneous(double(alpha), A, B, C, m3c, i, j);
00892 C.SetMatrix(i, j, m3c);
00893 m3c.Nullify();
00894 break;
00895 default:
00896 throw WrongArgument("Matrix<FloatDouble, DenseSparseCollection>"
00897 "::MltAdd(alpha, A, B, beta, C) ",
00898 "Underlying matrix C (" + to_str(i) + " ,"
00899 + to_str(j) + " ) not defined.");
00900 }
00901 }
00902 }
00903
00904
00906
00916 template <class T0,
00917 class T1, class Prop1, class Allocator1,
00918 class T2, class Prop2, class Allocator2,
00919 class T3,
00920 class T4, class Prop4, class Allocator4>
00921 void MltAdd(const T0 alpha,
00922 const Matrix<T1, Prop1, RowSparse, Allocator1>& A,
00923 const Matrix<T2, Prop2, RowSparse, Allocator2>& B,
00924 const T3 beta,
00925 Matrix<T4, Prop4, RowSparse, Allocator4>& C)
00926 {
00927 if (beta == T3(0))
00928 {
00929 if (alpha == T0(0))
00930 Mlt(alpha, C);
00931 else
00932 {
00933 Mlt(A, B, C);
00934 if (alpha != T0(1))
00935 Mlt(alpha, C);
00936 }
00937 }
00938 else
00939 {
00940 if (alpha == T0(0))
00941 Mlt(beta, C);
00942 else
00943 {
00944 Matrix<T4, Prop4, RowSparse, Allocator4> tmp;
00945 Mlt(A, B, tmp);
00946 if (beta != T0(1))
00947 Mlt(beta, C);
00948 Add(alpha, tmp, C);
00949 }
00950 }
00951 }
00952
00953
00955
00967 template <class T0,
00968 class T1, class Prop1, class Allocator1,
00969 class T2, class Prop2, class Allocator2,
00970 class T3,
00971 class T4, class Prop4, class Allocator4>
00972 void MltNoTransTransAdd(const T0 alpha,
00973 const Matrix<T1, Prop1, RowSparse, Allocator1>& A,
00974 const Matrix<T2, Prop2, RowSparse, Allocator2>& B,
00975 const T3 beta,
00976 Matrix<T4, Prop4, RowSparse, Allocator4>& C)
00977 {
00978 if (beta == T3(0))
00979 {
00980 if (alpha == T0(0))
00981 Mlt(alpha, C);
00982 else
00983 {
00984 MltNoTransTrans(A, B, C);
00985 if (alpha != T0(1))
00986 Mlt(alpha, C);
00987 }
00988 }
00989 else
00990 {
00991 if (alpha == T0(0))
00992 Mlt(beta, C);
00993 else
00994 {
00995 Matrix<T4, Prop4, RowSparse, Allocator4> tmp;
00996 MltNoTransTrans(A, B, tmp);
00997 if (beta != T0(1))
00998 Mlt(beta, C);
00999 Add(alpha, tmp, C);
01000 }
01001 }
01002 }
01003
01004
01006
01022 template <class T0,
01023 class T1, class Prop1, class Allocator1,
01024 class T2, class Prop2, class Allocator2,
01025 class T3,
01026 class T4, class Prop4, class Allocator4>
01027 void MltAdd(const T0 alpha,
01028 const SeldonTranspose& TransA,
01029 const Matrix<T1, Prop1, RowSparse, Allocator1>& A,
01030 const SeldonTranspose& TransB,
01031 const Matrix<T2, Prop2, RowSparse, Allocator2>& B,
01032 const T3 beta,
01033 Matrix<T4, Prop4, RowSparse, Allocator4>& C)
01034 {
01035 if (!TransA.NoTrans())
01036 throw WrongArgument("MltAdd(T0 alpha, SeldonTranspose TransA, "
01037 "const Matrix<RowSparse>& A, SeldonTranspose "
01038 "TransB, const Matrix<RowSparse>& B, T3 beta, "
01039 "Matrix<RowSparse>& C)",
01040 "'TransA' must be equal to 'SeldonNoTrans'.");
01041 if (!TransB.NoTrans() && !TransB.Trans())
01042 throw WrongArgument("MltAdd(T0 alpha, SeldonTranspose TransA, "
01043 "const Matrix<RowSparse>& A, SeldonTranspose "
01044 "TransB, const Matrix<RowSparse>& B, T3 beta, "
01045 "Matrix<RowSparse>& C)",
01046 "'TransB' must be equal to 'SeldonNoTrans' or "
01047 "'SeldonTrans'.");
01048
01049 if (TransB.Trans())
01050 MltNoTransTransAdd(alpha, A, B, beta, C);
01051 else
01052 MltAdd(alpha, A, B, beta, C);
01053 }
01054
01055
01056
01058
01059
01060
01062
01063
01064
01066
01073 template<class T0, class T1, class Prop1, class Storage1, class Allocator1,
01074 class T2, class Prop2, class Storage2, class Allocator2>
01075 void Add(const T0& alpha,
01076 const Matrix<T1, Prop1, Storage1, Allocator1>& A,
01077 Matrix<T2, Prop2, Storage2, Allocator2>& B)
01078 {
01079 int i, j;
01080 for (i = 0; i < A.GetM(); i++)
01081 for (j = 0; j < A.GetN(); j++)
01082 B(i, j) += alpha * A(i, j);
01083 }
01084
01085
01087
01094 template<class T0,
01095 class T1, class Prop1, class Allocator1,
01096 class T2, class Prop2, class Allocator2>
01097 void Add(const T0& alpha,
01098 const Matrix<T1, Prop1, RowMajorCollection, Allocator1>& A,
01099 Matrix<T2, Prop2, RowMajorCollection, Allocator2>& B)
01100 {
01101 int na = A.GetNmatrix();
01102 int ma = A.GetMmatrix();
01103
01104 typedef typename T2::value_type value_type;
01105
01106 for (int i = 0; i < ma; i++ )
01107 for (int j = 0; j < na; j++)
01108 Add(value_type(alpha), A.GetMatrix(i, j), B.GetMatrix(i, j));
01109 }
01110
01111
01113
01120 template<class T0,
01121 class T1, class Prop1, class Allocator1,
01122 class T2, class Prop2, class Allocator2>
01123 void Add(const T0& alpha,
01124 const Matrix<T1, Prop1, ColMajorCollection, Allocator1>& A,
01125 Matrix<T2, Prop2, ColMajorCollection, Allocator2>& B)
01126 {
01127 int na = A.GetNmatrix();
01128 int ma = A.GetMmatrix();
01129
01130 typedef typename T2::value_type value_type;
01131
01132 for (int i = 0; i < ma; i++ )
01133 for (int j = 0; j < na; j++)
01134 Add(value_type(alpha), A.GetMatrix(i, j), B.GetMatrix(i, j));
01135 }
01136
01137
01138 template <class T0,
01139 class T1, class Prop1, class Storage1, class Allocator1,
01140 class Allocator2>
01141 void Add_heterogeneous(const T0 alpha,
01142 const Matrix<T1, Prop1, Storage1, Allocator1 >& ma,
01143 Matrix<FloatDouble, General,
01144 DenseSparseCollection, Allocator2>& B,
01145 int i, int j)
01146 {
01147 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01148 ::float_dense_m m0b;
01149 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01150 ::float_sparse_m m1b;
01151 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01152 ::double_dense_m m2b;
01153 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01154 ::double_sparse_m m3b;
01155
01156 T0 alpha_ = alpha;
01157
01158 switch (B.GetType(i, j))
01159 {
01160 case 0:
01161 B.GetMatrix(i, j, m0b);
01162 Add(float(alpha_), ma, m0b);
01163 B.SetMatrix(i, j, m0b);
01164 m0b.Nullify();
01165 break;
01166 case 1:
01167 B.GetMatrix(i, j, m1b);
01168 Add(float(alpha_), ma, m1b);
01169 B.SetMatrix(i, j, m1b);
01170 m1b.Nullify();
01171 break;
01172 case 2:
01173 B.GetMatrix(i, j, m2b);
01174 Add(double(alpha_), ma, m2b);
01175 B.SetMatrix(i, j, m2b);
01176 m2b.Nullify();
01177 break;
01178 case 3:
01179 B.GetMatrix(i, j, m3b);
01180 Add(double(alpha_), ma, m3b);
01181 B.SetMatrix(i, j, m3b);
01182 m3b.Nullify();
01183 break;
01184 default:
01185 throw WrongArgument("Add_heterogeneous(alpha, Matrix<FloatDouble, "
01186 "DenseSparseCollection>, Matrix<FloatDouble,"
01187 "DenseSparseCollection> )",
01188 "Underlying matrix (" + to_str(i) + " ,"
01189 + to_str(j) + " ) not defined.");
01190 }
01191 }
01192
01193
01195
01199 template <class T0, class Allocator1, class Allocator2>
01200 void Add(const T0 alpha,
01201 const Matrix<FloatDouble, General,
01202 DenseSparseCollection, Allocator1>& A,
01203 Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>& B)
01204 {
01205 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01206 ::float_dense_m m0a;
01207 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01208 ::float_sparse_m m1a;
01209 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01210 ::double_dense_m m2a;
01211 typename Matrix<FloatDouble, General, DenseSparseCollection, Allocator2>
01212 ::double_sparse_m m3a;
01213
01214 T0 alpha_ = alpha;
01215
01216 for (int i = 0; i < B.GetMmatrix(); i++)
01217 for (int j = 0; j < B.GetNmatrix(); j++)
01218 {
01219 switch (B.GetType(i, j))
01220 {
01221 case 0:
01222 A.GetMatrix(i, j, m0a);
01223 Add_heterogeneous(float(alpha_), m0a, B, i, j);
01224 m0a.Nullify();
01225 break;
01226 case 1:
01227 A.GetMatrix(i, j, m1a);
01228 Add_heterogeneous(float(alpha_), m1a, B, i, j);
01229 m1a.Nullify();
01230 break;
01231 case 2:
01232 A.GetMatrix(i, j, m2a);
01233 Add_heterogeneous(double(alpha_), m2a, B, i, j);
01234 m2a.Nullify();
01235 break;
01236 case 3:
01237 A.GetMatrix(i, j, m3a);
01238 Add_heterogeneous(double(alpha_), m3a, B, i, j);
01239 m3a.Nullify();
01240 break;
01241 default:
01242 throw
01243 WrongArgument("Add(alpha, Matrix<FloatDouble, "
01244 "DenseSparseCollection>, Matrix<FloatDouble,"
01245 "DenseSparseCollection> )",
01246 "Underlying matrix (" + to_str(i) + " ,"
01247 + to_str(j) + " ) not defined.");
01248 }
01249 }
01250 }
01251
01252
01253 template<class T0, class T1, class Prop1, class Allocator1,
01254 class T2, class Prop2, class Allocator2>
01255 void Add(const T0& alpha,
01256 const Matrix<T1, Prop1, RowMajor, Allocator1>& A,
01257 Matrix<T2, Prop2, RowSparse, Allocator2>& B) throw()
01258 {
01259 throw Undefined("void Add(const T0& alpha,"
01260 "const Matrix<T1, Prop1, RowMajor, Allocator1>& A,"
01261 "Matrix<T2, Prop2, RowSparse, Allocator2>& B)");
01262 }
01263
01264
01265 template<class T0, class T1, class Prop1, class Allocator1,
01266 class T2, class Prop2, class Allocator2>
01267 void Add(const T0& alpha,
01268 const Matrix<T1, Prop1, ColMajor, Allocator1>& A,
01269 Matrix<T2, Prop2, RowSparse, Allocator2>& B) throw()
01270 {
01271 throw Undefined("void Add(const T0& alpha,"
01272 "const Matrix<T1, Prop1, RowMajor, Allocator1>& A,"
01273 "Matrix<T2, Prop2, RowSparse, Allocator2>& B)");
01274 }
01275
01276
01277 template<class T0, class T1, class Storage1, class Allocator1,
01278 class T2, class Storage2, class Allocator2>
01279 void Add(const T0& alpha,
01280 const Matrix<T1, Symmetric, Storage1, Allocator1>& A,
01281 Matrix<T2, Symmetric, Storage2, Allocator2>& B)
01282 {
01283 int i, j;
01284 for (i = 0; i < A.GetM(); i++)
01285 for (j = i; j < A.GetN(); j++)
01286 B(i, j) += alpha * A(i, j);
01287 }
01288
01289
01291
01298 template<class T0, class T1, class Prop1, class Allocator1,
01299 class T2, class Prop2, class Allocator2>
01300 void Add(const T0& alpha,
01301 const Matrix<T1, Prop1, RowSparse, Allocator1>& A,
01302 Matrix<T2, Prop2, RowSparse, Allocator2>& B)
01303 {
01304 #ifdef SELDON_CHECK_BOUNDS
01305 if (A.GetM() != B.GetM() || A.GetN() != B.GetN())
01306 throw WrongDim("Add(alpha, const Matrix<RowSparse>& A, "
01307 "Matrix<RowSparse>& B)",
01308 "Unable to add a " + to_str(A.GetM()) + " x "
01309 + to_str(A.GetN()) + " matrix with a "
01310 + to_str(B.GetM()) + " x " + to_str(B.GetN())
01311 + " matrix.");
01312 #endif
01313
01314 int i = 0;
01315 int j = 0;
01316 int k;
01317
01318 if (A.GetNonZeros() == B.GetNonZeros())
01319
01320 {
01321
01322
01323 for (i = 0; i < A.GetM(); i++)
01324 if (A.GetPtr()[i + 1] == B.GetPtr()[i + 1])
01325 {
01326 for (j = A.GetPtr()[i]; j < A.GetPtr()[i + 1]; j++)
01327 if (A.GetInd()[j] == B.GetInd()[j])
01328 B.GetData()[j] += alpha * A.GetData()[j];
01329 else
01330 break;
01331 if (j != A.GetPtr()[i + 1])
01332 break;
01333 }
01334 else
01335 break;
01336
01337 if (i == A.GetM())
01338 return;
01339 }
01340
01341
01342
01343
01344 for (k = A.GetPtr()[i]; k < j; k++)
01345 if (A.GetInd()[k] == B.GetInd()[k])
01346 B.GetData()[k] -= alpha * A.GetData()[k];
01347
01348
01349 int Nnonzero = A.GetPtr()[i];
01350
01351
01352
01353
01354 int* c_ptr = NULL;
01355 int* c_ind = NULL;
01356 T2* c_data = NULL;
01357
01358 #ifdef SELDON_CHECK_MEMORY
01359 try
01360 {
01361 #endif
01362
01363 c_ptr = reinterpret_cast<int*>(calloc(A.GetM() + 1, sizeof(int)));
01364
01365 #ifdef SELDON_CHECK_MEMORY
01366 }
01367 catch (...)
01368 {
01369 c_ptr = NULL;
01370 }
01371
01372 if (c_ptr == NULL)
01373 throw NoMemory("Add(alpha, const Matrix<RowSparse>& A, "
01374 "Matrix<RowSparse>& B)",
01375 "Unable to allocate memory for an array of "
01376 + to_str(A.GetM() + 1) + " integers.");
01377 #endif
01378
01379 #ifdef SELDON_CHECK_MEMORY
01380 try
01381 {
01382 #endif
01383
01384
01385 c_ind = reinterpret_cast<int*>
01386 (realloc(reinterpret_cast<void*>(c_ind), Nnonzero * sizeof(int)));
01387 c_data = reinterpret_cast<T2*>
01388 (B.GetAllocator().reallocate(c_data, Nnonzero));
01389
01390 #ifdef SELDON_CHECK_MEMORY
01391 }
01392 catch (...)
01393 {
01394 c_ind = NULL;
01395 c_data = NULL;
01396 }
01397
01398 if ((c_ind == NULL || c_data == NULL)
01399 && Nnonzero != 0)
01400 throw NoMemory("Add(alpha, const Matrix<RowSparse>& A, "
01401 "Matrix<RowSparse>& B)",
01402 "Unable to allocate memory for an array of "
01403 + to_str(Nnonzero) + " integers and for an array of "
01404 + to_str(sizeof(T2) * Nnonzero) + " bytes.");
01405 #endif
01406
01407
01408 for (k = 0; k < i + 1; k++)
01409 c_ptr[k] = B.GetPtr()[k];
01410
01411
01412 for (k = 0; k < Nnonzero; k++)
01413 {
01414 c_ind[k] = B.GetInd()[k];
01415 c_data[k] = B.GetData()[k];
01416 }
01417
01418 int Nnonzero_row_max;
01419 int Nnonzero_max;
01420 int ja, jb(0), ka, kb;
01421
01422 for (; i < A.GetM(); i++)
01423 {
01424 Nnonzero_row_max = A.GetPtr()[i + 1] - A.GetPtr()[i]
01425 + B.GetPtr()[i + 1] - B.GetPtr()[i];
01426
01427 Nnonzero_max = Nnonzero + Nnonzero_row_max;
01428
01429 #ifdef SELDON_CHECK_MEMORY
01430 try
01431 {
01432 #endif
01433
01434 c_ind = reinterpret_cast<int*>
01435 (realloc(reinterpret_cast<void*>(c_ind),
01436 Nnonzero_max * sizeof(int)));
01437 c_data = reinterpret_cast<T2*>
01438 (B.GetAllocator().reallocate(c_data, Nnonzero_max));
01439
01440 #ifdef SELDON_CHECK_MEMORY
01441 }
01442 catch (...)
01443 {
01444 c_ind = NULL;
01445 c_data = NULL;
01446 }
01447
01448 if ((c_ind == NULL || c_data == NULL)
01449 && Nnonzero_max != 0)
01450 throw NoMemory("Add(alpha, const Matrix<RowSparse>& A, "
01451 "Matrix<RowSparse>& B)",
01452 "Unable to allocate memory for an array of "
01453 + to_str(Nnonzero_max) + " integers and for an "
01454 "array of "
01455 + to_str(sizeof(T2) * Nnonzero_max) + " bytes.");
01456 #endif
01457
01458 kb = B.GetPtr()[i];
01459 if (kb < B.GetPtr()[i + 1])
01460 jb = B.GetInd()[kb];
01461 for (ka = A.GetPtr()[i]; ka < A.GetPtr()[i + 1]; ka++)
01462 {
01463 ja = A.GetInd()[ka];
01464 while (kb < B.GetPtr()[i + 1] && jb < ja)
01465
01466 {
01467 c_ind[Nnonzero] = jb;
01468 c_data[Nnonzero] = B.GetData()[kb];
01469 kb++;
01470 if (kb < B.GetPtr()[i + 1])
01471 jb = B.GetInd()[kb];
01472 Nnonzero++;
01473 }
01474
01475 if (kb < B.GetPtr()[i + 1] && ja == jb)
01476
01477 {
01478 c_ind[Nnonzero] = jb;
01479 c_data[Nnonzero] = B.GetData()[kb] + alpha * A.GetData()[ka];
01480 kb++;
01481 if (kb < B.GetPtr()[i + 1])
01482 jb = B.GetInd()[kb];
01483 }
01484 else
01485 {
01486 c_ind[Nnonzero] = ja;
01487 c_data[Nnonzero] = alpha * A.GetData()[ka];
01488 }
01489 Nnonzero++;
01490 }
01491
01492
01493 while (kb < B.GetPtr()[i + 1])
01494 {
01495 c_ind[Nnonzero] = jb;
01496 c_data[Nnonzero] = B.GetData()[kb];
01497 kb++;
01498 if (kb < B.GetPtr()[i + 1])
01499 jb = B.GetInd()[kb];
01500 Nnonzero++;
01501 }
01502
01503 c_ptr[i + 1] = Nnonzero;
01504 }
01505
01506 B.SetData(B.GetM(), B.GetN(), Nnonzero, c_data, c_ptr, c_ind);
01507 }
01508
01509
01510
01512
01513
01514
01516
01517
01518
01520
01530 template <class T0, class Prop0, class Storage0, class Allocator0>
01531 void GetLU(Matrix<T0, Prop0, Storage0, Allocator0>& A)
01532 {
01533 int i, p, q, k;
01534 T0 temp;
01535
01536 int ma = A.GetM();
01537
01538 #ifdef SELDON_CHECK_BOUNDS
01539 int na = A.GetN();
01540 if (na != ma)
01541 throw WrongDim("GetLU(A)", "The matrix must be squared.");
01542 #endif
01543
01544 for (i = 0; i < ma; i++)
01545 {
01546 for (p = i; p < ma; p++)
01547 {
01548 temp = 0;
01549 for (k = 0; k < i; k++)
01550 temp += A(p, k) * A(k, i);
01551 A(p, i) -= temp;
01552 }
01553 for (q = i+1; q < ma; q++)
01554 {
01555 temp = 0;
01556 for (k = 0; k < i; k++)
01557 temp += A(i, k) * A(k, q);
01558 A(i, q) = (A(i,q ) - temp) / A(i, i);
01559 }
01560 }
01561 }
01562
01563
01564
01566
01567
01568
01570
01571
01572
01574
01583 template <class T0, class Prop0, class Storage0, class Allocator0,
01584 class T1, class Prop1, class Storage1, class Allocator1,
01585 class T2, class Prop2, class Storage2, class Allocator2>
01586 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01587 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
01588 const Matrix<T2, Prop2, Storage2, Allocator2>& C,
01589 string function = "")
01590 {
01591 if (B.GetM() != A.GetN() || C.GetM() != A.GetM() || B.GetN() != C.GetN())
01592 throw WrongDim(function, string("Operation A B + C -> C not permitted:")
01593 + string("\n A (") + to_str(&A) + string(") is a ")
01594 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01595 + string(" matrix;\n B (") + to_str(&B)
01596 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01597 + to_str(B.GetN()) + string(" matrix;\n C (")
01598 + to_str(&C) + string(") is a ") + to_str(C.GetM())
01599 + string(" x ") + to_str(C.GetN()) + string(" matrix."));
01600 }
01601
01602
01604
01614 template <class T0, class Prop0, class Storage0, class Allocator0,
01615 class T1, class Prop1, class Storage1, class Allocator1,
01616 class T2, class Prop2, class Storage2, class Allocator2>
01617 void CheckDim(const SeldonSide& side,
01618 const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01619 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
01620 const Matrix<T2, Prop2, Storage2, Allocator2>& C,
01621 string function = "")
01622 {
01623 if ( SeldonSide(side).Left() &&
01624 (B.GetM() != A.GetN() || C.GetM() != A.GetM()
01625 || B.GetN() != C.GetN()) )
01626 throw WrongDim(function, string("Operation A B + C -> C not permitted:")
01627 + string("\n A (") + to_str(&A) + string(") is a ")
01628 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01629 + string(" matrix;\n B (") + to_str(&B)
01630 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01631 + to_str(B.GetN()) + string(" matrix;\n C (")
01632 + to_str(&C) + string(") is a ") + to_str(C.GetM())
01633 + string(" x ") + to_str(C.GetN()) + string(" matrix."));
01634 else if ( SeldonSide(side).Right() &&
01635 (B.GetN() != A.GetM() || C.GetM() != B.GetM()
01636 || A.GetN() != C.GetN()) )
01637 throw WrongDim(function, string("Operation B A + C -> C not permitted:")
01638 + string("\n A (") + to_str(&A) + string(") is a ")
01639 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01640 + string(" matrix;\n B (") + to_str(&B)
01641 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01642 + to_str(B.GetN()) + string(" matrix;\n C (")
01643 + to_str(&C) + string(") is a ") + to_str(C.GetM())
01644 + string(" x ") + to_str(C.GetN()) + string(" matrix."));
01645 }
01646
01647
01649
01659 template <class T0, class Prop0, class Storage0, class Allocator0,
01660 class T1, class Prop1, class Storage1, class Allocator1>
01661 void CheckDim(const SeldonTranspose& TransA,
01662 const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01663 const SeldonTranspose& TransB,
01664 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
01665 string function = "")
01666 {
01667 SeldonTranspose status_A(TransA);
01668 SeldonTranspose status_B(TransB);
01669 string op;
01670 if (status_A.Trans())
01671 op = string("A'");
01672 else if (status_A.ConjTrans())
01673 op = string("A*");
01674 else
01675 op = string("A");
01676 if (status_B.Trans())
01677 op += string(" B'");
01678 else if (status_B.ConjTrans())
01679 op += string(" B*");
01680 else
01681 op += string(" B");
01682 op = string("Operation ") + op + string(" not permitted:");
01683 if (B.GetM(status_B) != A.GetN(status_A))
01684 throw WrongDim(function, op
01685 + string("\n A (") + to_str(&A) + string(") is a ")
01686 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01687 + string(" matrix;\n B (") + to_str(&B)
01688 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01689 + to_str(B.GetN()) + string(" matrix."));
01690 }
01691
01692
01694
01705 template <class T0, class Prop0, class Storage0, class Allocator0,
01706 class T1, class Prop1, class Storage1, class Allocator1,
01707 class T2, class Prop2, class Storage2, class Allocator2>
01708 void CheckDim(const SeldonTranspose& TransA,
01709 const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01710 const SeldonTranspose& TransB,
01711 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
01712 const Matrix<T2, Prop2, Storage2, Allocator2>& C,
01713 string function = "")
01714 {
01715 string op;
01716 if (TransA.Trans())
01717 op = string("A'");
01718 else if (TransA.ConjTrans())
01719 op = string("A*");
01720 else
01721 op = string("A");
01722 if (TransB.Trans())
01723 op += string(" B' + C");
01724 else if (TransB.ConjTrans())
01725 op += string(" B* + C");
01726 else
01727 op += string(" B + C");
01728 op = string("Operation ") + op + string(" not permitted:");
01729 if (B.GetM(TransB) != A.GetN(TransA) || C.GetM() != A.GetM(TransA)
01730 || B.GetN(TransB) != C.GetN())
01731 throw WrongDim(function, op
01732 + string("\n A (") + to_str(&A) + string(") is a ")
01733 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01734 + string(" matrix;\n B (") + to_str(&B)
01735 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01736 + to_str(B.GetN()) + string(" matrix;\n C (")
01737 + to_str(&C) + string(") is a ") + to_str(C.GetM())
01738 + string(" x ") + to_str(C.GetN()) + string(" matrix."));
01739 }
01740
01741
01743
01751 template <class T0, class Prop0, class Storage0, class Allocator0,
01752 class T1, class Prop1, class Storage1, class Allocator1>
01753 void CheckDim(const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01754 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
01755 string function = "")
01756 {
01757 CheckDim(SeldonLeft, A, B, function);
01758 }
01759
01760
01762
01771 template <class T0, class Prop0, class Storage0, class Allocator0,
01772 class T1, class Prop1, class Storage1, class Allocator1>
01773 void CheckDim(const SeldonSide& side,
01774 const Matrix<T0, Prop0, Storage0, Allocator0>& A,
01775 const Matrix<T1, Prop1, Storage1, Allocator1>& B,
01776 string function = "")
01777 {
01778 if (side.Left() && B.GetM() != A.GetN())
01779 throw WrongDim(function, string("Operation A B not permitted:")
01780 + string("\n A (") + to_str(&A) + string(") is a ")
01781 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01782 + string(" matrix;\n B (") + to_str(&B)
01783 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01784 + to_str(B.GetN()) + string(" matrix."));
01785 else if (side.Right() && B.GetN() != A.GetM())
01786 throw WrongDim(function, string("Operation B A not permitted:")
01787 + string("\n A (") + to_str(&A) + string(") is a ")
01788 + to_str(A.GetM()) + string(" x ") + to_str(A.GetN())
01789 + string(" matrix;\n B (") + to_str(&B)
01790 + string(") is a ") + to_str(B.GetM()) + string(" x ")
01791 + to_str(B.GetN()) + string(" matrix."));
01792 }
01793
01794
01795
01797
01798
01800
01801
01802
01804
01808 template <class T, class Prop, class Storage, class Allocator>
01809 T MaxAbs(const Matrix<T, Prop, Storage, Allocator>& A)
01810 {
01811 T res(0);
01812 for (int i = 0; i < A.GetM(); i++)
01813 for (int j = 0; j < A.GetN(); j++)
01814 res = max(res, abs(A(i, j)) );
01815
01816 return res;
01817 }
01818
01819
01821
01825 template <class T, class Prop, class Storage, class Allocator>
01826 T Norm1(const Matrix<T, Prop, Storage, Allocator>& A)
01827 {
01828 T res(0), sum;
01829 for (int j = 0; j < A.GetN(); j++)
01830 {
01831 sum = T(0);
01832 for (int i = 0; i < A.GetM(); i++)
01833 sum += abs( A(i, j) );
01834
01835 res = max(res, sum);
01836 }
01837
01838 return res;
01839 }
01840
01841
01843
01847 template <class T, class Prop, class Storage, class Allocator>
01848 T NormInf(const Matrix<T, Prop, Storage, Allocator>& A)
01849 {
01850 T res(0), sum;
01851 for (int i = 0; i < A.GetM(); i++)
01852 {
01853 sum = T(0);
01854 for (int j = 0; j < A.GetN(); j++)
01855 sum += abs( A(i, j) );
01856
01857 res = max(res, sum);
01858 }
01859
01860 return res;
01861 }
01862
01863
01865
01869 template <class T, class Prop, class Storage, class Allocator>
01870 T MaxAbs(const Matrix<complex<T>, Prop, Storage, Allocator>& A)
01871 {
01872 T res(0);
01873 for (int i = 0; i < A.GetM(); i++)
01874 for (int j = 0; j < A.GetN(); j++)
01875 {
01876 res = max(res, abs(A(i, j)) );
01877 }
01878
01879 return res;
01880 }
01881
01882
01884
01888 template <class T, class Prop, class Storage, class Allocator>
01889 T Norm1(const Matrix<complex<T>, Prop, Storage, Allocator>& A)
01890 {
01891 T res(0), sum;
01892 for (int j = 0; j < A.GetN(); j++)
01893 {
01894 sum = T(0);
01895 for (int i = 0; i < A.GetM(); i++)
01896 sum += abs( A(i, j) );
01897
01898 res = max(res, sum);
01899 }
01900
01901 return res;
01902 }
01903
01904
01906
01910 template <class T, class Prop, class Storage, class Allocator>
01911 T NormInf(const Matrix<complex<T>, Prop, Storage, Allocator>& A)
01912 {
01913 T res(0), sum;
01914 for (int i = 0; i < A.GetM(); i++)
01915 {
01916 sum = T(0);
01917 for (int j = 0; j < A.GetN(); j++)
01918 sum += abs( A(i, j) );
01919
01920 res = max(res, sum);
01921 }
01922
01923 return res;
01924 }
01925
01926
01927
01929
01930
01931
01933
01934
01935
01937 template<class T, class Prop, class Storage, class Allocator>
01938 void Transpose(Matrix<T, Prop, Storage, Allocator>& A)
01939 {
01940 int m = A.GetM();
01941 int n = A.GetN();
01942
01943 if (m == n)
01944 {
01945 T tmp;
01946 for (int i = 0; i < m; i++)
01947 for (int j = 0; j < i; j++)
01948 {
01949 tmp = A(i,j);
01950 A(i,j) = A(j,i);
01951 A(j,i) = tmp;
01952 }
01953 }
01954 else
01955 {
01956 Matrix<T, Prop, Storage, Allocator> B;
01957 B = A;
01958 A.Reallocate(n,m);
01959 for (int i = 0; i < m; i++)
01960 for (int j = 0; j < n; j++)
01961 A(j,i) = B(i,j);
01962 }
01963 }
01964
01965
01967 template<class T, class Allocator>
01968 void Transpose(Matrix<T, General, RowSparse, Allocator>& A)
01969 {
01970 int m = A.GetM();
01971 int n = A.GetN();
01972 int nnz = A.GetDataSize();
01973 Vector<int, VectFull, CallocAlloc<int> > ptr_T(n+1), ptr;
01974 Vector<int, VectFull, CallocAlloc<int> > ind_T(nnz), ind;
01975 Vector<T, VectFull, Allocator> data_T(nnz), data;
01976
01977 ptr.SetData(m+1, A.GetPtr());
01978 ind.SetData(nnz, A.GetInd());
01979 data.SetData(nnz, A.GetData());
01980
01981 ptr_T.Zero();
01982 ind_T.Zero();
01983 data_T.Zero();
01984
01985
01986
01987 for (int i = 0; i < nnz; i++)
01988 ptr_T(ind(i) + 1)++;
01989
01990
01991 for (int j = 1; j < n + 1; j++)
01992 ptr_T(j) += ptr_T(j - 1);
01993
01994 Vector<int, VectFull, CallocAlloc<int> > row_ind(n+1);
01995 row_ind.Fill(0);
01996 for (int i = 0; i < m; i++)
01997 for (int jp = ptr(i); jp < ptr(i+1); jp++)
01998 {
01999 int j = ind(jp);
02000 int k = ptr_T(j) + row_ind(j);
02001 ++row_ind(j);
02002 data_T(k) = data(jp);
02003 ind_T(k) = i;
02004 }
02005
02006 A.SetData(n, m, data_T, ptr_T, ind_T);
02007
02008 data.Nullify();
02009 ptr.Nullify();
02010 ind.Nullify();
02011 }
02012
02013
02015 template<class T, class Prop, class Storage, class Allocator>
02016 void TransposeConj(Matrix<T, Prop, Storage, Allocator>& A)
02017 {
02018 int i, j;
02019
02020 int m = A.GetM();
02021 int n = A.GetN();
02022
02023 if (m == n)
02024 {
02025 T tmp;
02026 for (i = 0; i < m; i++)
02027 {
02028
02029 for (j = 0; j < i; j++)
02030 {
02031 tmp = A(i, j);
02032 A(i, j) = conj(A(j, i));
02033 A(j, i) = conj(tmp);
02034 }
02035
02036
02037 A(i, i) = conj(A(i, i));
02038 }
02039 }
02040 else
02041 {
02042 Matrix<T, Prop, Storage, Allocator> B;
02043 B = A;
02044 A.Reallocate(n, m);
02045 for (i = 0; i < m; i++)
02046 for (j = 0; j < n; j++)
02047 A(j, i) = conj(B(i, j));
02048 }
02049 }
02050
02051
02052
02054
02055
02057
02058
02059
02061 template<class T, class Prop, class Storage, class Allocator>
02062 bool IsSymmetricMatrix(const Matrix<T, Prop, Storage, Allocator>& A)
02063 {
02064 return false;
02065 }
02066
02067
02069 template<class T, class Storage, class Allocator>
02070 bool IsSymmetricMatrix(const Matrix<T, Symmetric, Storage, Allocator>& A)
02071 {
02072 return true;
02073 }
02074
02075
02076
02078
02079 }
02080
02081 #define SELDON_FILE_FUNCTIONS_MATRIX_CXX
02082 #endif