Warning: this documentation for the development version is under construction.
00001 // Copyright (C) 2001-2010 INRIA, Vivien Mallet 00002 // Author(s): Marc Fragu, Vivien Mallet 00003 // 00004 // This file is part of the linear-algebra library Seldon, 00005 // http://seldon.sourceforge.net/. 00006 // 00007 // Seldon is free software; you can redistribute it and/or modify it under the 00008 // terms of the GNU Lesser General Public License as published by the Free 00009 // Software Foundation; either version 2.1 of the License, or (at your option) 00010 // any later version. 00011 // 00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY 00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 00015 // more details. 00016 // 00017 // You should have received a copy of the GNU Lesser General Public License 00018 // along with Seldon. If not, see http://www.gnu.org/licenses/. 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 // The column to be changed. 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 // Built a vector indexed with the rows of column_j and X. 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 // Built the new pointer vector. 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 // Built the new index and the new data vectors row by row. 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 // Collision. 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 // Suppression. 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 // Addition. 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 } // namespace Seldon. 00630 00631 #define SELDON_FILE_FUNCTIONS_CXX 00632 #endif