IBSimu
1.0.4
|
00001 00005 /* Copyright (c) 2005-2010 Taneli Kalvas. All rights reserved. 00006 * 00007 * You can redistribute this software and/or modify it under the terms 00008 * of the GNU General Public License as published by the Free Software 00009 * Foundation; either version 2 of the License, or (at your option) 00010 * any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, but 00013 * WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this library (file "COPYING" included in the package); 00019 * if not, write to the Free Software Foundation, Inc., 51 Franklin 00020 * Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 * If you have questions about your rights to use or distribute this 00023 * software, please contact Berkeley Lab's Technology Transfer 00024 * Department at TTD@lbl.gov. Other questions, comments and bug 00025 * reports should be sent directly to the author via email at 00026 * taneli.kalvas@jyu.fi. 00027 * 00028 * NOTICE. This software was developed under partial funding from the 00029 * U.S. Department of Energy. As such, the U.S. Government has been 00030 * granted for itself and others acting on its behalf a paid-up, 00031 * nonexclusive, irrevocable, worldwide license in the Software to 00032 * reproduce, prepare derivative works, and perform publicly and 00033 * display publicly. Beginning five (5) years after the date 00034 * permission to assert copyright is obtained from the U.S. Department 00035 * of Energy, and subject to any subsequent five (5) year renewals, 00036 * the U.S. Government is granted for itself and others acting on its 00037 * behalf a paid-up, nonexclusive, irrevocable, worldwide license in 00038 * the Software to reproduce, prepare derivative works, distribute 00039 * copies to the public, perform publicly and display publicly, and to 00040 * permit others to do so. 00041 */ 00042 00043 #ifndef MVECTOR_HPP 00044 #define MVECTOR_HPP 1 00045 00046 00047 #include <vector> 00048 #include <iostream> 00049 #include "matrix.hpp" 00050 #include "error.hpp" 00051 00052 00068 class Vector { 00069 int _n; 00070 double *_val; 00071 00072 void allocate( void ); 00073 void callocate( void ); 00074 void reallocate( void ); 00075 00076 public: 00077 00083 struct VectorRef { 00084 const Vector *_vec; 00085 double _coef; 00086 00089 VectorRef() : _vec(NULL), _coef(1.0) {} 00090 00093 VectorRef( const Vector *vec, double coef ) : _vec(vec), _coef(coef) {} 00094 }; 00095 00102 struct VectorLA { 00103 std::vector<VectorRef> _refs; 00104 00107 VectorLA() {} 00108 00111 VectorLA( const VectorLA &vecla ) : _refs(vecla._refs) {} 00112 00115 VectorLA( const Vector &vec ) { 00116 VectorRef ref( &vec, 1.0 ); 00117 _refs.push_back( ref ); 00118 } 00119 00122 VectorLA( const Vector &vec, double coef ) { 00123 VectorRef ref( &vec, coef ); 00124 _refs.push_back( ref ); 00125 } 00126 00137 double operator[]( int i ) const; 00138 00145 double operator()( int i ) const; 00146 00149 VectorLA operator+( const VectorLA &vecla ) const; 00150 00153 VectorLA operator-( const VectorLA &vecla ) const; 00154 00157 VectorLA operator-() const; 00158 00161 VectorLA operator*( double x ) const; 00162 00165 friend VectorLA operator*( double x, const VectorLA &vecla ); 00166 }; 00167 00168 /* ************************************** * 00169 * Constructors and destructor * 00170 * ************************************** */ 00171 00176 Vector() : _n(0), _val(NULL) {} 00177 00183 Vector( int n ); 00184 00192 Vector( int n, const double *val ); 00193 00201 Vector( int n, double val ); 00202 00208 Vector( const Vector &vec ); 00209 00212 Vector( const VectorLA &vecla ); 00213 00216 Vector( const struct MatrixMulVec &matvec ); 00217 00220 ~Vector(); 00221 00224 int size( void ) const { return( _n ); } 00225 00233 void resize( int n ); 00234 00240 void clear( void ); 00241 00248 void merge( Vector &vec ); 00249 00256 double *get_data( void ) { return( _val ); } 00257 00261 const double *get_data( void ) const { return( _val ); } 00262 00265 VectorLA operator+( const VectorLA &vecla ) const; 00266 00269 VectorLA operator-( const VectorLA &vecla ) const; 00270 00273 VectorLA operator-() const; 00274 00277 VectorLA operator*( double x ) const; 00278 00281 Vector &operator+=( const VectorLA &vecla ); 00282 00285 Vector &operator-=( const VectorLA &vecla ); 00286 00289 Vector &operator*=( double x ); 00290 00293 Vector &operator=( double x ); 00294 00297 Vector &operator=( const Vector &vec ); 00298 00301 Vector &operator=( const VectorLA &vecla ); 00302 00305 Vector &operator=( const struct MatrixMulVec &matvec ); 00306 00315 bool operator==( const Vector &vec ) const; 00316 00325 bool operator!=( const Vector &vec ) const; 00326 00333 double &operator[]( int i ); 00334 00341 double &operator()( int i ); 00342 00349 double operator[]( int i ) const; 00350 00357 double operator()( int i ) const; 00358 00359 friend class HBIO; 00360 friend class Matrix; 00361 friend class CRowMatrix; 00362 friend class CColMatrix; 00363 friend class CoordMatrix; 00364 00367 friend VectorLA operator*( double x, Vector &vec ); 00368 00371 friend std::ostream &operator<<( std::ostream &os, const Vector &vec ); 00372 00375 friend double dot_prod( const Vector &vec1, const Vector &vec2 ); 00376 00381 friend double norm1( const Vector &vec ); 00382 00387 friend double norm2( const Vector &vec ); 00388 00393 friend double ssqr( const Vector &vec ); 00394 00397 friend double min( const Vector &vec ); 00398 00401 friend double min_abs( const Vector &vec ); 00402 00405 friend double max( const Vector &vec ); 00406 00409 friend double max_abs( const Vector &vec ); 00410 00413 friend void swap( Vector &vec1, Vector &vec2 ); 00414 }; 00415 00416 00417 inline double Vector::VectorLA::operator[]( int i ) const { 00418 #ifdef SPM_RANGE_CHECK 00419 if( i >= _refs[0]._vec->_n ) 00420 throw( ErrorRange( ERROR_LOCATION, i, _refs[0]._vec->_n ) ); 00421 #endif 00422 double res = 0.0; 00423 std::vector<VectorRef>::const_iterator itend = _refs.end(); 00424 for( std::vector<VectorRef>::const_iterator it = _refs.begin(); it != itend; it++ ) 00425 res += (it->_coef) * (*(it->_vec))[i]; 00426 return( res ); 00427 } 00428 00429 00430 inline double Vector::VectorLA::operator()( int i ) const { 00431 #ifdef SPM_RANGE_CHECK 00432 if( i >= _refs[0]._vec->_n ) 00433 throw( ErrorRange( ERROR_LOCATION, i, _refs[0]._vec->_n ) ); 00434 #endif 00435 double res = 0.0; 00436 std::vector<VectorRef>::const_iterator itend = _refs.end(); 00437 for( std::vector<VectorRef>::const_iterator it = _refs.begin(); it != itend; it++ ) 00438 res += (it->_coef) * (*(it->_vec))[i]; 00439 return( res ); 00440 } 00441 00442 00443 inline double &Vector::operator[]( int i ) { 00444 #ifdef SPM_RANGE_CHECK 00445 if( i >= _n ) 00446 throw( ErrorRange( ERROR_LOCATION, i, _n ) ); 00447 #endif 00448 return( _val[i] ); 00449 } 00450 00451 00452 inline double &Vector::operator()( int i ) { 00453 #ifdef SPM_RANGE_CHECK 00454 if( i >= _n ) 00455 throw( ErrorRange( ERROR_LOCATION, i, _n ) ); 00456 #endif 00457 return( _val[i] ); 00458 } 00459 00460 00461 inline double Vector::operator[]( int i ) const { 00462 #ifdef SPM_RANGE_CHECK 00463 if( i >= _n ) 00464 throw( ErrorRange( ERROR_LOCATION, i, _n ) ); 00465 #endif 00466 return( _val[i] ); 00467 } 00468 00469 00470 inline double Vector::operator()( int i ) const { 00471 #ifdef SPM_RANGE_CHECK 00472 if( i >= _n ) 00473 throw( ErrorRange( ERROR_LOCATION, i, _n ) ); 00474 #endif 00475 return( _val[i] ); 00476 } 00477 00478 00479 00480 00481 00482 #endif 00483 00484 00485 00486 00487 00488 00489 00490 00491 00492 00493 00494 00495 00496 00497 00498 00499 00500 00501