Warning: this documentation for the development version is under construction.
00001 // Copyright (C) 2003-2011 Marc Duruflé 00002 // 00003 // This file is part of the linear-algebra library Seldon, 00004 // http://seldon.sourceforge.net/. 00005 // 00006 // Seldon is free software; you can redistribute it and/or modify it under the 00007 // terms of the GNU Lesser General Public License as published by the Free 00008 // Software Foundation; either version 2.1 of the License, or (at your option) 00009 // any later version. 00010 // 00011 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY 00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00013 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 00014 // more details. 00015 // 00016 // You should have received a copy of the GNU Lesser General Public License 00017 // along with Seldon. If not, see http://www.gnu.org/licenses/. 00018 00019 00020 #ifndef SELDON_FILE_MATRIX_ARRAY_SPARSE_CXX 00021 00022 #include "Matrix_ArraySparse.hxx" 00023 00024 namespace Seldon 00025 { 00026 00028 00031 template <class T, class Prop, class Storage, class Allocator> 00032 inline Matrix_ArraySparse<T, Prop, Storage, Allocator>::Matrix_ArraySparse() 00033 : val_() 00034 { 00035 this->m_ = 0; 00036 this->n_ = 0; 00037 } 00038 00039 00041 00046 template <class T, class Prop, class Storage, class Allocator> 00047 inline Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00048 Matrix_ArraySparse(int i, int j) : 00049 val_(Storage::GetFirst(i, j)) 00050 { 00051 this->m_ = i; 00052 this->n_ = j; 00053 } 00054 00055 00057 template <class T, class Prop, class Storage, class Allocat> 00058 inline Matrix_ArraySparse<T, Prop, Storage, Allocat>::~Matrix_ArraySparse() 00059 { 00060 this->m_ = 0; 00061 this->n_ = 0; 00062 } 00063 00064 00066 00069 template <class T, class Prop, class Storage, class Allocator> 00070 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Clear() 00071 { 00072 this->~Matrix_ArraySparse(); 00073 } 00074 00075 00076 /********************* 00077 * MEMORY MANAGEMENT * 00078 *********************/ 00079 00080 00082 00088 template <class T, class Prop, class Storage, class Allocator> 00089 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00090 Reallocate(int i, int j) 00091 { 00092 // Clears previous entries. 00093 Clear(); 00094 00095 this->m_ = i; 00096 this->n_ = j; 00097 00098 int n = Storage::GetFirst(i, j); 00099 val_.Reallocate(n); 00100 } 00101 00102 00104 00110 template <class T, class Prop, class Storage, class Allocator> 00111 void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Resize(int i, int j) 00112 { 00113 int n = Storage::GetFirst(this->m_, n_); 00114 int new_n = Storage::GetFirst(i, j); 00115 if (n != new_n) 00116 { 00117 Vector<Vector<T, VectSparse, Allocator>, VectFull, 00118 NewAlloc<Vector<T, VectSparse, Allocator> > > new_val; 00119 00120 new_val.Reallocate(new_n); 00121 00122 for (int k = 0 ; k < min(n, new_n) ; k++) 00123 Swap(new_val(k), this->val_(k)); 00124 00125 val_.SetData(new_n, new_val.GetData()); 00126 new_val.Nullify(); 00127 00128 } 00129 00130 this->m_ = i; 00131 this->n_ = j; 00132 } 00133 00134 00135 /******************* 00136 * BASIC FUNCTIONS * 00137 *******************/ 00138 00139 00141 00144 template <class T, class Prop, class Storage, class Allocator> 00145 inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetM() const 00146 { 00147 return m_; 00148 } 00149 00150 00152 00155 template <class T, class Prop, class Storage, class Allocator> 00156 inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetN() const 00157 { 00158 return n_; 00159 } 00160 00161 00163 00167 template <class T, class Prop, class Storage, class Allocator> 00168 inline int Matrix_ArraySparse<T, Prop, Storage, Allocator> 00169 ::GetM(const SeldonTranspose& status) const 00170 { 00171 if (status.NoTrans()) 00172 return m_; 00173 else 00174 return n_; 00175 } 00176 00177 00179 00183 template <class T, class Prop, class Storage, class Allocator> 00184 inline int Matrix_ArraySparse<T, Prop, Storage, Allocator> 00185 ::GetN(const SeldonTranspose& status) const 00186 { 00187 if (status.NoTrans()) 00188 return n_; 00189 else 00190 return m_; 00191 } 00192 00193 00195 00198 template <class T, class Prop, class Storage, class Allocator> 00199 inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetNonZeros() 00200 const 00201 { 00202 int nnz = 0; 00203 for (int i = 0; i < this->val_.GetM(); i++) 00204 nnz += this->val_(i).GetM(); 00205 00206 return nnz; 00207 } 00208 00209 00211 00216 template <class T, class Prop, class Storage, class Allocator> 00217 inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetDataSize() 00218 const 00219 { 00220 return GetNonZeros(); 00221 } 00222 00223 00225 00230 template <class T, class Prop, class Storage, class Allocator> 00231 inline int* Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetIndex(int i) 00232 const 00233 { 00234 return val_(i).GetIndex(); 00235 } 00236 00237 00239 00243 template <class T, class Prop, class Storage, class Allocator> 00244 inline T* 00245 Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetData(int i) const 00246 { 00247 return val_(i).GetData(); 00248 } 00249 00250 00252 00256 template <class T, class Prop, class Storage, class Allocat> 00257 inline Vector<T, VectSparse, Allocat>* 00258 Matrix_ArraySparse<T, Prop, Storage, Allocat>::GetData() const 00259 { 00260 return val_.GetData(); 00261 } 00262 00263 00264 /********************************** 00265 * ELEMENT ACCESS AND AFFECTATION * 00266 **********************************/ 00267 00268 00270 00276 template <class T, class Prop, class Storage, class Allocator> 00277 inline T 00278 Matrix_ArraySparse<T, Prop, Storage, Allocator>::operator() (int i, int j) 00279 const 00280 { 00281 00282 #ifdef SELDON_CHECK_BOUNDS 00283 if (i < 0 || i >= this->m_) 00284 throw WrongRow("Matrix_ArraySparse::operator()", 00285 "Index should be in [0, " + to_str(this->m_-1) + 00286 "],but is equal to " + to_str(i) + "."); 00287 00288 if (j < 0 || j >= this->n_) 00289 throw WrongCol("Matrix_ArraySparse::operator()", 00290 "Index should be in [0, " + to_str(this->n_-1) + 00291 "], but is equal to " + to_str(j) + "."); 00292 #endif 00293 00294 return this->val_(Storage::GetFirst(i, j))(Storage::GetSecond(i, j)); 00295 } 00296 00297 00299 00305 template <class T, class Prop, class Storage, class Allocator> 00306 inline T& 00307 Matrix_ArraySparse<T, Prop, Storage, Allocator>::Get(int i, int j) 00308 { 00309 00310 #ifdef SELDON_CHECK_BOUNDS 00311 if (i < 0 || i >= this->m_) 00312 throw WrongRow("Matrix_ArraySparse::operator()", 00313 "Index should be in [0, " + to_str(this->m_-1) + 00314 "],but is equal to " + to_str(i) + "."); 00315 00316 if (j < 0 || j >= this->n_) 00317 throw WrongCol("Matrix_ArraySparse::operator()", 00318 "Index should be in [0, " + to_str(this->n_-1) + 00319 "], but is equal to " + to_str(j) + "."); 00320 #endif 00321 00322 return this->val_(Storage::GetFirst(i, j)).Get(Storage::GetSecond(i, j)); 00323 } 00324 00325 00327 00333 template <class T, class Prop, class Storage, class Allocator> 00334 inline const T& 00335 Matrix_ArraySparse<T, Prop, Storage, Allocator>::Get(int i, int j) const 00336 { 00337 00338 #ifdef SELDON_CHECK_BOUNDS 00339 if (i < 0 || i >= this->m_) 00340 throw WrongRow("Matrix_ArraySparse::operator()", 00341 "Index should be in [0, " + to_str(this->m_-1) + 00342 "],but is equal to " + to_str(i) + "."); 00343 00344 if (j < 0 || j >= this->n_) 00345 throw WrongCol("Matrix_ArraySparse::operator()", 00346 "Index should be in [0, " + to_str(this->n_-1) + 00347 "], but is equal to " + to_str(j) + "."); 00348 #endif 00349 00350 return this->val_(Storage::GetFirst(i, j)).Get(Storage::GetSecond(i, j)); 00351 } 00352 00353 00355 00361 template <class T, class Prop, class Storage, class Allocator> 00362 inline T& 00363 Matrix_ArraySparse<T, Prop, Storage, Allocator>::Val(int i, int j) 00364 { 00365 00366 #ifdef SELDON_CHECK_BOUNDS 00367 if (i < 0 || i >= this->m_) 00368 throw WrongRow("Matrix_ArraySparse::operator()", 00369 "Index should be in [0, " + to_str(this->m_-1) + 00370 "], but is equal to " + to_str(i) + "."); 00371 00372 if (j < 0 || j >= this->n_) 00373 throw WrongCol("Matrix_ArraySparse::operator()", 00374 "Index should be in [0, " + to_str(this->n_-1) + 00375 "], but is equal to " + to_str(j) + "."); 00376 #endif 00377 00378 return 00379 this->val_(Storage::GetFirst(i, j)).Val(Storage::GetSecond(i, j)); 00380 } 00381 00382 00384 00390 template <class T, class Prop, class Storage, class Allocator> 00391 inline const T& 00392 Matrix_ArraySparse<T, Prop, Storage, Allocator>::Val(int i, int j) const 00393 { 00394 00395 #ifdef SELDON_CHECK_BOUNDS 00396 if (i < 0 || i >= this->m_) 00397 throw WrongRow("Matrix_ArraySparse::operator()", 00398 "Index should be in [0, " + to_str(this->m_-1) + 00399 "], but is equal to " + to_str(i) + "."); 00400 00401 if (j < 0 || j >= this->n_) 00402 throw WrongCol("Matrix_ArraySparse::operator()", 00403 "Index should be in [0, " + to_str(this->n_-1) + 00404 "], but is equal to " + to_str(j) + "."); 00405 #endif 00406 00407 return 00408 this->val_(Storage::GetFirst(i, j)).Val(Storage::GetSecond(i, j)); 00409 } 00410 00411 00413 00418 template <class T, class Prop, class Storage, class Allocator> 00419 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator> 00420 ::Set(int i, int j, const T& x) 00421 { 00422 this->Get(i, j) = x; 00423 } 00424 00425 00427 00432 template <class T, class Prop, class Storage, class Allocator> 00433 inline const T& Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00434 Value (int i, int j) const 00435 { 00436 00437 #ifdef SELDON_CHECK_BOUNDS 00438 if (i < 0 || i >= Storage::GetFirst(this->m_, this->n_)) 00439 throw WrongRow("Matrix_ArraySparse::value", "Index should be in [0, " 00440 + to_str(Storage::GetFirst(this->m_, this->n_)-1) 00441 + "], but is equal to " + to_str(i) + "."); 00442 00443 if ((j < 0)||(j >= this->val_(i).GetM())) 00444 throw WrongCol("Matrix_ArraySparse::value", "Index should be in [0, " + 00445 to_str(this->val_(i).GetM()-1) + "], but is equal to " 00446 + to_str(j) + "."); 00447 #endif 00448 00449 return val_(i).Value(j); 00450 } 00451 00452 00454 00459 template <class T, class Prop, class Storage, class Allocator> 00460 inline T& 00461 Matrix_ArraySparse<T, Prop, Storage, Allocator>::Value (int i, int j) 00462 { 00463 00464 #ifdef SELDON_CHECK_BOUNDS 00465 if (i < 0 || i >= Storage::GetFirst(this->m_, this->n_)) 00466 throw WrongRow("Matrix_ArraySparse::value", "Index should be in [0, " 00467 + to_str(Storage::GetFirst(this->m_, this->n_)-1) 00468 + "], but is equal to " + to_str(i) + "."); 00469 00470 if ((j < 0)||(j >= this->val_(i).GetM())) 00471 throw WrongCol("Matrix_ArraySparse::value", "Index should be in [0, " + 00472 to_str(this->val_(i).GetM()-1) + "], but is equal to " 00473 + to_str(j) + "."); 00474 #endif 00475 00476 return val_(i).Value(j); 00477 } 00478 00479 00481 00486 template <class T, class Prop, class Storage, class Allocator> inline 00487 int Matrix_ArraySparse<T, Prop, Storage, Allocator>::Index(int i, int j) 00488 const 00489 { 00490 00491 #ifdef SELDON_CHECK_BOUNDS 00492 if (i < 0 || i >= Storage::GetFirst(this->m_, this->n_)) 00493 throw WrongRow("Matrix_ArraySparse::index", "Index should be in [0, " 00494 + to_str(Storage::GetFirst(this->m_, this->n_)-1) 00495 + "], but is equal to " + to_str(i) + "."); 00496 00497 if ((j < 0)||(j >= this->val_(i).GetM())) 00498 throw WrongCol("Matrix_ArraySparse::index", "Index should be in [0, " + 00499 to_str(this->val_(i).GetM()-1) + "], but is equal to " 00500 + to_str(j) + "."); 00501 #endif 00502 00503 return val_(i).Index(j); 00504 } 00505 00506 00508 00513 template <class T, class Prop, class Storage, class Allocator> inline 00514 int& Matrix_ArraySparse<T, Prop, Storage, Allocator>::Index(int i, int j) 00515 { 00516 00517 #ifdef SELDON_CHECK_BOUNDS 00518 if (i < 0 || i >= Storage::GetFirst(this->m_, this->n_)) 00519 throw WrongRow("Matrix_ArraySparse::index", "Index should be in [0, " 00520 + to_str(Storage::GetFirst(this->m_, this->n_)-1) 00521 + "], but is equal to " + to_str(i) + "."); 00522 00523 if (j < 0 || j >= this->val_(i).GetM()) 00524 throw WrongCol("Matrix_ArraySparse::index", "Index should be in [0, " + 00525 to_str(this->val_(i).GetM()-1) + "], but is equal to " 00526 + to_str(j) + "."); 00527 #endif 00528 00529 return val_(i).Index(j); 00530 } 00531 00532 00534 00540 template <class T, class Prop, class Storage, class Allocator> 00541 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00542 SetData(int i, int n, T* val, int* ind) 00543 { 00544 val_(i).SetData(n, val, ind); 00545 } 00546 00547 00549 00553 template <class T, class Prop, class Storage, class Allocator> 00554 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Nullify(int i) 00555 { 00556 val_(i).Nullify(); 00557 } 00558 00559 00561 00566 template <class T, class Prop, class Storage, class Allocator> 00567 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00568 SetData(int m, int n, Vector<T, VectSparse, Allocator>* val) 00569 { 00570 m_ = m; 00571 n_ = n; 00572 val_.SetData(Storage::GetFirst(m, n), val); 00573 } 00574 00575 00577 00581 template <class T, class Prop, class Storage, class Allocator> 00582 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Nullify() 00583 { 00584 m_ = 0; 00585 n_ = 0; 00586 val_.Nullify(); 00587 } 00588 00589 00590 /************************ 00591 * CONVENIENT FUNCTIONS * 00592 ************************/ 00593 00594 00596 00601 template <class T, class Prop, class Storage, class Allocator> 00602 void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Print() const 00603 { 00604 if (Storage::GetFirst(1, 0) == 1) 00605 for (int i = 0; i < this->m_; i++) 00606 { 00607 for (int j = 0; j < this->val_(i).GetM(); j++) 00608 cout << (i+1) << " " << this->val_(i).Index(j)+1 00609 << " " << this->val_(i).Value(j) << endl; 00610 } 00611 else 00612 for (int i = 0; i < this->n_; i++) 00613 { 00614 for (int j = 0; j < this->val_(i).GetM(); j++) 00615 cout << this->val_(i).Index(j)+1 << " " << i+1 00616 << " " << this->val_(i).Value(j) << endl; 00617 } 00618 } 00619 00620 00622 00628 template <class T, class Prop, class Storage, class Allocator> 00629 void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Assemble() 00630 { 00631 for (int i = 0; i < val_.GetM(); i++) 00632 val_(i).Assemble(); 00633 } 00634 00635 00637 00640 template <class T, class Prop, class Storage, class Allocator> 00641 template<class T0> 00642 void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00643 RemoveSmallEntry(const T0& epsilon) 00644 { 00645 for (int i = 0; i < val_.GetM(); i++) 00646 val_(i).RemoveSmallEntry(epsilon); 00647 } 00648 00649 00651 template <class T, class Prop, class Storage, class Allocator> 00652 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::SetIdentity() 00653 { 00654 this->n_ = this->m_; 00655 for (int i = 0; i < this->m_; i++) 00656 { 00657 val_(i).Reallocate(1); 00658 val_(i).Index(0) = i; 00659 val_(i).Value(0) = T(1); 00660 } 00661 } 00662 00663 00665 template <class T, class Prop, class Storage, class Allocator> 00666 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Zero() 00667 { 00668 for (int i = 0; i < val_.GetM(); i++) 00669 val_(i).Zero(); 00670 } 00671 00672 00674 template <class T, class Prop, class Storage, class Allocator> 00675 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Fill() 00676 { 00677 int value = 0; 00678 for (int i = 0; i < val_.GetM(); i++) 00679 for (int j = 0; j < val_(i).GetM(); j++) 00680 val_(i).Value(j) = value++; 00681 } 00682 00683 00685 template <class T, class Prop, class Storage, class Allo> template<class T0> 00686 inline void Matrix_ArraySparse<T, Prop, Storage, Allo>::Fill(const T0& x) 00687 { 00688 for (int i = 0; i < val_.GetM(); i++) 00689 val_(i).Fill(x); 00690 } 00691 00692 00694 template <class T, class Prop, class Storage, class Allocator> 00695 template <class T0> 00696 inline Matrix_ArraySparse<T, Prop, Storage, Allocator>& 00697 Matrix_ArraySparse<T, Prop, Storage, Allocator>::operator= (const T0& x) 00698 { 00699 this->Fill(x); 00700 } 00701 00702 00704 template <class T, class Prop, class Storage, class Allocator> 00705 inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::FillRand() 00706 { 00707 for (int i = 0; i < val_.GetM(); i++) 00708 val_(i).FillRand(); 00709 } 00710 00711 00713 00720 template <class T, class Prop, class Storage, class Allocator> 00721 void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00722 Write(string FileName) const 00723 { 00724 ofstream FileStream; 00725 FileStream.open(FileName.c_str(), ofstream::binary); 00726 00727 #ifdef SELDON_CHECK_IO 00728 // Checks if the file was opened. 00729 if (!FileStream.is_open()) 00730 throw IOError("Matrix_ArraySparse::Write(string FileName)", 00731 string("Unable to open file \"") + FileName + "\"."); 00732 #endif 00733 00734 this->Write(FileStream); 00735 00736 FileStream.close(); 00737 } 00738 00739 00741 00748 template <class T, class Prop, class Storage, class Allocator> 00749 void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00750 Write(ostream& FileStream) const 00751 { 00752 00753 #ifdef SELDON_CHECK_IO 00754 // Checks if the stream is ready. 00755 if (!FileStream.good()) 00756 throw IOError("Matrix_ArraySparse::Write(ofstream& FileStream)", 00757 "Stream is not ready."); 00758 #endif 00759 00760 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)), 00761 sizeof(int)); 00762 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)), 00763 sizeof(int)); 00764 00765 for (int i = 0; i < val_.GetM(); i++) 00766 val_(i).Write(FileStream); 00767 } 00768 00769 00771 00775 template <class T, class Prop, class Storage, class Allocator> 00776 void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00777 WriteText(string FileName) const 00778 { 00779 ofstream FileStream; FileStream.precision(14); 00780 FileStream.open(FileName.c_str()); 00781 00782 #ifdef SELDON_CHECK_IO 00783 // Checks if the file was opened. 00784 if (!FileStream.is_open()) 00785 throw IOError("Matrix_ArraySparse::Write(string FileName)", 00786 string("Unable to open file \"") + FileName + "\"."); 00787 #endif 00788 00789 this->WriteText(FileStream); 00790 00791 FileStream.close(); 00792 } 00793 00794 00796 00800 template <class T, class Prop, class Storage, class Allocator> 00801 void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00802 WriteText(ostream& FileStream) const 00803 { 00804 00805 #ifdef SELDON_CHECK_IO 00806 // Checks if the stream is ready. 00807 if (!FileStream.good()) 00808 throw IOError("Matrix_ArraySparse::Write(ofstream& FileStream)", 00809 "Stream is not ready."); 00810 #endif 00811 00812 // conversion in coordinate format (1-index convention) 00813 IVect IndRow, IndCol; Vector<T> Value; 00814 const Matrix<T, Prop, Storage, Allocator>& leaf_class = 00815 static_cast<const Matrix<T, Prop, Storage, Allocator>& >(*this); 00816 00817 ConvertMatrix_to_Coordinates(leaf_class, IndRow, IndCol, 00818 Value, 1, true); 00819 00820 for (int i = 0; i < IndRow.GetM(); i++) 00821 FileStream << IndRow(i) << " " << IndCol(i) << " " << Value(i) << '\n'; 00822 00823 // If the last element a_{m,n} does not exist, we add a zero. 00824 int m = Storage::GetFirst(this->m_, this->n_); 00825 int n = Storage::GetSecond(this->m_, this->n_); 00826 if (m > 0 && n > 0) 00827 { 00828 bool presence_last_elt = false; 00829 if (this->val_(m-1).GetM() > 0) 00830 { 00831 int p = this->val_(m-1).GetM(); 00832 if (this->val_(m-1).Index(p-1) == n-1) 00833 presence_last_elt = true; 00834 } 00835 00836 if (!presence_last_elt) 00837 { 00838 T zero; 00839 SetComplexZero(zero); 00840 FileStream << this->m_ << " " << this->n_ << " " << zero << '\n'; 00841 } 00842 } 00843 } 00844 00845 00847 00854 template <class T, class Prop, class Storage, class Allocator> 00855 void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00856 Read(string FileName) 00857 { 00858 ifstream FileStream; 00859 FileStream.open(FileName.c_str(), ifstream::binary); 00860 00861 #ifdef SELDON_CHECK_IO 00862 // Checks if the file was opened. 00863 if (!FileStream.is_open()) 00864 throw IOError("Matrix_ArraySparse::Read(string FileName)", 00865 string("Unable to open file \"") + FileName + "\"."); 00866 #endif 00867 00868 this->Read(FileStream); 00869 00870 FileStream.close(); 00871 } 00872 00873 00875 00882 template <class T, class Prop, class Storage, class Allocator> 00883 void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00884 Read(istream& FileStream) 00885 { 00886 00887 #ifdef SELDON_CHECK_IO 00888 // Checks if the stream is ready. 00889 if (!FileStream.good()) 00890 throw IOError("Matrix_ArraySparse::Read(ofstream& FileStream)", 00891 "Stream is not ready."); 00892 #endif 00893 00894 FileStream.read(reinterpret_cast<char*>(const_cast<int*>(&this->m_)), 00895 sizeof(int)); 00896 FileStream.read(reinterpret_cast<char*>(const_cast<int*>(&this->n_)), 00897 sizeof(int)); 00898 00899 val_.Reallocate(Storage::GetFirst(this->m_, this->n_)); 00900 for (int i = 0; i < val_.GetM(); i++) 00901 val_(i).Read(FileStream); 00902 00903 #ifdef SELDON_CHECK_IO 00904 // Checks if data was read. 00905 if (!FileStream.good()) 00906 throw IOError("Matrix_ArraySparse::Read(istream& FileStream)", 00907 string("Input operation failed.") 00908 + string(" The input file may have been removed") 00909 + " or may not contain enough data."); 00910 #endif 00911 00912 } 00913 00914 00916 00920 template <class T, class Prop, class Storage, class Allocator> 00921 void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00922 ReadText(string FileName) 00923 { 00924 ifstream FileStream; 00925 FileStream.open(FileName.c_str()); 00926 00927 #ifdef SELDON_CHECK_IO 00928 // Checks if the file was opened. 00929 if (!FileStream.is_open()) 00930 throw IOError("Matrix_ArraySparse::ReadText(string FileName)", 00931 string("Unable to open file \"") + FileName + "\"."); 00932 #endif 00933 00934 this->ReadText(FileStream); 00935 00936 FileStream.close(); 00937 } 00938 00939 00941 00945 template <class T, class Prop, class Storage, class Allocator> 00946 void Matrix_ArraySparse<T, Prop, Storage, Allocator>:: 00947 ReadText(istream& FileStream) 00948 { 00949 Matrix<T, Prop, Storage, Allocator>& leaf_class = 00950 static_cast<Matrix<T, Prop, Storage, Allocator>& >(*this); 00951 00952 T zero; int index = 1; 00953 ReadCoordinateMatrix(leaf_class, FileStream, zero, index); 00954 } 00955 00956 00958 // MATRIX<ARRAY_COLSPARSE> // 00960 00961 00963 00966 template <class T, class Prop, class Allocator> 00967 inline Matrix<T, Prop, ArrayColSparse, Allocator>::Matrix(): 00968 Matrix_ArraySparse<T, Prop, ArrayColSparse, Allocator>() 00969 { 00970 } 00971 00972 00974 00979 template <class T, class Prop, class Allocator> 00980 inline Matrix<T, Prop, ArrayColSparse, Allocator>::Matrix(int i, int j): 00981 Matrix_ArraySparse<T, Prop, ArrayColSparse, Allocator>(i, j) 00982 { 00983 } 00984 00985 00987 template <class T, class Prop, class Allocator> 00988 inline void Matrix<T, Prop, ArrayColSparse, Allocator>::ClearColumn(int i) 00989 { 00990 this->val_(i).Clear(); 00991 } 00992 00993 00995 00999 template <class T, class Prop, class Alloc> inline 01000 void Matrix<T, Prop, ArrayColSparse, Alloc>::ReallocateColumn(int i,int j) 01001 { 01002 this->val_(i).Reallocate(j); 01003 } 01004 01005 01007 01011 template <class T, class Prop, class Allocator> inline 01012 void Matrix<T, Prop, ArrayColSparse, Allocator>::ResizeColumn(int i,int j) 01013 { 01014 this->val_(i).Resize(j); 01015 } 01016 01017 01019 01023 template <class T, class Prop, class Allocator> inline 01024 void Matrix<T, Prop, ArrayColSparse, Allocator>::SwapColumn(int i,int j) 01025 { 01026 Swap(this->val_(i), this->val_(j)); 01027 } 01028 01029 01031 01035 template <class T, class Prop, class Allocator> 01036 inline void Matrix<T, Prop, ArrayColSparse, Allocator>:: 01037 ReplaceIndexColumn(int i, IVect& new_index) 01038 { 01039 for (int j = 0; j < this->val_(i).GetM(); j++) 01040 this->val_(i).Index(j) = new_index(j); 01041 } 01042 01043 01045 01049 template <class T, class Prop, class Allocator> 01050 inline int Matrix<T, Prop, ArrayColSparse, Allocator>:: 01051 GetColumnSize(int i) const 01052 { 01053 return this->val_(i).GetSize(); 01054 } 01055 01056 01058 template <class T, class Prop, class Allocator> inline 01059 void Matrix<T, Prop, ArrayColSparse, Allocator>::PrintColumn(int i) const 01060 { 01061 this->val_(i).Print(); 01062 } 01063 01064 01066 01071 template <class T, class Prop, class Allocator> inline 01072 void Matrix<T, Prop, ArrayColSparse, Allocator>::AssembleColumn(int i) 01073 { 01074 this->val_(i).Assemble(); 01075 } 01076 01077 01079 01084 template <class T, class Prop, class Allocator> 01085 inline void Matrix<T, Prop, ArrayColSparse, Allocator>:: 01086 AddInteraction(int i, int j, const T& val) 01087 { 01088 this->val_(j).AddInteraction(i, val); 01089 } 01090 01091 01093 01099 template <class T, class Prop, class Allocator> 01100 inline void Matrix<T, Prop, ArrayColSparse, Allocator>:: 01101 AddInteractionRow(int i, int nb, int* col_, T* value_) 01102 { 01103 IVect col; 01104 col.SetData(nb, col_); 01105 Vector<T> val; 01106 val.SetData(nb, value_); 01107 AddInteractionRow(i, nb, col, val); 01108 col.Nullify(); 01109 val.Nullify(); 01110 } 01111 01112 01114 01120 template <class T, class Prop, class Allocator> 01121 inline void Matrix<T, Prop, ArrayColSparse, Allocator>:: 01122 AddInteractionColumn(int i, int nb, int* row_, T* value_) 01123 { 01124 IVect row; 01125 row.SetData(nb, row_); 01126 Vector<T> val; 01127 val.SetData(nb, value_); 01128 AddInteractionColumn(i, nb, row, val); 01129 row.Nullify(); 01130 val.Nullify(); 01131 } 01132 01133 01135 01141 template <class T, class Prop, class Allocator> template <class Alloc1> 01142 inline void Matrix<T, Prop, ArrayColSparse, Allocator>:: 01143 AddInteractionRow(int i, int nb, const IVect& col, 01144 const Vector<T, VectFull, Alloc1>& val) 01145 { 01146 for (int j = 0; j < nb; j++) 01147 this->val_(col(j)).AddInteraction(i, val(j)); 01148 } 01149 01150 01152 01158 template <class T, class Prop, class Allocator> template <class Alloc1> 01159 inline void Matrix<T, Prop, ArrayColSparse, Allocator>:: 01160 AddInteractionColumn(int i, int nb, const IVect& row, 01161 const Vector<T, VectFull, Alloc1>& val) 01162 { 01163 this->val_(i).AddInteractionRow(nb, row, val); 01164 } 01165 01166 01168 // MATRIX<ARRAY_ROWSPARSE> // 01170 01171 01173 01176 template <class T, class Prop, class Allocator> 01177 inline Matrix<T, Prop, ArrayRowSparse, Allocator>::Matrix(): 01178 Matrix_ArraySparse<T, Prop, ArrayRowSparse, Allocator>() 01179 { 01180 } 01181 01182 01184 01189 template <class T, class Prop, class Allocator> 01190 inline Matrix<T, Prop, ArrayRowSparse, Allocator>::Matrix(int i, int j): 01191 Matrix_ArraySparse<T, Prop, ArrayRowSparse, Allocator>(i, j) 01192 { 01193 } 01194 01195 01197 template <class T, class Prop, class Allocator> 01198 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::ClearRow(int i) 01199 { 01200 this->val_(i).Clear(); 01201 } 01202 01203 01205 01210 template <class T, class Prop, class Allocator> 01211 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>:: 01212 ReallocateRow(int i, int j) 01213 { 01214 this->val_(i).Reallocate(j); 01215 } 01216 01217 01219 01224 template <class T, class Prop, class Allocator> inline 01225 void Matrix<T, Prop, ArrayRowSparse, Allocator>::ResizeRow(int i, int j) 01226 { 01227 this->val_(i).Resize(j); 01228 } 01229 01230 01232 01236 template <class T, class Prop, class Allocator> 01237 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::SwapRow(int i,int j) 01238 { 01239 Swap(this->val_(i), this->val_(j)); 01240 } 01241 01242 01244 01248 template <class T, class Prop, class Allocator> 01249 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>:: 01250 ReplaceIndexRow(int i, IVect& new_index) 01251 { 01252 for (int j = 0; j < this->val_(i).GetM(); j++) 01253 this->val_(i).Index(j) = new_index(j); 01254 } 01255 01256 01258 01262 template <class T, class Prop, class Allocator> inline 01263 int Matrix<T, Prop, ArrayRowSparse, Allocator>::GetRowSize(int i) const 01264 { 01265 return this->val_(i).GetSize(); 01266 } 01267 01268 01270 template <class T, class Prop, class Allocator> inline 01271 void Matrix<T, Prop, ArrayRowSparse, Allocator>::PrintRow(int i) const 01272 { 01273 this->val_(i).Print(); 01274 } 01275 01276 01278 01283 template <class T, class Prop, class Allocator> 01284 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::AssembleRow(int i) 01285 { 01286 this->val_(i).Assemble(); 01287 } 01288 01290 01295 template <class T, class Prop, class Allocator> 01296 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>:: 01297 AddInteraction(int i, int j, const T& val) 01298 { 01299 this->val_(i).AddInteraction(j, val); 01300 } 01301 01302 01304 01310 template <class T, class Prop, class Allocator> 01311 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>:: 01312 AddInteractionRow(int i, int nb, int* col_, T* value_) 01313 { 01314 IVect col; 01315 col.SetData(nb, col_); 01316 Vector<T> val; 01317 val.SetData(nb, value_); 01318 AddInteractionRow(i, nb, col, val); 01319 col.Nullify(); 01320 val.Nullify(); 01321 } 01322 01323 01325 01331 template <class T, class Prop, class Allocator> 01332 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>:: 01333 AddInteractionColumn(int i, int nb, int* row_, T* value_) 01334 { 01335 IVect row; 01336 row.SetData(nb, row_); 01337 Vector<T> val; 01338 val.SetData(nb, value_); 01339 AddInteractionColumn(i, nb, row, val); 01340 row.Nullify(); 01341 val.Nullify(); 01342 } 01343 01344 01346 01352 template <class T, class Prop, class Allocator> template <class Alloc1> 01353 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>:: 01354 AddInteractionRow(int i, int nb, const IVect& col, 01355 const Vector<T, VectFull, Alloc1>& val) 01356 { 01357 this->val_(i).AddInteractionRow(nb, col, val); 01358 } 01359 01360 01362 01368 template <class T, class Prop, class Allocator> template <class Alloc1> 01369 inline void Matrix<T, Prop, ArrayRowSparse, Allocator>:: 01370 AddInteractionColumn(int i, int nb, const IVect& row, 01371 const Vector<T, VectFull, Alloc1>& val) 01372 { 01373 for (int j = 0; j < nb; j++) 01374 this->val_(row(j)).AddInteraction(i, val(j)); 01375 } 01376 01377 01379 // MATRIX<ARRAY_COLSYMSPARSE> // 01381 01382 01384 01387 template <class T, class Prop, class Allocator> 01388 inline Matrix<T, Prop, ArrayColSymSparse, Allocator>::Matrix(): 01389 Matrix_ArraySparse<T, Prop, ArrayColSymSparse, Allocator>() 01390 { 01391 } 01392 01393 01395 01400 template <class T, class Prop, class Allocator> 01401 inline Matrix<T, Prop, ArrayColSymSparse, Allocator>::Matrix(int i, int j): 01402 Matrix_ArraySparse<T, Prop, ArrayColSymSparse, Allocator>(i, j) 01403 { 01404 } 01405 01406 01407 /********************************** 01408 * ELEMENT ACCESS AND AFFECTATION * 01409 **********************************/ 01410 01411 01413 01419 template <class T, class Prop, class Allocator> 01420 inline T 01421 Matrix<T, Prop, ArrayColSymSparse, Allocator>::operator() (int i, int j) 01422 const 01423 { 01424 01425 #ifdef SELDON_CHECK_BOUNDS 01426 if (i < 0 || i >= this->m_) 01427 throw WrongRow("Matrix::operator()", "Index should be in [0, " 01428 + to_str(this->m_-1) + "], but is equal to " 01429 + to_str(i) + "."); 01430 if (j < 0 || j >= this->n_) 01431 throw WrongCol("Matrix::operator()", "Index should be in [0, " 01432 + to_str(this->n_-1) + "], but is equal to " 01433 + to_str(j) + "."); 01434 #endif 01435 01436 if (i < j) 01437 return this->val_(j)(i); 01438 01439 return this->val_(i)(j); 01440 } 01441 01442 01444 01450 template <class T, class Prop, class Allocator> 01451 inline T& 01452 Matrix<T, Prop, ArrayColSymSparse, Allocator>::Get(int i, int j) 01453 { 01454 01455 #ifdef SELDON_CHECK_BOUNDS 01456 if (i < 0 || i >= this->m_) 01457 throw WrongRow("Matrix::operator()", "Index should be in [0, " 01458 + to_str(this->m_-1) + "], but is equal to " 01459 + to_str(i) + "."); 01460 if (j < 0 || j >= this->n_) 01461 throw WrongCol("Matrix::operator()", "Index should be in [0, " 01462 + to_str(this->n_-1) + "], but is equal to " 01463 + to_str(j) + "."); 01464 #endif 01465 01466 if (i < j) 01467 return this->val_(j).Get(i); 01468 01469 return this->val_(i).Get(j); 01470 } 01471 01472 01474 01480 template <class T, class Prop, class Allocator> 01481 inline const T& 01482 Matrix<T, Prop, ArrayColSymSparse, Allocator>::Get(int i, int j) const 01483 { 01484 01485 #ifdef SELDON_CHECK_BOUNDS 01486 if (i < 0 || i >= this->m_) 01487 throw WrongRow("Matrix::operator()", "Index should be in [0, " 01488 + to_str(this->m_-1) + "], but is equal to " 01489 + to_str(i) + "."); 01490 if (j < 0 || j >= this->n_) 01491 throw WrongCol("Matrix::operator()", "Index should be in [0, " 01492 + to_str(this->n_-1) + "], but is equal to " 01493 + to_str(j) + "."); 01494 #endif 01495 01496 if (i < j) 01497 return this->val_(j).Get(i); 01498 01499 return this->val_(i).Get(j); 01500 } 01501 01502 01504 01510 template <class T, class Prop, class Allocator> 01511 inline T& 01512 Matrix<T, Prop, ArrayColSymSparse, Allocator>::Val(int i, int j) 01513 { 01514 01515 #ifdef SELDON_CHECK_BOUNDS 01516 if (i < 0 || i >= this->m_) 01517 throw WrongRow("Matrix::operator()", "Index should be in [0, " 01518 + to_str(this->m_-1) + "], but is equal to " 01519 + to_str(i) + "."); 01520 if (j < 0 || j >= this->n_) 01521 throw WrongCol("Matrix::operator()", "Index should be in [0, " 01522 + to_str(this->n_-1) + "], but is equal to " 01523 + to_str(j) + "."); 01524 if (i > j) 01525 throw WrongArgument("Matrix::Val()", string("With this function, you ") 01526 + "can only access upper part of matrix."); 01527 #endif 01528 01529 return this->val_(j).Val(i); 01530 } 01531 01532 01534 01540 template <class T, class Prop, class Allocator> 01541 inline const T& 01542 Matrix<T, Prop, ArrayColSymSparse, Allocator>::Val(int i, int j) const 01543 { 01544 01545 #ifdef SELDON_CHECK_BOUNDS 01546 if (i < 0 || i >= this->m_) 01547 throw WrongRow("Matrix::operator()", "Index should be in [0, " 01548 + to_str(this->m_-1) + "], but is equal to " 01549 + to_str(i) + "."); 01550 if (j < 0 || j >= this->n_) 01551 throw WrongCol("Matrix::operator()", "Index should be in [0, " 01552 + to_str(this->n_-1) + "], but is equal to " 01553 + to_str(j) + "."); 01554 #endif 01555 01556 return this->val_(j).Val(i); 01557 } 01558 01559 01561 01566 template <class T, class Prop, class Allocator> 01567 inline void 01568 Matrix<T, Prop, ArrayColSymSparse, Allocator>::Set(int i, int j, const T& x) 01569 { 01570 if (i < j) 01571 this->val_(j).Get(i) = x; 01572 else 01573 this->val_(i).Get(j) = x; 01574 } 01575 01576 01578 template <class T, class Prop, class Allocator> inline 01579 void Matrix<T, Prop, ArrayColSymSparse, Allocator>::ClearColumn(int i) 01580 { 01581 this->val_(i).Clear(); 01582 } 01583 01584 01586 01591 template <class T, class Prop, class Allocator> 01592 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01593 ReallocateColumn(int i, int j) 01594 { 01595 this->val_(i).Reallocate(j); 01596 } 01597 01598 01600 01604 template <class T, class Prop, class Allocator> 01605 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01606 ResizeColumn(int i, int j) 01607 { 01608 this->val_(i).Resize(j); 01609 } 01610 01611 01613 01617 template <class T, class Prop, class Allocator> 01618 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01619 SwapColumn(int i, int j) 01620 { 01621 Swap(this->val_(i), this->val_(j)); 01622 } 01623 01624 01626 01630 template <class T, class Prop, class Allocator> 01631 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01632 ReplaceIndexColumn(int i, IVect& new_index) 01633 { 01634 for (int j = 0; j < this->val_(i).GetM(); j++) 01635 this->val_(i).Index(j) = new_index(j); 01636 } 01637 01638 01640 01644 template <class T, class Prop, class Allocator> 01645 inline int Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01646 GetColumnSize(int i) const 01647 { 01648 return this->val_(i).GetSize(); 01649 } 01650 01651 01653 template <class T, class Prop, class Allocator> 01654 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01655 PrintColumn(int i) const 01656 { 01657 this->val_(i).Print(); 01658 } 01659 01660 01662 01667 template <class T, class Prop, class Allocator> 01668 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01669 AssembleColumn(int i) 01670 { 01671 this->val_(i).Assemble(); 01672 } 01673 01674 01676 01682 template <class T, class Prop, class Allocator> 01683 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01684 AddInteractionRow(int i, int nb, int* col_, T* value_) 01685 { 01686 IVect col; 01687 col.SetData(nb, col_); 01688 Vector<T> val; 01689 val.SetData(nb, value_); 01690 AddInteractionRow(i, nb, col, val); 01691 col.Nullify(); 01692 val.Nullify(); 01693 } 01694 01695 01697 01703 template <class T, class Prop, class Allocator> 01704 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01705 AddInteractionColumn(int i, int nb, int* row_, T* value_) 01706 { 01707 IVect row; 01708 row.SetData(nb, row_); 01709 Vector<T> val; 01710 val.SetData(nb, value_); 01711 AddInteractionColumn(i, nb, row, val); 01712 row.Nullify(); 01713 val.Nullify(); 01714 } 01715 01716 01718 01723 template <class T, class Prop, class Allocator> 01724 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01725 AddInteraction(int i, int j, const T& val) 01726 { 01727 if (i <= j) 01728 this->val_(j).AddInteraction(i, val); 01729 } 01730 01731 01733 01739 template <class T, class Prop, class Allocator> template <class Alloc1> 01740 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01741 AddInteractionRow(int i, int nb, const IVect& col, 01742 const Vector<T, VectFull, Alloc1>& val) 01743 { 01744 for (int j = 0; j < nb; j++) 01745 if (i <= col(j)) 01746 this->val_(col(j)).AddInteraction(i, val(j)); 01747 } 01748 01749 01751 01757 template <class T, class Prop, class Allocator> template <class Alloc1> 01758 inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>:: 01759 AddInteractionColumn(int i, int nb, const IVect& row, 01760 const Vector<T, VectFull, Alloc1>& val) 01761 { 01762 IVect new_row(nb); 01763 Vector<T, VectFull, Alloc1> new_val(nb); 01764 nb = 0; 01765 for (int j = 0; j < new_row.GetM(); j++) 01766 if (row(j) <= i) 01767 { 01768 new_row(nb) = row(j); 01769 new_val(nb) = val(j); nb++; 01770 } 01771 01772 this->val_(i).AddInteractionRow(nb, new_row, new_val); 01773 } 01774 01775 01777 // MATRIX<ARRAY_ROWSYMSPARSE> // 01779 01780 01782 01785 template <class T, class Prop, class Allocator> 01786 inline Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Matrix(): 01787 Matrix_ArraySparse<T, Prop, ArrayRowSymSparse, Allocator>() 01788 { 01789 } 01790 01791 01793 01798 template <class T, class Prop, class Allocator> 01799 inline Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Matrix(int i, int j): 01800 Matrix_ArraySparse<T, Prop, ArrayRowSymSparse, Allocator>(i, j) 01801 { 01802 } 01803 01804 01805 /********************************** 01806 * ELEMENT ACCESS AND AFFECTATION * 01807 **********************************/ 01808 01809 01811 01817 template <class T, class Prop, class Allocator> 01818 inline T 01819 Matrix<T, Prop, ArrayRowSymSparse, Allocator>::operator() (int i, int j) 01820 const 01821 { 01822 01823 #ifdef SELDON_CHECK_BOUNDS 01824 if (i < 0 || i >= this->m_) 01825 throw WrongRow("Matrix_ArraySparse::operator()", 01826 "Index should be in [0, " 01827 + to_str(this->m_-1) + "], but is equal to " 01828 + to_str(i) + "."); 01829 if (j < 0 || j >= this->n_) 01830 throw WrongCol("Matrix_ArraySparse::operator()", 01831 "Index should be in [0, " 01832 + to_str(this->n_-1) + "], but is equal to " 01833 + to_str(j) + "."); 01834 #endif 01835 01836 if (i < j) 01837 return this->val_(i)(j); 01838 01839 return this->val_(j)(i); 01840 } 01841 01842 01844 01850 template <class T, class Prop, class Allocator> 01851 inline T& 01852 Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Get(int i, int j) 01853 { 01854 01855 #ifdef SELDON_CHECK_BOUNDS 01856 if (i < 0 || i >= this->m_) 01857 throw WrongRow("Matrix::operator()", "Index should be in [0, " 01858 + to_str(this->m_-1) + "], but is equal to " 01859 + to_str(i) + "."); 01860 if (j < 0 || j >= this->n_) 01861 throw WrongCol("Matrix::operator()", "Index should be in [0, " 01862 + to_str(this->n_-1) + "], but is equal to " 01863 + to_str(j) + "."); 01864 #endif 01865 01866 if (i < j) 01867 return this->val_(i).Get(j); 01868 01869 return this->val_(j).Get(i); 01870 } 01871 01872 01874 01880 template <class T, class Prop, class Allocator> 01881 inline const T& 01882 Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Get(int i, int j) const 01883 { 01884 01885 #ifdef SELDON_CHECK_BOUNDS 01886 if (i < 0 || i >= this->m_) 01887 throw WrongRow("Matrix::operator()", "Index should be in [0, " 01888 + to_str(this->m_-1) + "], but is equal to " 01889 + to_str(i) + "."); 01890 if (j < 0 || j >= this->n_) 01891 throw WrongCol("Matrix::operator()", "Index should be in [0, " 01892 + to_str(this->n_-1) + "], but is equal to " 01893 + to_str(j) + "."); 01894 #endif 01895 01896 if (i < j) 01897 return this->val_(i).Get(j); 01898 01899 return this->val_(j).Get(i); 01900 } 01901 01902 01904 01910 template <class T, class Prop, class Allocator> 01911 inline T& 01912 Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Val(int i, int j) 01913 { 01914 01915 #ifdef SELDON_CHECK_BOUNDS 01916 if (i < 0 || i >= this->m_) 01917 throw WrongRow("Matrix::operator()", "Index should be in [0, " 01918 + to_str(this->m_-1) + "], but is equal to " 01919 + to_str(i) + "."); 01920 if (j < 0 || j >= this->n_) 01921 throw WrongCol("Matrix::operator()", "Index should be in [0, " 01922 + to_str(this->n_-1) + "], but is equal to " 01923 + to_str(j) + "."); 01924 if (i > j) 01925 throw WrongArgument("Matrix::Val()", string("With this function, you ") 01926 + "can only access upper part of matrix."); 01927 #endif 01928 01929 return this->val_(i).Val(j); 01930 } 01931 01932 01934 01940 template <class T, class Prop, class Allocator> 01941 inline const T& 01942 Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Val(int i, int j) const 01943 { 01944 01945 #ifdef SELDON_CHECK_BOUNDS 01946 if (i < 0 || i >= this->m_) 01947 throw WrongRow("Matrix::operator()", "Index should be in [0, " 01948 + to_str(this->m_-1) + "], but is equal to " 01949 + to_str(i) + "."); 01950 if (j < 0 || j >= this->n_) 01951 throw WrongCol("Matrix::operator()", "Index should be in [0, " 01952 + to_str(this->n_-1) + "], but is equal to " 01953 + to_str(j) + "."); 01954 if (i > j) 01955 throw WrongArgument("Matrix::Val()", string("With this function, you ") 01956 + "can only access upper part of matrix."); 01957 #endif 01958 01959 return this->val_(i).Val(j); 01960 } 01961 01962 01964 01969 template <class T, class Prop, class Allocator> 01970 inline void 01971 Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Set(int i, int j, const T& x) 01972 { 01973 if (i < j) 01974 this->val_(i).Get(j) = x; 01975 else 01976 this->val_(j).Get(i) = x; 01977 } 01978 01979 01981 template <class T, class Prop, class Allocator> 01982 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::ClearRow(int i) 01983 { 01984 this->val_(i).Clear(); 01985 } 01986 01987 01989 01994 template <class T, class Prop, class Allocator> 01995 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>:: 01996 ReallocateRow(int i,int j) 01997 { 01998 this->val_(i).Reallocate(j); 01999 } 02000 02001 02003 02007 template <class T, class Prop, class Allocator> 02008 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>:: 02009 ResizeRow(int i,int j) 02010 { 02011 this->val_(i).Resize(j); 02012 } 02013 02014 02016 02020 template <class T, class Prop, class Allocator> 02021 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>:: 02022 SwapRow(int i,int j) 02023 { 02024 Swap(this->val_(i), this->val_(j)); 02025 } 02026 02027 02029 02033 template <class T, class Prop, class Allocator> 02034 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>:: 02035 ReplaceIndexRow(int i,IVect& new_index) 02036 { 02037 for (int j = 0; j < this->val_(i).GetM(); j++) 02038 this->val_(i).Index(j) = new_index(j); 02039 } 02040 02041 02043 02047 template <class T, class Prop, class Allocator> 02048 inline int Matrix<T, Prop, ArrayRowSymSparse, Allocator>::GetRowSize(int i) 02049 const 02050 { 02051 return this->val_(i).GetSize(); 02052 } 02053 02054 02056 template <class T, class Prop, class Allocator> 02057 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::PrintRow(int i) 02058 const 02059 { 02060 this->val_(i).Print(); 02061 } 02062 02063 02065 02070 template <class T, class Prop, class Allocator> 02071 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator> 02072 ::AssembleRow(int i) 02073 { 02074 this->val_(i).Assemble(); 02075 } 02076 02077 02079 02084 template <class T, class Prop, class Allocator> 02085 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>:: 02086 AddInteraction(int i, int j, const T& val) 02087 { 02088 if (i <= j) 02089 this->val_(i).AddInteraction(j, val); 02090 } 02091 02092 02094 02100 template <class T, class Prop, class Allocator> 02101 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>:: 02102 AddInteractionRow(int i, int nb, int* col_, T* value_) 02103 { 02104 IVect col; 02105 col.SetData(nb, col_); 02106 Vector<T> val; 02107 val.SetData(nb, value_); 02108 AddInteractionRow(i, nb, col, val); 02109 col.Nullify(); 02110 val.Nullify(); 02111 } 02112 02113 02115 02121 template <class T, class Prop, class Allocator> 02122 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>:: 02123 AddInteractionColumn(int i, int nb, int* row_, T* value_) 02124 { 02125 IVect row; 02126 row.SetData(nb, row_); 02127 Vector<T> val; 02128 val.SetData(nb, value_); 02129 AddInteractionColumn(i, nb, row, val); 02130 row.Nullify(); 02131 val.Nullify(); 02132 } 02133 02134 02136 02142 template <class T, class Prop, class Allocator> template <class Alloc1> 02143 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>:: 02144 AddInteractionRow(int i, int nb, const IVect& col, 02145 const Vector<T, VectFull, Alloc1>& val) 02146 { 02147 IVect new_col(nb); 02148 Vector<T, VectFull, Alloc1> new_val(nb); 02149 nb = 0; 02150 for (int j = 0; j < new_col.GetM(); j++) 02151 if (i <= col(j)) 02152 { 02153 new_col(nb) = col(j); 02154 new_val(nb) = val(j); nb++; 02155 } 02156 02157 this->val_(i).AddInteractionRow(nb, new_col, new_val); 02158 } 02159 02160 02162 02168 template <class T, class Prop, class Allocator> template <class Alloc1> 02169 inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>:: 02170 AddInteractionColumn(int i, int nb, const IVect& row, 02171 const Vector<T,VectFull,Alloc1>& val) 02172 { 02173 for (int j = 0; j < nb; j++) 02174 if (row(j) <= i) 02175 this->val_(row(j)).AddInteraction(i, val(j)); 02176 } 02177 02178 02179 template <class T, class Prop, class Allocator> 02180 ostream& operator <<(ostream& out, 02181 const Matrix<T, Prop, ArrayRowSparse, Allocator>& A) 02182 { 02183 A.WriteText(out); 02184 02185 return out; 02186 } 02187 02188 02189 template <class T, class Prop, class Allocator> 02190 ostream& operator <<(ostream& out, 02191 const Matrix<T, Prop, ArrayColSparse, Allocator>& A) 02192 { 02193 A.WriteText(out); 02194 02195 return out; 02196 } 02197 02198 02199 template <class T, class Prop, class Allocator> 02200 ostream& operator <<(ostream& out, 02201 const Matrix<T, Prop, ArrayRowSymSparse, Allocator>& A) 02202 { 02203 A.WriteText(out); 02204 02205 return out; 02206 } 02207 02208 02209 template <class T, class Prop, class Allocator> 02210 ostream& operator <<(ostream& out, 02211 const Matrix<T, Prop, ArrayColSymSparse, Allocator>& A) 02212 { 02213 A.WriteText(out); 02214 02215 return out; 02216 } 02217 02218 02219 } // namespace Seldon 02220 02221 #define SELDON_FILE_MATRIX_ARRAY_SPARSE_CXX 02222 #endif