Warning: this documentation for the development version is under construction.
00001 // Copyright (C) 2001-2009 Vivien Mallet 00002 // Copyright (C) 2003-2009 Marc Duruflé 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_MATRIX_SYMCOMPLEXSPARSE_CXX 00022 00023 #include "Matrix_SymComplexSparse.hxx" 00024 00025 namespace Seldon 00026 { 00027 00028 00029 /**************** 00030 * CONSTRUCTORS * 00031 ****************/ 00032 00033 00035 00038 template <class T, class Prop, class Storage, class Allocator> 00039 inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 00040 ::Matrix_SymComplexSparse(): Matrix_Base<T, Allocator>() 00041 { 00042 real_nz_ = 0; 00043 imag_nz_ = 0; 00044 real_ptr_ = NULL; 00045 imag_ptr_ = NULL; 00046 real_ind_ = NULL; 00047 imag_ind_ = NULL; 00048 real_data_ = NULL; 00049 imag_data_ = NULL; 00050 } 00051 00052 00054 00060 template <class T, class Prop, class Storage, class Allocator> 00061 inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 00062 ::Matrix_SymComplexSparse(int i, int j): Matrix_Base<T, Allocator>() 00063 { 00064 real_nz_ = 0; 00065 imag_nz_ = 0; 00066 real_ptr_ = NULL; 00067 imag_ptr_ = NULL; 00068 real_ind_ = NULL; 00069 imag_ind_ = NULL; 00070 real_data_ = NULL; 00071 imag_data_ = NULL; 00072 00073 Reallocate(i, i); 00074 } 00075 00076 00078 00090 template <class T, class Prop, class Storage, class Allocator> 00091 inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 00092 ::Matrix_SymComplexSparse(int i, int j, int real_nz, int imag_nz): 00093 Matrix_Base<T, Allocator>() 00094 { 00095 real_nz_ = 0; 00096 imag_nz_ = 0; 00097 real_ptr_ = NULL; 00098 imag_ptr_ = NULL; 00099 real_ind_ = NULL; 00100 imag_ind_ = NULL; 00101 real_data_ = NULL; 00102 imag_data_ = NULL; 00103 00104 Reallocate(i, i, real_nz, imag_nz); 00105 } 00106 00107 00109 00128 template <class T, class Prop, class Storage, class Allocator> 00129 template <class Storage0, class Allocator0, 00130 class Storage1, class Allocator1, 00131 class Storage2, class Allocator2> 00132 inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator>:: 00133 Matrix_SymComplexSparse(int i, int j, 00134 Vector<T, Storage0, Allocator0>& real_values, 00135 Vector<int, Storage1, Allocator1>& real_ptr, 00136 Vector<int, Storage2, Allocator2>& real_ind, 00137 Vector<T, Storage0, Allocator0>& imag_values, 00138 Vector<int, Storage1, Allocator1>& imag_ptr, 00139 Vector<int, Storage2, Allocator2>& imag_ind): 00140 Matrix_Base<T, Allocator>(i, j) 00141 { 00142 real_nz_ = real_values.GetLength(); 00143 imag_nz_ = imag_values.GetLength(); 00144 00145 #ifdef SELDON_CHECK_DIMENSIONS 00146 // Checks whether vector sizes are acceptable. 00147 00148 if (real_ind.GetLength() != real_nz_) 00149 { 00150 this->m_ = 0; 00151 this->n_ = 0; 00152 real_nz_ = 0; 00153 imag_nz_ = 0; 00154 real_ptr_ = NULL; 00155 imag_ptr_ = NULL; 00156 real_ind_ = NULL; 00157 imag_ind_ = NULL; 00158 this->real_data_ = NULL; 00159 this->imag_data_ = NULL; 00160 throw WrongDim(string("Matrix_SymComplexSparse::") 00161 + string("Matrix_SymComplexSparse(int, int, ") 00162 + string("const Vector&, const Vector&, const Vector&") 00163 + ", const Vector&, const Vector&, const Vector&)", 00164 string("There are ") + to_str(real_nz_) 00165 + " values (real part) but " 00166 + to_str(real_ind.GetLength()) 00167 + " row or column indices."); 00168 } 00169 00170 if (imag_ind.GetLength() != imag_nz_) 00171 { 00172 this->m_ = 0; 00173 this->n_ = 0; 00174 real_nz_ = 0; 00175 imag_nz_ = 0; 00176 real_ptr_ = NULL; 00177 imag_ptr_ = NULL; 00178 real_ind_ = NULL; 00179 imag_ind_ = NULL; 00180 this->real_data_ = NULL; 00181 this->imag_data_ = NULL; 00182 throw WrongDim(string("Matrix_SymComplexSparse::") 00183 + string("Matrix_SymComplexSparse(int, int, ") 00184 + string("const Vector&, const Vector&, const Vector&") 00185 + ", const Vector&, const Vector&, const Vector&)", 00186 string("There are ") + to_str(imag_nz_) 00187 + " values (imaginary part) but " 00188 + to_str(imag_ind.GetLength()) 00189 + " row or column indices."); 00190 } 00191 00192 if (real_ptr.GetLength() - 1 != i) 00193 { 00194 this->m_ = 0; 00195 this->n_ = 0; 00196 real_nz_ = 0; 00197 imag_nz_ = 0; 00198 real_ptr_ = NULL; 00199 imag_ptr_ = NULL; 00200 real_ind_ = NULL; 00201 imag_ind_ = NULL; 00202 this->real_data_ = NULL; 00203 this->imag_data_ = NULL; 00204 throw WrongDim(string("Matrix_SymComplexSparse::") 00205 + string("Matrix_SymComplexSparse(int, int, ") 00206 + string("const Vector&, const Vector&, const Vector&") 00207 + ", const Vector&, const Vector&, const Vector&)", 00208 string("The vector of start indices (real part)") 00209 + " contains " + to_str(real_ptr.GetLength()-1) 00210 + string(" row or column start indices (plus the") 00211 + " number of non-zero entries) but there are " 00212 + to_str(i) + " rows or columns (" 00213 + to_str(i) + " by " + to_str(i) + " matrix)."); 00214 } 00215 00216 if (imag_ptr.GetLength() - 1 != i) 00217 { 00218 this->m_ = 0; 00219 this->n_ = 0; 00220 real_nz_ = 0; 00221 imag_nz_ = 0; 00222 real_ptr_ = NULL; 00223 imag_ptr_ = NULL; 00224 real_ind_ = NULL; 00225 imag_ind_ = NULL; 00226 this->real_data_ = NULL; 00227 this->imag_data_ = NULL; 00228 throw WrongDim(string("Matrix_SymComplexSparse::") 00229 + string("Matrix_SymComplexSparse(int, int, ") 00230 + string("const Vector&, const Vector&, const Vector&") 00231 + ", const Vector&, const Vector&, const Vector&)", 00232 string("The vector of start indices (imaginary part)") 00233 + " contains " + to_str(imag_ptr.GetLength()-1) 00234 + string(" row or column start indices (plus the") 00235 + " number of non-zero entries) but there are " 00236 + to_str(i) + " rows or columns (" 00237 + to_str(i) + " by " + to_str(i) + " matrix)."); 00238 } 00239 00240 if ( (static_cast<long int>(2 * real_nz_ - 2) 00241 / static_cast<long int>(i + 1) 00242 >= static_cast<long int>(i)) || 00243 (static_cast<long int>(2 * imag_nz_ - 2) 00244 / static_cast<long int>(i + 1) 00245 >= static_cast<long int>(i)) ) 00246 { 00247 this->m_ = 0; 00248 this->n_ = 0; 00249 real_nz_ = 0; 00250 imag_nz_ = 0; 00251 real_ptr_ = NULL; 00252 imag_ptr_ = NULL; 00253 real_ind_ = NULL; 00254 imag_ind_ = NULL; 00255 this->real_data_ = NULL; 00256 this->imag_data_ = NULL; 00257 throw WrongDim(string("Matrix_SymComplexSparse::") 00258 + string("Matrix_SymComplexSparse(int, int, ") 00259 + string("const Vector&, const Vector&, const Vector&") 00260 + ", const Vector&, const Vector&, const Vector&)", 00261 string("There are more values (") 00262 + to_str(real_values.GetLength()) 00263 + " values for the real part and " 00264 + to_str(real_values.GetLength()) + " values for" 00265 + string(" the imaginary part) than elements in the") 00266 + " matrix (" + to_str(i) + " by " + to_str(i) + ")."); 00267 } 00268 #endif 00269 00270 this->real_ptr_ = real_ptr.GetData(); 00271 this->imag_ptr_ = imag_ptr.GetData(); 00272 this->real_ind_ = real_ind.GetData(); 00273 this->imag_ind_ = imag_ind.GetData(); 00274 this->real_data_ = real_values.GetData(); 00275 this->imag_data_ = imag_values.GetData(); 00276 00277 real_ptr.Nullify(); 00278 imag_ptr.Nullify(); 00279 real_ind.Nullify(); 00280 imag_ind.Nullify(); 00281 real_values.Nullify(); 00282 imag_values.Nullify(); 00283 } 00284 00285 00287 template <class T, class Prop, class Storage, class Allocator> 00288 Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 00289 ::Matrix_SymComplexSparse(const Matrix_SymComplexSparse<T, Prop, 00290 Storage, Allocator>& A) 00291 { 00292 this->m_ = 0; 00293 this->n_ = 0; 00294 real_nz_ = 0; 00295 imag_nz_ = 0; 00296 real_ptr_ = NULL; 00297 imag_ptr_ = NULL; 00298 real_ind_ = NULL; 00299 imag_ind_ = NULL; 00300 real_data_ = NULL; 00301 imag_data_ = NULL; 00302 00303 this->Copy(A); 00304 } 00305 00306 00307 /************** 00308 * DESTRUCTOR * 00309 **************/ 00310 00311 00313 template <class T, class Prop, class Storage, class Allocator> 00314 inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 00315 ::~Matrix_SymComplexSparse() 00316 { 00317 this->m_ = 0; 00318 this->n_ = 0; 00319 00320 #ifdef SELDON_CHECK_MEMORY 00321 try 00322 { 00323 #endif 00324 00325 if (real_ptr_ != NULL) 00326 { 00327 free(real_ptr_); 00328 real_ptr_ = NULL; 00329 } 00330 00331 #ifdef SELDON_CHECK_MEMORY 00332 } 00333 catch (...) 00334 { 00335 real_ptr_ = NULL; 00336 } 00337 #endif 00338 00339 #ifdef SELDON_CHECK_MEMORY 00340 try 00341 { 00342 #endif 00343 00344 if (imag_ptr_ != NULL) 00345 { 00346 free(imag_ptr_); 00347 imag_ptr_ = NULL; 00348 } 00349 00350 #ifdef SELDON_CHECK_MEMORY 00351 } 00352 catch (...) 00353 { 00354 imag_ptr_ = NULL; 00355 } 00356 #endif 00357 00358 #ifdef SELDON_CHECK_MEMORY 00359 try 00360 { 00361 #endif 00362 00363 if (real_ind_ != NULL) 00364 { 00365 free(real_ind_); 00366 real_ind_ = NULL; 00367 } 00368 00369 #ifdef SELDON_CHECK_MEMORY 00370 } 00371 catch (...) 00372 { 00373 real_ind_ = NULL; 00374 } 00375 #endif 00376 00377 #ifdef SELDON_CHECK_MEMORY 00378 try 00379 { 00380 #endif 00381 00382 if (imag_ind_ != NULL) 00383 { 00384 free(imag_ind_); 00385 imag_ind_ = NULL; 00386 } 00387 00388 #ifdef SELDON_CHECK_MEMORY 00389 } 00390 catch (...) 00391 { 00392 imag_ind_ = NULL; 00393 } 00394 #endif 00395 00396 #ifdef SELDON_CHECK_MEMORY 00397 try 00398 { 00399 #endif 00400 00401 if (this->real_data_ != NULL) 00402 { 00403 this->allocator_.deallocate(this->real_data_, real_nz_); 00404 this->real_data_ = NULL; 00405 } 00406 00407 #ifdef SELDON_CHECK_MEMORY 00408 } 00409 catch (...) 00410 { 00411 this->real_nz_ = 0; 00412 this->real_data_ = NULL; 00413 } 00414 #endif 00415 00416 #ifdef SELDON_CHECK_MEMORY 00417 try 00418 { 00419 #endif 00420 00421 if (this->imag_data_ != NULL) 00422 { 00423 this->allocator_.deallocate(this->imag_data_, imag_nz_); 00424 this->imag_data_ = NULL; 00425 } 00426 00427 #ifdef SELDON_CHECK_MEMORY 00428 } 00429 catch (...) 00430 { 00431 this->imag_nz_ = 0; 00432 this->imag_data_ = NULL; 00433 } 00434 #endif 00435 00436 this->real_nz_ = 0; 00437 this->imag_nz_ = 0; 00438 } 00439 00440 00442 00445 template <class T, class Prop, class Storage, class Allocator> 00446 inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::Clear() 00447 { 00448 this->~Matrix_SymComplexSparse(); 00449 } 00450 00451 00452 /********************* 00453 * MEMORY MANAGEMENT * 00454 *********************/ 00455 00456 00458 00476 template <class T, class Prop, class Storage, class Allocator> 00477 template <class Storage0, class Allocator0, 00478 class Storage1, class Allocator1, 00479 class Storage2, class Allocator2> 00480 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>:: 00481 SetData(int i, int j, 00482 Vector<T, Storage0, Allocator0>& real_values, 00483 Vector<int, Storage1, Allocator1>& real_ptr, 00484 Vector<int, Storage2, Allocator2>& real_ind, 00485 Vector<T, Storage0, Allocator0>& imag_values, 00486 Vector<int, Storage1, Allocator1>& imag_ptr, 00487 Vector<int, Storage2, Allocator2>& imag_ind) 00488 { 00489 this->Clear(); 00490 this->m_ = i; 00491 this->n_ = i; 00492 real_nz_ = real_values.GetLength(); 00493 imag_nz_ = imag_values.GetLength(); 00494 00495 #ifdef SELDON_CHECK_DIMENSIONS 00496 // Checks whether vector sizes are acceptable. 00497 00498 if (real_ind.GetLength() != real_nz_) 00499 { 00500 this->m_ = 0; 00501 this->n_ = 0; 00502 real_nz_ = 0; 00503 imag_nz_ = 0; 00504 real_ptr_ = NULL; 00505 imag_ptr_ = NULL; 00506 real_ind_ = NULL; 00507 imag_ind_ = NULL; 00508 this->real_data_ = NULL; 00509 this->imag_data_ = NULL; 00510 throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ") 00511 + string("const Vector&, const Vector&, const Vector&") 00512 + ", const Vector&, const Vector&, const Vector&)", 00513 string("There are ") + to_str(real_nz_) 00514 + " values (real part) but " 00515 + to_str(real_ind.GetLength()) 00516 + " row or column indices."); 00517 } 00518 00519 if (imag_ind.GetLength() != imag_nz_) 00520 { 00521 this->m_ = 0; 00522 this->n_ = 0; 00523 real_nz_ = 0; 00524 imag_nz_ = 0; 00525 real_ptr_ = NULL; 00526 imag_ptr_ = NULL; 00527 real_ind_ = NULL; 00528 imag_ind_ = NULL; 00529 this->real_data_ = NULL; 00530 this->imag_data_ = NULL; 00531 throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ") 00532 + string("const Vector&, const Vector&, const Vector&") 00533 + ", const Vector&, const Vector&, const Vector&)", 00534 string("There are ") + to_str(imag_nz_) 00535 + " values (imaginary part) but " 00536 + to_str(imag_ind.GetLength()) 00537 + " row or column indices."); 00538 } 00539 00540 if (real_ptr.GetLength() - 1 != i) 00541 { 00542 this->m_ = 0; 00543 this->n_ = 0; 00544 real_nz_ = 0; 00545 imag_nz_ = 0; 00546 real_ptr_ = NULL; 00547 imag_ptr_ = NULL; 00548 real_ind_ = NULL; 00549 imag_ind_ = NULL; 00550 this->real_data_ = NULL; 00551 this->imag_data_ = NULL; 00552 throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ") 00553 + string("const Vector&, const Vector&, const Vector&") 00554 + ", const Vector&, const Vector&, const Vector&)", 00555 string("The vector of start indices (real part)") 00556 + " contains " + to_str(real_ptr.GetLength() - 1) 00557 + string(" row or column start indices (plus the") 00558 + " number of non-zero entries) but there are " 00559 + to_str(i) + " rows or columns (" 00560 + to_str(i) + " by " + to_str(i) + " matrix)."); 00561 } 00562 00563 if (imag_ptr.GetLength() - 1 != i) 00564 { 00565 this->m_ = 0; 00566 this->n_ = 0; 00567 real_nz_ = 0; 00568 imag_nz_ = 0; 00569 real_ptr_ = NULL; 00570 imag_ptr_ = NULL; 00571 real_ind_ = NULL; 00572 imag_ind_ = NULL; 00573 this->real_data_ = NULL; 00574 this->imag_data_ = NULL; 00575 throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ") 00576 + string("const Vector&, const Vector&, const Vector&") 00577 + ", const Vector&, const Vector&, const Vector&)", 00578 string("The vector of start indices (imaginary part)") 00579 + " contains " + to_str(imag_ptr.GetLength()-1) 00580 + string(" row or column start indices (plus the") 00581 + " number of non-zero entries) but there are " 00582 + to_str(i) + " rows or columns (" 00583 + to_str(i) + " by " + to_str(i) + " matrix)."); 00584 } 00585 00586 if ( (static_cast<long int>(2 * real_nz_ - 2) / static_cast<long int>(i) 00587 >= static_cast<long int>(i + 1)) || 00588 (static_cast<long int>(2 * imag_nz_ - 2) / static_cast<long int>(i) 00589 >= static_cast<long int>(i + 1)) ) 00590 { 00591 this->m_ = 0; 00592 this->n_ = 0; 00593 real_nz_ = 0; 00594 imag_nz_ = 0; 00595 real_ptr_ = NULL; 00596 imag_ptr_ = NULL; 00597 real_ind_ = NULL; 00598 imag_ind_ = NULL; 00599 this->real_data_ = NULL; 00600 this->imag_data_ = NULL; 00601 throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ") 00602 + string("const Vector&, const Vector&, const Vector&") 00603 + ", const Vector&, const Vector&, const Vector&)", 00604 string("There are more values (") 00605 + to_str(real_values.GetLength()) 00606 + " values for the real part and " 00607 + to_str(real_values.GetLength()) + string(" values") 00608 + string(" for the imaginary part) than elements in") 00609 + " the matrix (" + to_str(i) 00610 + " by " + to_str(i) + ")."); 00611 } 00612 #endif 00613 00614 this->real_ptr_ = real_ptr.GetData(); 00615 this->imag_ptr_ = imag_ptr.GetData(); 00616 this->real_ind_ = real_ind.GetData(); 00617 this->imag_ind_ = imag_ind.GetData(); 00618 this->real_data_ = real_values.GetData(); 00619 this->imag_data_ = imag_values.GetData(); 00620 00621 real_ptr.Nullify(); 00622 imag_ptr.Nullify(); 00623 real_ind.Nullify(); 00624 imag_ind.Nullify(); 00625 real_values.Nullify(); 00626 imag_values.Nullify(); 00627 } 00628 00629 00631 00653 template <class T, class Prop, class Storage, class Allocator> 00654 inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>:: 00655 SetData(int i, int j, int real_nz, 00656 typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 00657 ::pointer real_values, 00658 int* real_ptr, int* real_ind, int imag_nz, 00659 typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 00660 ::pointer imag_values, 00661 int* imag_ptr, int* imag_ind) 00662 { 00663 this->Clear(); 00664 00665 this->m_ = i; 00666 this->n_ = i; 00667 00668 this->real_nz_ = real_nz; 00669 this->imag_nz_ = imag_nz; 00670 00671 real_data_ = real_values; 00672 imag_data_ = imag_values; 00673 real_ind_ = real_ind; 00674 imag_ind_ = imag_ind; 00675 real_ptr_ = real_ptr; 00676 imag_ptr_ = imag_ptr; 00677 } 00678 00679 00681 00685 template <class T, class Prop, class Storage, class Allocator> 00686 inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::Nullify() 00687 { 00688 this->data_ = NULL; 00689 this->m_ = 0; 00690 this->n_ = 0; 00691 real_nz_ = 0; 00692 real_ptr_ = NULL; 00693 real_ind_ = NULL; 00694 imag_nz_ = 0; 00695 imag_ptr_ = NULL; 00696 imag_ind_ = NULL; 00697 real_data_ = NULL; 00698 imag_data_ = NULL; 00699 } 00700 00701 00703 template <class T, class Prop, class Storage, class Allocator> 00704 inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 00705 ::Reallocate(int i, int j) 00706 { 00707 // previous entries are removed 00708 Clear(); 00709 00710 this->m_ = i; 00711 this->n_ = i; 00712 00713 // we try to allocate real_ptr_ and imag_ptr_ 00714 #ifdef SELDON_CHECK_MEMORY 00715 try 00716 { 00717 #endif 00718 00719 real_ptr_ = reinterpret_cast<int*>(calloc(i+1, sizeof(int))); 00720 00721 imag_ptr_ = reinterpret_cast<int*>(calloc(i+1, sizeof(int))); 00722 00723 #ifdef SELDON_CHECK_MEMORY 00724 } 00725 catch (...) 00726 { 00727 this->m_ = 0; 00728 this->n_ = 0; 00729 real_nz_ = 0; 00730 real_ptr_ = NULL; 00731 real_ind_ = NULL; 00732 imag_nz_ = 0; 00733 imag_ptr_ = NULL; 00734 imag_ind_ = NULL; 00735 real_data_ = NULL; 00736 imag_data_ = NULL; 00737 } 00738 if ((real_ptr_ == NULL) || (imag_ptr_ == NULL)) 00739 { 00740 this->m_ = 0; 00741 this->n_ = 0; 00742 real_nz_ = 0; 00743 real_ptr_ = NULL; 00744 real_ind_ = NULL; 00745 imag_nz_ = 0; 00746 imag_ptr_ = NULL; 00747 imag_ind_ = NULL; 00748 real_data_ = NULL; 00749 imag_data_ = NULL; 00750 } 00751 if (((real_ptr_ == NULL) || (imag_ptr_ == NULL)) && i != 0 && j != 0) 00752 throw NoMemory("Matrix_SymComplexSparse::Reallocate(int, int)", 00753 string("Unable to allocate ") 00754 + to_str(sizeof(int) * (i+1) ) 00755 + " bytes to store " + to_str(i+1) 00756 + " row or column start indices, for a " 00757 + to_str(i) + " by " + to_str(j) + " matrix."); 00758 #endif 00759 00760 // then filing real_ptr_ with 0 00761 for (int k = 0; k <= i; k++) 00762 { 00763 real_ptr_[k] = 0; 00764 imag_ptr_[k] = 0; 00765 } 00766 } 00767 00768 00770 template <class T, class Prop, class Storage, class Allocator> 00771 inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 00772 ::Reallocate(int i, int j, int real_nz, int imag_nz) 00773 { 00774 // previous entries are removed 00775 Clear(); 00776 00777 this->m_ = i; 00778 this->n_ = j; 00779 this->real_nz_ = real_nz; 00780 this->imag_nz_ = imag_nz; 00781 00782 #ifdef SELDON_CHECK_DIMENSIONS 00783 if ( (static_cast<long int>(2 * real_nz_ - 2) / static_cast<long int>(i+1) 00784 >= static_cast<long int>(i)) || 00785 (static_cast<long int>(2 * imag_nz_ - 2) / static_cast<long int>(i+1) 00786 >= static_cast<long int>(i)) ) 00787 { 00788 this->m_ = 0; 00789 this->n_ = 0; 00790 real_nz_ = 0; 00791 imag_nz_ = 0; 00792 real_ptr_ = NULL; 00793 imag_ptr_ = NULL; 00794 real_ind_ = NULL; 00795 imag_ind_ = NULL; 00796 this->real_data_ = NULL; 00797 this->imag_data_ = NULL; 00798 throw WrongDim(string("Matrix_SymComplexSparse::") 00799 + "Matrix_SymComplexSparse(int, int, int, int)", 00800 string("There are more values to be stored (") 00801 + to_str(real_nz) + " values for the real part and " 00802 + to_str(imag_nz) + string(" values for the imaginary") 00803 + " part) than elements in the matrix (" 00804 + to_str(i) + " by " + to_str(j) + ")."); 00805 } 00806 #endif 00807 00808 #ifdef SELDON_CHECK_MEMORY 00809 try 00810 { 00811 #endif 00812 00813 real_ptr_ = reinterpret_cast<int*>(calloc(i + 1, sizeof(int))); 00814 00815 #ifdef SELDON_CHECK_MEMORY 00816 } 00817 catch (...) 00818 { 00819 this->m_ = 0; 00820 this->n_ = 0; 00821 real_nz_ = 0; 00822 imag_nz_ = 0; 00823 real_ptr_ = NULL; 00824 imag_ptr_ = NULL; 00825 real_ind_ = NULL; 00826 imag_ind_ = NULL; 00827 this->real_data_ = NULL; 00828 this->imag_data_ = NULL; 00829 } 00830 if (real_ptr_ == NULL) 00831 { 00832 this->m_ = 0; 00833 this->n_ = 0; 00834 real_nz_ = 0; 00835 imag_nz_ = 0; 00836 imag_ptr_ = 0; 00837 real_ind_ = NULL; 00838 imag_ind_ = NULL; 00839 this->real_data_ = NULL; 00840 this->imag_data_ = NULL; 00841 } 00842 if (real_ptr_ == NULL && i != 0) 00843 throw NoMemory(string("Matrix_SymComplexSparse::") 00844 + "Matrix_SymComplexSparse(int, int, int, int)", 00845 string("Unable to allocate ") 00846 + to_str(sizeof(int) * (i + 1)) + " bytes to store " 00847 + to_str(i + 1) + string(" row or column") 00848 + " start indices (for the real part), for a " 00849 + to_str(i) + " by " + to_str(i) + " matrix."); 00850 #endif 00851 00852 #ifdef SELDON_CHECK_MEMORY 00853 try 00854 { 00855 #endif 00856 00857 imag_ptr_ = reinterpret_cast<int*>(calloc(i + 1, sizeof(int))); 00858 00859 #ifdef SELDON_CHECK_MEMORY 00860 } 00861 catch (...) 00862 { 00863 this->m_ = 0; 00864 this->n_ = 0; 00865 real_nz_ = 0; 00866 imag_nz_ = 0; 00867 free(real_ptr_); 00868 real_ptr_ = NULL; 00869 imag_ptr_ = NULL; 00870 real_ind_ = NULL; 00871 imag_ind_ = NULL; 00872 this->real_data_ = NULL; 00873 this->imag_data_ = NULL; 00874 } 00875 if (imag_ptr_ == NULL) 00876 { 00877 this->m_ = 0; 00878 this->n_ = 0; 00879 real_nz_ = 0; 00880 imag_nz_ = 0; 00881 free(real_ptr_); 00882 real_ptr_ = 0; 00883 real_ind_ = NULL; 00884 imag_ind_ = NULL; 00885 this->real_data_ = NULL; 00886 this->imag_data_ = NULL; 00887 } 00888 if (imag_ptr_ == NULL && i != 0) 00889 throw NoMemory(string("Matrix_SymComplexSparse::") 00890 + "Matrix_SymComplexSparse(int, int, int, int)", 00891 string("Unable to allocate ") 00892 + to_str(sizeof(int) * (i + 1) ) + " bytes to store " 00893 + to_str(i + 1) + string(" row or column") 00894 + " start indices (for the imaginary part), for a " 00895 + to_str(i) + " by " + to_str(i) + " matrix."); 00896 #endif 00897 00898 #ifdef SELDON_CHECK_MEMORY 00899 try 00900 { 00901 #endif 00902 00903 real_ind_ = reinterpret_cast<int*>(calloc(real_nz_, sizeof(int))); 00904 00905 #ifdef SELDON_CHECK_MEMORY 00906 } 00907 catch (...) 00908 { 00909 this->m_ = 0; 00910 this->n_ = 0; 00911 real_nz_ = 0; 00912 imag_nz_ = 0; 00913 free(real_ptr_); 00914 free(imag_ptr_); 00915 real_ptr_ = NULL; 00916 imag_ptr_ = NULL; 00917 real_ind_ = NULL; 00918 imag_ind_ = NULL; 00919 this->real_data_ = NULL; 00920 this->imag_data_ = NULL; 00921 } 00922 if (real_ind_ == NULL) 00923 { 00924 this->m_ = 0; 00925 this->n_ = 0; 00926 real_nz_ = 0; 00927 imag_nz_ = 0; 00928 free(real_ptr_); 00929 free(imag_ptr_); 00930 real_ptr_ = NULL; 00931 imag_ptr_ = NULL; 00932 this->real_data_ = NULL; 00933 this->imag_data_ = NULL; 00934 } 00935 if (real_ind_ == NULL && i != 0) 00936 throw NoMemory(string("Matrix_SymComplexSparse::") 00937 + "Matrix_SymComplexSparse(int, int, int, int)", 00938 string("Unable to allocate ") 00939 + to_str(sizeof(int) * real_nz) + " bytes to store " 00940 + to_str(real_nz) 00941 + " row or column indices (real part), for a " 00942 + to_str(i) + " by " + to_str(i) + " matrix."); 00943 #endif 00944 00945 #ifdef SELDON_CHECK_MEMORY 00946 try 00947 { 00948 #endif 00949 00950 imag_ind_ = reinterpret_cast<int*>( calloc(imag_nz_, sizeof(int)) ); 00951 00952 #ifdef SELDON_CHECK_MEMORY 00953 } 00954 catch (...) 00955 { 00956 this->m_ = 0; 00957 this->n_ = 0; 00958 real_nz_ = 0; 00959 imag_nz_ = 0; 00960 free(real_ptr_); 00961 free(imag_ptr_); 00962 real_ptr_ = NULL; 00963 imag_ptr_ = NULL; 00964 free(imag_ind_); 00965 real_ind_ = NULL; 00966 imag_ind_ = NULL; 00967 this->real_data_ = NULL; 00968 this->imag_data_ = NULL; 00969 } 00970 if (real_ind_ == NULL) 00971 { 00972 this->m_ = 0; 00973 this->n_ = 0; 00974 real_nz_ = 0; 00975 imag_nz_ = 0; 00976 free(real_ptr_); 00977 free(imag_ptr_); 00978 real_ptr_ = NULL; 00979 imag_ptr_ = NULL; 00980 free(imag_ind_); 00981 imag_ind_ = NULL; 00982 this->real_data_ = NULL; 00983 this->imag_data_ = NULL; 00984 } 00985 if (imag_ind_ == NULL && i != 0) 00986 throw NoMemory(string("Matrix_SymComplexSparse::") 00987 + "Matrix_SymComplexSparse(int, int, int, int)", 00988 string("Unable to allocate ") 00989 + to_str(sizeof(int) * imag_nz) + " bytes to store " 00990 + to_str(imag_nz) 00991 + " row or column indices (imaginary part), for a " 00992 + to_str(i) + " by " + to_str(i) + " matrix."); 00993 #endif 00994 00995 #ifdef SELDON_CHECK_MEMORY 00996 try 00997 { 00998 #endif 00999 01000 this->real_data_ = this->allocator_.allocate(real_nz_, this); 01001 01002 #ifdef SELDON_CHECK_MEMORY 01003 } 01004 catch (...) 01005 { 01006 this->m_ = 0; 01007 this->n_ = 0; 01008 free(real_ptr_); 01009 free(imag_ptr_); 01010 real_ptr_ = NULL; 01011 imag_ptr_ = NULL; 01012 free(real_ind_); 01013 free(imag_ind_); 01014 real_ind_ = NULL; 01015 imag_ind_ = NULL; 01016 this->real_data_ = NULL; 01017 this->imag_data_ = NULL; 01018 } 01019 if (real_data_ == NULL) 01020 { 01021 this->m_ = 0; 01022 this->n_ = 0; 01023 free(real_ptr_); 01024 free(imag_ptr_); 01025 real_ptr_ = NULL; 01026 imag_ptr_ = NULL; 01027 free(real_ind_); 01028 free(imag_ind_); 01029 real_ind_ = NULL; 01030 imag_ind_ = NULL; 01031 imag_data_ = NULL; 01032 } 01033 if (real_data_ == NULL && i != 0) 01034 throw NoMemory(string("Matrix_SymComplexSparse::") 01035 + "Matrix_SymComplexSparse(int, int, int, int)", 01036 string("Unable to allocate ") 01037 + to_str(sizeof(int) * real_nz) + " bytes to store " 01038 + to_str(real_nz) + " values (real part), for a " 01039 + to_str(i) + " by " + to_str(i) + " matrix."); 01040 #endif 01041 01042 #ifdef SELDON_CHECK_MEMORY 01043 try 01044 { 01045 #endif 01046 01047 this->imag_data_ = this->allocator_.allocate(imag_nz_, this); 01048 01049 #ifdef SELDON_CHECK_MEMORY 01050 } 01051 catch (...) 01052 { 01053 this->m_ = 0; 01054 this->n_ = 0; 01055 free(real_ptr_); 01056 free(imag_ptr_); 01057 real_ptr_ = NULL; 01058 imag_ptr_ = NULL; 01059 free(real_ind_); 01060 free(imag_ind_); 01061 real_ind_ = NULL; 01062 imag_ind_ = NULL; 01063 this->allocator_.deallocate(this->real_data_, real_nz_); 01064 this->real_data_ = NULL; 01065 this->imag_data_ = NULL; 01066 } 01067 if (real_data_ == NULL) 01068 { 01069 this->m_ = 0; 01070 this->n_ = 0; 01071 free(real_ptr_); 01072 free(imag_ptr_); 01073 real_ptr_ = NULL; 01074 imag_ptr_ = NULL; 01075 free(real_ind_); 01076 free(imag_ind_); 01077 real_ind_ = NULL; 01078 imag_ind_ = NULL; 01079 this->allocator_.deallocate(this->real_data_, real_nz_); 01080 real_data_ = NULL; 01081 } 01082 if (imag_data_ == NULL && i != 0) 01083 throw NoMemory(string("Matrix_SymComplexSparse::") 01084 + "Matrix_SymComplexSparse(int, int, int, int)", 01085 string("Unable to allocate ") 01086 + to_str(sizeof(int) * imag_nz) + " bytes to store " 01087 + to_str(imag_nz) + " values (imaginary part), for a " 01088 + to_str(i) + " by " + to_str(i) + " matrix."); 01089 #endif 01090 } 01091 01092 01094 01099 template <class T, class Prop, class Storage, class Allocator> 01100 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01101 ::Resize(int i, int j) 01102 { 01103 if (i < this->m_) 01104 Resize(i, i, real_ptr_[i], imag_ptr_[i]); 01105 else 01106 Resize(i, i, real_nz_, imag_nz_); 01107 } 01108 01109 01111 01118 template <class T, class Prop, class Storage, class Allocator> 01119 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01120 ::Resize(int i, int j, int real_nz, int imag_nz) 01121 { 01122 #ifdef SELDON_CHECK_DIMENSIONS 01123 if (real_nz < 0 || imag_nz < 0) 01124 { 01125 this->m_ = 0; 01126 this->n_ = 0; 01127 real_nz_ = 0; 01128 imag_nz_ = 0; 01129 real_ptr_ = NULL; 01130 imag_ptr_ = NULL; 01131 real_ind_ = NULL; 01132 imag_ind_ = NULL; 01133 this->real_data_ = NULL; 01134 this->imag_data_ = NULL; 01135 throw WrongDim(string("Matrix_SymComplexSparse::") 01136 + "Resize(int, int, int, int)", 01137 "Invalid number of non-zero elements: " 01138 + to_str(real_nz) + " in the real part and " 01139 + to_str(imag_nz) + " in the imaginary part."); 01140 } 01141 if ((real_nz > 0 01142 && (j == 0 01143 || static_cast<long int>(real_nz-1) / static_cast<long int>(j) 01144 >= static_cast<long int>(i))) 01145 || 01146 (imag_nz > 0 01147 && (j == 0 01148 || static_cast<long int>(imag_nz-1) / static_cast<long int>(j) 01149 >= static_cast<long int>(i)))) 01150 { 01151 this->m_ = 0; 01152 this->n_ = 0; 01153 real_nz_ = 0; 01154 imag_nz_ = 0; 01155 real_ptr_ = NULL; 01156 imag_ptr_ = NULL; 01157 real_ind_ = NULL; 01158 imag_ind_ = NULL; 01159 this->real_data_ = NULL; 01160 this->imag_data_ = NULL; 01161 throw WrongDim(string("Matrix_SymComplexSparse::") 01162 + "Resize(int, int, int, int)", 01163 string("There are more values (") + to_str(real_nz) 01164 + " values for the real part and " + to_str(imag_nz) 01165 + string(" values for the imaginary part) than") 01166 + " elements in the matrix (" + to_str(i) + " by " 01167 + to_str(j) + ")."); 01168 } 01169 #endif 01170 01171 if (this->m_ != i) 01172 { 01173 #ifdef SELDON_CHECK_MEMORY 01174 try 01175 { 01176 #endif 01177 01178 real_ptr_ 01179 = reinterpret_cast<int*>( realloc(real_ptr_, 01180 (i+1)*sizeof(int)) ); 01181 01182 #ifdef SELDON_CHECK_MEMORY 01183 } 01184 catch (...) 01185 { 01186 this->m_ = 0; 01187 this->n_ = 0; 01188 real_nz_ = 0; 01189 imag_nz_ = 0; 01190 real_ptr_ = NULL; 01191 imag_ptr_ = NULL; 01192 real_ind_ = NULL; 01193 imag_ind_ = NULL; 01194 this->real_data_ = NULL; 01195 this->imag_data_ = NULL; 01196 } 01197 if (real_ptr_ == NULL) 01198 { 01199 this->m_ = 0; 01200 this->n_ = 0; 01201 real_nz_ = 0; 01202 imag_nz_ = 0; 01203 imag_ptr_ = 0; 01204 real_ind_ = NULL; 01205 imag_ind_ = NULL; 01206 this->real_data_ = NULL; 01207 this->imag_data_ = NULL; 01208 } 01209 if (real_ptr_ == NULL && i != 0 && j != 0) 01210 throw NoMemory(string("Matrix_SymComplexSparse::") 01211 + "Resize(int, int, int, int)", 01212 string("Unable to allocate ") 01213 + to_str(sizeof(int) * (i+1)) 01214 + " bytes to store " + to_str(i+1) 01215 + string(" row or column start indices (for the real") 01216 + " part), for a " 01217 + to_str(i) + " by " + to_str(j) + " matrix."); 01218 #endif 01219 01220 #ifdef SELDON_CHECK_MEMORY 01221 try 01222 { 01223 #endif 01224 01225 imag_ptr_ 01226 = reinterpret_cast<int*>( realloc(imag_ptr_, 01227 (i+1)*sizeof(int)) ); 01228 01229 #ifdef SELDON_CHECK_MEMORY 01230 } 01231 catch (...) 01232 { 01233 this->m_ = 0; 01234 this->n_ = 0; 01235 real_nz_ = 0; 01236 imag_nz_ = 0; 01237 free(real_ptr_); 01238 real_ptr_ = NULL; 01239 imag_ptr_ = NULL; 01240 real_ind_ = NULL; 01241 imag_ind_ = NULL; 01242 this->real_data_ = NULL; 01243 this->imag_data_ = NULL; 01244 } 01245 if (imag_ptr_ == NULL) 01246 { 01247 this->m_ = 0; 01248 this->n_ = 0; 01249 real_nz_ = 0; 01250 imag_nz_ = 0; 01251 free(real_ptr_); 01252 real_ptr_ = 0; 01253 real_ind_ = NULL; 01254 imag_ind_ = NULL; 01255 this->real_data_ = NULL; 01256 this->imag_data_ = NULL; 01257 } 01258 if (imag_ptr_ == NULL && i != 0 && j != 0) 01259 throw NoMemory(string("Matrix_SymComplexSparse::") 01260 + "Resize(int, int, int, int)", 01261 string("Unable to allocate ") 01262 + to_str(sizeof(int) * (i+1)) 01263 + " bytes to store " + to_str(i+1) 01264 + string(" row or column start indices (for the") 01265 + string(" imaginary part), for a ") 01266 + to_str(i) + " by " + to_str(j) + " matrix."); 01267 #endif 01268 } 01269 01270 if (real_nz != real_nz_) 01271 { 01272 #ifdef SELDON_CHECK_MEMORY 01273 try 01274 { 01275 #endif 01276 01277 real_ind_ 01278 = reinterpret_cast<int*>( realloc(real_ind_, 01279 real_nz*sizeof(int)) ); 01280 01281 #ifdef SELDON_CHECK_MEMORY 01282 } 01283 catch (...) 01284 { 01285 this->m_ = 0; 01286 this->n_ = 0; 01287 real_nz_ = 0; 01288 imag_nz_ = 0; 01289 free(real_ptr_); 01290 free(imag_ptr_); 01291 real_ptr_ = NULL; 01292 imag_ptr_ = NULL; 01293 real_ind_ = NULL; 01294 imag_ind_ = NULL; 01295 this->real_data_ = NULL; 01296 this->imag_data_ = NULL; 01297 } 01298 if (real_ind_ == NULL) 01299 { 01300 this->m_ = 0; 01301 this->n_ = 0; 01302 real_nz_ = 0; 01303 imag_nz_ = 0; 01304 free(real_ptr_); 01305 free(imag_ptr_); 01306 real_ptr_ = NULL; 01307 imag_ptr_ = NULL; 01308 this->real_data_ = NULL; 01309 this->imag_data_ = NULL; 01310 } 01311 if (real_ind_ == NULL && i != 0 && j != 0) 01312 throw NoMemory(string("Matrix_SymComplexSparse::") 01313 + "Resize(int, int, int, int)", 01314 string("Unable to allocate ") 01315 + to_str(sizeof(int) * real_nz) 01316 + " bytes to store " + to_str(real_nz) 01317 + " row or column indices (real part), for a " 01318 + to_str(i) + " by " + to_str(j) + " matrix."); 01319 #endif 01320 } 01321 01322 if (imag_nz != imag_nz_) 01323 { 01324 #ifdef SELDON_CHECK_MEMORY 01325 try 01326 { 01327 #endif 01328 01329 imag_ind_ 01330 = reinterpret_cast<int*>( realloc(imag_ind_, 01331 imag_nz*sizeof(int)) ); 01332 01333 #ifdef SELDON_CHECK_MEMORY 01334 } 01335 catch (...) 01336 { 01337 this->m_ = 0; 01338 this->n_ = 0; 01339 real_nz_ = 0; 01340 imag_nz_ = 0; 01341 free(real_ptr_); 01342 free(imag_ptr_); 01343 real_ptr_ = NULL; 01344 imag_ptr_ = NULL; 01345 free(imag_ind_); 01346 real_ind_ = NULL; 01347 imag_ind_ = NULL; 01348 this->real_data_ = NULL; 01349 this->imag_data_ = NULL; 01350 } 01351 if (real_ind_ == NULL) 01352 { 01353 this->m_ = 0; 01354 this->n_ = 0; 01355 real_nz_ = 0; 01356 imag_nz_ = 0; 01357 free(real_ptr_); 01358 free(imag_ptr_); 01359 real_ptr_ = NULL; 01360 imag_ptr_ = NULL; 01361 free(imag_ind_); 01362 imag_ind_ = NULL; 01363 this->real_data_ = NULL; 01364 this->imag_data_ = NULL; 01365 } 01366 if (imag_ind_ == NULL && i != 0 && j != 0) 01367 throw NoMemory(string("Matrix_SymComplexSparse::") 01368 + "Resize(int, int, int, int)", 01369 string("Unable to allocate ") 01370 + to_str(sizeof(int) * imag_nz) 01371 + " bytes to store " + to_str(imag_nz) 01372 + " row or column indices (imaginary part), for a " 01373 + to_str(i) + " by " + to_str(j) + " matrix."); 01374 #endif 01375 } 01376 01377 if (real_nz != real_nz_) 01378 { 01379 Vector<T, VectFull, Allocator> val; 01380 val.SetData(real_nz_, real_data_); 01381 val.Resize(real_nz); 01382 01383 real_data_ = val.GetData(); 01384 val.Nullify(); 01385 } 01386 01387 if (imag_nz != imag_nz_) 01388 { 01389 Vector<T, VectFull, Allocator> val; 01390 val.SetData(imag_nz_, imag_data_); 01391 val.Resize(imag_nz); 01392 01393 imag_data_ = val.GetData(); 01394 val.Nullify(); 01395 } 01396 01397 // then filing last values of ptr_ with nz_ 01398 for (int k = this->m_; k <= i; k++) 01399 { 01400 real_ptr_[k] = real_nz_; 01401 imag_ptr_[k] = imag_nz_; 01402 } 01403 01404 this->m_ = i; 01405 this->n_ = i; 01406 real_nz_ = real_nz; 01407 imag_nz_ = imag_nz; 01408 } 01409 01410 01412 template <class T, class Prop, class Storage, class Allocator> 01413 inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>:: 01414 Copy(const Matrix_SymComplexSparse<T, Prop, Storage, Allocator>& A) 01415 { 01416 this->Clear(); 01417 int i = A.m_; 01418 int j = A.n_; 01419 real_nz_ = A.real_nz_; 01420 imag_nz_ = A.imag_nz_; 01421 this->m_ = i; 01422 this->n_ = j; 01423 if ((i == 0)||(j == 0)) 01424 { 01425 this->m_ = 0; 01426 this->n_ = 0; 01427 this->real_nz_ = 0; 01428 this->imag_nz_ = 0; 01429 return; 01430 } 01431 01432 #ifdef SELDON_CHECK_DIMENSIONS 01433 if ( (static_cast<long int>(2 * real_nz_ - 2) / static_cast<long int>(i+1) 01434 >= static_cast<long int>(i)) || 01435 (static_cast<long int>(2 * imag_nz_ - 2) / static_cast<long int>(i+1) 01436 >= static_cast<long int>(i)) ) 01437 { 01438 this->m_ = 0; 01439 this->n_ = 0; 01440 real_nz_ = 0; 01441 imag_nz_ = 0; 01442 real_ptr_ = NULL; 01443 imag_ptr_ = NULL; 01444 real_ind_ = NULL; 01445 imag_ind_ = NULL; 01446 this->real_data_ = NULL; 01447 this->imag_data_ = NULL; 01448 throw WrongDim(string("Matrix_SymComplexSparse::") 01449 + "Matrix_SymComplexSparse(int, int, int, int)", 01450 string("There are more values to be stored (") 01451 + to_str(real_nz_) + " values for the real part and " 01452 + to_str(imag_nz_) + string(" values for the imaginary") 01453 + " part) than elements in the matrix (" 01454 + to_str(i) + " by " + to_str(j) + ")."); 01455 } 01456 #endif 01457 01458 #ifdef SELDON_CHECK_MEMORY 01459 try 01460 { 01461 #endif 01462 01463 real_ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) ); 01464 memcpy(this->real_ptr_, A.real_ptr_, (i + 1) * sizeof(int)); 01465 01466 #ifdef SELDON_CHECK_MEMORY 01467 } 01468 catch (...) 01469 { 01470 this->m_ = 0; 01471 this->n_ = 0; 01472 real_nz_ = 0; 01473 imag_nz_ = 0; 01474 real_ptr_ = NULL; 01475 imag_ptr_ = NULL; 01476 real_ind_ = NULL; 01477 imag_ind_ = NULL; 01478 this->real_data_ = NULL; 01479 this->imag_data_ = NULL; 01480 } 01481 if (real_ptr_ == NULL) 01482 { 01483 this->m_ = 0; 01484 this->n_ = 0; 01485 real_nz_ = 0; 01486 imag_nz_ = 0; 01487 imag_ptr_ = 0; 01488 real_ind_ = NULL; 01489 imag_ind_ = NULL; 01490 this->real_data_ = NULL; 01491 this->imag_data_ = NULL; 01492 } 01493 if (real_ptr_ == NULL && i != 0) 01494 throw NoMemory(string("Matrix_SymComplexSparse::") 01495 + "Matrix_SymComplexSparse(int, int, int, int)", 01496 string("Unable to allocate ") 01497 + to_str(sizeof(int) * (i + 1)) + " bytes to store " 01498 + to_str(i + 1) + string(" row or column") 01499 + " start indices (for the real part), for a " 01500 + to_str(i) + " by " + to_str(i) + " matrix."); 01501 #endif 01502 01503 #ifdef SELDON_CHECK_MEMORY 01504 try 01505 { 01506 #endif 01507 01508 imag_ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) ); 01509 memcpy(this->imag_ptr_, A.imag_ptr_, (i + 1) * sizeof(int)); 01510 01511 #ifdef SELDON_CHECK_MEMORY 01512 } 01513 catch (...) 01514 { 01515 this->m_ = 0; 01516 this->n_ = 0; 01517 real_nz_ = 0; 01518 imag_nz_ = 0; 01519 free(real_ptr_); 01520 real_ptr_ = NULL; 01521 imag_ptr_ = NULL; 01522 real_ind_ = NULL; 01523 imag_ind_ = NULL; 01524 this->real_data_ = NULL; 01525 this->imag_data_ = NULL; 01526 } 01527 if (imag_ptr_ == NULL) 01528 { 01529 this->m_ = 0; 01530 this->n_ = 0; 01531 real_nz_ = 0; 01532 imag_nz_ = 0; 01533 free(real_ptr_); 01534 real_ptr_ = 0; 01535 real_ind_ = NULL; 01536 imag_ind_ = NULL; 01537 this->real_data_ = NULL; 01538 this->imag_data_ = NULL; 01539 } 01540 if (imag_ptr_ == NULL && i != 0) 01541 throw NoMemory(string("Matrix_SymComplexSparse::") 01542 + "Matrix_SymComplexSparse(int, int, int, int)", 01543 string("Unable to allocate ") 01544 + to_str(sizeof(int) * (i + 1) ) + " bytes to store " 01545 + to_str(i + 1) + string(" row or column") 01546 + " start indices (for the imaginary part), for a " 01547 + to_str(i) + " by " + to_str(i) + " matrix."); 01548 #endif 01549 01550 #ifdef SELDON_CHECK_MEMORY 01551 try 01552 { 01553 #endif 01554 01555 real_ind_ = reinterpret_cast<int*>( calloc(real_nz_, sizeof(int)) ); 01556 memcpy(this->real_ind_, A.real_ind_, real_nz_ * sizeof(int)); 01557 01558 #ifdef SELDON_CHECK_MEMORY 01559 } 01560 catch (...) 01561 { 01562 this->m_ = 0; 01563 this->n_ = 0; 01564 real_nz_ = 0; 01565 imag_nz_ = 0; 01566 free(real_ptr_); 01567 free(imag_ptr_); 01568 real_ptr_ = NULL; 01569 imag_ptr_ = NULL; 01570 real_ind_ = NULL; 01571 imag_ind_ = NULL; 01572 this->real_data_ = NULL; 01573 this->imag_data_ = NULL; 01574 } 01575 if (real_ind_ == NULL) 01576 { 01577 this->m_ = 0; 01578 this->n_ = 0; 01579 real_nz_ = 0; 01580 imag_nz_ = 0; 01581 free(real_ptr_); 01582 free(imag_ptr_); 01583 real_ptr_ = NULL; 01584 imag_ptr_ = NULL; 01585 this->real_data_ = NULL; 01586 this->imag_data_ = NULL; 01587 } 01588 if (real_ind_ == NULL && i != 0) 01589 throw NoMemory(string("Matrix_SymComplexSparse::") 01590 + "Matrix_SymComplexSparse(int, int, int, int)", 01591 string("Unable to allocate ") 01592 + to_str(sizeof(int) * real_nz_) + " bytes to store " 01593 + to_str(real_nz_) 01594 + " row or column indices (real part), for a " 01595 + to_str(i) + " by " + to_str(i) + " matrix."); 01596 #endif 01597 01598 #ifdef SELDON_CHECK_MEMORY 01599 try 01600 { 01601 #endif 01602 01603 imag_ind_ = reinterpret_cast<int*>( calloc(imag_nz_, sizeof(int)) ); 01604 memcpy(this->imag_ind_, A.imag_ind_, imag_nz_ * sizeof(int)); 01605 01606 #ifdef SELDON_CHECK_MEMORY 01607 } 01608 catch (...) 01609 { 01610 this->m_ = 0; 01611 this->n_ = 0; 01612 real_nz_ = 0; 01613 imag_nz_ = 0; 01614 free(real_ptr_); 01615 free(imag_ptr_); 01616 real_ptr_ = NULL; 01617 imag_ptr_ = NULL; 01618 free(imag_ind_); 01619 real_ind_ = NULL; 01620 imag_ind_ = NULL; 01621 this->real_data_ = NULL; 01622 this->imag_data_ = NULL; 01623 } 01624 if (real_ind_ == NULL) 01625 { 01626 this->m_ = 0; 01627 this->n_ = 0; 01628 real_nz_ = 0; 01629 imag_nz_ = 0; 01630 free(real_ptr_); 01631 free(imag_ptr_); 01632 real_ptr_ = NULL; 01633 imag_ptr_ = NULL; 01634 free(imag_ind_); 01635 imag_ind_ = NULL; 01636 this->real_data_ = NULL; 01637 this->imag_data_ = NULL; 01638 } 01639 if (imag_ind_ == NULL && i != 0) 01640 throw NoMemory(string("Matrix_SymComplexSparse::") 01641 + "Matrix_SymComplexSparse(int, int, int, int)", 01642 string("Unable to allocate ") 01643 + to_str(sizeof(int) * imag_nz_) + " bytes to store " 01644 + to_str(imag_nz_) 01645 + " row or column indices (imaginary part), for a " 01646 + to_str(i) + " by " + to_str(i) + " matrix."); 01647 #endif 01648 01649 #ifdef SELDON_CHECK_MEMORY 01650 try 01651 { 01652 #endif 01653 01654 this->real_data_ = this->allocator_.allocate(real_nz_, this); 01655 this->allocator_.memorycpy(this->real_data_, A.real_data_, real_nz_); 01656 01657 #ifdef SELDON_CHECK_MEMORY 01658 } 01659 catch (...) 01660 { 01661 this->m_ = 0; 01662 this->n_ = 0; 01663 free(real_ptr_); 01664 free(imag_ptr_); 01665 real_ptr_ = NULL; 01666 imag_ptr_ = NULL; 01667 free(real_ind_); 01668 free(imag_ind_); 01669 real_ind_ = NULL; 01670 imag_ind_ = NULL; 01671 this->real_data_ = NULL; 01672 this->imag_data_ = NULL; 01673 } 01674 if (real_data_ == NULL) 01675 { 01676 this->m_ = 0; 01677 this->n_ = 0; 01678 free(real_ptr_); 01679 free(imag_ptr_); 01680 real_ptr_ = NULL; 01681 imag_ptr_ = NULL; 01682 free(real_ind_); 01683 free(imag_ind_); 01684 real_ind_ = NULL; 01685 imag_ind_ = NULL; 01686 imag_data_ = NULL; 01687 } 01688 if (real_data_ == NULL && i != 0) 01689 throw NoMemory(string("Matrix_SymComplexSparse::") 01690 + "Matrix_SymComplexSparse(int, int, int, int)", 01691 string("Unable to allocate ") 01692 + to_str(sizeof(int) * real_nz_) + " bytes to store " 01693 + to_str(real_nz_) + " values (real part), for a " 01694 + to_str(i) + " by " + to_str(i) + " matrix."); 01695 #endif 01696 01697 #ifdef SELDON_CHECK_MEMORY 01698 try 01699 { 01700 #endif 01701 01702 this->imag_data_ = this->allocator_.allocate(imag_nz_, this); 01703 this->allocator_.memorycpy(this->imag_data_, A.imag_data_, imag_nz_); 01704 01705 #ifdef SELDON_CHECK_MEMORY 01706 } 01707 catch (...) 01708 { 01709 this->m_ = 0; 01710 this->n_ = 0; 01711 free(real_ptr_); 01712 free(imag_ptr_); 01713 real_ptr_ = NULL; 01714 imag_ptr_ = NULL; 01715 free(real_ind_); 01716 free(imag_ind_); 01717 real_ind_ = NULL; 01718 imag_ind_ = NULL; 01719 this->allocator_.deallocate(this->real_data_, real_nz_); 01720 this->real_data_ = NULL; 01721 this->imag_data_ = NULL; 01722 } 01723 if (real_data_ == NULL) 01724 { 01725 this->m_ = 0; 01726 this->n_ = 0; 01727 free(real_ptr_); 01728 free(imag_ptr_); 01729 real_ptr_ = NULL; 01730 imag_ptr_ = NULL; 01731 free(real_ind_); 01732 free(imag_ind_); 01733 real_ind_ = NULL; 01734 imag_ind_ = NULL; 01735 this->allocator_.deallocate(this->real_data_, real_nz_); 01736 real_data_ = NULL; 01737 } 01738 if (imag_data_ == NULL && i != 0) 01739 throw NoMemory(string("Matrix_SymComplexSparse::") 01740 + "Matrix_SymComplexSparse(int, int, int, int)", 01741 string("Unable to allocate ") 01742 + to_str(sizeof(int) * imag_nz_) + " bytes to store " 01743 + to_str(imag_nz_) + " values (imaginary part), for a " 01744 + to_str(i) + " by " + to_str(i) + " matrix."); 01745 #endif 01746 01747 } 01748 01749 01750 /******************* 01751 * BASIC FUNCTIONS * 01752 *******************/ 01753 01754 01756 01762 template <class T, class Prop, class Storage, class Allocator> 01763 int Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01764 ::GetDataSize() const 01765 { 01766 return real_nz_ + imag_nz_; 01767 } 01768 01769 01771 01775 template <class T, class Prop, class Storage, class Allocator> 01776 int* Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01777 ::GetRealPtr() const 01778 { 01779 return real_ptr_; 01780 } 01781 01782 01784 01788 template <class T, class Prop, class Storage, class Allocator> 01789 int* Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01790 ::GetImagPtr() const 01791 { 01792 return imag_ptr_; 01793 } 01794 01795 01797 01804 template <class T, class Prop, class Storage, class Allocator> 01805 int* Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01806 ::GetRealInd() const 01807 { 01808 return real_ind_; 01809 } 01810 01811 01814 01821 template <class T, class Prop, class Storage, class Allocator> 01822 int* Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01823 ::GetImagInd() const 01824 { 01825 return imag_ind_; 01826 } 01827 01828 01830 01833 template <class T, class Prop, class Storage, class Allocator> 01834 int Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01835 ::GetRealPtrSize() const 01836 { 01837 return (this->m_ + 1); 01838 } 01839 01840 01842 01845 template <class T, class Prop, class Storage, class Allocator> 01846 int Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01847 ::GetImagPtrSize() const 01848 { 01849 return (this->m_ + 1); 01850 } 01851 01852 01855 01865 template <class T, class Prop, class Storage, class Allocator> 01866 int Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01867 ::GetRealIndSize() const 01868 { 01869 return real_nz_; 01870 } 01871 01872 01875 01885 template <class T, class Prop, class Storage, class Allocator> 01886 int Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01887 ::GetImagIndSize() const 01888 { 01889 return imag_nz_; 01890 } 01891 01892 01895 01905 template <class T, class Prop, class Storage, class Allocator> 01906 int Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01907 ::GetRealDataSize() const 01908 { 01909 return real_nz_; 01910 } 01911 01912 01915 01925 template <class T, class Prop, class Storage, class Allocator> 01926 int Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01927 ::GetImagDataSize() const 01928 { 01929 return imag_nz_; 01930 } 01931 01932 01934 01937 template <class T, class Prop, class Storage, class Allocator> 01938 T* Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::GetRealData() const 01939 { 01940 return real_data_; 01941 } 01942 01943 01945 01948 template <class T, class Prop, class Storage, class Allocator> 01949 T* Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::GetImagData() const 01950 { 01951 return imag_data_; 01952 } 01953 01954 01955 /********************************** 01956 * ELEMENT ACCESS AND AFFECTATION * 01957 **********************************/ 01958 01959 01961 01967 template <class T, class Prop, class Storage, class Allocator> 01968 inline complex<typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01969 ::value_type> 01970 Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 01971 ::operator() (int i, int j) const 01972 { 01973 01974 #ifdef SELDON_CHECK_BOUNDS 01975 if (i < 0 || i >= this->m_) 01976 throw WrongRow("Matrix_SymComplexSparse::operator()", 01977 string("Index should be in [0, ") + to_str(this->m_-1) 01978 + "], but is equal to " + to_str(i) + "."); 01979 if (j < 0 || j >= this->n_) 01980 throw WrongCol("Matrix_SymComplexSparse::operator()", 01981 string("Index should be in [0, ") + to_str(this->n_-1) 01982 + "], but is equal to " + to_str(j) + "."); 01983 #endif 01984 01985 int real_k, imag_k, l; 01986 int real_a, real_b; 01987 int imag_a, imag_b; 01988 01989 // Only the upper part is stored. 01990 if (i > j) 01991 { 01992 l = i; 01993 i = j; 01994 j = l; 01995 } 01996 01997 real_a = real_ptr_[Storage::GetFirst(i, j)]; 01998 real_b = real_ptr_[Storage::GetFirst(i, j) + 1]; 01999 02000 imag_a = imag_ptr_[Storage::GetFirst(i, j)]; 02001 imag_b = imag_ptr_[Storage::GetFirst(i, j) + 1]; 02002 02003 if (real_a != real_b) 02004 { 02005 l = Storage::GetSecond(i, j); 02006 for (real_k = real_a; 02007 (real_k < real_b - 1) && (real_ind_[real_k] < l); 02008 real_k++); 02009 if (imag_a != imag_b) 02010 { 02011 for (imag_k = imag_a; 02012 (imag_k < imag_b - 1) && (imag_ind_[imag_k] < l); 02013 imag_k++); 02014 if (real_ind_[real_k] == l) 02015 { 02016 if (imag_ind_[imag_k] == l) 02017 return complex<T>(real_data_[real_k], imag_data_[imag_k]); 02018 else 02019 return complex<T>(real_data_[real_k], T(0)); 02020 } 02021 else 02022 if (imag_ind_[imag_k] == l) 02023 return complex<T>(T(0), imag_data_[imag_k]); 02024 else 02025 return complex<T>(T(0), T(0)); 02026 } 02027 else 02028 { 02029 if (real_ind_[real_k] == l) 02030 return complex<T>(real_data_[real_k], T(0)); 02031 else 02032 return complex<T>(T(0), T(0)); 02033 } 02034 } 02035 else 02036 { 02037 if (imag_a != imag_b) 02038 { 02039 l = Storage::GetSecond(i, j); 02040 for (imag_k = imag_a; 02041 (imag_k < imag_b - 1) && (imag_ind_[imag_k] < l); 02042 imag_k++); 02043 if (imag_ind_[imag_k] == l) 02044 return complex<T>(T(0), imag_data_[imag_k]); 02045 else 02046 return complex<T>(T(0), T(0)); 02047 } 02048 else 02049 return complex<T>(T(0), T(0)); 02050 } 02051 } 02052 02053 02055 02063 template <class T, class Prop, class Storage, class Allocator> 02064 inline typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02065 ::value_type& 02066 Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::ValReal(int i, int j) 02067 { 02068 02069 #ifdef SELDON_CHECK_BOUNDS 02070 if (i < 0 || i >= this->m_) 02071 throw WrongRow("Matrix_SymComplexSparse::ValReal(int, int)", 02072 string("Index should be in [0, ") + to_str(this->m_-1) 02073 + "], but is equal to " + to_str(i) + "."); 02074 if (j < 0 || j >= this->n_) 02075 throw WrongCol("Matrix_SymComplexSparse::ValReal(int, int)", 02076 string("Index should be in [0, ") + to_str(this->n_-1) 02077 + "], but is equal to " + to_str(j) + "."); 02078 #endif 02079 02080 int k, l; 02081 int a, b; 02082 02083 // Only the upper part is stored. 02084 if (i > j) 02085 { 02086 l = i; 02087 i = j; 02088 j = l; 02089 } 02090 02091 a = real_ptr_[Storage::GetFirst(i, j)]; 02092 b = real_ptr_[Storage::GetFirst(i, j) + 1]; 02093 02094 if (a == b) 02095 throw WrongArgument("Matrix_SymComplexSparse::ValReal(int, int)", 02096 "No reference to element (" + to_str(i) + ", " 02097 + to_str(j) 02098 + ") can be returned: it is a zero entry."); 02099 02100 l = Storage::GetSecond(i, j); 02101 02102 for (k = a; (k < b-1) && (real_ind_[k] < l); k++); 02103 02104 if (real_ind_[k] == l) 02105 return this->real_data_[k]; 02106 else 02107 throw WrongArgument("Matrix_SymComplexSparse::ValReal(int, int)", 02108 "No reference to element (" + to_str(i) + ", " 02109 + to_str(j) 02110 + ") can be returned: it is a zero entry."); 02111 } 02112 02113 02115 02123 template <class T, class Prop, class Storage, class Allocator> 02124 inline const typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02125 ::value_type& 02126 Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::ValReal(int i, int j) const 02127 { 02128 02129 #ifdef SELDON_CHECK_BOUNDS 02130 if (i < 0 || i >= this->m_) 02131 throw WrongRow("Matrix_SymComplexSparse::ValReal(int, int)", 02132 string("Index should be in [0, ") + to_str(this->m_-1) 02133 + "], but is equal to " + to_str(i) + "."); 02134 if (j < 0 || j >= this->n_) 02135 throw WrongCol("Matrix_SymComplexSparse::ValReal(int, int)", 02136 string("Index should be in [0, ") + to_str(this->n_-1) 02137 + "], but is equal to " + to_str(j) + "."); 02138 #endif 02139 02140 int k, l; 02141 int a, b; 02142 02143 // Only the upper part is stored. 02144 if (i > j) 02145 { 02146 l = i; 02147 i = j; 02148 j = l; 02149 } 02150 02151 a = real_ptr_[Storage::GetFirst(i, j)]; 02152 b = real_ptr_[Storage::GetFirst(i, j) + 1]; 02153 02154 if (a == b) 02155 throw WrongArgument("Matrix_SymComplexSparse::ValReal(int, int)", 02156 "No reference to element (" + to_str(i) + ", " 02157 + to_str(j) 02158 + ") can be returned: it is a zero entry."); 02159 02160 l = Storage::GetSecond(i, j); 02161 02162 for (k = a; (k < b-1) && (real_ind_[k] < l); k++); 02163 02164 if (real_ind_[k] == l) 02165 return this->real_data_[k]; 02166 else 02167 throw WrongArgument("Matrix_SymComplexSparse::ValReal(int, int)", 02168 "No reference to element (" + to_str(i) + ", " 02169 + to_str(j) 02170 + ") can be returned: it is a zero entry."); 02171 } 02172 02173 02175 02183 template <class T, class Prop, class Storage, class Allocator> 02184 inline typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02185 ::value_type& 02186 Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::ValImag(int i, int j) 02187 { 02188 02189 #ifdef SELDON_CHECK_BOUNDS 02190 if (i < 0 || i >= this->m_) 02191 throw WrongRow("Matrix_SymComplexSparse::ValImag(int, int)", 02192 string("Index should be in [0, ") + to_str(this->m_-1) 02193 + "], but is equal to " + to_str(i) + "."); 02194 if (j < 0 || j >= this->n_) 02195 throw WrongCol("Matrix_SymComplexSparse::ValImag(int, int)", 02196 string("Index should be in [0, ") + to_str(this->n_-1) 02197 + "], but is equal to " + to_str(j) + "."); 02198 #endif 02199 02200 int k, l; 02201 int a, b; 02202 02203 // Only the upper part is stored. 02204 if (i > j) 02205 { 02206 l = i; 02207 i = j; 02208 j = l; 02209 } 02210 02211 a = imag_ptr_[Storage::GetFirst(i, j)]; 02212 b = imag_ptr_[Storage::GetFirst(i, j) + 1]; 02213 02214 if (a == b) 02215 throw WrongArgument("Matrix_SymComplexSparse::ValImag(int, int)", 02216 "No reference to element (" + to_str(i) + ", " 02217 + to_str(j) 02218 + ") can be returned: it is a zero entry."); 02219 02220 l = Storage::GetSecond(i, j); 02221 02222 for (k = a; (k < b-1) && (imag_ind_[k] < l); k++); 02223 02224 if (imag_ind_[k] == l) 02225 return this->imag_data_[k]; 02226 else 02227 throw WrongArgument("Matrix_SymComplexSparse::ValImag(int, int)", 02228 "No reference to element (" + to_str(i) + ", " 02229 + to_str(j) 02230 + ") can be returned: it is a zero entry."); 02231 } 02232 02233 02235 02243 template <class T, class Prop, class Storage, class Allocator> 02244 inline const typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02245 ::value_type& 02246 Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::ValImag(int i, int j) const 02247 { 02248 02249 #ifdef SELDON_CHECK_BOUNDS 02250 if (i < 0 || i >= this->m_) 02251 throw WrongRow("Matrix_SymComplexSparse::ValImag(int, int)", 02252 string("Index should be in [0, ") + to_str(this->m_-1) 02253 + "], but is equal to " + to_str(i) + "."); 02254 if (j < 0 || j >= this->n_) 02255 throw WrongCol("Matrix_SymComplexSparse::ValImag(int, int)", 02256 string("Index should be in [0, ") + to_str(this->n_-1) 02257 + "], but is equal to " + to_str(j) + "."); 02258 #endif 02259 02260 int k, l; 02261 int a, b; 02262 02263 // Only the upper part is stored. 02264 if (i > j) 02265 { 02266 l = i; 02267 i = j; 02268 j = l; 02269 } 02270 02271 a = imag_ptr_[Storage::GetFirst(i, j)]; 02272 b = imag_ptr_[Storage::GetFirst(i, j) + 1]; 02273 02274 if (a == b) 02275 throw WrongArgument("Matrix_SymComplexSparse::ValImag(int, int)", 02276 "No reference to element (" + to_str(i) + ", " 02277 + to_str(j) 02278 + ") can be returned: it is a zero entry."); 02279 02280 l = Storage::GetSecond(i, j); 02281 02282 for (k = a; (k < b-1) && (imag_ind_[k] < l); k++); 02283 02284 if (imag_ind_[k] == l) 02285 return this->imag_data_[k]; 02286 else 02287 throw WrongArgument("Matrix_SymComplexSparse::ValImag(int, int)", 02288 "No reference to element (" + to_str(i) + ", " 02289 + to_str(j) 02290 + ") can be returned: it is a zero entry."); 02291 } 02292 02293 02295 02302 template <class T, class Prop, class Storage, class Allocator> 02303 inline typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02304 ::value_type& 02305 Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::GetReal(int i, int j) 02306 { 02307 02308 #ifdef SELDON_CHECK_BOUNDS 02309 if (i < 0 || i >= this->m_) 02310 throw WrongRow("Matrix_SymComplexSparse::GetReal(int, int)", 02311 string("Index should be in [0, ") + to_str(this->m_-1) 02312 + "], but is equal to " + to_str(i) + "."); 02313 if (j < 0 || j >= this->n_) 02314 throw WrongCol("Matrix_SymComplexSparse::GetReal(int, int)", 02315 string("Index should be in [0, ") + to_str(this->n_-1) 02316 + "], but is equal to " + to_str(j) + "."); 02317 #endif 02318 02319 int k, l; 02320 int a, b; 02321 02322 // Only the upper part is stored. 02323 if (i > j) 02324 { 02325 l = i; 02326 i = j; 02327 j = l; 02328 } 02329 02330 a = real_ptr_[Storage::GetFirst(i, j)]; 02331 b = real_ptr_[Storage::GetFirst(i, j) + 1]; 02332 02333 if (a < b) 02334 { 02335 l = Storage::GetSecond(i, j); 02336 02337 for (k = a; (k < b) && (real_ind_[k] < l); k++); 02338 02339 if ( (k < b) && (real_ind_[k] == l)) 02340 return this->real_data_[k]; 02341 } 02342 else 02343 k = a; 02344 02345 // adding a non-zero entry 02346 Resize(this->m_, this->n_, real_nz_+1, imag_nz_); 02347 02348 for (int m = Storage::GetFirst(i, j)+1; 02349 m <= Storage::GetFirst(this->m_, this->n_); m++) 02350 real_ptr_[m]++; 02351 02352 for (int m = real_nz_-1; m >= k+1; m--) 02353 { 02354 real_ind_[m] = real_ind_[m-1]; 02355 this->real_data_[m] = this->real_data_[m-1]; 02356 } 02357 02358 real_ind_[k] = Storage::GetSecond(i, j); 02359 02360 // value of new non-zero entry is set to 0 02361 SetComplexZero(this->real_data_[k]); 02362 02363 return this->real_data_[k]; 02364 } 02365 02366 02368 02375 template <class T, class Prop, class Storage, class Allocator> 02376 inline const typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02377 ::value_type& 02378 Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::GetReal(int i, int j) const 02379 { 02380 return ValReal(i, j); 02381 } 02382 02383 02385 02392 template <class T, class Prop, class Storage, class Allocator> 02393 inline typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02394 ::value_type& 02395 Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::GetImag(int i, int j) 02396 { 02397 02398 #ifdef SELDON_CHECK_BOUNDS 02399 if (i < 0 || i >= this->m_) 02400 throw WrongRow("Matrix_SymComplexSparse::GetImag(int, int)", 02401 string("Index should be in [0, ") + to_str(this->m_-1) 02402 + "], but is equal to " + to_str(i) + "."); 02403 if (j < 0 || j >= this->n_) 02404 throw WrongCol("Matrix_SymComplexSparse::GetImag(int, int)", 02405 string("Index should be in [0, ") + to_str(this->n_-1) 02406 + "], but is equal to " + to_str(j) + "."); 02407 #endif 02408 02409 int k, l; 02410 int a, b; 02411 02412 // Only the upper part is stored. 02413 if (i > j) 02414 { 02415 l = i; 02416 i = j; 02417 j = l; 02418 } 02419 02420 a = imag_ptr_[Storage::GetFirst(i, j)]; 02421 b = imag_ptr_[Storage::GetFirst(i, j) + 1]; 02422 02423 if (a < b) 02424 { 02425 l = Storage::GetSecond(i, j); 02426 02427 for (k = a; (k < b) && (imag_ind_[k] < l); k++); 02428 02429 if ( (k < b) && (imag_ind_[k] == l)) 02430 return this->imag_data_[k]; 02431 } 02432 else 02433 k = a; 02434 02435 // adding a non-zero entry 02436 Resize(this->m_, this->n_, real_nz_, imag_nz_+1); 02437 02438 for (int m = Storage::GetFirst(i, j)+1; 02439 m <= Storage::GetFirst(this->m_, this->n_); m++) 02440 imag_ptr_[m]++; 02441 02442 for (int m = imag_nz_-1; m >= k+1; m--) 02443 { 02444 imag_ind_[m] = imag_ind_[m-1]; 02445 this->imag_data_[m] = this->imag_data_[m-1]; 02446 } 02447 02448 imag_ind_[k] = Storage::GetSecond(i, j); 02449 02450 // value of new non-zero entry is set to 0 02451 SetComplexZero(this->imag_data_[k]); 02452 02453 return this->imag_data_[k]; 02454 } 02455 02456 02458 02465 template <class T, class Prop, class Storage, class Allocator> 02466 inline const typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02467 ::value_type& 02468 Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::GetImag(int i, int j) const 02469 { 02470 return ValImag(i, j); 02471 } 02472 02473 02475 02482 template <class T, class Prop, class Storage, class Allocator> 02483 inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02484 ::AddInteraction(int i, int j, const complex<T>& val) 02485 { 02486 if (i <= j) 02487 { 02488 if (real(val) != T(0)) 02489 GetReal(i, j) += real(val); 02490 02491 if (imag(val) != T(0)) 02492 GetImag(i, j) += imag(val); 02493 } 02494 } 02495 02496 02498 02503 template <class T, class Prop, class Storage, class Allocator> 02504 inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02505 ::Set(int i, int j, const complex<T>& val) 02506 { 02507 GetReal(i, j) = real(val); 02508 GetImag(i, j) = imag(val); 02509 } 02510 02511 02513 02518 template <class T, class Prop, class Storage, class Allocator> 02519 inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator>& 02520 Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02521 ::operator= (const Matrix_SymComplexSparse<T, Prop, Storage, Allocator>& A) 02522 { 02523 this->Copy(A); 02524 02525 return *this; 02526 } 02527 02528 02529 /************************ 02530 * CONVENIENT FUNCTIONS * 02531 ************************/ 02532 02533 02535 02536 template <class T, class Prop, class Storage, class Allocator> 02537 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::Zero() 02538 { 02539 this->allocator_.memoryset(this->real_data_, char(0), 02540 this->real_nz_ * sizeof(value_type)); 02541 02542 this->allocator_.memoryset(this->imag_data_, char(0), 02543 this->imag_nz_ * sizeof(value_type)); 02544 } 02545 02546 02548 02550 template <class T, class Prop, class Storage, class Allocator> 02551 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::SetIdentity() 02552 { 02553 int m = this->m_; 02554 int n = this->n_; 02555 int nz = min(m, n); 02556 02557 if (nz == 0) 02558 return; 02559 02560 Clear(); 02561 02562 Vector<T, VectFull, Allocator> real_values(nz), imag_values; 02563 Vector<int, VectFull, CallocAlloc<int> > real_ptr(m + 1); 02564 Vector<int, VectFull, CallocAlloc<int> > real_ind(nz); 02565 Vector<int, VectFull, CallocAlloc<int> > imag_ptr(real_ptr); 02566 Vector<int, VectFull, CallocAlloc<int> > imag_ind; 02567 02568 real_values.Fill(T(1)); 02569 real_ind.Fill(); 02570 imag_ind.Zero(); 02571 real_ptr.Fill(); 02572 02573 SetData(m, n, real_values, real_ptr, real_ind, 02574 imag_values, imag_ptr, imag_ind); 02575 } 02576 02577 02579 02582 template <class T, class Prop, class Storage, class Allocator> 02583 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::Fill() 02584 { 02585 for (int i = 0; i < this->real_nz_; i++) 02586 this->real_data_[i] = i; 02587 02588 for (int i = 0; i < this->imag_nz_; i++) 02589 this->imag_data_[i] = T(0); 02590 } 02591 02592 02594 02597 template <class T, class Prop, class Storage, class Allocator> 02598 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02599 ::Fill(const complex<T>& x) 02600 { 02601 for (int i = 0; i < this->real_nz_; i++) 02602 this->real_data_[i] = real(x); 02603 02604 for (int i = 0; i < this->imag_nz_; i++) 02605 this->imag_data_[i] = imag(x); 02606 } 02607 02608 02610 02613 template <class T, class Prop, class Storage, class Allocator> 02614 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::FillRand() 02615 { 02616 srand(time(NULL)); 02617 for (int i = 0; i < this->real_nz_; i++) 02618 this->real_data_[i] = rand(); 02619 02620 for (int i = 0; i < this->imag_nz_; i++) 02621 this->imag_data_[i] = rand(); 02622 } 02623 02624 02626 02631 template <class T, class Prop, class Storage, class Allocator> 02632 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::Print() const 02633 { 02634 for (int i = 0; i < this->m_; i++) 02635 { 02636 for (int j = 0; j < this->n_; j++) 02637 cout << (*this)(i, j) << "\t"; 02638 cout << endl; 02639 } 02640 } 02641 02642 02644 02648 template <class T, class Prop, class Storage, class Allocator> 02649 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02650 ::Write(string FileName) const 02651 { 02652 ofstream FileStream; 02653 FileStream.open(FileName.c_str()); 02654 02655 #ifdef SELDON_CHECK_IO 02656 // Checks if the file was opened. 02657 if (!FileStream.is_open()) 02658 throw IOError("Matrix_SymComplexSparse::Write(string FileName)", 02659 string("Unable to open file \"") + FileName + "\"."); 02660 #endif 02661 02662 this->Write(FileStream); 02663 02664 FileStream.close(); 02665 } 02666 02667 02669 02673 template <class T, class Prop, class Storage, class Allocator> 02674 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02675 ::Write(ostream& FileStream) const 02676 { 02677 #ifdef SELDON_CHECK_IO 02678 // Checks if the stream is ready. 02679 if (!FileStream.good()) 02680 throw IOError("Matrix_SymComplexSparse::Write(ofstream& FileStream)", 02681 "Stream is not ready."); 02682 #endif 02683 02684 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)), 02685 sizeof(int)); 02686 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)), 02687 sizeof(int)); 02688 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->real_nz_)), 02689 sizeof(int)); 02690 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->imag_nz_)), 02691 sizeof(int)); 02692 02693 FileStream.write(reinterpret_cast<char*>(this->real_ptr_), 02694 sizeof(int)*(Storage::GetFirst(this->m_, this->n_)+1)); 02695 FileStream.write(reinterpret_cast<char*>(this->real_ind_), 02696 sizeof(int)*this->real_nz_); 02697 FileStream.write(reinterpret_cast<char*>(this->real_data_), 02698 sizeof(T)*this->real_nz_); 02699 02700 FileStream.write(reinterpret_cast<char*>(this->imag_ptr_), 02701 sizeof(int)*(Storage::GetFirst(this->m_, this->n_)+1)); 02702 FileStream.write(reinterpret_cast<char*>(this->imag_ind_), 02703 sizeof(int)*this->imag_nz_); 02704 FileStream.write(reinterpret_cast<char*>(this->imag_data_), 02705 sizeof(T)*this->imag_nz_); 02706 } 02707 02708 02710 02716 template <class T, class Prop, class Storage, class Allocator> 02717 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>:: 02718 WriteText(string FileName) const 02719 { 02720 ofstream FileStream; FileStream.precision(14); 02721 FileStream.open(FileName.c_str()); 02722 02723 #ifdef SELDON_CHECK_IO 02724 // Checks if the file was opened. 02725 if (!FileStream.is_open()) 02726 throw IOError("Matrix_SymComplexSparse::Write(string FileName)", 02727 string("Unable to open file \"") + FileName + "\"."); 02728 #endif 02729 02730 this->WriteText(FileStream); 02731 02732 FileStream.close(); 02733 } 02734 02735 02737 02743 template <class T, class Prop, class Storage, class Allocator> 02744 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>:: 02745 WriteText(ostream& FileStream) const 02746 { 02747 02748 #ifdef SELDON_CHECK_IO 02749 // Checks if the stream is ready. 02750 if (!FileStream.good()) 02751 throw IOError("Matrix_SymComplexSparse::Write(ofstream& FileStream)", 02752 "Stream is not ready."); 02753 #endif 02754 02755 // conversion in coordinate format (1-index convention) 02756 IVect IndRow, IndCol; Vector<complex<T> > Value; 02757 const Matrix<T, Prop, Storage, Allocator>& leaf_class = 02758 static_cast<const Matrix<T, Prop, Storage, Allocator>& >(*this); 02759 02760 ConvertMatrix_to_Coordinates(leaf_class, IndRow, IndCol, 02761 Value, 1, true); 02762 02763 for (int i = 0; i < IndRow.GetM(); i++) 02764 FileStream << IndRow(i) << " " << IndCol(i) << " " << Value(i) << '\n'; 02765 02766 } 02767 02768 02770 02774 template <class T, class Prop, class Storage, class Allocator> 02775 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>:: 02776 Read(string FileName) 02777 { 02778 ifstream FileStream; 02779 FileStream.open(FileName.c_str()); 02780 02781 #ifdef SELDON_CHECK_IO 02782 // Checks if the file was opened. 02783 if (!FileStream.is_open()) 02784 throw IOError("Matrix_SymComplexSparse::Read(string FileName)", 02785 string("Unable to open file \"") + FileName + "\"."); 02786 #endif 02787 02788 this->Read(FileStream); 02789 02790 FileStream.close(); 02791 } 02792 02793 02795 02799 template <class T, class Prop, class Storage, class Allocator> 02800 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02801 ::Read(istream& FileStream) 02802 { 02803 02804 #ifdef SELDON_CHECK_IO 02805 // Checks if the stream is ready. 02806 if (!FileStream.good()) 02807 throw IOError("Matrix_SymComplexSparse::Read(istream& FileStream)", 02808 "Stream is not ready."); 02809 #endif 02810 02811 int m, n, real_nz, imag_nz; 02812 FileStream.read(reinterpret_cast<char*>(&m), sizeof(int)); 02813 FileStream.read(reinterpret_cast<char*>(&n), sizeof(int)); 02814 FileStream.read(reinterpret_cast<char*>(&real_nz), sizeof(int)); 02815 FileStream.read(reinterpret_cast<char*>(&imag_nz), sizeof(int)); 02816 02817 Reallocate(m, n, real_nz, imag_nz); 02818 02819 FileStream.read(reinterpret_cast<char*>(real_ptr_), 02820 sizeof(int)*(Storage::GetFirst(m, n)+1)); 02821 FileStream.read(reinterpret_cast<char*>(real_ind_), sizeof(int)*real_nz); 02822 FileStream.read(reinterpret_cast<char*>(this->real_data_), sizeof(T)*real_nz); 02823 02824 FileStream.read(reinterpret_cast<char*>(imag_ptr_), 02825 sizeof(int)*(Storage::GetFirst(m, n)+1)); 02826 FileStream.read(reinterpret_cast<char*>(imag_ind_), sizeof(int)*imag_nz); 02827 FileStream.read(reinterpret_cast<char*>(this->imag_data_), sizeof(T)*imag_nz); 02828 02829 #ifdef SELDON_CHECK_IO 02830 // Checks if data was read. 02831 if (!FileStream.good()) 02832 throw IOError("Matrix_SymComplexSparse::Read(istream& FileStream)", 02833 string("Input operation failed.") 02834 + string(" The input file may have been removed") 02835 + " or may not contain enough data."); 02836 #endif 02837 02838 } 02839 02840 02842 02846 template <class T, class Prop, class Storage, class Allocator> 02847 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02848 ::ReadText(string FileName) 02849 { 02850 ifstream FileStream; 02851 FileStream.open(FileName.c_str()); 02852 02853 #ifdef SELDON_CHECK_IO 02854 // Checks if the file was opened. 02855 if (!FileStream.is_open()) 02856 throw IOError("Matrix_SymComplexSparse::ReadText(string FileName)", 02857 string("Unable to open file \"") + FileName + "\"."); 02858 #endif 02859 02860 this->ReadText(FileStream); 02861 02862 FileStream.close(); 02863 } 02864 02865 02867 02871 template <class T, class Prop, class Storage, class Allocator> 02872 void Matrix_SymComplexSparse<T, Prop, Storage, Allocator> 02873 ::ReadText(istream& FileStream) 02874 { 02875 Matrix<T, Prop, Storage, Allocator>& leaf_class = 02876 static_cast<Matrix<T, Prop, Storage, Allocator>& >(*this); 02877 02878 complex<T> zero; int index = 1; 02879 ReadCoordinateMatrix(leaf_class, FileStream, zero, index); 02880 } 02881 02882 02884 // MATRIX<COLSYMCOMPLEXSPARSE> // 02886 02887 02888 /**************** 02889 * CONSTRUCTORS * 02890 ****************/ 02891 02893 02896 template <class T, class Prop, class Allocator> 02897 Matrix<T, Prop, ColSymComplexSparse, Allocator>::Matrix(): 02898 Matrix_SymComplexSparse<T, Prop, ColSymComplexSparse, Allocator>() 02899 { 02900 } 02901 02902 02904 02908 template <class T, class Prop, class Allocator> 02909 Matrix<T, Prop, ColSymComplexSparse, Allocator> 02910 ::Matrix(int i, int j): 02911 Matrix_SymComplexSparse<T, Prop, ColSymComplexSparse, Allocator>(i, j, 02912 0, 0) 02913 { 02914 } 02915 02916 02918 02929 template <class T, class Prop, class Allocator> 02930 Matrix<T, Prop, ColSymComplexSparse, Allocator>::Matrix(int i, int j, 02931 int real_nz, 02932 int imag_nz): 02933 Matrix_SymComplexSparse<T, Prop, 02934 ColSymComplexSparse, Allocator>(i, j, 02935 real_nz, imag_nz) 02936 { 02937 } 02938 02939 02941 02960 template <class T, class Prop, class Allocator> 02961 template <class Storage0, class Allocator0, 02962 class Storage1, class Allocator1, 02963 class Storage2, class Allocator2> 02964 Matrix<T, Prop, ColSymComplexSparse, Allocator>:: 02965 Matrix(int i, int j, 02966 Vector<T, Storage0, Allocator0>& real_values, 02967 Vector<int, Storage1, Allocator1>& real_ptr, 02968 Vector<int, Storage2, Allocator2>& real_ind, 02969 Vector<T, Storage0, Allocator0>& imag_values, 02970 Vector<int, Storage1, Allocator1>& imag_ptr, 02971 Vector<int, Storage2, Allocator2>& imag_ind): 02972 Matrix_SymComplexSparse<T, Prop, 02973 ColSymComplexSparse, Allocator>(i, j, 02974 real_values, 02975 real_ptr, 02976 real_ind, 02977 imag_values, 02978 imag_ptr, 02979 imag_ind) 02980 { 02981 } 02982 02983 02984 02986 // MATRIX<ROWSYMCOMPLEXSPARSE> // 02988 02989 02990 /**************** 02991 * CONSTRUCTORS * 02992 ****************/ 02993 02995 02998 template <class T, class Prop, class Allocator> 02999 Matrix<T, Prop, RowSymComplexSparse, Allocator>::Matrix(): 03000 Matrix_SymComplexSparse<T, Prop, RowSymComplexSparse, Allocator>() 03001 { 03002 } 03003 03004 03006 03010 template <class T, class Prop, class Allocator> 03011 Matrix<T, Prop, RowSymComplexSparse, Allocator> 03012 ::Matrix(int i, int j): 03013 Matrix_SymComplexSparse<T, Prop, RowSymComplexSparse, Allocator>(i, j, 03014 0, 0) 03015 { 03016 } 03017 03018 03030 template <class T, class Prop, class Allocator> 03031 Matrix<T, Prop, RowSymComplexSparse, Allocator> 03032 ::Matrix(int i, int j, int real_nz, int imag_nz): 03033 Matrix_SymComplexSparse<T, Prop, RowSymComplexSparse, Allocator>(i, j, 03034 real_nz, 03035 imag_nz) 03036 { 03037 } 03038 03039 03041 03060 template <class T, class Prop, class Allocator> 03061 template <class Storage0, class Allocator0, 03062 class Storage1, class Allocator1, 03063 class Storage2, class Allocator2> 03064 Matrix<T, Prop, RowSymComplexSparse, Allocator>:: 03065 Matrix(int i, int j, 03066 Vector<T, Storage0, Allocator0>& real_values, 03067 Vector<int, Storage1, Allocator1>& real_ptr, 03068 Vector<int, Storage2, Allocator2>& real_ind, 03069 Vector<T, Storage0, Allocator0>& imag_values, 03070 Vector<int, Storage1, Allocator1>& imag_ptr, 03071 Vector<int, Storage2, Allocator2>& imag_ind): 03072 Matrix_SymComplexSparse<T, Prop, 03073 RowSymComplexSparse, Allocator>(i, j, 03074 real_values, 03075 real_ptr, 03076 real_ind, 03077 imag_values, 03078 imag_ptr, 03079 imag_ind) 03080 { 03081 } 03082 03083 03084 } // namespace Seldon. 03085 03086 #define SELDON_FILE_MATRIX_SYMCOMPLEXSPARSE_CXX 03087 #endif