MC++
|
00001 // Copyright (C) 2009-2011 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 merchantibility 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 00025 // *************************************************************** 00026 // ANY USE OF THIS CODE CONSTITUTES ACCEPTANCE OF THE TERMS OF THE 00027 // COPYRIGHT NOTICE 00028 // *************************************************************** 00029 00294 #ifndef MC__TMODEL_H 00295 #define MC__TMODEL_H 00296 00297 #include <iostream> 00298 #include <iomanip> 00299 #include <typeinfo> 00300 #include <sstream> 00301 #include <string> 00302 #include <stdarg.h> 00303 #include <cassert> 00304 #include "mcfunc.h" 00305 #include "mcop.h" 00306 00307 #undef MC__TMODEL_DEBUG 00308 #define MC__TMODEL_CHECK 00309 #undef MC__TVAR_DEBUG_EXP 00310 #undef MC__TVAR_DEBUG_EIGEN 00311 #undef MC__TVAR_HYBRID_EIGEN 00312 00313 extern "C" void dsyev_ 00314 ( const char*jobz, const char*uplo, const unsigned int*n, double*a, 00315 const unsigned int*lda, double*w, double*work, const int*lwork, int*info ); 00316 00317 namespace mc 00318 { 00319 00320 template <typename T> class TVar; 00321 00329 template <typename T> 00330 class TModel 00332 { 00333 00334 //template <typename U> friend TVar<U>::TVar 00335 // ( TModel<U>*TM, const unsigned int ivar, const U&X ); 00336 //template <typename U> friend void TVar<U>::_update_bndord(); 00337 friend class TVar<T>; 00338 template <typename U> friend class TModel; 00339 00340 public: 00341 00343 TModel 00344 ( const unsigned int nvar, const unsigned int nord ) 00345 { _size( nvar, nord ); } 00346 // //! @brief Copy constructor for different range bounder with implicit type conversion 00347 // template <typename U> TModel 00348 // ( const TModel<U>&TM ); 00349 // //! @brief Copy constructor for different range bounder with explicit type conversion member function 00350 // template <typename U> TModel 00351 // ( const TModel<U>&TM, const T& (U::*method)() const ); 00352 // //! @brief Copy constructor for different range bounder with explicit type conversion non-class function 00353 // template <typename U> TModel 00354 // ( const TModel<U>&TM, T (*method)( const U& ) ); 00355 00357 ~TModel() 00358 { _cleanup(); } 00359 00361 unsigned int nvar() const 00362 { return _nvar; }; 00364 unsigned int nord() const 00365 { return _nord; }; 00367 void reset() 00368 { _reset(); }; 00369 00371 class Exceptions 00372 { 00373 public: 00375 enum TYPE{ 00376 DIV=1, 00377 INTER, 00378 EIGEN, 00379 SCALING, 00380 SIZE=-1, 00381 INIT=-2, 00382 INCON=-3, 00383 TMODEL=-4, 00384 UNDEF=-33 00385 }; 00387 Exceptions( TYPE ierr ) : _ierr( ierr ){} 00389 int ierr(){ return _ierr; } 00390 00391 private: 00392 TYPE _ierr; 00393 }; 00394 00396 struct Options 00397 { 00399 Options(): 00400 BOUNDER_TYPE(LSB), PROPAGATE_BNDT(false), INTER_WITH_BNDT(false), 00401 SCALE_VARIABLES(true), CENTER_REMAINDER(true), REF_MIDPOINT(true), 00402 REF_INTER(0.) 00403 {} 00405 template <typename U> Options 00406 ( U&options ) 00407 : BOUNDER_TYPE( options.BOUNDER_TYPE ), 00408 PROPAGATE_BNDT( options.PROPAGATE_BNDT ), 00409 INTER_WITH_BNDT( options.INTER_WITH_BNDT ), 00410 SCALE_VARIABLES( options.SCALE_VARIABLES ), 00411 CENTER_REMAINDER( options.CENTER_REMAINDER ), 00412 REF_MIDPOINT( options.REF_MIDPOINT ) 00413 {} 00414 template <typename U> Options& operator = 00415 ( U&options ){ 00416 BOUNDER_TYPE = options.BOUNDER_TYPE; 00417 PROPAGATE_BNDT = options.PROPAGATE_BNDT; 00418 INTER_WITH_BNDT = options.INTER_WITH_BNDT; 00419 SCALE_VARIABLES = options.SCALE_VARIABLES; 00420 CENTER_REMAINDER = options.CENTER_REMAINDER; 00421 REF_MIDPOINT = options.REF_MIDPOINT; 00422 return *this; 00423 } 00425 enum BOUNDER{ 00426 NAIVE=0, 00427 LSB, 00428 EIGEN, 00429 HYBRID 00430 }; 00432 int BOUNDER_TYPE; 00434 bool PROPAGATE_BNDT; 00436 bool INTER_WITH_BNDT; 00438 bool SCALE_VARIABLES; 00440 bool CENTER_REMAINDER; 00442 bool REF_MIDPOINT; 00444 double REF_INTER; 00445 } options; 00446 00448 static void pause(); 00449 00450 private: 00452 unsigned int _nord; 00454 unsigned int _nvar; 00456 unsigned int _nmon; 00458 unsigned int *_posord; 00460 unsigned int *_expmon; 00462 unsigned int **_prodmon; 00464 T *_bndmon; 00466 bool _modvar; 00468 unsigned int *_binom; 00470 T **_bndpow; 00472 double *_refpoint; 00474 double *_scaling; 00475 00477 TVar<T>* _TV; 00478 00480 void _size 00481 ( const unsigned int nvar, const unsigned int nord ); 00482 00483 // //! @brief Set the order (nord) and number of variables (nvar) 00484 // template <typename U> void _copy_data 00485 // ( const TModel<U>&TM ); 00486 00488 void _set_bndpow 00489 ( const unsigned int ix, const T&X, const double scaling ); 00490 00492 void _set_bndmon(); 00493 00495 void _set_posord(); 00496 00498 void _set_expmon(); 00499 00501 void _next_expmon 00502 ( unsigned int *iexp, const unsigned int iord ); 00503 00505 void _set_prodmon(); 00506 00508 unsigned int _loc_expmon 00509 ( const unsigned int *iexp ); 00510 00512 void _set_binom(); 00513 00515 unsigned int _get_binom 00516 ( const unsigned int n, const unsigned int k ) const; 00517 00519 void _reset(); 00520 00522 void _cleanup(); 00523 00525 template< typename U > static void _display 00526 ( const unsigned int m, const unsigned int n, U*&a, const unsigned int lda, 00527 const std::string&stra, std::ostream&os ); 00528 } ; 00529 00537 template <typename T> 00538 class TVar 00540 { 00541 // friends of class TVar 00542 template <typename U> friend void TModel<U>::_size 00543 ( const unsigned int nvar, const unsigned int nord ); 00544 00545 template <typename U> friend class TVar; 00546 00547 template <typename U> friend TVar<U> operator+ 00548 ( const TVar<U>& ); 00549 template <typename U, typename V> friend TVar<U> operator+ 00550 ( const TVar<U>&, const TVar<V>& ); 00551 template <typename U, typename V> friend TVar<U> operator+ 00552 ( const TVar<U>&, const V& ); 00553 template <typename U, typename V> friend TVar<U> operator+ 00554 ( const V&, const TVar<U>& ); 00555 template <typename U> friend TVar<U> operator+ 00556 ( const double, const TVar<U>& ); 00557 template <typename U> friend TVar<U> operator+ 00558 ( const TVar<U>&, const double ); 00559 template <typename U> friend TVar<U> operator- 00560 ( const TVar<U>& ); 00561 template <typename U, typename V> friend TVar<U> operator- 00562 ( const TVar<U>&, const TVar<V>& ); 00563 template <typename U, typename V> friend TVar<U> operator- 00564 ( const TVar<U>&, const V& ); 00565 template <typename U, typename V> friend TVar<U> operator- 00566 ( const V&, const TVar<U>& ); 00567 template <typename U> friend TVar<U> operator- 00568 ( const double, const TVar<U>& ); 00569 template <typename U> friend TVar<U> operator- 00570 ( const TVar<U>&, const double ); 00571 template <typename U> friend TVar<U> operator* 00572 ( const TVar<U>&, const TVar<U>& ); 00573 template <typename U> friend TVar<U> operator* 00574 ( const double, const TVar<U>& ); 00575 template <typename U> friend TVar<U> operator* 00576 ( const TVar<U>&, const double ); 00577 template <typename U> friend TVar<U> operator* 00578 ( const U&, const TVar<U>& ); 00579 template <typename U> friend TVar<U> operator* 00580 ( const TVar<U>&, const U& ); 00581 template <typename U> friend TVar<U> operator/ 00582 ( const TVar<U>&, const TVar<U>& ); 00583 template <typename U> friend TVar<U> operator/ 00584 ( const double, const TVar<U>& ); 00585 template <typename U> friend TVar<U> operator/ 00586 ( const TVar<U>&, const double ); 00587 template <typename U> friend std::ostream& operator<< 00588 ( std::ostream&, const TVar<U>& ); 00589 00590 template <typename U> friend TVar<U> inv 00591 ( const TVar<U>& ); 00592 template <typename U> friend TVar<U> sqr 00593 ( const TVar<U>& ); 00594 template <typename U> friend TVar<U> sqrt 00595 ( const TVar<U>& ); 00596 template <typename U> friend TVar<U> exp 00597 ( const TVar<U>& ); 00598 template <typename U> friend TVar<U> log 00599 ( const TVar<U>& ); 00600 template <typename U> friend TVar<U> xlog 00601 ( const TVar<U>& ); 00602 template <typename U> friend TVar<U> pow 00603 ( const TVar<U>&, const int ); 00604 template <typename U> friend TVar<U> pow 00605 ( const TVar<U>&, const double ); 00606 template <typename U> friend TVar<U> pow 00607 ( const double, const TVar<U>& ); 00608 template <typename U> friend TVar<U> pow 00609 ( const TVar<U>&, const TVar<U>& ); 00610 template <typename U> friend TVar<U> monomial 00611 ( const unsigned int, const TVar<U>*, const int* ); 00612 template <typename U> friend TVar<U> cos 00613 ( const TVar<U>& ); 00614 template <typename U> friend TVar<U> sin 00615 ( const TVar<U>& ); 00616 template <typename U> friend TVar<U> tan 00617 ( const TVar<U>& ); 00618 template <typename U> friend TVar<U> acos 00619 ( const TVar<U>& ); 00620 template <typename U> friend TVar<U> asin 00621 ( const TVar<U>& ); 00622 template <typename U> friend TVar<U> atan 00623 ( const TVar<U>& ); 00624 template <typename U> friend TVar<U> hull 00625 ( const TVar<U>&, const TVar<U>& ); 00626 template <typename U> friend bool inter 00627 ( TVar<U>&, const TVar<U>&, const TVar<U>& ); 00628 00629 private: 00631 TModel<T> *_TM; 00633 TVar<T>* _TV() const 00634 { return _TM->_TV; }; 00636 unsigned int _nord() const 00637 { return _TM->_nord; }; 00639 unsigned int _nvar() const 00640 { return _TM->_nvar; }; 00642 unsigned int _nmon() const 00643 { return _TM->_nmon; }; 00645 unsigned int _posord 00646 ( const unsigned int i ) const 00647 { return _TM->_posord[i]; }; 00649 unsigned int _expmon 00650 ( const unsigned int i ) const 00651 { return _TM->_expmon[i]; }; 00653 unsigned int _prodmon 00654 ( const unsigned int i, const unsigned int j ) const 00655 { return _TM->_prodmon[i][j]; }; 00657 const T& _bndmon 00658 ( const unsigned int i ) const 00659 { return _TM->_bndmon[i]; }; 00661 double _refpoint 00662 ( const unsigned int i ) const 00663 { return _TM->_refpoint[i]; }; 00665 double _scaling 00666 ( const unsigned int i ) const 00667 { return _TM->_scaling[i]; }; 00668 00669 public: 00673 00674 TVar 00675 ( const double d=0. ); 00677 TVar 00678 ( const T&B ); 00680 TVar 00681 ( TModel<T>*TM, const unsigned int ix, const T&X ); 00683 TVar 00684 ( const TVar<T>&TV ); 00686 template <typename U> TVar 00687 ( TModel<T>*&TM, const TVar<U>&TV ); 00689 template <typename U> TVar 00690 ( TModel<T>*&TM, const TVar<U>&TV, const T& (U::*method)() const ); 00692 template <typename U> TVar 00693 ( TModel<T>*&TM, const TVar<U>&TV, T (*method)( const U& ) ); 00694 00696 ~TVar() 00697 { delete [] _coefmon; delete [] _bndord; } 00698 00700 TVar<T>& set 00701 ( TModel<T>*TM, const unsigned int ix, const T&X ) 00702 { *this = TVar( TM, ix, X ); return *this; } 00703 00705 TModel<T>* env() const 00706 { return _TM; } 00707 00709 T bound() const 00710 { T bndmod; return _bound( bndmod ); } 00711 00713 T B() const 00714 { T bndmod; return _bound( bndmod ); } 00715 00717 const T& boundT() const 00718 { return _bndT; } 00719 00721 T remainder() const 00722 { return( *_bndrem ); } 00723 00725 T R() const 00726 { return remainder(); } 00727 00729 //T& R() 00730 // { return remainder(); } 00731 00733 TVar<T>& center() 00734 { _center_TM(); return *this; } 00735 00737 TVar<T>& C() 00738 { return center(); } 00739 00741 TVar<T> polynomial() const 00742 { TVar<T> TV = *this; *(TV._bndrem) = 0.; return TV; } 00743 00745 double polynomial 00746 ( const double*x ) const; 00747 00749 TVar<T> P() const 00750 { return polynomial(); } 00751 00753 double P 00754 ( const double*x ) const 00755 { return polynomial( x ); } 00756 00758 double* reference() const; 00759 00761 double constant() const; 00762 00764 double* linear() const; 00765 00767 double* quadratic 00768 ( const int opt=0 ) const; 00771 00772 TVar<T>& operator = 00773 ( const double ); 00774 TVar<T>& operator = 00775 ( const TVar<T>& ); 00776 TVar<T>& operator = 00777 ( const T& ); 00778 template <typename U> TVar<T>& operator += 00779 ( const TVar<U>& ); 00780 template <typename U> TVar<T>& operator += 00781 ( const U& ); 00782 TVar<T>& operator += 00783 ( const double ); 00784 template <typename U> TVar<T>& operator -= 00785 ( const TVar<U>& ); 00786 template <typename U> TVar<T>& operator -= 00787 ( const U& ); 00788 TVar<T>& operator -= 00789 ( const double ); 00790 TVar<T>& operator *= 00791 ( const TVar<T>& ); 00792 TVar<T>& operator *= 00793 ( const double ); 00794 TVar<T>& operator *= 00795 ( const T& ); 00796 TVar<T>& operator /= 00797 ( const TVar<T>& ); 00798 TVar<T>& operator /= 00799 ( const double ); 00800 00801 private: 00802 00804 TVar 00805 ( TModel<T>*TM, const double d=0. ); 00807 TVar 00808 ( TModel<T>*TM, const T&B ); 00809 00811 double *_coefmon; 00813 T * _bndord; 00815 T * _bndrem; 00817 T _bndT; 00818 00820 void _init(); 00822 void _reinit(); 00824 void _clean(); 00825 00827 void _update_bndord(); 00828 00830 void _center_TM(); 00831 00833 T& _bound 00834 ( T& bndmod ) const; 00836 T& _bound_naive 00837 ( T& bndmod ) const; 00839 T& _bound_LSB 00840 ( T& bndmod ) const; 00842 T& _bound_eigen 00843 ( T& bndmod ) const; 00845 static double* _eigen 00846 ( const unsigned int n, double*a ); 00847 00849 TVar<T> _intpow 00850 ( const TVar<T>&TM, const int n ); 00851 00852 }; 00853 00855 00856 // template <typename T> template <typename U> inline 00857 // TModel<T>::TModel 00858 // ( const TModel<U>&TM ) 00859 // { 00860 // // Set size and copy integer arrays 00861 // _copy_data( TM ); 00862 // 00863 // // Copy bound arrays 00864 // _bndpow = new T*[_nvar]; 00865 // for( unsigned int i=0; i<_nvar; i++ ){ 00866 // if( TM._bndpow[i] ){ 00867 // _bndpow[i] = new T[_nord+1]; 00868 // for( unsigned int k=0; k<_nord+1; k++ ) 00869 // _bndpow[i][k] = T(TM._bndpow[i][k]); 00870 // } 00871 // else 00872 // _bndpow[i] = 0; 00873 // } 00874 // _modvar = true; 00875 // _bndmon = new T[_nmon]; 00876 // for( unsigned int i=0; i<_nmon; i++ ) 00877 // _bndmon[i] = T(TM._bndmon[i]); 00878 // 00879 // return; 00880 // } 00881 // 00882 // template <typename T> template <typename U> inline 00883 // TModel<T>::TModel 00884 // ( const TModel<U>&TM, T (*method)( const U& ) ) 00885 // { 00886 // assert( method ); 00887 // // Set size and copy integer arrays 00888 // _copy_data( TM ); 00889 // 00890 // // Copy bound arrays 00891 // _bndpow = new T*[_nvar]; 00892 // for( unsigned int i=0; i<_nvar; i++ ){ 00893 // if( TM._bndpow[i] ){ 00894 // _bndpow[i] = new T[_nord+1]; 00895 // for( unsigned int k=0; k<_nord+1; k++ ) 00896 // //_bndpow[i][k] = ( method? (*method)( TM._bndpow[i][k] ): 00897 // // T( TM._bndpow[i][k] ) ); 00898 // _bndpow[i][k] = (*method)( TM._bndpow[i][k] ); 00899 // } 00900 // else 00901 // _bndpow[i] = 0; 00902 // } 00903 // _modvar = true; 00904 // _bndmon = new T[_nmon]; 00905 // for( unsigned int i=0; i<_nmon; i++ ) 00906 // //_bndmon[i] = ( method? (*method)( TM._bndmon[i] ): T( TM._bndmon[i] ) ); 00907 // _bndmon[i] = (*method)( TM._bndmon[i] ); 00908 // 00909 // return; 00910 // } 00911 // 00912 // template <typename T> template <typename U> inline 00913 // TModel<T>::TModel 00914 // ( const TModel<U>&TM, const T& (U::*method)() const ) 00915 // { 00916 // // Set size and copy integer arrays 00917 // _copy_data( TM ); 00918 // 00919 // // Copy bound arrays 00920 // _bndpow = new T*[_nvar]; 00921 // for( unsigned int i=0; i<_nvar; i++ ){ 00922 // if( TM._bndpow[i] ){ 00923 // _bndpow[i] = new T[_nord+1]; 00924 // for( unsigned int k=0; k<_nord+1; k++ ) 00925 // _bndpow[i][k] = (TM._bndpow[i][k].*method)(); 00926 // } 00927 // else 00928 // _bndpow[i] = 0; 00929 // } 00930 // _modvar = true; 00931 // _bndmon = new T[_nmon]; 00932 // for( unsigned int i=0; i<_nmon; i++ ) 00933 // _bndmon[i] = (TM._bndmon[i].*method)(); 00934 // } 00935 00936 template <typename T> inline void 00937 TModel<T>::_size 00938 ( const unsigned int nvar, const unsigned int nord ) 00939 { 00940 if( !nvar ) throw Exceptions( Exceptions::SIZE ); 00941 00942 //_cleanup(); 00943 _nvar = nvar; 00944 _nord = nord; 00945 _set_binom(); 00946 _set_posord(); 00947 _nmon = _posord[_nord+1]; 00948 _set_expmon(); 00949 _set_prodmon(); 00950 _bndpow = new T*[_nvar]; 00951 for( unsigned int i=0; i<_nvar; i++ ) _bndpow[i] = 0; 00952 _bndmon = new T[_nmon]; 00953 _refpoint = new double[_nvar]; 00954 _scaling = new double[_nvar]; 00955 _modvar = true; 00956 00957 _TV = new TVar<T>( this ); 00958 } 00959 00960 // template <typename T> template <typename U> inline void 00961 // TModel<T>::_copy_data 00962 // ( const TModel<U>&TM ) 00963 // { 00964 // _nvar = TM._nvar; 00965 // _nord = TM._nord; 00966 // _binom = new unsigned int[(_nvar+_nord-1)*(_nord+1)]; 00967 // for( unsigned int i=0; i<(_nvar+_nord-1)*(_nord+1); i++ ) 00968 // _binom[i] = TM._binom[i]; 00969 // _posord = new unsigned int[_nord+2]; 00970 // for( unsigned int i=0; i<_nord+2; i++ ) 00971 // _posord[i] = TM._posord[i]; 00972 // _nmon = _posord[_nord+1]; 00973 // _expmon = new unsigned int[_nmon*_nvar]; 00974 // for( unsigned int i=0; i<_nord*_nvar; i++ ) 00975 // _expmon[i] = TM._expmon[i]; 00976 // // Copy prodmon 00977 // _prodmon = new unsigned int*[_nmon]; 00978 // _prodmon[0] = new unsigned int[_nmon+1]; 00979 // for( unsigned int i=0; i<_nmon+1; i++ ) 00980 // _prodmon[0][i] = TM._prodmon[0][i]; 00981 // for( unsigned int i=1; i<_nord; i++ ){ 00982 // for( unsigned int j=_posord[i]; j<_posord[i+1]; j++ ){ 00983 // _prodmon[j] = new unsigned int [_posord[_nord+1-i]+1]; 00984 // for( unsigned int k=0; k<_posord[_nord+1-i]+1; k++ ) 00985 // _prodmon[j][k] = TM._prodmon[j][k]; 00986 // } 00987 // } 00988 // for( unsigned int i=_posord[_nord]; i<_nmon; i++ ){ 00989 // _prodmon[i] = new unsigned int[2]; 00990 // for( unsigned int k=0; k<2; k++ ) 00991 // _prodmon[i][k] = TM._prodmon[i][k]; 00992 // } 00993 // // Copy reference and scaling arrays 00994 // _refpoint = new double[_nvar]; 00995 // _scaling = new double[_nvar]; 00996 // for( unsigned int i=0; i<_nvar; i++ ){ 00997 // _refpoint[i] = TM._refpoint[i]; 00998 // _scaling[i] = TM._scaling[i]; 00999 // } 01000 // // Copy options 01001 // options = TM.options; 01002 // } 01003 01004 template <typename T> inline void 01005 TModel<T>::_set_bndpow 01006 ( const unsigned int ivar, const T&X, const double scaling ) 01007 { 01008 if( ivar>=_nvar ) throw Exceptions( Exceptions::INIT ); 01009 01010 delete[] _bndpow[ivar]; 01011 _bndpow[ivar] = new T [_nord+1]; 01012 _refpoint[ivar] = Op<T>::mid(X)/scaling; 01013 _scaling[ivar] = scaling; 01014 T Xr = X/scaling - _refpoint[ivar]; 01015 _bndpow[ivar][0] = 1.; 01016 for( unsigned int i=1; i<=_nord; i++ ){ 01017 _bndpow[ivar][i] = Op<T>::pow(Xr,(int)i); 01018 } 01019 _modvar = true; 01020 } 01021 01022 template <typename T> inline void 01023 TModel<T>::_set_bndmon() 01024 { 01025 if( !_modvar ) return; 01026 01027 _bndmon[0] = 1.; 01028 for( unsigned int i=1; i<_nmon; i++ ){ 01029 _bndmon[i] = 1.; 01030 for( unsigned int j=0; j<_nvar; j++) 01031 if( _bndpow[j] ) _bndmon[i] *= _bndpow[j][_expmon[i*_nvar+j]]; 01032 } 01033 _modvar = false; 01034 01035 #ifdef MC__TMODEL_DEBUG 01036 _display( 1, _nmon, _bndmon, 1, "_bndmon", std::cout ); 01037 #endif 01038 } 01039 01040 template <typename T> inline void 01041 TModel<T>::_set_posord() 01042 { 01043 _posord = new unsigned int[_nord+2]; 01044 _posord[0] = 0; 01045 _posord[1] = 1; 01046 for( unsigned int i=1; i<=_nord; i++ ) 01047 _posord[i+1] = _posord[i] + _get_binom( _nvar+i-1, i ); 01048 01049 #ifdef MC__TMODEL_DEBUG 01050 _display( 1, _nord+2, _posord, 1, "_posord", std::cout ); 01051 #endif 01052 } 01053 01054 template <typename T> inline void 01055 TModel<T>::_set_expmon() 01056 { 01057 _expmon = new unsigned int[_nmon*_nvar]; 01058 unsigned int *iexp = new unsigned int[_nvar] ; 01059 for( unsigned int k=0; k<_nvar; k++ ) _expmon[k] = 0; 01060 for( unsigned int i=1; i<=_nord; i++ ){ 01061 for( unsigned int j=0; j<_nvar; j++ ) iexp[j] = 0; 01062 for( unsigned int j=_posord[i]; j<_posord[i+1]; j++ ){ 01063 _next_expmon( iexp, i ); 01064 for( unsigned int k=0; k<_nvar; k++ ) 01065 _expmon[j*_nvar+k] = iexp[k]; 01066 } 01067 } 01068 delete[] iexp; 01069 01070 #ifdef MC__TMODEL_DEBUG 01071 _display( _nvar, _nmon, _expmon, _nvar, "_expmon", std::cout ); 01072 #endif 01073 } 01074 01075 template <typename T> inline void 01076 TModel<T>::_next_expmon 01077 ( unsigned int *iexp, const unsigned int iord ) 01078 { 01079 unsigned int curord; 01080 do{ 01081 iexp[_nvar-1] += iord; 01082 unsigned int j = _nvar; 01083 while( j > 0 && iexp[j-1] > iord ){ 01084 iexp[j-1] -= iord + 1; 01085 j-- ; 01086 iexp[j-1]++; 01087 } 01088 curord = 0; 01089 for( unsigned int i=0; i<_nvar; i++ ) curord += iexp[i]; 01090 } while( curord != iord ); 01091 } 01092 01093 template <typename T> inline void 01094 TModel<T>::_set_prodmon() 01095 { 01096 _prodmon = new unsigned int*[_nmon]; 01097 _prodmon[0] = new unsigned int[_nmon+1]; 01098 _prodmon[0][0] = _nmon; 01099 for( unsigned int i=1; i<=_nmon; i++ ) _prodmon[0][i] = i-1; 01100 #ifdef MC__TMODEL_DEBUG 01101 std::ostringstream ohead0; 01102 ohead0 << "_prodmon[" << 0 << "]"; 01103 _display( 1, _nmon+1, _prodmon[0], 1, ohead0.str(), std::cout ); 01104 #endif 01105 01106 unsigned int *iexp = new unsigned int[_nvar]; 01107 for( unsigned int i=1; i<_nord; i++ ){ 01108 for( unsigned int j=_posord[i]; j<_posord[i+1]; j++ ){ 01109 _prodmon[j] = new unsigned int [_posord[_nord+1-i]+1]; 01110 _prodmon[j][0] = _posord[_nord+1-i]; 01111 for( unsigned int k=0; k<_posord[_nord+1-i]; k++ ){ 01112 for( unsigned int in=0; in<_nvar; in++ ) 01113 iexp[in] = _expmon[j*_nvar+in] + _expmon[k*_nvar+in] ; 01114 _prodmon[j][k+1] = _loc_expmon( iexp ); 01115 } 01116 #ifdef MC__TMODEL_DEBUG 01117 std::ostringstream oheadj; 01118 oheadj << "_prodmon[" << j << "]"; 01119 _display( 1, _posord[_nord+1-i]+1, _prodmon[j], 1, oheadj.str(), std::cout ); 01120 #endif 01121 } 01122 } 01123 delete[] iexp; 01124 01125 for( unsigned int i=_posord[_nord]; i<_nmon; i++ ){ 01126 _prodmon[i] = new unsigned int[2]; 01127 _prodmon[i][0] = 1; 01128 _prodmon[i][1] = i; 01129 #ifdef MC__TMODEL_DEBUG 01130 std::ostringstream oheadi; 01131 oheadi << "_prodmon[" << i << "]"; 01132 _display( 1, 2, _prodmon[i], 1, oheadi.str(), std::cout ); 01133 #endif 01134 } 01135 } 01136 01137 template <typename T> inline unsigned int 01138 TModel<T>::_loc_expmon 01139 ( const unsigned int *iexp ) 01140 { 01141 unsigned int ord = 0; 01142 for( unsigned int i=0; i<_nvar; i++ ) ord += iexp[i]; 01143 assert( ord<_nord+2 ); 01144 unsigned int pos = _posord[ord]; 01145 01146 unsigned int p = _nvar ; 01147 for( unsigned int i=0; i<_nvar-1; i++ ){ 01148 p--; 01149 for( unsigned int j=0; j<iexp[i]; j++ ) 01150 pos += _get_binom( p-1+ord-j, ord-j ); 01151 ord -= iexp[i]; 01152 } 01153 01154 return pos; 01155 } 01156 01157 template <typename T> inline void 01158 TModel<T>::_set_binom() 01159 { 01160 _binom = new unsigned int[(_nvar+_nord-1)*(_nord+1)]; 01161 unsigned int *p, k; 01162 for( unsigned int i=0; i<_nvar+_nord-1; i++ ){ 01163 p = &_binom[i*(_nord+1)]; 01164 *p = 1; 01165 p++; 01166 *p = i+1; 01167 p++; 01168 k = ( i+1<_nord? i+1: _nord ); 01169 for( unsigned int j=2; j<=k; j++, p++ ) *p = *(p-1) * (i+2-j)/j; 01170 for( unsigned int j=k+1; j<=_nord; j++, p++ ) *p = 0.; 01171 } 01172 #ifdef MC__TMODEL_DEBUG 01173 _display( _nord+1, _nvar+_nord-1, _binom, _nord+1, "_binom", std::cout ); 01174 #endif 01175 } 01176 01177 template <typename T> inline unsigned int 01178 TModel<T>::_get_binom 01179 ( const unsigned int n, const unsigned int k ) const 01180 { 01181 #ifdef MC__TMODEL_CHECK 01182 assert( n>0 && n<_nord+_nvar && k<=n ); 01183 #endif 01184 return _binom[(n-1)*(_nord+1)+k] ; 01185 } 01186 01187 template <typename T> inline void 01188 TModel<T>::_reset() 01189 { 01190 for( unsigned int i=0; i<_nvar; i++ ){ 01191 delete[] _bndpow[i]; 01192 _bndpow[i] = 0; 01193 } 01194 } 01195 01196 template <typename T> inline void 01197 TModel<T>::_cleanup() 01198 { 01199 for( unsigned int i=0; i<_nmon; i++ ) delete[] _prodmon[i]; 01200 delete[] _prodmon; 01201 delete[] _expmon; 01202 delete[] _posord; 01203 for( unsigned int i=0; i<_nvar; i++ ) delete[] _bndpow[i]; 01204 delete[] _bndpow; 01205 delete[] _bndmon; 01206 delete[] _refpoint; 01207 delete[] _scaling; 01208 delete[] _binom; 01209 delete _TV; 01210 } 01211 01212 template <typename T> template< typename U > inline void 01213 TModel<T>::_display 01214 ( const unsigned int m, const unsigned int n, U*&a, const unsigned int lda, 01215 const std::string&stra, std::ostream&os ) 01216 { 01217 os << stra << " =" << std::endl << std::scientific 01218 << std::setprecision(5); 01219 for( unsigned int im=0; a && im<m; im++ ){ 01220 for( unsigned int in=0; in<n; in++ ){ 01221 os << a[in*lda+im] << " "; 01222 } 01223 os << std::endl; 01224 } 01225 os << std::endl; 01226 01227 if( os == std::cout || os == std::cerr ) pause(); 01228 } 01229 01230 template <typename T> void 01231 TModel<T>::pause() 01232 { 01233 double tmp; 01234 std::cout << "ENTER <1> TO CONTINUE" << std::endl; 01235 std::cin >> tmp; 01236 } 01237 01239 01240 template <typename T> inline 01241 TVar<T>::TVar 01242 ( const double d ) 01243 : _TM( 0 ), _bndT( d ) 01244 { 01245 _init(); 01246 _coefmon[0] = d; 01247 _bndord[0] = 0.; 01248 } 01249 01250 template <typename T> inline TVar<T>& 01251 TVar<T>::operator = 01252 ( const double d ) 01253 { 01254 if( _TM ){ _TM = 0; _reinit(); } 01255 _coefmon[0] = d; 01256 _bndord[0] = 0.; 01257 return *this; 01258 } 01259 01260 template <typename T> inline 01261 TVar<T>::TVar 01262 ( TModel<T>*TM, const double d ) 01263 : _TM( TM ) 01264 { 01265 if( !_TM ){ 01266 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INIT ); 01267 } 01268 _init(); 01269 _coefmon[0] = d; 01270 for( unsigned int i=1; i<_nmon(); i++ ) _coefmon[i] = 0.; 01271 _bndord[0] = d; 01272 for( unsigned int i=1; i<_nord()+2; i++) _bndord[i] = 0.; 01273 if( _TM->options.PROPAGATE_BNDT ) _bndT = d; 01274 } 01275 01276 template <typename T> inline 01277 TVar<T>::TVar 01278 ( const T&B ) 01279 : _TM( 0 ), _bndT( B ) 01280 { 01281 _init(); 01282 _coefmon[0] = 0.; 01283 _bndord[0] = B; 01284 } 01285 01286 template <typename T> inline TVar<T>& 01287 TVar<T>::operator = 01288 ( const T&B ) 01289 { 01290 if( _TM ){ _TM = 0; _reinit(); } 01291 _coefmon[0] = 0.; 01292 _bndord[0] = B; 01293 return *this; 01294 } 01295 01296 template <typename T> inline 01297 TVar<T>::TVar 01298 ( TModel<T>*TM, const T&B ) 01299 : _TM( TM ) 01300 { 01301 if( !_TM ) throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INIT ); 01302 _init(); 01303 for( unsigned int i=0; i<_nmon(); i++ ) _coefmon[i] = 0.; 01304 for( unsigned int i=0; i<_nord()+1; i++) _bndord[i] = 0.; 01305 *_bndrem = B; 01306 if( _TM->options.PROPAGATE_BNDT ) _bndT = B; 01307 if( _TM->options.CENTER_REMAINDER ) _center_TM(); 01308 } 01309 01310 template <typename T> inline 01311 TVar<T>::TVar 01312 ( const TVar<T>&TV ) 01313 : _TM(0) 01314 { 01315 _init(); 01316 *this = TV; 01317 } 01318 01319 template <typename T> inline TVar<T>& 01320 TVar<T>::operator = 01321 ( const TVar<T>&TV ) 01322 { 01323 // Same TVar 01324 if( this == &TV ) return *this; 01325 01326 // Reinitialization needed? 01327 if( _TM != TV._TM ){ _TM = TV._TM; _reinit(); } 01328 01329 // Set to TVar not linked to TModel (either scalar or range) 01330 if( !_TM ){ 01331 _coefmon[0] = TV._coefmon[0]; 01332 _bndord[0] = TV._bndord[0]; 01333 return *this; 01334 } 01335 // Set to TVar linked to TModel 01336 for( unsigned int i=0; i<_nmon(); i++ ) _coefmon[i] = TV._coefmon[i]; 01337 for( unsigned int i=0; i<_nord()+2; i++) _bndord[i] = TV._bndord[i]; 01338 if( _TM->options.PROPAGATE_BNDT ) _bndT = TV._bndT; 01339 return *this; 01340 } 01341 01342 template <typename T> template <typename U> inline 01343 TVar<T>::TVar 01344 ( TModel<T>*&TM, const TVar<U>&TV ) 01345 : _TM(TM), _coefmon(0), _bndord(0), _bndrem(0) 01346 { 01347 _init(); 01348 TVar<U> TVtrunc( TV ); 01349 _coefmon[0] = TVtrunc._coefmon[0]; 01350 TVtrunc._coefmon[0] = 0. ; 01351 for( unsigned int i=1; _TM && i<_nmon(); i++ ){ 01352 if( TVtrunc._TM && i < TVtrunc._nmon() ){ 01353 _coefmon[i] = TVtrunc._coefmon[i]; 01354 TVtrunc._coefmon[i] = 0.; 01355 } 01356 else 01357 _coefmon[i] = 0.; 01358 } 01359 TVtrunc._update_bndord(); 01360 *_bndrem = T( TVtrunc.B() ); 01361 if( !_TM ) return; 01362 _update_bndord(); 01363 // std::cout << TV; 01364 // std::cout << *this; 01365 // int dum; std::cin >> dum; 01366 if( _TM->options.PROPAGATE_BNDT ) _bndT = T( TV._bndT ); 01367 return; 01368 } 01369 01370 // template <typename T> template <typename U> inline 01371 // TVar<T>::TVar 01372 // ( TModel<T>*&TM, const TVar<U>&TV ) 01373 // : _TM(TM), _coefmon(0), _bndord(0), _bndrem(0) 01374 // { 01375 // if( !_TM && TV._TM ) 01376 // throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INIT ); 01377 // 01378 // // Set to TVar linked to TModel 01379 // //if( !_TM && TV._TM ) _TM = new TModel<T>( *(TV._TM) ); 01380 // 01381 // _init(); 01382 // if( !_TM ){ 01383 // _coefmon[0] = TV._coefmon[0]; 01384 // *_bndrem = T( *TV._bndrem ); 01385 // } 01386 // else{ 01387 // _coefmon[0] = TV._coefmon[0]; 01388 // for( unsigned int i=1; i<_nmon(); i++ ) 01389 // _coefmon[i] = ( TV._TM? TV._coefmon[i]: 0. ); 01390 // *_bndrem = T( *TV._bndrem ); 01391 // _update_bndord(); 01392 // if( _TM->options.PROPAGATE_BNDT ) _bndT = T( TV._bndT ); 01393 // } 01394 // return; 01395 // } 01396 01397 template <typename T> template <typename U> inline 01398 TVar<T>::TVar 01399 ( TModel<T>*&TM, const TVar<U>&TV, T (*method)( const U& ) ) 01400 : _TM(TM), _coefmon(0), _bndord(0), _bndrem( 0 ) 01401 { 01402 if( !method ) 01403 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INIT ); 01404 _init(); 01405 TVar<U> TVtrunc( TV ); 01406 _coefmon[0] = TVtrunc._coefmon[0]; 01407 TVtrunc._coefmon[0] = 0. ; 01408 for( unsigned int i=1; _TM && i<_nmon(); i++ ){ 01409 if( TVtrunc._TM && i < TVtrunc._nmon() ){ 01410 _coefmon[i] = TVtrunc._coefmon[i]; 01411 TVtrunc._coefmon[i] = 0.; 01412 } 01413 else 01414 _coefmon[i] = 0.; 01415 } 01416 TVtrunc._update_bndord(); 01417 *_bndrem = (*method)( TVtrunc.B() ); 01418 if( !_TM ) return; 01419 _update_bndord(); 01420 if( _TM->options.PROPAGATE_BNDT ) _bndT = (*method)( TV._bndT ); 01421 return; 01422 } 01423 01424 // template <typename T> template <typename U> inline 01425 // TVar<T>::TVar 01426 // ( TModel<T>*&TM, const TVar<U>&TV, T (*method)( const U& ) ) 01427 // : _TM(TM), _coefmon(0), _bndord(0), _bndrem( 0 ) 01428 // { 01429 // if( !method || ( !_TM && TV._TM ) ) 01430 // throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INIT ); 01431 // 01432 // // Set to TVar linked to TModel 01433 // //if( !_TM && TV._TM ) _TM = new TModel<T>( *(TV._TM), method ); 01434 // 01435 // _init(); 01436 // if( !_TM ){ 01437 // _coefmon[0] = TV._coefmon[0]; 01438 // *_bndrem = (*method)( *TV._bndrem ); 01439 // } 01440 // else{ 01441 // _coefmon[0] = TV._coefmon[0]; 01442 // for( unsigned int i=1; i<_nmon(); i++ ) 01443 // _coefmon[i] = ( TV._TM? TV._coefmon[i]: 0. ); 01444 // *_bndrem = (*method)( *TV._bndrem ); 01445 // _update_bndord(); 01446 // if( _TM->options.PROPAGATE_BNDT ) _bndT = (*method)( TV._bndT ); 01447 // } 01448 // return; 01449 // } 01450 01451 template <typename T> template <typename U> inline 01452 TVar<T>::TVar 01453 ( TModel<T>*&TM, const TVar<U>&TV, const T& (U::*method)() const ) 01454 : _TM(TM), _coefmon(0), _bndord(0), _bndrem( 0 ) 01455 { 01456 if( !method ) 01457 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INIT ); 01458 _init(); 01459 TVar<U> TVtrunc( TV ); 01460 _coefmon[0] = TVtrunc._coefmon[0]; 01461 TVtrunc._coefmon[0] = 0. ; 01462 for( unsigned int i=1; _TM && i<_nmon(); i++ ){ 01463 if( TVtrunc._TM && i < TVtrunc._nmon() ){ 01464 _coefmon[i] = TVtrunc._coefmon[i]; 01465 TVtrunc._coefmon[i] = 0.; 01466 } 01467 else 01468 _coefmon[i] = 0.; 01469 } 01470 TVtrunc._update_bndord(); 01471 *_bndrem = (TVtrunc.B().*method)(); 01472 if( !_TM ) return; 01473 _update_bndord(); 01474 if( _TM->options.PROPAGATE_BNDT ) _bndT = (TV._bndT.*method)(); 01475 return; 01476 } 01477 01478 // template <typename T> template <typename U> inline 01479 // TVar<T>::TVar 01480 // ( TModel<T>*&TM, const TVar<U>&TV, const T& (U::*method)() const ) 01481 // : _TM(TM), _coefmon(0), _bndord(0), _bndrem( 0 ) 01482 // { 01483 // if( !_TM && TV._TM ) 01484 // throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INIT ); 01485 // 01486 // // Set to TVar linked to TModel 01487 // //if( !_TM && TV._TM ) _TM = new TModel<T>( *(TV._TM), method ); 01488 // 01489 // _init(); 01490 // if( !_TM ){ 01491 // _coefmon[0] = TV._coefmon[0]; 01492 // *_bndrem = (TV._bndrem->*method)(); 01493 // } 01494 // else{ 01495 // _coefmon[0] = TV._coefmon[0]; 01496 // for( unsigned int i=1; i<_nmon(); i++ ) 01497 // _coefmon[i] = ( TV._TM? TV._coefmon[i]: 0. ); 01498 // *_bndrem = (TV._bndrem->*method)(); 01499 // _update_bndord(); 01500 // if( _TM->options.PROPAGATE_BNDT ) _bndT = (TV._bndT.*method)(); 01501 // } 01502 // return; 01503 // } 01504 01505 template <typename T> inline 01506 TVar<T>::TVar 01507 ( TModel<T>*TM, const unsigned int ivar, const T&X ) 01508 : _TM( TM ) 01509 { 01510 if( !TM ){ 01511 std::cerr << "No Environment!\n"; 01512 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INIT ); 01513 } 01514 01515 // Scale variables and keep track of them in TModel 01516 double scaling = ( _TM->options.SCALE_VARIABLES? Op<T>::diam(X)/2.: 1. ); 01517 if( isequal( scaling, 0. ) ) scaling = 1.; 01518 //if( isequal( scaling, 0. ) ){ 01519 // std::cerr << "P(" << ivar << ") = " << X << std::endl; 01520 // throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::SCALING ); 01521 //} 01522 _TM->_set_bndpow( ivar, X, scaling ); 01523 _TM->_set_bndmon(); 01524 _init(); 01525 01526 // Populate _coefmon w/ TVar coefficients 01527 _coefmon[0] = Op<T>::mid(X); 01528 for( unsigned int i=1; i<_nmon(); i++ ) _coefmon[i] = 0.; 01529 if( _nord() > 0 ) _coefmon[_nvar()-ivar] = scaling; 01530 01531 // Populate _bndord w/ bounds on TVar terms 01532 _bndord[0] = _coefmon[0]; 01533 _bndord[1] = X-_coefmon[0]; 01534 for( unsigned int i=2; i<_nord()+2; i++) _bndord[i] = 0.; 01535 if( _TM->options.PROPAGATE_BNDT ) _bndT = X; 01536 } 01537 01538 template <typename T> inline void 01539 TVar<T>::_init() 01540 { 01541 if( !_TM ){ 01542 _coefmon = new double[1]; 01543 _bndord = new T[1]; 01544 _bndrem = _bndord; 01545 return; 01546 } 01547 _coefmon = new double[_nmon()]; 01548 _bndord = new T[_nord()+2]; 01549 _bndrem = _bndord + _nord()+1; 01550 } 01551 01552 template <typename T> inline void 01553 TVar<T>::_clean() 01554 { 01555 delete [] _coefmon; delete [] _bndord; 01556 _coefmon = 0; _bndord = _bndrem = 0; 01557 } 01558 01559 template <typename T> inline void 01560 TVar<T>::_reinit() 01561 { 01562 _clean(); _init(); 01563 } 01564 01565 template <typename T> inline void 01566 TVar<T>::_update_bndord() 01567 { 01568 if( !_TM ) return; 01569 _TM->_set_bndmon(); 01570 _bndord[0] = _coefmon[0]; 01571 for( unsigned int i=1; i<=_nord(); i++ ){ 01572 _bndord[i] = 0.; 01573 for( unsigned int j=_posord(i); j<_posord(i+1); j++ ) 01574 _bndord[i] += _coefmon[j] * _bndmon(j); 01575 } 01576 } 01577 01578 template <typename T> inline void 01579 TVar<T>::_center_TM() 01580 { 01581 const double remmid = Op<T>::mid(*_bndrem); 01582 _coefmon[0] += remmid; 01583 if( _TM ) _bndord[0] = _coefmon[0]; 01584 *_bndrem -= remmid; 01585 } 01586 01587 template <typename T> inline double* 01588 TVar<T>::_eigen 01589 ( const unsigned int n, double*a ) 01590 { 01591 int info; 01592 double*d = new double[n]; 01593 #ifdef MC__TVAR_DEBUG_EIGEN 01594 TModel<T>::_display( n, n, a, n, "Matrix Q", std::cout ); 01595 #endif 01596 01597 // get optimal size 01598 double worktmp; 01599 int lwork = -1; 01600 dsyev_( "Vectors", "Upper", &n, a, &n, d, &worktmp, &lwork, &info ); 01601 01602 // perform eigenvalue decomposition 01603 lwork = (int)worktmp; 01604 double*work = new double[lwork]; 01605 dsyev_( "Vectors", "Upper", &n, a, &n, d, work, &lwork, &info ); 01606 #ifdef MC__TVAR_DEBUG_EIGEN 01607 TModel<T>::_display( n, n, a, n, "Matrix U", std::cout ); 01608 TModel<T>::_display( 1, n, d, 1, "Matrix D", std::cout ); 01609 #endif 01610 delete[] work; 01611 01612 #ifdef MC__TVAR_DEBUG_EIGEN 01613 std::cout << "INFO: " << info << std::endl; 01614 TModel<T>::pause(); 01615 #endif 01616 if( info ){ delete[] d; return 0; } 01617 return d; 01618 } 01619 01620 template <typename T> inline T& 01621 TVar<T>::_bound_eigen 01622 ( T& bndmod ) const 01623 { 01624 static const double TOL = 1e-8; 01625 01626 bndmod = _coefmon[0]; 01627 if( _nord() == 1 ) bndmod += _bndord[1]; 01628 01629 else if( _nord() > 1 ){ 01630 double*U = new double[_nvar()*_nvar()]; 01631 for( unsigned int i=0; i<_nvar(); i++ ){ 01632 for( unsigned int j=0; j<i; j++ ){ 01633 U[_nvar()*(_nvar()-i-1)+_nvar()-j-1] = 0.; 01634 U[_nvar()*(_nvar()-j-1)+_nvar()-i-1] = _coefmon[_prodmon(i+1,j+2)]/2.; 01635 } 01636 U[(_nvar()+1)*(_nvar()-i-1)] = _coefmon[_prodmon(i+1,i+2)]; 01637 } 01638 double*D = _eigen( _nvar(), U ); 01639 if( !D ){ 01640 delete[] U; 01641 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::EIGEN ); 01642 } 01643 01644 #ifdef MC__TVAR_HYBRID_EIGEN 01645 T bndtype1(0.); 01646 #endif 01647 T bndtype2(0.); 01648 for( unsigned int i=0; i<_nvar(); i++ ){ 01649 double linaux = 0.; 01650 T bndaux(0.); 01651 for( unsigned int k=0; k<_nvar(); k++ ){ 01652 linaux += U[i*_nvar()+k] * _coefmon[_nvar()-k]; 01653 bndaux += U[i*_nvar()+k] * _bndmon(_nvar()-k); 01654 } 01655 #ifdef MC__TVAR_DEBUG_EIGEN 01656 std::cout << i << ": LINAUX = " << linaux 01657 << " BNDAUX = " << bndaux << std::endl; 01658 #endif 01659 #ifdef MC__TVAR_HYBRID_EIGEN 01660 bndtype1 += _coefmon[i+1] * _bndmon(i+1) + D[i] * Op<T>::sqr( bndaux ); 01661 #endif 01662 #ifdef MC__TVAR_DEBUG_EIGEN 01663 std::cout << std::endl << "BNDTYPE1: " << bndtype1 << std::endl; 01664 #endif 01665 if( std::fabs(D[i]) > TOL ) 01666 bndtype2 += D[i] * Op<T>::sqr( linaux/D[i]/2. + bndaux ) 01667 - linaux*linaux/D[i]/4.; 01668 else 01669 //bndtype2 += _coefmon[i+1] * _bndmon(i+1) + D[i] * Op<T>::sqr( bndaux ); 01670 bndtype2 += linaux * bndaux + D[i] * Op<T>::sqr( bndaux ); 01671 #ifdef MC__TVAR_DEBUG_EIGEN 01672 std::cout << "BNDTYPE2: " << bndtype2 << std::endl; 01673 #endif 01674 } 01675 delete[] U; 01676 delete[] D; 01677 01678 #ifdef MC__TVAR_HYBRID_EIGEN 01679 if( !Op<T>::inter( bndtype1, bndtype1, bndtype2 ) ){ 01680 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INCON ); 01681 #ifdef MC__TVAR_DEBUG_EIGEN 01682 std::cout << "BNDTYPE3: " << bndtype1 << std::endl; 01683 #endif 01684 } 01685 bndmod += bndtype1; 01686 #else 01687 bndmod += bndtype2; 01688 #endif 01689 } 01690 #ifdef MC__TVAR_DEBUG_EIGEN 01691 int tmp; std::cin >> tmp; 01692 #endif 01693 01694 for( unsigned int i=3; i<=_nord(); i++ ) bndmod += _bndord[i]; 01695 bndmod += *_bndrem; 01696 01697 return bndmod; 01698 } 01699 01700 template <typename T> inline T& 01701 TVar<T>::_bound_LSB 01702 ( T& bndmod ) const 01703 { 01704 static const double TOL = 1e-8; 01705 bndmod = _coefmon[0]; 01706 if( _nord() == 1 ) bndmod += _bndord[1]; 01707 else if( _nord() > 1 ){ 01708 for( unsigned int i=1; i<=_nvar(); i++ ){ 01709 // linear and diagonal quadratic terms 01710 unsigned int ii = _prodmon(i,i+1); 01711 if( std::fabs(_coefmon[ii]) > TOL ) 01712 bndmod += _coefmon[ii] * Op<T>::sqr( _coefmon[i]/_coefmon[ii]/2. 01713 + _bndmon(i) ) - _coefmon[i]*_coefmon[i]/_coefmon[ii]/4.; 01714 else 01715 bndmod += _coefmon[i] * _bndmon(i) + _coefmon[ii] * _bndmon(ii); 01716 // off-diagonal quadratic terms 01717 for( unsigned int k=i+1; k<=_nvar(); k++ ){ 01718 unsigned int ik = _prodmon(i,k+1) ; 01719 bndmod += _coefmon[ik] * _bndmon(ik); 01720 } 01721 } 01722 } 01723 // higher-order terms 01724 for( unsigned int i=3; i<=_nord(); i++ ) bndmod += _bndord[i]; 01725 bndmod += *_bndrem; 01726 return bndmod; 01727 } 01728 01729 template <typename T> inline T& 01730 TVar<T>::_bound_naive 01731 ( T& bndmod ) const 01732 { 01733 bndmod = _coefmon[0]; 01734 for( unsigned int i=1; i<=_nord()+1; i++ ) bndmod += _bndord[i]; 01735 return bndmod; 01736 } 01737 01738 template <typename T> inline T& 01739 TVar<T>::_bound 01740 ( T& bndmod ) const 01741 { 01742 if( !_TM ){ bndmod = _coefmon[0] + _bndord[0]; return bndmod; } 01743 01744 switch( _TM->options.BOUNDER_TYPE ){ 01745 case TModel<T>::Options::NAIVE: bndmod = _bound_naive(bndmod); break; 01746 case TModel<T>::Options::LSB: bndmod = _bound_LSB(bndmod); break; 01747 case TModel<T>::Options::EIGEN: bndmod = _bound_eigen(bndmod); break; 01748 case TModel<T>::Options::HYBRID: default:{ 01749 T bndlsb(0.), bndeig(0.); 01750 if( !Op<T>::inter( bndmod, _bound_LSB(bndlsb), _bound_eigen(bndeig) ) ) 01751 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INCON ); 01752 } 01753 } 01754 01755 if( _TM->options.PROPAGATE_BNDT && _TM->options.INTER_WITH_BNDT 01756 && !Op<T>::inter( bndmod, bndmod, _bndT ) ) 01757 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INCON ); 01758 01759 return bndmod; 01760 } 01761 01762 template <typename T> inline double 01763 TVar<T>::polynomial 01764 ( const double*x ) const 01765 { 01766 if( !_TM ) return _coefmon[0]; 01767 double Pval = _coefmon[0]; 01768 for( unsigned int i=1; i<_nmon(); i++ ){ 01769 double valmon = 1.; 01770 for( unsigned int k=0; k<_nvar(); k++ ) 01771 valmon *= std::pow( x[k]/_scaling(k)-_refpoint(k), 01772 _expmon(i*_nvar()+k) ); 01773 Pval += _coefmon[i] * valmon; 01774 } 01775 return Pval; 01776 } 01777 01778 template <typename T> inline double* 01779 TVar<T>::reference() const 01780 { 01781 if( !_TM ) return 0; 01782 if( _nvar() < 1 ) return 0; 01783 double*pref = new double[_nvar()]; 01784 for( unsigned int i=0; i<_nvar(); i++ ) pref[i] = _refpoint(i)*_scaling(i); 01785 return pref; 01786 } 01787 01788 template <typename T> inline double 01789 TVar<T>::constant() const 01790 { 01791 return _coefmon[0]; 01792 } 01793 01794 template <typename T> inline double* 01795 TVar<T>::linear() const 01796 { 01797 if( !_TM || !_nvar() || !_nord() ) return 0; 01798 01799 double*plin = new double[_nvar()]; 01800 for( unsigned int i=0; i<_nvar(); i++ ) 01801 plin[i] = _coefmon[_nvar()-i] / _scaling(i); 01802 return plin; 01803 } 01804 01805 template <typename T> inline double* 01806 TVar<T>::quadratic 01807 ( const int opt ) const 01808 { 01809 if( !_TM || !_nvar() || _nord() < 2 ) return 0; 01810 01811 if( opt == 0 ){ 01812 double*pquad = new double[_nvar()]; 01813 for( unsigned int i=0; i<_nvar(); i++ ) 01814 pquad[_nvar()-i-1] = _coefmon[_prodmon(i+1,i+2)] 01815 / _scaling(_nvar()-i-1) / _scaling(_nvar()-i-1); 01816 return pquad; 01817 } 01818 01819 double*pquad = new double[_nvar()*_nvar()]; 01820 for( unsigned int i=0; i<_nvar(); i++ ){ 01821 for( unsigned int j=0; j<i; j++ ){ 01822 pquad[_nvar()*(_nvar()-i-1)+_nvar()-j-1] = 0.; 01823 pquad[_nvar()*(_nvar()-j-1)+_nvar()-i-1] = _coefmon[_prodmon(i+1,j+2)]/2. 01824 / _scaling(_nvar()-i-1) / _scaling(_nvar()-j-1); 01825 } 01826 pquad[(_nvar()+1)*(_nvar()-i-1)] = _coefmon[_prodmon(i+1,i+2)] 01827 / _scaling(_nvar()-i-1) / _scaling(_nvar()-i-1); 01828 } 01829 return pquad; 01830 } 01831 01832 template <typename T> inline std::ostream& 01833 operator << 01834 ( std::ostream&out, const TVar<T>&TV ) 01835 { 01836 const unsigned int iprec = 5; 01837 out << std::endl 01838 << std::scientific << std::setprecision(iprec) << std::right; 01839 01840 // Display constant model 01841 if( !TV._TM ){ 01842 out << " a0 = " << std::right << std::setw(12) << TV._coefmon[0] 01843 << std::endl << std::endl; 01844 out << " Order: Bound:" << std::endl; 01845 out << std::setw(8) << "R" << " " << *(TV._bndrem) << std::endl; 01846 } 01847 01848 // Display monomial term coefficients and corresponding exponents 01849 else{ 01850 for( unsigned int i=0; i<TV._nmon(); i++ ){ 01851 out << " a" << std::left << std::setw(3) << i << " = " 01852 << std::right << std::setw(12) << TV._coefmon[i] << " "; 01853 for( unsigned int k=0; k<TV._nvar(); k++ ) 01854 out << std::setw(3) << TV._expmon(i*TV._nvar()+k); 01855 out << " B" << std::left << std::setw(3) << i << " = " 01856 << TV._bndmon(i) << std::endl; 01857 } 01858 out << std::endl; 01859 01860 // Display bounds on terms of order 0,...,nord and remainder term 01861 out << " Order: Bound:" << std::endl; 01862 for( unsigned int i=0; i<=TV._nord(); i++ ) 01863 out << std::right << std::setw(8) << i << " " << TV._bndord[i] 01864 << std::endl; 01865 out << std::right << std::setw(8) << "R" << " " << *(TV._bndrem) 01866 << std::endl << std::endl 01867 << " TM Bounder:" << std::right << TV._TM->options.BOUNDER_TYPE; 01868 } 01869 01870 // Display Taylor model bounds 01871 out << std::endl 01872 << " TM Bound:" << std::right << std::setw(12) << TV.B() 01873 << std::endl; 01874 if( TV._TM && TV._TM->options.PROPAGATE_BNDT ) 01875 out << " T Bound:" << std::right << std::setw(12) << TV.boundT() 01876 << std::endl; 01877 01878 return out; 01879 } 01880 01881 template <typename T> inline TVar<T> 01882 operator + 01883 ( const TVar<T>&TV ) 01884 { 01885 return TV; 01886 } 01887 01888 template <typename T> template <typename U> inline TVar<T>& 01889 TVar<T>::operator += 01890 ( const TVar<U>&TV ) 01891 { 01892 if( !TV._TM ){ 01893 if( _TM && _TM->options.PROPAGATE_BNDT ) _bndT += TV._bndT; 01894 _coefmon[0] += TV._coefmon[0]; 01895 *_bndrem += *(TV._bndrem); 01896 } 01897 else if( !_TM ){ 01898 TVar<T> TV2(*this); 01899 *this = TV; *this += TV2; 01900 } 01901 else{ 01902 if( _TM != TV._TM ) 01903 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::TMODEL ); 01904 if( _TM->options.PROPAGATE_BNDT ) _bndT += TV._bndT; 01905 for( unsigned int i=0; i<_nmon(); i++ ) 01906 _coefmon[i] += TV._coefmon[i]; 01907 *_bndrem += *(TV._bndrem); 01908 _update_bndord(); 01909 } 01910 if( _TM && _TM->options.CENTER_REMAINDER ) _center_TM(); 01911 return *this; 01912 } 01913 01914 template <typename T, typename U> inline TVar<T> 01915 operator + 01916 ( const TVar<T>&TV1, const TVar<U>&TV2 ) 01917 { 01918 TVar<T> TV3( TV1 ); 01919 TV3 += TV2; 01920 return TV3; 01921 } 01922 01923 template <typename T> inline TVar<T>& 01924 TVar<T>::operator += 01925 ( const double c ) 01926 { 01927 _coefmon[0] += c; 01928 if( _TM ) _bndord[0] = _coefmon[0]; 01929 if( _TM && _TM->options.PROPAGATE_BNDT ) _bndT += c; 01930 return *this; 01931 } 01932 01933 template <typename T> inline TVar<T> 01934 operator + 01935 ( const TVar<T>&TV1, const double c ) 01936 { 01937 TVar<T> TV3( TV1 ); 01938 TV3 += c; 01939 return TV3; 01940 } 01941 01942 template <typename T> inline TVar<T> 01943 operator + 01944 ( const double c, const TVar<T>&TV2 ) 01945 { 01946 TVar<T> TV3( TV2 ); 01947 TV3 += c; 01948 return TV3; 01949 } 01950 01951 template <typename T> template <typename U> inline TVar<T>& 01952 TVar<T>::operator += 01953 ( const U&I ) 01954 { 01955 *_bndrem += I; 01956 if( _TM && _TM->options.PROPAGATE_BNDT ) _bndT += I; 01957 if( _TM && _TM->options.CENTER_REMAINDER ) _center_TM(); 01958 return *this; 01959 } 01960 01961 template <typename T, typename U> inline TVar<T> 01962 operator + 01963 ( const TVar<T>&TV1, const U&I ) 01964 { 01965 TVar<T> TV3( TV1 ); 01966 TV3 += I; 01967 return TV3; 01968 } 01969 01970 template <typename T, typename U> inline TVar<T> 01971 operator + 01972 ( const U&I, const TVar<T>&TV2 ) 01973 { 01974 TVar<T> TV3( TV2 ); 01975 TV2 += I; 01976 return TV3; 01977 } 01978 01979 template <typename T> inline TVar<T> 01980 operator - 01981 ( const TVar<T>&TV ) 01982 { 01983 if( !TV._TM ){ 01984 TVar<T> TV2; 01985 TV2._coefmon[0] = -TV._coefmon[0]; 01986 TV2._bndord[0] = -TV._bndord[0]; 01987 return TV2; 01988 } 01989 TVar<T>& TV2 = *TV._TV(); 01990 //TVar<T> TV2( TV._TM ); 01991 for( unsigned int i=0; i<TV._nmon(); i++ ) TV2._coefmon[i] = -TV._coefmon[i]; 01992 for( unsigned int i=0; i<TV._nord()+2; i++ ) TV2._bndord[i] = -TV._bndord[i]; 01993 if( TV._TM->options.PROPAGATE_BNDT ) TV2._bndT = -TV._bndT; 01994 if( TV._TM->options.CENTER_REMAINDER ) TV2._center_TM(); 01995 return TV2; 01996 } 01997 01998 template <typename T> template <typename U> inline TVar<T>& 01999 TVar<T>::operator -= 02000 ( const TVar<U>&TV ) 02001 { 02002 if( !TV._TM ){ 02003 if( _TM && _TM->options.PROPAGATE_BNDT ) _bndT -= TV._bndT; 02004 _coefmon[0] -= TV._coefmon[0]; 02005 *_bndrem -= *(TV._bndrem); 02006 } 02007 else if( !_TM ){ 02008 TVar<T> TV2(*this); 02009 *this = -TV; *this += TV2; 02010 } 02011 else{ 02012 if( _TM != TV._TM ) 02013 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::TMODEL ); 02014 if( _TM->options.PROPAGATE_BNDT ) _bndT -= TV._bndT; 02015 for( unsigned int i=0; i<_nmon(); i++ ) 02016 _coefmon[i] -= TV._coefmon[i]; 02017 *_bndrem -= *(TV._bndrem); 02018 _update_bndord(); 02019 } 02020 if( _TM && _TM->options.CENTER_REMAINDER ) _center_TM(); 02021 return *this; 02022 } 02023 02024 template <typename T, typename U> inline TVar<T> 02025 operator- 02026 ( const TVar<T>&TV1, const TVar<U>&TV2 ) 02027 { 02028 TVar<T> TV3( TV1 ); 02029 TV3 -= TV2; 02030 return TV3; 02031 } 02032 02033 template <typename T> inline TVar<T>& 02034 TVar<T>::operator -= 02035 ( const double c ) 02036 { 02037 _coefmon[0] -= c; 02038 if( _TM ) _bndord[0] = _coefmon[0]; 02039 if( _TM && _TM->options.PROPAGATE_BNDT ) _bndT -= c; 02040 return *this; 02041 } 02042 02043 template <typename T> inline TVar<T> 02044 operator - 02045 ( const TVar<T>&TV1, const double c ) 02046 { 02047 TVar<T> TV3( TV1 ); 02048 TV3 -= c; 02049 return TV3; 02050 } 02051 02052 template <typename T> inline TVar<T> 02053 operator - 02054 ( const double c, const TVar<T>&TV2 ) 02055 { 02056 TVar<T> TV3( -TV2 ); 02057 TV3 += c; 02058 return TV3; 02059 } 02060 02061 template <typename T> template <typename U> inline TVar<T>& 02062 TVar<T>::operator -= 02063 ( const U&I ) 02064 { 02065 *_bndrem -= I; 02066 if( _TM && _TM->options.PROPAGATE_BNDT ) _bndT -= I; 02067 if( _TM && _TM->options.CENTER_REMAINDER ) _center_TM(); 02068 return *this; 02069 } 02070 02071 template <typename T, typename U> inline TVar<T> 02072 operator - 02073 ( const TVar<T>&TV1, const U&I ) 02074 { 02075 TVar<T> TV3( TV1 ); 02076 TV3 -= I; 02077 return TV3; 02078 } 02079 02080 template <typename T, typename U> inline TVar<T> 02081 operator - 02082 ( const U&I, const TVar<T>&TV2 ) 02083 { 02084 TVar<T> TV3( -TV2 ); 02085 TV3 += I; 02086 return TV3; 02087 } 02088 02089 template <typename T> inline TVar<T>& 02090 TVar<T>::operator *= 02091 ( const TVar<T>&TV ) 02092 { 02093 TVar<T> TV2( *this ); 02094 *this = TV * TV2; 02095 return *this; 02096 } 02097 02098 template <typename T> inline TVar<T> 02099 operator * 02100 ( const TVar<T>&TV1, const TVar<T>&TV2 ) 02101 { 02102 if( !TV2._TM ) return( TV1 * TV2._coefmon[0] + TV1 * *(TV2._bndrem) ); 02103 else if( !TV1._TM ) return( TV2 * TV1._coefmon[0] + TV2 * *(TV1._bndrem) ); 02104 02105 if( TV1._TM != TV2._TM ) 02106 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::TMODEL ); 02107 TVar<T>& TV3 = *TV1._TV(); 02108 for( unsigned int i=0; i<TV3._nmon(); i++ ) TV3._coefmon[i] = 0.; 02109 //TVar<T> TV3( TV1._TM, 0. ); 02110 02111 // Populate _coefmon for product term 02112 for( unsigned int i=0; i<TV3._posord(TV3._nord()/2+1); i++){ 02113 TV3._coefmon[TV3._prodmon(i,i+1)] += TV1._coefmon[i] * TV2._coefmon[i]; 02114 for( unsigned int j=i+1; j<TV3._prodmon(i,0); j++ ) 02115 TV3._coefmon[TV3._prodmon(i,j+1)] += TV1._coefmon[i] * TV2._coefmon[j] 02116 + TV1._coefmon[j] * TV2._coefmon[i]; 02117 } 02118 // Calculate remainder term _bndrem for product term 02119 T s1 = 0., s2 = 0.; 02120 for( unsigned int i=0; i<=TV3._nord()+1; i++ ){ 02121 T r1 = 0., r2 = 0.; 02122 for( unsigned int j=TV3._nord()+1-i; j<=TV3._nord()+1; j++ ){ 02123 r1 += TV1._bndord[j]; 02124 r2 += TV2._bndord[j]; 02125 } 02126 s1 += TV2._bndord[i] * r1 ; 02127 s2 += TV1._bndord[i] * r2 ; 02128 } 02129 if( !Op<T>::inter( *(TV3._bndrem), s1, s2) ) 02130 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::INTER ); 02131 // Populate _bndord for product term (except remainder term) 02132 TV3._update_bndord(); 02133 if( TV3._TM->options.PROPAGATE_BNDT ) TV3._bndT = TV1._bndT * TV2._bndT; 02134 if( TV3._TM->options.CENTER_REMAINDER ) TV3._center_TM(); 02135 return TV3; 02136 } 02137 02138 template <typename T> inline TVar<T> 02139 sqr 02140 ( const TVar<T>&TV ) 02141 { 02142 if( !TV._TM ){ 02143 TVar<T> TV2( TV ); 02144 TV2._coefmon[0] *= TV2._coefmon[0]; 02145 *(TV2._bndrem) *= 2. + *(TV2._bndrem); 02146 return TV2; 02147 } 02148 02149 // Populate _coefmon for product term 02150 TVar<T> TV2( TV._TM, 0. ); 02151 for( unsigned int i=0; i<TV2._posord(TV2._nord()/2+1); i++){ 02152 TV2._coefmon[TV2._prodmon(i,i+1)] += TV._coefmon[i] * TV._coefmon[i]; 02153 for( unsigned int j=i+1; j<TV2._prodmon(i,0); j++ ) 02154 TV2._coefmon[TV2._prodmon(i,j+1)] += TV._coefmon[i] * TV._coefmon[j] * 2.; 02155 } 02156 02157 T s = 0.; 02158 for( unsigned int i=0; i<=TV2._nord()+1; i++ ){ 02159 unsigned int k = std::max(TV2._nord()+1-i, i+1); 02160 T r = 0.; 02161 for( unsigned int j=k; j<=TV2._nord()+1; j++ ) 02162 r += TV._bndord[j]; 02163 s += TV._bndord[i] * r; 02164 } 02165 02166 T r = 0.; 02167 for( unsigned int i=TV2._nord()/2+1; i<=TV2._nord()+1; i++ ) 02168 r += Op<T>::sqr(TV._bndord[i]) ; 02169 *(TV2._bndrem) = 2. * s + r; 02170 02171 // Populate _bndord for product term (except remainder term) 02172 TV2._update_bndord(); 02173 if( TV2._TM->options.PROPAGATE_BNDT ) TV2._bndT = Op<T>::sqr( TV._bndT ); 02174 if( TV2._TM->options.CENTER_REMAINDER ) TV2._center_TM(); 02175 return TV2; 02176 } 02177 02178 template <typename T> inline TVar<T>& 02179 TVar<T>::operator *= 02180 ( const double c ) 02181 { 02182 if( !_TM ){ 02183 _coefmon[0] *= c; 02184 *(_bndrem) *= c; 02185 } 02186 else{ 02187 for( unsigned int i=0; i<_nmon(); i++ ) _coefmon[i] *= c; 02188 for( unsigned int i=0; i<_nord()+2; i++ ) _bndord[i] *= c; 02189 if( _TM->options.PROPAGATE_BNDT ) _bndT *= c; 02190 } 02191 return *this; 02192 } 02193 02194 template <typename T> inline TVar<T> 02195 operator * 02196 ( const TVar<T>&TV1, const double c ) 02197 { 02198 TVar<T> TV3( TV1 ); 02199 TV3 *= c; 02200 return TV3; 02201 } 02202 02203 template <typename T> inline TVar<T> 02204 operator * 02205 ( const double c, const TVar<T>&TV2 ) 02206 { 02207 TVar<T> TV3( TV2 ); 02208 TV3 *= c; 02209 return TV3; 02210 } 02211 02212 template <typename T> inline TVar<T>& 02213 TVar<T>::operator *= 02214 ( const T&I ) 02215 { 02216 if( !_TM ){ 02217 *(_bndrem) += _coefmon[0]; 02218 _coefmon[0] = 0.; 02219 *(_bndrem) *= I; 02220 } 02221 else{ 02222 const double Imid = Op<T>::mid(I); 02223 T Icur = bound(); 02224 for( unsigned int i=0; i<_nmon(); i++ ) _coefmon[i] *= Imid; 02225 for( unsigned int i=0; i<_nord()+2; i++ ) _bndord[i] *= Imid; 02226 *_bndrem += (I-Imid)*Icur; 02227 } 02228 if( _TM && _TM->options.CENTER_REMAINDER ) _center_TM(); 02229 if( _TM && _TM->options.PROPAGATE_BNDT ) _bndT *= I; 02230 return (*this); 02231 } 02232 02233 template <typename T> inline TVar<T> 02234 operator * 02235 ( const TVar<T>&TV1, const T&I ) 02236 { 02237 TVar<T> TV3( TV1 ); 02238 TV3 *= I; 02239 return TV3; 02240 } 02241 02242 template <typename T> inline TVar<T> 02243 operator * 02244 ( const T&I, const TVar<T>&TV2 ) 02245 { 02246 TVar<T> TV3( TV2 ); 02247 TV3 *= I; 02248 return TV3; 02249 } 02250 02251 template <typename T> inline TVar<T>& 02252 TVar<T>::operator /= 02253 ( const TVar<T>&TV ) 02254 { 02255 *this *= inv(TV); 02256 return *this; 02257 } 02258 02259 template <typename T> inline TVar<T> 02260 operator / 02261 ( const TVar<T>&TV1, const TVar<T>&TV2 ) 02262 { 02263 return TV1 * inv(TV2); 02264 } 02265 02266 template <typename T> inline TVar<T>& 02267 TVar<T>::operator /= 02268 ( const double c ) 02269 { 02270 if ( isequal( c, 0. )) 02271 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::DIV ); 02272 *this *= (1./c); 02273 return *this; 02274 } 02275 02276 template <typename T> inline TVar<T> 02277 operator / 02278 ( const TVar<T>&TV, const double c ) 02279 { 02280 if ( isequal( c, 0. )) 02281 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::DIV ); 02282 return TV * (1./c); 02283 } 02284 02285 template <typename T> inline TVar<T> 02286 operator / 02287 ( const double c, const TVar<T>&TV ) 02288 { 02289 return inv(TV) * c; 02290 } 02291 02292 template <typename T> inline TVar<T> 02293 inv 02294 ( const TVar<T>&TV ) 02295 { 02296 if( !TV._TM ){ 02297 TVar<T> TV2( TV ); 02298 TV2._coefmon[0] = 0.; 02299 *(TV2._bndrem) = Op<T>::inv(TV._coefmon[0] + *(TV._bndrem)); 02300 return TV2; 02301 } 02302 02303 const T I( TV.B() ); 02304 double x0 = ( TV._TM->options.REF_MIDPOINT? Op<T>::mid(I): 02305 TV._coefmon[0] + Op<T>::mid(*TV._bndrem) ); 02306 const TVar<T> TVmx0( TV - x0 ); 02307 const T Imx0( I - x0 ); 02308 02309 TVar<T> TV2( 1. ), MON( 1. ); 02310 for( unsigned int i=1; i<=TV._nord(); i++ ){ 02311 MON *= TVmx0 / (-x0); 02312 TV2 += MON; 02313 } 02314 TV2 /= x0; 02315 TV2 += Op<T>::pow( -Imx0, (int)TV2._nord()+1 ) 02316 / Op<T>::pow( Op<T>::zeroone()*Imx0+x0, (int)TV2._nord()+2 ); 02317 if( TV2._TM->options.PROPAGATE_BNDT ) TV2._bndT = Op<T>::inv( TV._bndT ); 02318 if( TV2._TM->options.CENTER_REMAINDER ) TV2._center_TM(); 02319 return TV2; 02320 } 02321 02322 template <typename T> inline TVar<T> 02323 sqrt 02324 ( const TVar<T>&TV ) 02325 { 02326 if( !TV._TM ){ 02327 TVar<T> TV2( TV ); 02328 TV2._coefmon[0] = 0.; 02329 *(TV2._bndrem) = Op<T>::sqrt(TV._coefmon[0] + *(TV._bndrem)); 02330 return TV2; 02331 } 02332 02333 const T I( TV.B() ); 02334 double x0 = ( TV._TM->options.REF_MIDPOINT? Op<T>::mid(I): 02335 TV._coefmon[0] + Op<T>::mid(*TV._bndrem) ); 02336 const TVar<T> TVmx0( TV - x0 ); 02337 const T Imx0( I - x0 ); 02338 02339 double s = 0.5; 02340 TVar<T> TV2( 1. ), MON( 1. ); 02341 for( unsigned int i=1; i<=TV._nord(); i++ ){ 02342 MON *= TVmx0 / x0; 02343 TV2 += MON * s; 02344 s *= -(2.*i-1.)/(2.*i+2.); 02345 } 02346 TV2 *= std::sqrt(x0); 02347 TV2 += s * Op<T>::pow( Imx0, (int)TV2._nord()+1 ) 02348 / Op<T>::pow( Op<T>::zeroone()*Imx0+x0, (int)TV2._nord()+1/2 ); 02349 if( TV2._TM->options.PROPAGATE_BNDT ) TV2._bndT = Op<T>::sqrt( TV._bndT ); 02350 if( TV2._TM->options.CENTER_REMAINDER ) TV2._center_TM(); 02351 return TV2; 02352 } 02353 02354 template <typename T> inline TVar<T> 02355 exp 02356 ( const TVar<T>&TV ) 02357 { 02358 if( !TV._TM ){ 02359 TVar<T> TV2( TV ); 02360 TV2._coefmon[0] = 0.; 02361 *(TV2._bndrem) = Op<T>::exp(TV._coefmon[0] + *(TV._bndrem)); 02362 return TV2; 02363 } 02364 02365 const T I( TV.B() ); 02366 #ifdef MC__TVAR_DEBUG_EXP 02367 std::cout << "DEBUG EXP TV:" << TV << std::endl; 02368 #endif 02369 double x0 = ( TV._TM->options.REF_MIDPOINT? Op<T>::mid(I): 02370 TV._coefmon[0] + Op<T>::mid(*TV._bndrem) ); 02371 #ifdef MC__TVAR_DEBUG_EXP 02372 std::cout << "DEBUG EXP X0:" << x0 << std::endl; 02373 #endif 02374 const TVar<T> TVmx0( TV - x0 ); 02375 #ifdef MC__TVAR_DEBUG_EXP 02376 std::cout << "DEBUG EXP TV-X0:" << TVmx0 << std::endl; 02377 #endif 02378 const T Imx0( I - x0 ); 02379 02380 double s = 1.; 02381 TVar<T> TV2( 1. ), MON( 1. ); 02382 #ifdef MC__TVAR_DEBUG_EXP 02383 std::cout << "DEBUG EXP TV2:" << TV2 << std::endl; 02384 #endif 02385 for( unsigned int i=1; i<=TV._nord(); i++ ){ 02386 MON *= TVmx0; 02387 TV2 += MON * s; 02388 s /= i+1.; 02389 #ifdef MC__TVAR_DEBUG_EXP 02390 std::cout << "DEBUG EXP TV2:" << TV2 << std::endl; 02391 #endif 02392 } 02393 #ifdef MC__TVAR_DEBUG_EXP 02394 std::cout << "DEBUG EXP REM:" << s * Op<T>::pow( Imx0, (int)TV2._nord()+1 ) 02395 * Op<T>::exp( Op<T>::zeroone()*Imx0 ) << std::endl; 02396 #endif 02397 TV2 += s * Op<T>::pow( Imx0, (int)TV2._nord()+1 ) 02398 * Op<T>::exp( Op<T>::zeroone()*Imx0 ); 02399 #ifdef MC__TVAR_DEBUG_EXP 02400 std::cout << "DEBUG EXP TV2:" << TV2 << std::endl; 02401 #endif 02402 TV2 *= std::exp(x0); 02403 #ifdef MC__TVAR_DEBUG_EXP 02404 std::cout << "DEBUG EXP TV2:" << TV2 << std::endl; 02405 #endif 02406 if( TV2._TM->options.PROPAGATE_BNDT ) TV2._bndT = Op<T>::exp( TV._bndT ); 02407 if( TV2._TM->options.CENTER_REMAINDER ) TV2._center_TM(); 02408 return TV2; 02409 } 02410 02411 template <typename T> inline TVar<T> 02412 log 02413 ( const TVar<T>&TV ) 02414 { 02415 if( !TV._TM ){ 02416 TVar<T> TV2( TV ); 02417 TV2._coefmon[0] = 0.; 02418 *(TV2._bndrem) = Op<T>::log(TV._coefmon[0] + *(TV._bndrem)); 02419 return TV2; 02420 } 02421 02422 const T I( TV.B() ); 02423 double x0 = ( TV._TM->options.REF_MIDPOINT? Op<T>::mid(I): 02424 TV._coefmon[0] + Op<T>::mid(*TV._bndrem) ); 02425 const TVar<T> TVmx0( TV - x0 ); 02426 const T Imx0( I - x0 ); 02427 02428 TVar<T> TV2( 0. ), MON( -1. ); 02429 for( unsigned int i=1; i<=TV._nord(); i++ ){ 02430 MON *= TVmx0 / (-x0); 02431 TV2 += MON / (double)i; 02432 } 02433 TV2 += std::log(x0) - Op<T>::pow( - Imx0 / ( Op<T>::zeroone()*Imx0+x0 ), 02434 (int)TV2._nord()+1 ) / ( TV2._nord()+1. ); 02435 if( TV2._TM->options.PROPAGATE_BNDT ) TV2._bndT = Op<T>::log( TV._bndT ); 02436 if( TV2._TM->options.CENTER_REMAINDER ) TV2._center_TM(); 02437 return TV2; 02438 } 02439 02440 template <typename T> inline TVar<T> 02441 xlog 02442 ( const TVar<T>&TV ) 02443 { 02444 return TV * log( TV ); 02445 } 02446 02447 template <typename T> inline TVar<T> 02448 pow 02449 ( const TVar<T>&TV, const int n ) 02450 { 02451 if( !TV._TM ){ 02452 TVar<T> TV2( TV ); 02453 TV2._coefmon[0] = 0.; 02454 *(TV2._bndrem) = Op<T>::pow(TV._coefmon[0] + *(TV._bndrem), n); 02455 return TV2; 02456 } 02457 02458 if( n < 0 ) return pow( inv( TV ), -n ); 02459 TVar<T> TV2( _intpow( TV, n ) ); 02460 if( TV2._TM->options.PROPAGATE_BNDT ) TV2._bndT = Op<T>::pow( TV._bndT, n ); 02461 if( TV2._TM->options.CENTER_REMAINDER ) TV2._center_TM(); 02462 return TV2; 02463 } 02464 02465 template <typename T> inline TVar<T> 02466 _intpow 02467 ( const TVar<T>&TV, const int n ) 02468 { 02469 if( n == 0 ) return 1.; 02470 else if( n == 1 ) return TV; 02471 return n%2 ? sqr( _intpow( TV, n/2 ) ) * TV : sqr( _intpow( TV, n/2 ) ); 02472 } 02473 02474 template <typename T> inline TVar<T> 02475 pow 02476 ( const TVar<T> &TV, const double a ) 02477 { 02478 return exp( a * log( TV ) ); 02479 } 02480 02481 template <typename T> inline TVar<T> 02482 pow 02483 ( const TVar<T> &TV1, const TVar<T> &TV2 ) 02484 { 02485 return exp( TV2 * log( TV1 ) ); 02486 } 02487 02488 template <typename T> inline TVar<T> 02489 pow 02490 ( const double a, const TVar<T> &TV ) 02491 { 02492 return exp( TV * std::log( a ) ); 02493 } 02494 02495 template <typename T> inline TVar<T> 02496 monomial 02497 (const unsigned int n, const TVar<T>*TV, const int*k) 02498 { 02499 if( n == 0 ){ 02500 return 1.; 02501 } 02502 if( n == 1 ){ 02503 return pow( TV[0], k[0] ); 02504 } 02505 return pow( TV[0], k[0] ) * monomial( n-1, TV+1, k+1 ); 02506 } 02507 02508 template <typename T> inline TVar<T> 02509 cos 02510 ( const TVar<T> &TV ) 02511 { 02512 if( !TV._TM ){ 02513 TVar<T> TV2( TV ); 02514 TV2._coefmon[0] = 0.; 02515 *(TV2._bndrem) = Op<T>::cos(TV._coefmon[0] + *(TV._bndrem)); 02516 return TV2; 02517 } 02518 02519 const T I( TV.B() ); 02520 double x0 = ( TV._TM->options.REF_MIDPOINT? Op<T>::mid(I): 02521 TV._coefmon[0] + Op<T>::mid(*TV._bndrem) ); 02522 const TVar<T> TVmx0( TV - x0 ); 02523 const T Imx0( I - x0 ); 02524 double s = 1., c; 02525 02526 TVar<T> TV2( 0. ), MON( 1. ); 02527 for( unsigned int i=1; i<=TV._nord(); i++ ){ 02528 switch( i%4 ){ 02529 case 0: c = std::cos(x0); break; 02530 case 1: c = -std::sin(x0); break; 02531 case 2: c = -std::cos(x0); break; 02532 case 3: 02533 default: c = std::sin(x0); break; 02534 } 02535 MON *= TVmx0; 02536 TV2 += c * s * MON; 02537 s /= i+1; 02538 } 02539 02540 switch( (TV2._nord()+1)%4 ){ 02541 case 0: TV2 += s * Op<T>::pow( Imx0, (int)TV2._nord()+1 ) 02542 * Op<T>::cos( Op<T>::zeroone()*Imx0+x0 ); break; 02543 case 1: TV2 -= s * Op<T>::pow( Imx0, (int)TV2._nord()+1 ) 02544 * Op<T>::sin( Op<T>::zeroone()*Imx0+x0 ); break; 02545 case 2: TV2 -= s * Op<T>::pow( Imx0, (int)TV2._nord()+1 ) 02546 * Op<T>::cos( Op<T>::zeroone()*Imx0+x0 ); break; 02547 case 3: TV2 += s * Op<T>::pow( Imx0, (int)TV2._nord()+1 ) 02548 * Op<T>::sin( Op<T>::zeroone()*Imx0+x0 ); break; 02549 } 02550 TV2 += std::cos(x0); 02551 02552 if( TV2._TM->options.PROPAGATE_BNDT ) TV2._bndT = Op<T>::cos( TV._bndT ); 02553 if( TV2._TM->options.CENTER_REMAINDER ) TV2._center_TM(); 02554 return TV2; 02555 } 02556 02557 template <typename T> inline TVar<T> 02558 sin 02559 ( const TVar<T> &TV ) 02560 { 02561 return cos( TV - PI/2. ); 02562 } 02563 02564 template <typename T> inline TVar<T> 02565 asin 02566 ( const TVar<T> &TV ) 02567 { 02568 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::UNDEF ); 02569 return 0.; 02570 } 02571 02572 template <typename T> inline TVar<T> 02573 acos 02574 ( const TVar<T> &TV ) 02575 { 02576 return asin( -TV ) + PI/2.; 02577 } 02578 02579 template <typename T> inline TVar<T> 02580 tan 02581 ( const TVar<T> &TV ) 02582 { 02583 return sin(TV) / cos(TV); 02584 } 02585 02586 template <typename T> inline TVar<T> 02587 atan 02588 ( const TVar<T> &TV ) 02589 { 02590 return asin(TV) / acos(TV); 02591 } 02592 02593 template <typename T> inline TVar<T> 02594 hull 02595 ( const TVar<T>&TV1, const TVar<T>&TV2 ) 02596 { 02597 if( TV1._TM != TV2._TM ) 02598 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::TMODEL ); 02599 return TV1.P() + ( TV2.P() - TV1.P() ).B() + Op<T>::hull( TV1.R(), TV2.R() ); 02600 } 02601 02602 template <typename T> inline bool 02603 inter 02604 ( TVar<T>&TVR, const TVar<T>&TV1, const TVar<T>&TV2 ) 02605 { 02606 if( TV1._TM != TV2._TM ) 02607 throw typename TModel<T>::Exceptions( TModel<T>::Exceptions::TMODEL ); 02608 TVar<T> TV1C( TV1 ), TV2C( TV2 ); 02609 02610 // if( !TV1._TM->options.REF_INTER ){ 02611 // T R1C = TV1C.C().R(), R2C = TV2C.C().R(); 02612 // TVR = TV1C; 02613 // T R1C = TV1C.R(), R2C = TV2C.C().R(); 02614 // TV1C -= TV2C; 02615 // *(TV1C._bndrem) = 0; 02616 // T BTVD = TV1C.B(); 02617 // return Op<T>::inter(*(TVR._bndrem), R1C, R2C-BTVD)? true: false; 02618 // } 02619 02620 double eta = TV1._TM->options.REF_INTER; 02621 T R1C = TV1C.C().R(), R2C = TV2C.C().R(); 02622 TVR = (1.-eta)*TV1C + eta*TV2C; 02623 TV1C -= TV2C; 02624 *(TV1C._bndrem) = 0; 02625 T BTVD = TV1C.B(); 02626 return Op<T>::inter(*(TVR._bndrem), R1C+eta*BTVD, R2C-(1.-eta)*BTVD)? true: false; 02627 02628 // TVR = TV1C.C(); 02629 // T R1C = TV1C.R(), R2C = TV2C.C().R(); 02630 // TV1C -= TV2C; 02631 // TV1C *= 0.5; 02632 // *(TV1C._bndrem) = 0; 02633 // T BTVD = TV1C.B(); 02634 // return( Op<T>::inter( *(TVR._bndrem), R1C+BTVD, R2C-BTVD ) ? true: false ); 02635 } 02636 02637 } // namespace mc 02638 02639 #include "mcop.h" 02640 02641 namespace mc 02642 { 02643 02645 template <> template<typename T> struct Op< mc::TVar<T> > 02646 { 02647 typedef mc::TVar<T> TV; 02648 static TV point( const double c ) { return TV(c); } 02649 static TV zeroone() { return TV( mc::Op<T>::zeroone() ); } 02650 static void I(TV& x, const TV&y) { x = y; } 02651 static double l(const TV& x) { return mc::Op<T>::l(x.B()); } 02652 static double u(const TV& x) { return mc::Op<T>::u(x.B()); } 02653 static double abs (const TV& x) { return mc::Op<T>::abs(x.B()); } 02654 static double mid (const TV& x) { return mc::Op<T>::mid(x.B()); } 02655 static double diam(const TV& x) { return mc::Op<T>::diam(x.B()); } 02656 static TV inv (const TV& x) { return mc::inv(x); } 02657 static TV sqr (const TV& x) { return mc::sqr(x); } 02658 static TV sqrt(const TV& x) { return mc::sqrt(x); } 02659 static TV log (const TV& x) { return mc::log(x); } 02660 static TV xlog(const TV& x) { return x*mc::log(x); } 02661 static TV fabs(const TV& x) { return TV( mc::Op<T>::fabs(x.B()) ); } 02662 static TV exp (const TV& x) { return mc::exp(x); } 02663 static TV sin (const TV& x) { return mc::sin(x); } 02664 static TV cos (const TV& x) { return mc::cos(x); } 02665 static TV tan (const TV& x) { return mc::tan(x); } 02666 static TV asin(const TV& x) { return mc::asin(x); } 02667 static TV acos(const TV& x) { return mc::acos(x); } 02668 static TV atan(const TV& x) { return mc::atan(x); } 02669 static TV erf (const TV& x) { throw typename mc::TModel<T>::Exceptions( TModel<T>::Exceptions::UNDEF ); return 0.; } 02670 static TV erfc(const TV& x) { throw typename mc::TModel<T>::Exceptions( TModel<T>::Exceptions::UNDEF ); return 0.; } 02671 static TV hull(const TV& x, const TV& y) { return mc::hull(x,y); } 02672 static TV min (const TV& x, const TV& y) { return mc::Op<T>::min(x.B(),y.B()); } 02673 static TV max (const TV& x, const TV& y) { return mc::Op<T>::max(x.B(),y.B()); } 02674 static TV arh (const TV& x, const double k) { return mc::exp(-k/x); } 02675 template <typename X, typename Y> static TV pow(const X& x, const Y& y) { return mc::pow(x,y); } 02676 static TV monomial (const unsigned int n, const T* x, const int* k) { return mc::monomial(n,x,k); } 02677 static bool inter(TV& xIy, const TV& x, const TV& y) { return mc::inter(xIy,x,y); }//T xIy0; bool flag = mc::Op<T>::inter(xIy0,x.B(),y.B()); xIy = xIy0; return flag; } 02678 static bool eq(const TV& x, const TV& y) { return mc::Op<T>::eq(x.B(),y.B()); } 02679 static bool ne(const TV& x, const TV& y) { return mc::Op<T>::ne(x.B(),y.B()); } 02680 static bool lt(const TV& x, const TV& y) { return mc::Op<T>::lt(x.B(),y.B()); } 02681 static bool le(const TV& x, const TV& y) { return mc::Op<T>::le(x.B(),y.B()); } 02682 static bool gt(const TV& x, const TV& y) { return mc::Op<T>::gt(x.B(),y.B()); } 02683 static bool ge(const TV& x, const TV& y) { return mc::Op<T>::ge(x.B(),y.B()); } 02684 }; 02685 02686 } // namespace mc 02687 02688 #endif