00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef SELDON_FILE_FUNCTIONS_CXX
00022
00023 #include "Functions.hxx"
00024
00025 #include "../computation/basic_functions/Functions_Vector.cxx"
00026
00027 namespace Seldon
00028 {
00029
00030
00032
00037 template <class T0, class Allocator0, class T1, class Allocator1>
00038 void GetRow(const Matrix<T0, General, RowSparse, Allocator0>& M,
00039 int i, Vector<T1, VectSparse, Allocator1>& X)
00040 {
00041 #ifdef SELDON_CHECK_BOUNDS
00042 int m = M.GetM();
00043 if (i < 0 || i >= m)
00044 throw WrongIndex("GetRow()",
00045 string("Index should be in [0, ") + to_str(m - 1)
00046 + "], but is equal to " + to_str(i) + ".");
00047 #endif
00048
00049 int* ptr = M.GetPtr();
00050 int* ind = M.GetInd();
00051 double* data = M.GetData();
00052 int size_row = ptr[i+1] - ptr[i];
00053
00054 X.Reallocate(size_row);
00055 int shift = ptr[i];
00056 for (int j = 0; j < size_row; j++)
00057 {
00058 X.Index(j) = ind[shift + j];
00059 X.Value(j) = data[shift + j];
00060 }
00061 }
00062
00063
00065
00070 template <class T0, class Prop0, class Storage0, class Allocator0,
00071 class T1, class Storage1, class Allocator1>
00072 void GetRow(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
00073 int i, Vector<T1, Storage1, Allocator1>& X)
00074 {
00075 X.Reallocate(M.GetN());
00076 for (int j = 0; j < M.GetN(); j++)
00077 X(j) = M(i, j);
00078 }
00079
00080
00082
00087 template <class T0, class Allocator0, class T1, class Allocator1>
00088 void GetCol(const Matrix<T0, General, RowSparse, Allocator0>& M,
00089 int j, Vector<T1, VectSparse, Allocator1>& X)
00090 {
00091 #ifdef SELDON_CHECK_BOUNDS
00092 int n = M.GetN();
00093 if (j < 0 || j >= n)
00094 throw WrongIndex("GetCol()",
00095 string("Index should be in [0, ") + to_str(n - 1)
00096 + "], but is equal to " + to_str(j) + ".");
00097 #endif
00098
00099 int* ptr = M.GetPtr();
00100 int* ind = M.GetInd();
00101 double* data = M.GetData();
00102 int m = M.GetM();
00103 Vector<int> index;
00104 Vector<double> value;
00105
00106 for (int i = 0; i < m; i++)
00107 for (int k = ptr[i]; k < ptr[i+1]; k++)
00108 if (ind[k] == j)
00109 {
00110 index.PushBack(i);
00111 value.PushBack(data[k]);
00112 }
00113
00114 X.SetData(value, index);
00115 }
00116
00117
00119
00124 template <class T0, class Prop0, class Allocator0,
00125 class T1, class Allocator1>
00126 void GetCol(const Matrix<T0, Prop0, PETScSeqDense, Allocator0>& M,
00127 int j, Vector<T1, PETScSeq, Allocator1>& X)
00128 {
00129 int a, b;
00130 M.GetProcessorRowRange(a, b);
00131 for (int i = a; i < b; i++)
00132 X.SetBuffer(i, M(i, j));
00133 X.Flush();
00134 }
00135
00136
00138
00143 template <class T0, class Prop0, class Allocator0,
00144 class T1, class Allocator1>
00145 void GetCol(const Matrix<T0, Prop0, PETScMPIDense, Allocator0>& M,
00146 int j, Vector<T1, PETScPar, Allocator1>& X)
00147 {
00148 int a, b;
00149 M.GetProcessorRowRange(a, b);
00150 for (int i = a; i < b; i++)
00151 X.SetBuffer(i, M(i, j));
00152 X.Flush();
00153 }
00154
00155
00157
00162 template <class T0, class Prop0, class Storage0, class Allocator0,
00163 class T1, class Storage1, class Allocator1>
00164 void GetCol(const Matrix<T0, Prop0, Storage0, Allocator0>& M,
00165 int j, Vector<T1, Storage1, Allocator1>& X)
00166 {
00167 X.Reallocate(M.GetM());
00168 for (int i = 0; i < M.GetM(); i++)
00169 X(i) = M(i, j);
00170 }
00171
00172
00174
00181 template <class T0, class Prop0, class Storage0, class Allocator0,
00182 class T1, class Prop1, class Storage1, class Allocator1>
00183 void GetCol(const Matrix<T0, Prop0, Storage0, Allocator0>& M_in,
00184 int begin, int end,
00185 Matrix<T1, Prop1, Storage1, Allocator1>& M_out)
00186 {
00187 M_out.Reallocate(M_in.GetM(), end - begin);
00188 for (int i = 0; i < M_in.GetM(); i++)
00189 for (int j = begin, k = 0; j < end; j++, k++)
00190 M_out(i, k) = M_in(i, j);
00191 }
00192
00193
00195
00200 template <class T0, class Prop0, class Storage0, class Allocator0,
00201 class T1, class Storage1, class Allocator1>
00202 void SetRow(const Vector<T1, Storage1, Allocator1>& X,
00203 int i, Matrix<T0, Prop0, Storage0, Allocator0>& M)
00204 {
00205 for (int j = 0; j < M.GetN(); j++)
00206 M.Set(i, j, X(j));
00207 }
00208
00209
00211
00216 template <class T0, class Prop0, class Allocator0,
00217 class T1, class Allocator1>
00218 void SetRow(const Vector<T1, PETScSeq, Allocator1>& X,
00219 int i, Matrix<T0, Prop0, PETScSeqDense, Allocator0>& M)
00220 {
00221 for (int j = 0; j < M.GetN(); j++)
00222 M.SetBuffer(i, j, X(j));
00223 M.Flush();
00224 }
00225
00226
00228
00233 template <class T0, class Prop0, class Allocator0,
00234 class T1, class Allocator1>
00235 void SetRow(const Vector<T1, PETScPar, Allocator1>& X,
00236 int i, Matrix<T0, Prop0, PETScMPIDense, Allocator0>& M)
00237 {
00238 for (int j = 0; j < M.GetN(); j++)
00239 M.SetBuffer(i, j, X(j));
00240 M.Flush();
00241 }
00242
00243
00245
00250 template <class T0, class Allocator0, class T1, class Allocator1>
00251 void SetRow(const Vector<T1, VectSparse, Allocator1>& X,
00252 int i, Matrix<T0, General, RowSparse, Allocator0>& M)
00253 {
00254 int m = M.GetM();
00255 int n = M.GetN();
00256 int nnz = M.GetDataSize();
00257 int Nx = X.GetSize();
00258
00259 #ifdef SELDON_CHECK_BOUNDS
00260 if (i < 0 || i >= m)
00261 throw WrongIndex("SetRow(Vector, int, Matrix<RowSparse>)",
00262 string("Index should be in [0, ") + to_str(m - 1)
00263 + "], but is equal to " + to_str(i) + ".");
00264 #endif
00265
00266 int *ptr_vector = M.GetPtr();
00267 int ptr_i0 = ptr_vector[i], ptr_i1 = ptr_vector[i + 1];
00268 int row_size_difference = Nx - ptr_i1 + ptr_i0;
00269
00270 if (row_size_difference == 0)
00271 {
00272 for (int k = 0; k < Nx; k++)
00273 M.GetInd()[k + ptr_i0] = X.Index(k);
00274 for (int k = 0; k < Nx; k++)
00275 M.GetData()[k + ptr_i0] = X.Value(k);
00276 return;
00277 }
00278
00279 Vector<int, VectFull, CallocAlloc<int> >
00280 new_ind_vector(nnz + row_size_difference);
00281 for (int k = 0; k < ptr_i0; k++)
00282 new_ind_vector(k) = M.GetInd()[k];
00283 for (int k = 0; k < Nx; k++)
00284 new_ind_vector(k + ptr_i0) = X.Index(k);
00285 for (int k = 0; k < nnz - ptr_i1; k++)
00286 new_ind_vector(k + ptr_i0 + Nx) = M.GetInd()[k + ptr_i1];
00287
00288 Vector<T1, VectFull, Allocator0 >
00289 new_data_vector(nnz + row_size_difference);
00290 for (int k = 0; k < ptr_i0; k++)
00291 new_data_vector(k) = M.GetData()[k];
00292 for (int k = 0; k < Nx; k++)
00293 new_data_vector(k + ptr_i0) = X.Value(k);
00294 for (int k = 0; k < nnz - ptr_i1; k++)
00295 new_data_vector(k + ptr_i0 + Nx) = M.GetData()[k + ptr_i1];
00296
00297 Vector<int, VectFull, CallocAlloc<int> > new_ptr_vector(m + 1);
00298 for (int j = 0; j < i + 1; j++)
00299 new_ptr_vector(j) = ptr_vector[j];
00300 for (int j = i + 1; j < m+1; j++)
00301 new_ptr_vector(j) = ptr_vector[j] + row_size_difference;
00302
00303 M.SetData(m, n, new_data_vector, new_ptr_vector, new_ind_vector);
00304 }
00305
00306
00308
00313 template <class T0, class Prop0, class Storage0, class Allocator0,
00314 class T1, class Storage1, class Allocator1>
00315 void SetCol(const Vector<T1, Storage1, Allocator1>& X,
00316 int j, Matrix<T0, Prop0, Storage0, Allocator0>& M)
00317 {
00318 for (int i = 0; i < M.GetM(); i++)
00319 M.Set(i, j, X(i));
00320 }
00321
00322
00324
00329 template <class T0, class Prop0, class Allocator0,
00330 class T1, class Allocator1>
00331 void SetCol(const Vector<T1, PETScSeq, Allocator1>& X,
00332 int j, Matrix<T0, Prop0, PETScSeqDense, Allocator0>& M)
00333 {
00334 int a, b;
00335 M.GetProcessorRowRange(a, b);
00336 for (int i = a; i < b; i++)
00337 M.SetBuffer(i, j, X(i));
00338 M.Flush();
00339 }
00340
00341
00343
00348 template <class T0, class Prop0, class Allocator0,
00349 class T1, class Allocator1>
00350 void SetCol(const Vector<T1, PETScPar, Allocator1>& X,
00351 int j, Matrix<T0, Prop0, PETScMPIDense, Allocator0>& M)
00352 {
00353 int a, b;
00354 M.GetProcessorRowRange(a, b);
00355 for (int i = a; i < b; i++)
00356 M.SetBuffer(i, j, X(i));
00357 M.Flush();
00358 }
00359
00360
00362
00367 template <class T0, class Allocator0,
00368 class T1, class Allocator1>
00369 void SetCol(const Vector<T1, VectFull, Allocator1>& X,
00370 int j, Matrix<T0, General, RowSparse, Allocator0>& M)
00371 {
00372 Vector<T1, VectSparse, Allocator1> X_sparse;
00373 for (int k = 0; k < X.GetLength(); k++)
00374 {
00375 T1 value = X(k);
00376 if (value != T1(0.))
00377 X_sparse.AddInteraction(k, value);
00378 }
00379
00380 SetCol(X_sparse, j, M);
00381 }
00382
00383
00385
00390 template <class T0, class Allocator0, class T1, class Allocator1>
00391 void SetCol(const Vector<T1, VectSparse, Allocator1>& X,
00392 int j, Matrix<T0, General, RowSparse, Allocator0>& M)
00393 {
00394 int m = M.GetM();
00395 int n = M.GetN();
00396 int nnz = M.GetDataSize();
00397 int Nx = X.GetSize();
00398
00399 #ifdef SELDON_CHECK_BOUNDS
00400 if (j < 0 || j >= n)
00401 throw WrongIndex("SetCol(Vector, int, Matrix<RowSparse>)",
00402 string("Index should be in [0, ") + to_str(n - 1)
00403 + "], but is equal to " + to_str(j) + ".");
00404 #endif
00405
00406
00407 Vector<T1, VectSparse, Allocator1> column_j;
00408 GetCol(M, j, column_j);
00409 int Ncolumn_j = column_j.GetSize();
00410 int column_size_difference = Nx - Ncolumn_j;
00411
00412
00413 Vector<int, VectSparse> column_j_mask;
00414 Vector<int> index_j(Ncolumn_j);
00415 Vector<int> value_j(Ncolumn_j);
00416 for (int p = 0; p < Ncolumn_j; p++)
00417 index_j(p) = column_j.Index(p);
00418 value_j.Fill(-1);
00419 column_j_mask.SetData(value_j, index_j);
00420 value_j.Nullify();
00421 index_j.Nullify();
00422 Vector<int, VectSparse> X_mask;
00423 Vector<int> index_x(Nx);
00424 Vector<int> value_x(Nx);
00425 for (int p = 0; p < Nx; p++)
00426 index_x(p) = X.Index(p);
00427 value_x.Fill(1);
00428 X_mask.SetData(value_x, index_x);
00429 value_x.Nullify();
00430 index_x.Nullify();
00431 X_mask.AddInteractionRow(column_j_mask.GetSize(),
00432 column_j_mask.GetIndex(),
00433 column_j_mask.GetData(), true);
00434
00435
00436 Vector<int, VectFull, CallocAlloc<int> > ptr_vector;
00437 ptr_vector.SetData(m + 1, M.GetPtr());
00438 Vector<int, VectFull, CallocAlloc<int> > new_ptr_vector(m + 1);
00439 new_ptr_vector.Zero();
00440 for (int p = 0; p < X_mask.GetSize(); p++)
00441 new_ptr_vector(X_mask.Index(p) + 1) = X_mask.Value(p);
00442 for (int p = 0; p < m; p++)
00443 new_ptr_vector(p + 1) += new_ptr_vector(p);
00444
00445 Add(1, ptr_vector, new_ptr_vector);
00446
00447
00448 Vector<int, VectFull, CallocAlloc<int> >
00449 new_ind_vector(nnz + column_size_difference);
00450 Vector<T0, VectFull, Allocator0>
00451 new_data_vector(nnz + column_size_difference);
00452
00453 Vector<T0, VectSparse, Allocator0> working_vector;
00454 int Nworking_vector;
00455
00456 int line = 0;
00457 for (int interaction = 0; interaction < X_mask.GetSize(); interaction++)
00458 {
00459 int ind_x = X_mask.Index(interaction);
00460 for (int k = 0; k < ptr_vector(ind_x) - ptr_vector(line); k++)
00461 new_ind_vector.GetData()[k + new_ptr_vector(line)] =
00462 M.GetInd()[k + ptr_vector(line)];
00463 for (int k = 0; k < ptr_vector(ind_x) - ptr_vector(line); k++)
00464 new_data_vector.GetData()[k + new_ptr_vector(line)] =
00465 M.GetData()[k + ptr_vector(line)];
00466
00467 int ind_j;
00468 Nworking_vector = ptr_vector(ind_x + 1) - ptr_vector(ind_x);
00469 working_vector.SetData(Nworking_vector,
00470 M.GetData() + ptr_vector(ind_x),
00471 M.GetInd() + ptr_vector(ind_x));
00472 switch(X_mask.Value(interaction))
00473 {
00474
00475 case 0:
00476 working_vector.Get(j) = X(ind_x);
00477 for (int k = 0; k < Nworking_vector; k++)
00478 new_ind_vector.GetData()[k + new_ptr_vector(ind_x)] =
00479 working_vector.GetIndex()[k];
00480 for (int k = 0; k < Nworking_vector; k++)
00481 new_data_vector.GetData()[k + new_ptr_vector(ind_x)] =
00482 working_vector.GetData()[k];
00483 break;
00484
00485
00486 case -1:
00487 ind_j = 0;
00488 while (ind_j < Nworking_vector &&
00489 working_vector.Index(ind_j) != j)
00490 ind_j++;
00491
00492 for (int k = 0; k < ind_j; k++)
00493 new_ind_vector.GetData()[k + new_ptr_vector(ind_x)] =
00494 working_vector.GetIndex()[k];
00495 for (int k = 0; k < Nworking_vector - ind_j - 1; k++)
00496 new_ind_vector.GetData()[k + new_ptr_vector(ind_x) + ind_j] =
00497 working_vector.GetIndex()[k + ind_j + 1];
00498
00499 for (int k = 0; k < ind_j; k++)
00500 new_data_vector.GetData()[k + new_ptr_vector(ind_x)] =
00501 working_vector.GetData()[k];
00502 for (int k = 0; k < Nworking_vector - ind_j - 1; k++)
00503 new_data_vector.GetData()[k + new_ptr_vector(ind_x) + ind_j] =
00504 working_vector.GetData()[k + ind_j + 1];
00505 break;
00506
00507
00508 case 1:
00509 ind_j = 0;
00510 while (ind_j < Nworking_vector &&
00511 working_vector.Index(ind_j) < j)
00512 ind_j++;
00513 for (int k = 0; k < ind_j; k++)
00514 new_ind_vector.GetData()[k + new_ptr_vector(ind_x)] =
00515 working_vector.GetIndex()[k];
00516 new_ind_vector.GetData()[new_ptr_vector(ind_x) + ind_j] = j;
00517 for (int k = 0; k < Nworking_vector - ind_j; k++)
00518 new_ind_vector.GetData()[k + new_ptr_vector(ind_x) + ind_j + 1]
00519 = working_vector.GetIndex()[k + ind_j];
00520
00521 for (int k = 0; k < ind_j; k++)
00522 new_data_vector.GetData()[k + new_ptr_vector(ind_x)] =
00523 working_vector.GetData()[k];
00524 new_data_vector.GetData()[new_ptr_vector(ind_x) + ind_j]
00525 = X(ind_x);
00526 for (int k = 0; k < Nworking_vector - ind_j; k++)
00527 new_data_vector.GetData()[k + new_ptr_vector(ind_x) + ind_j + 1]
00528 = working_vector.GetData()[k + ind_j];
00529 }
00530
00531 line = ind_x + 1;
00532 working_vector.Nullify();
00533 }
00534 for (int k = 0; k < ptr_vector(m) - ptr_vector(line); k++)
00535 new_ind_vector.GetData()[k + new_ptr_vector(line)] =
00536 M.GetInd()[k + ptr_vector(line)];
00537 for (int k = 0; k < ptr_vector(m) - ptr_vector(line); k++)
00538 new_data_vector.GetData()[k + new_ptr_vector(line)] =
00539 M.GetData()[k + ptr_vector(line)];
00540
00541 M.SetData(m, n, new_data_vector, new_ptr_vector, new_ind_vector);
00542 ptr_vector.Nullify();
00543 new_data_vector.Nullify();
00544 new_ind_vector.Nullify();
00545 new_ptr_vector.Nullify();
00546 }
00547
00548
00550
00553 template<class T, class Prop, class Allocator>
00554 void ApplyPermutation(Matrix<T, Prop, RowMajor, Allocator>& A,
00555 const Vector<int>& row_perm,
00556 const Vector<int>& col_perm,
00557 int starting_index)
00558 {
00559 Matrix<T, Prop, RowMajor, Allocator> A_copy = A;
00560
00561 for (int i = 0; i < A.GetM(); i++)
00562 for (int j = 0; j < A.GetN(); j++)
00563 A(i, j) = A_copy(row_perm(i) - starting_index,
00564 col_perm(j) - starting_index);
00565 }
00566
00567
00569
00572 template<class T, class Prop, class Allocator>
00573 void ApplyPermutation(Matrix<T, Prop, ColMajor, Allocator>& A,
00574 const Vector<int>& row_perm,
00575 const Vector<int>& col_perm,
00576 int starting_index)
00577 {
00578 Matrix<T, Prop, ColMajor, Allocator> A_copy = A;
00579
00580 for (int j = 0; j < A.GetN(); j++)
00581 for (int i = 0; i < A.GetM(); i++)
00582 A(i, j) = A_copy(row_perm(i) - starting_index,
00583 col_perm(j) - starting_index);
00584 }
00585
00586
00588
00593 template<class T, class Prop, class Allocator>
00594 void ApplyInversePermutation(Matrix<T, Prop, RowMajor, Allocator>& A,
00595 const Vector<int>& row_perm,
00596 const Vector<int>& col_perm,
00597 int starting_index)
00598 {
00599 Matrix<T, Prop, RowMajor, Allocator> A_copy = A;
00600
00601 for (int i = 0; i < A.GetM(); i++)
00602 for (int j = 0; j < A.GetN(); j++)
00603 A(row_perm(i) - starting_index, col_perm(j) - starting_index)
00604 = A_copy(i, j);
00605 }
00606
00607
00609
00614 template<class T, class Prop, class Allocator>
00615 void ApplyInversePermutation(Matrix<T, Prop, ColMajor, Allocator>& A,
00616 const Vector<int>& row_perm,
00617 const Vector<int>& col_perm,
00618 int starting_index)
00619 {
00620 Matrix<T, Prop, ColMajor, Allocator> A_copy = A;
00621
00622 for (int j = 0; j < A.GetN(); j++)
00623 for (int i = 0; i < A.GetM(); i++)
00624 A(row_perm(i) - starting_index, col_perm(j) - starting_index)
00625 = A_copy(i, j);
00626 }
00627
00628
00629 }
00630
00631 #define SELDON_FILE_FUNCTIONS_CXX
00632 #endif