MC++
|
00001 // Copyright (C) 2011-2012 Benoit Chachuat (b.chachuat@imperial.ac.uk) 00002 // All rights reserved. 00003 00004 // This code is provided "as is", without any warranty of any kind, 00005 // either expressed or implied, including but not limited to, any implied 00006 // warranty of merchantability or fitness for any purpose. In no event 00007 // will any party who distributed the code be liable for damages or for 00008 // any claim(s) by any other party, including but not limited to, any 00009 // lost profits, lost monies, lost data or data rendered inaccurate, 00010 // losses sustained by third parties, or any other special, incidental or 00011 // consequential damages arising out of the use or inability to use the 00012 // program, even if the possibility of such damages has been advised 00013 // against. The entire risk as to the quality, the performance, and the 00014 // fitness of the program for any particular purpose lies with the party 00015 // using the code. 00016 00017 // This code, and any derivative of this code, may not be used in a 00018 // commercial package without the prior explicit written permission of 00019 // the authors. Verbatim copies of this code may be made and distributed 00020 // in any medium, provided that this copyright notice is not removed or 00021 // altered in any way. No fees may be charged for distribution of the 00022 // codes, other than a fee to cover the cost of the media and a 00023 // reasonable handling fee. 00024 00097 #ifndef MC__SPARSE_H 00098 #define MC__SPARSE_H 00099 00100 #include <iostream> 00101 #include <map> 00102 00103 namespace mc 00104 { 00105 00111 class Structure 00113 { 00114 // friends of class Structure for operator overloading 00115 friend Structure operator+ 00116 ( const Structure& ); 00117 friend Structure operator+ 00118 ( const Structure&, const Structure& ); 00119 friend Structure operator+ 00120 ( const double, const Structure& ); 00121 friend Structure operator+ 00122 ( const Structure&, const double ); 00123 friend Structure operator- 00124 ( const Structure& ); 00125 friend Structure operator- 00126 ( const Structure&, const Structure& ); 00127 friend Structure operator- 00128 ( const double, const Structure& ); 00129 friend Structure operator- 00130 ( const Structure&, const double ); 00131 friend Structure operator* 00132 ( const Structure&, const Structure& ); 00133 friend Structure operator* 00134 ( const Structure&, const double ); 00135 friend Structure operator* 00136 ( const double, const Structure& ); 00137 friend Structure operator/ 00138 ( const Structure&, const Structure& ); 00139 friend Structure operator/ 00140 ( const Structure&, const double ); 00141 friend Structure operator/ 00142 ( const double, const Structure& ); 00143 friend std::ostream& operator<< 00144 ( std::ostream&, const Structure& ); 00145 friend bool operator== 00146 ( const Structure&, const Structure& ); 00147 friend bool operator!= 00148 ( const Structure&, const Structure& ); 00149 friend bool operator<= 00150 ( const Structure&, const Structure& ); 00151 friend bool operator>= 00152 ( const Structure&, const Structure& ); 00153 friend bool operator< 00154 ( const Structure&, const Structure& ); 00155 friend bool operator> 00156 ( const Structure&, const Structure& ); 00157 00158 // friends of class Structure for function overloading 00159 friend Structure inv 00160 ( const Structure& ); 00161 friend Structure sqr 00162 ( const Structure& ); 00163 friend Structure exp 00164 ( const Structure& ); 00165 friend Structure log 00166 ( const Structure& ); 00167 friend Structure cos 00168 ( const Structure& ); 00169 friend Structure sin 00170 ( const Structure& ); 00171 friend Structure tan 00172 ( const Structure& ); 00173 friend Structure acos 00174 ( const Structure& ); 00175 friend Structure asin 00176 ( const Structure& ); 00177 friend Structure atan 00178 ( const Structure& ); 00179 friend Structure fabs 00180 ( const Structure& ); 00181 friend Structure sqrt 00182 ( const Structure& ); 00183 friend Structure xlog 00184 ( const Structure& ); 00185 friend Structure erf 00186 ( const Structure& ); 00187 friend Structure erfc 00188 ( const Structure& ); 00189 friend Structure arh 00190 ( const Structure&, const double ); 00191 friend Structure pow 00192 ( const Structure&, const int ); 00193 friend Structure pow 00194 ( const Structure&, const double ); 00195 friend Structure pow 00196 ( const Structure&, const Structure& ); 00197 friend Structure min 00198 ( const Structure&, const Structure& ); 00199 friend Structure max 00200 ( const Structure&, const Structure& ); 00201 friend Structure min 00202 ( const unsigned int, const Structure* ); 00203 friend Structure max 00204 ( const unsigned int, const Structure* ); 00205 00206 public: 00207 00209 class Exceptions 00210 { 00211 public: 00213 enum TYPE{ 00214 UNDEF=-33 00215 }; 00217 Exceptions( TYPE ierr ) : _ierr( ierr ){} 00218 00220 int ierr(){ return _ierr; } 00221 private: 00222 TYPE _ierr; 00223 }; 00224 00225 typedef std::map<int,bool> t_Structure; 00226 typedef t_Structure::iterator it_Structure; 00227 typedef t_Structure::const_iterator cit_Structure; 00228 00229 // other operator overloadings (inlined) 00230 Structure& operator= 00231 ( const double c ) 00232 { _dep.clear(); return *this; } 00233 Structure& operator= 00234 ( const Structure&S ) 00235 { if( this != &S ) _dep = S._dep; return *this; } 00236 Structure& operator+= 00237 ( const double c ) 00238 { return *this; } 00239 Structure& operator+= 00240 ( const Structure&S ) 00241 { return combine( S ); } 00242 Structure& operator-= 00243 ( const double c ) 00244 { return *this; } 00245 Structure& operator-= 00246 ( const Structure&S ) 00247 { return combine( S ); } 00248 Structure& operator*= 00249 ( const double c ) 00250 { return *this; } 00251 Structure& operator*= 00252 ( const Structure&S ) 00253 { return combine( S, false ); } 00254 Structure& operator/= 00255 ( const double c ) 00256 { return *this; } 00257 Structure& operator/= 00258 ( const Structure&S ) 00259 { return combine( S, false ); } 00260 00264 00265 Structure 00266 ( const double c=0. ) 00267 {} 00268 /* //! @brief Constructor for a variable with index <a>index</a> 00269 Structure 00270 ( const int ind ) 00271 { _dep.insert( std::make_pair(ind,true) ); } 00272 */ 00274 Structure 00275 ( const Structure&S ): 00276 _dep(S._dep) 00277 {} 00279 ~Structure() 00280 {} 00281 00283 Structure& indep 00284 ( const int ind ) 00285 { _dep.clear(); _dep.insert( std::make_pair(ind,true) ); return *this; } 00286 00288 std::pair<bool,bool> dep 00289 ( const int ind ) 00290 { cit_Structure it = _dep.find(ind); 00291 return( it==_dep.end()? std::make_pair(false,true): 00292 std::make_pair(true,it->second) ); } 00293 // //! @brief Determines if the current object is dependent on the variable <a>S</a> 00294 // bool dep 00295 // ( const Structure&S ) 00296 // { return( _dep.size()==combine(*this,S)._dep.size()? true: false); } 00297 00299 const t_Structure& dep() const 00300 { return _dep; } 00301 t_Structure& dep() 00302 { return _dep; } 00303 00305 Structure& combine 00306 ( const Structure&S, const bool linear=true ); 00308 static Structure combine 00309 ( const Structure&S1, const Structure&S2, const bool linear=true ); 00311 static Structure combine 00312 ( const unsigned int n, const Structure*S, const bool linear=true ); 00313 00315 Structure& nonlinear(); 00317 static Structure nonlinear 00318 ( const Structure&S ); 00321 private: 00322 00324 t_Structure _dep; 00325 }; 00326 00328 00329 inline Structure& 00330 Structure::nonlinear() 00331 { 00332 it_Structure it = _dep.begin(); 00333 for( ; it != _dep.end(); ++it ) it->second = false; 00334 return *this; 00335 } 00336 00337 inline Structure 00338 Structure::nonlinear 00339 ( const Structure&S ) 00340 { 00341 Structure S2( S ); 00342 return S2.nonlinear(); 00343 } 00344 00345 inline Structure& 00346 Structure::combine 00347 ( const Structure&S, const bool linear ) 00348 { 00349 cit_Structure cit = S._dep.begin(); 00350 for( ; cit != S._dep.end(); ++cit ){ 00351 std::pair<it_Structure,bool> ins = _dep.insert( *cit ); 00352 if( !ins.second ) ins.first->second = ( ins.first->second && cit->second ); 00353 } 00354 return( linear? *this: nonlinear() ); 00355 } 00356 00357 inline Structure 00358 Structure::combine 00359 ( const Structure&S1, const Structure&S2, const bool linear ) 00360 { 00361 Structure S3( S1 ); 00362 return S3.combine( S2, linear ); 00363 } 00364 00365 inline Structure 00366 Structure::combine 00367 ( const unsigned int n, const Structure*S, const bool linear ) 00368 { 00369 Structure S2; 00370 for( unsigned int i=0; S && i<n; i++ ) S2.combine( S[i], linear ); 00371 return S2; 00372 } 00373 00374 inline std::ostream& 00375 operator<< 00376 ( std::ostream&out, const Structure&S) 00377 { 00378 out << "{ "; 00379 Structure::cit_Structure iS = S._dep.begin(); 00380 for( ; iS != S._dep.end(); ++iS ) 00381 out << iS->first << (iS->second?"L":"NL") << " "; 00382 out << "}"; 00383 return out; 00384 } 00385 00386 inline Structure 00387 operator+ 00388 ( const Structure&S ) 00389 { 00390 return S; 00391 } 00392 00393 inline Structure 00394 operator- 00395 ( const Structure&S ) 00396 { 00397 return S; 00398 } 00399 00400 inline Structure 00401 operator+ 00402 ( const double c, const Structure&S ) 00403 { 00404 return S; 00405 } 00406 00407 inline Structure 00408 operator+ 00409 ( const Structure&S, const double c ) 00410 { 00411 return S; 00412 } 00413 00414 inline Structure 00415 operator+ 00416 ( const Structure&S1, const Structure&S2 ) 00417 { 00418 return Structure::combine( S1, S2 ); 00419 } 00420 00421 inline Structure 00422 operator- 00423 ( const double c, const Structure&S ) 00424 { 00425 return S; 00426 } 00427 00428 inline Structure 00429 operator- 00430 ( const Structure&S, const double c ) 00431 { 00432 return S; 00433 } 00434 00435 inline Structure 00436 operator- 00437 ( const Structure&S1, const Structure&S2 ) 00438 { 00439 return Structure::combine( S1, S2 ); 00440 } 00441 00442 inline Structure 00443 operator* 00444 ( const double c, const Structure&S ) 00445 { 00446 return S; 00447 } 00448 00449 inline Structure 00450 operator* 00451 ( const Structure&S, const double c ) 00452 { 00453 return S; 00454 } 00455 00456 inline Structure 00457 operator* 00458 ( const Structure&S1, const Structure&S2 ) 00459 { 00460 return Structure::combine( S1, S2, false ); 00461 } 00462 00463 inline Structure 00464 operator/ 00465 ( const Structure&S, const double c ) 00466 { 00467 return S; 00468 } 00469 00470 inline Structure 00471 operator/ 00472 ( const double c, const Structure&S ) 00473 { 00474 return S; 00475 } 00476 00477 inline Structure 00478 operator/ 00479 ( const Structure&S1, const Structure&S2 ) 00480 { 00481 return Structure::combine( S1, S2, false ); 00482 } 00483 00484 inline Structure 00485 inv 00486 ( const Structure &S ) 00487 { 00488 return Structure::nonlinear( S ); 00489 } 00490 00491 inline Structure 00492 sqr 00493 ( const Structure&S ) 00494 { 00495 return Structure::nonlinear( S ); 00496 } 00497 00498 inline Structure 00499 exp 00500 ( const Structure &S ) 00501 { 00502 return Structure::nonlinear( S ); 00503 } 00504 00505 inline Structure 00506 arh 00507 ( const Structure &S, const double a ) 00508 { 00509 return Structure::nonlinear( S ); 00510 } 00511 00512 inline Structure 00513 log 00514 ( const Structure &S ) 00515 { 00516 return Structure::nonlinear( S ); 00517 } 00518 00519 inline Structure 00520 xlog 00521 ( const Structure&S ) 00522 { 00523 return Structure::nonlinear( S ); 00524 } 00525 00526 inline Structure 00527 erf 00528 ( const Structure &S ) 00529 { 00530 return Structure::nonlinear( S ); 00531 } 00532 00533 inline Structure 00534 erfc 00535 ( const Structure &S ) 00536 { 00537 return Structure::nonlinear( S ); 00538 } 00539 00540 inline Structure 00541 sqrt 00542 ( const Structure&S ) 00543 { 00544 return Structure::nonlinear( S ); 00545 } 00546 00547 inline Structure 00548 fabs 00549 ( const Structure&S ) 00550 { 00551 return Structure::nonlinear( S ); 00552 } 00553 00554 inline Structure 00555 pow 00556 ( const Structure&S, const int n ) 00557 { 00558 if( n == 0 ){ Structure S2; return S2; } 00559 if( n == 1 ) return S; 00560 return Structure::nonlinear( S ); 00561 } 00562 00563 inline Structure 00564 pow 00565 ( const Structure&S, const double a ) 00566 { 00567 return Structure::nonlinear( S ); 00568 } 00569 00570 inline Structure 00571 pow 00572 ( const Structure&S1, const Structure&S2 ) 00573 { 00574 return Structure::combine( S1, S2, false ); 00575 } 00576 00577 inline Structure 00578 min 00579 ( const Structure&S1, const Structure&S2 ) 00580 { 00581 return Structure::combine( S1, S2, false ); 00582 } 00583 00584 inline Structure 00585 max 00586 ( const Structure&S1, const Structure&S2 ) 00587 { 00588 return Structure::combine( S1, S2, false ); 00589 } 00590 00591 inline Structure 00592 min 00593 ( const unsigned int n, const Structure*S ) 00594 { 00595 return Structure::combine( n, S, false ); 00596 } 00597 00598 inline Structure 00599 max 00600 ( const unsigned int n, const Structure*S ) 00601 { 00602 return Structure::combine( n, S, false ); 00603 } 00604 00605 inline Structure 00606 cos 00607 ( const Structure&S ) 00608 { 00609 return Structure::nonlinear( S ); 00610 } 00611 00612 inline Structure 00613 sin 00614 ( const Structure &S ) 00615 { 00616 return Structure::nonlinear( S ); 00617 } 00618 00619 inline Structure 00620 tan 00621 ( const Structure&S ) 00622 { 00623 return Structure::nonlinear( S ); 00624 } 00625 00626 inline Structure 00627 acos 00628 ( const Structure &S ) 00629 { 00630 return Structure::nonlinear( S ); 00631 } 00632 00633 inline Structure 00634 asin 00635 ( const Structure &S ) 00636 { 00637 return Structure::nonlinear( S ); 00638 } 00639 00640 inline Structure 00641 atan 00642 ( const Structure &S ) 00643 { 00644 return Structure::nonlinear( S ); 00645 } 00646 00647 inline bool 00648 operator== 00649 ( const Structure&S1, const Structure&S2 ) 00650 { 00651 return( S1._dep == S2._dep ); 00652 } 00653 00654 inline bool 00655 operator!= 00656 ( const Structure&S1, const Structure&S2 ) 00657 { 00658 return( S1._dep != S2._dep ); 00659 } 00660 00661 inline bool 00662 operator<= 00663 ( const Structure&S1, const Structure&S2 ) 00664 { 00665 return( S1._dep <= S2._dep ); 00666 } 00667 00668 inline bool 00669 operator>= 00670 ( const Structure&S1, const Structure&S2 ) 00671 { 00672 return( S1._dep >= S2._dep ); 00673 } 00674 00675 inline bool 00676 operator< 00677 ( const Structure&S1, const Structure&S2 ) 00678 { 00679 return( S1._dep < S2._dep ); 00680 } 00681 00682 inline bool 00683 operator> 00684 ( const Structure&S1, const Structure&S2 ) 00685 { 00686 return( S1._dep > S2._dep ); 00687 } 00688 00689 } // namespace mc 00690 00691 #endif