193 #include "polymodel.hpp"
195 #include "mclapack.hpp"
197 #undef MC__CMODEL_DEBUG
198 #undef MC__CMODEL_DEBUG_SCALE
199 #define MC__CMODEL_CHECK
200 #undef MC__CMODEL_CHECK_PMODEL
201 #undef MC__CVAR_DEBUG_EXP
202 #undef MC__CVAR_DEBUG_BERSTEIN
207 template <
typename T>
class CVar;
217 template <
typename T>
221 friend class CVar<T>;
222 template <
typename U>
friend class CModel;
224 template <
typename U>
friend CVar<U> pow
234 (
const unsigned int nvar,
const unsigned int nord )
271 return "mc::CModel\t Division by zero scalar";
273 return "mc::CModel\t Inverse operation with zero in range";
275 return "mc::CModel\t Log operation with non-positive numbers in range";
277 return "mc::CModel\t Square-root operation with negative numbers in range";
279 return "mc::CModel\t Sine/Cosine inverse operation with range outside [-1,1]";
281 return "mc::CModel\t Range bounder with eigenvalue decomposition failed";
283 return "mc::CModel\t Chebyshev variable initialization failed";
285 return "mc::CModel\t Inconsistent bounds with template parameter arithmetic";
287 return "mc::CModel\t Operation between Chebyshev variables in different Chebyshev model environment not allowed";
289 return "mc::CModel\t Feature not yet implemented in mc::CModel class";
291 return "mc::CModel\t Undocumented error";
317 template <
typename U>
Options&
operator =
351 unsigned int ***_prodmon;
360 unsigned int _ncoefinterp;
376 double* _resize_coefinterp();
382 void _set_prodmon_exp
383 (
unsigned int&ivar,
const unsigned int*iexp,
const unsigned int iord,
384 unsigned int*iprodexp,
unsigned int&nprodmon );
388 (
const unsigned int ivar,
const T&X );
392 (
const unsigned int iord,
const T&X );
395 typedef double (puniv)
400 (
const CVar<T>&CV,
const int n )
const;
403 static void _interpolation
404 (
double*coefmon,
const unsigned nord,
const T&X, puniv f );
408 (
const double* coefmon,
const unsigned nord,
const CVar<T>& CVI );
412 = {
"NAIVE",
"LSB",
"EIGEN",
"BERNSTEIN",
"HYBRID" };
420 template <
typename T>
421 class CVar:
public PolyVar<T>
424 template <
typename U>
friend class CVar;
425 template <
typename U>
friend class CModel;
427 template <
typename U>
friend CVar<U>
operator+
429 template <
typename U,
typename V>
friend CVar<U>
operator+
430 (
const CVar<U>&,
const CVar<V>& );
431 template <
typename U>
friend CVar<U>
operator+
432 (
const CVar<U>&,
const U& );
433 template <
typename U>
friend CVar<U>
operator+
434 (
const U&,
const CVar<U>& );
435 template <
typename U>
friend CVar<U>
operator+
436 (
const double,
const CVar<U>& );
437 template <
typename U>
friend CVar<U>
operator+
438 (
const CVar<U>&,
const double );
439 template <
typename U>
friend CVar<U>
operator-
441 template <
typename U,
typename V>
friend CVar<U>
operator-
442 (
const CVar<U>&,
const CVar<V>& );
443 template <
typename U>
friend CVar<U>
operator-
444 (
const CVar<U>&,
const U& );
445 template <
typename U>
friend CVar<U>
operator-
446 (
const U&,
const CVar<U>& );
447 template <
typename U>
friend CVar<U>
operator-
448 (
const double,
const CVar<U>& );
449 template <
typename U>
friend CVar<U>
operator-
450 (
const CVar<U>&,
const double );
451 template <
typename U>
friend CVar<U>
operator*
452 (
const CVar<U>&,
const CVar<U>& );
453 template <
typename U>
friend CVar<U>
operator*
454 (
const CVar<U>&,
const U& );
455 template <
typename U>
friend CVar<U>
operator*
456 (
const U&,
const CVar<U>& );
457 template <
typename U>
friend CVar<U>
operator*
458 (
const CVar<U>&,
const double );
459 template <
typename U>
friend CVar<U>
operator*
460 (
const double,
const CVar<U>& );
461 template <
typename U>
friend CVar<U>
operator/
462 (
const CVar<U>&,
const CVar<U>& );
463 template <
typename U>
friend CVar<U>
operator/
464 (
const double,
const CVar<U>& );
465 template <
typename U>
friend CVar<U>
operator/
466 (
const CVar<U>&,
const double );
467 template <
typename U>
friend std::ostream&
operator<<
468 ( std::ostream&,
const CVar<U>& );
470 template <
typename U>
friend CVar<U> inv
472 template <
typename U>
friend CVar<U> sqr
474 template <
typename U>
friend U funcptr
475 (
const U,
const unsigned int );
476 template <
typename U>
friend void interpolation
477 (
double*,
const CVar<U>&,
const unsigned int );
478 template <
typename U>
friend CVar<U> composition
479 (
const double*,
const CVar<U>& );
480 template <
typename U>
friend CVar<U> sqrt
482 template <
typename U>
friend CVar<U> exp
484 template <
typename U>
friend CVar<U> log
486 template <
typename U>
friend CVar<U> xlog
488 template <
typename U>
friend CVar<U> pow
489 (
const CVar<U>&,
const int );
490 template <
typename U>
friend CVar<U> pow
491 (
const CVar<U>&,
const double );
492 template <
typename U>
friend CVar<U> pow
493 (
const double,
const CVar<U>& );
494 template <
typename U>
friend CVar<U> pow
495 (
const CVar<U>&,
const CVar<U>& );
496 template <
typename U>
friend CVar<U> monomial
497 (
const unsigned int,
const CVar<U>*,
const int* );
498 template <
typename U>
friend CVar<U> cos
500 template <
typename U>
friend CVar<U> sin
502 template <
typename U>
friend CVar<U> tan
504 template <
typename U>
friend CVar<U> acos
506 template <
typename U>
friend CVar<U> asin
508 template <
typename U>
friend CVar<U> atan
510 template <
typename U>
friend CVar<U> fabs
512 template <
typename U>
friend CVar<U> hull
513 (
const CVar<U>&,
const CVar<U>& );
514 template <
typename U>
friend bool inter
515 ( CVar<U>&,
const CVar<U>&,
const CVar<U>& );
518 using PolyVar<T>::_coefmon;
519 using PolyVar<T>::_bndord;
520 using PolyVar<T>::_bndord_uptd;
521 using PolyVar<T>::_bndrem;
522 using PolyVar<T>::_bndpol;
523 using PolyVar<T>::_set_bndpol;
524 using PolyVar<T>::_unset_bndpol;
525 using PolyVar<T>::nvar;
526 using PolyVar<T>::nord;
527 using PolyVar<T>::nmon;
528 using PolyVar<T>::_posord;
529 using PolyVar<T>::_expmon;
530 using PolyVar<T>::_loc_expmon;
531 using PolyVar<T>::_get_binom;
532 using PolyVar<T>::_resize;
533 using PolyVar<T>::_set;
534 using PolyVar<T>::set;
535 using PolyVar<T>::get;
536 using PolyVar<T>::bound;
537 using PolyVar<T>::bndord;
538 using PolyVar<T>::_center;
546 {
return _CM->_CV; };
549 unsigned int* _prodmon
550 (
const unsigned int imon,
const unsigned int jmon )
const
551 {
return _CM->_prodmon[imon][jmon]; };
555 (
const unsigned int ivar )
const
556 {
return _CM->_bndvar[ivar]; };
559 double* _coefinterp()
const
560 {
return _CM->_resize_coefinterp(); };
566 CModel<T>*
env()
const
572 (
const double d=0. );
580 ( CModel<T>*CM,
const unsigned int ix,
const T&X );
583 template <
typename U> CVar
584 ( CModel<T>*&CM,
const CVar<U>&CV );
587 template <
typename U> CVar
588 ( CModel<T>*&CM,
const CVar<U>&CV,
const T& (U::*method)()
const );
590 template <
typename U> CVar
591 ( CModel<T>*&CM,
const CVar<U>&CV, T (*method)(
const U& ) );
598 #ifdef MC__CMODEL_CHECK_PMODEL
619 (
const unsigned int ivar,
const T&X );
628 {
set( CM ); _set( ix, X );
return *
this; }
637 (
const double*x )
const;
641 (
const double*x )
const
648 {
CVar<T> var = *
this; *(var._bndrem) = 0.;
return var; }
666 (
const bool reset=
false );
673 (
const unsigned int ivar,
const bool reset=
false );
682 template <
typename U>
CVar<T>&
operator +=
684 template <
typename U>
CVar<T>&
operator +=
688 template <
typename U>
CVar<T>&
operator -=
690 template <
typename U>
CVar<T>&
operator -=
707 void _update_bndord()
const;
711 (
const int type )
const;
716 {
return _polybound( _CM? _CM->options.BOUNDER_TYPE: 0 ); }
719 T _polybound_naive()
const;
722 T _polybound_LSB()
const;
725 T _polybound_eigen()
const;
728 T _polybound_bernstein()
const;
731 typedef double (puniv)
736 (
double*
coefmon, puniv f )
const
737 { CModel<T>::_interpolation( coefmon,
nord()+_CM->options.INTERP_EXTRA,
bound(), f ); }
741 (
const double* coefmon )
const
742 {
return CModel<T>::_composition( coefmon,
nord(), *
this ); }
746 (
const double w,
const double c )
const
747 {
return( !isequal(w,0.)? (*
this-c)*(2./w): c ); }
757 template <
typename T>
inline void
762 _bndvar =
new T[_nvar];
763 for(
unsigned int i=0; i<_nvar; i++ ) _bndvar[i] = 0.;
764 _ncoefinterp = 0; _coefinterp = 0;
766 _CV =
new CVar<T>( this );
777 template <
typename T>
inline void
778 CModel<T>::_cleanup()
780 for(
unsigned int i=0; i<_nmon; i++ ){
781 for(
unsigned int j=0; j<=i; j++ )
782 delete[] _prodmon[i][j];
783 delete[] _prodmon[i];
787 delete[] _coefinterp;
791 template <
typename T>
inline double*
792 CModel<T>::_resize_coefinterp()
794 if( _ncoefinterp > _nord+options.INTERP_EXTRA )
return _coefinterp;
795 delete[] _coefinterp;
796 _ncoefinterp = _nord+options.INTERP_EXTRA+1;
797 _coefinterp =
new double[_ncoefinterp];
801 template <
typename T>
inline void
802 CModel<T>::_set_prodmon()
804 _prodmon =
new unsigned int**[_nmon];
805 size_t prodmon_max = _nvar+1;
806 for(
unsigned int i=0; i<_nvar && i<_nord; i++ ){
807 if( prodmon_max > std::numeric_limits<size_t>::max()/2 )
811 unsigned int *iexp =
new unsigned int[prodmon_max];
814 for(
unsigned int iord=0; iord<=_nord; iord++ ){
815 for(
unsigned int imon=_posord[iord]; imon<_posord[iord+1]; imon++ ){
818 _prodmon[imon] =
new unsigned int*[imon+1];
819 for(
unsigned int jord=0, jmon=0; jord<=iord; jord++ ){
820 for( ; jmon<_posord[jord+1] && jmon<=imon; jmon++ ){
824 for(
unsigned int ivar=0; ivar<_nvar; ivar++ )
825 iexp[ivar+1] = _expmon[imon*_nvar+ivar];
826 #ifdef MC__CMODEL_DEBUG
827 mc::display( 1, _nvar, iexp+1, 1,
"iexp:", std::cout );
828 mc::display( 1, _nvar, _expmon+jmon*_nvar, 1,
"jexp:", std::cout );
831 unsigned int nprodmax = 1, nprodmon = 1, kvar = 0;
832 for(
unsigned int ivar=0; ivar<_nvar; ivar++ )
833 if( iexp[ivar+1] && _expmon[jmon*_nvar+ivar] ) nprodmax*=2;
834 _set_prodmon_exp( kvar, _expmon+jmon*_nvar, jord, iexp, nprodmon );
835 _prodmon[imon][jmon] =
new unsigned int[nprodmon+2];
836 _prodmon[imon][jmon][0] = nprodmax;
837 _prodmon[imon][jmon][1] = 0;
838 for(
unsigned int kmon=0; kmon<nprodmon; kmon++ ){
839 #ifdef MC__CMODEL_DEBUG
840 mc::display( 1, _nvar+1, iexp+kmon*(_nvar+1), 1,
"ijexp:", std::cout );
843 if( iexp[kmon*(_nvar+1)] > _nord )
continue;
844 _prodmon[imon][jmon][++_prodmon[imon][jmon][1]+1] = _loc_expmon( iexp+kmon*(_nvar+1)+1 );
846 #ifdef MC__CMODEL_DEBUG
847 std::ostringstream oheadi;
848 oheadi <<
"_prodmon[" << imon <<
"," << jmon <<
"]: max=" << nprodmax
849 <<
" cur=" << _prodmon[imon][jmon][1];
850 mc::display( 1, _prodmon[imon][jmon][1], _prodmon[imon][jmon]+2, 1, oheadi.str(), std::cout );
860 template <
typename T>
inline void
861 CModel<T>::_set_prodmon_exp
862 (
unsigned int&kvar,
const unsigned int*iexp,
const unsigned int iord,
863 unsigned int*iprodexp,
unsigned int&nprodmon )
865 if( kvar == _nvar || !nprodmon )
return;
868 for(
unsigned int imon=0; imon<nprodmon; imon++ ){
870 if( !iexp[kvar] || !iprodexp[imon*(_nvar+1)+kvar+1] ){
871 iprodexp[imon*(_nvar+1)] += iprodexp[imon*(_nvar+1)+kvar+1] + iexp[kvar];
872 if( iprodexp[imon*(_nvar+1)] <= _nord )
873 iprodexp[imon*(_nvar+1)+kvar+1] += iexp[kvar];
878 if( iprodexp[imon*(_nvar+1)] + iprodexp[imon*(_nvar+1)+kvar+1] + iexp[kvar] <= _nord ){
879 for(
unsigned int ivar=0; ivar<=_nvar; ivar++ )
880 iprodexp[(nprodmon+nprodnew)*(_nvar+1)+ivar] = iprodexp[imon*(_nvar+1)+ivar];
881 iprodexp[(nprodmon+nprodnew)*(_nvar+1)] += iprodexp[imon*(_nvar+1)+kvar+1] + iexp[kvar];
882 iprodexp[(nprodmon+nprodnew)*(_nvar+1)+kvar+1] += iexp[kvar];
885 if( iexp[kvar] <= iprodexp[imon*(_nvar+1)+kvar+1] ){
886 iprodexp[imon*(_nvar+1)] += iprodexp[imon*(_nvar+1)+kvar+1] - iexp[kvar];
887 if( iprodexp[imon*(_nvar+1)] <= _nord )
888 iprodexp[imon*(_nvar+1)+kvar+1] -= iexp[kvar];
891 iprodexp[imon*(_nvar+1)] += iexp[kvar] - iprodexp[imon*(_nvar+1)+kvar+1];
892 if( iprodexp[imon*(_nvar+1)] <= _nord )
893 iprodexp[imon*(_nvar+1)+kvar+1] = iexp[kvar] - iprodexp[imon*(_nvar+1)+kvar+1];
897 nprodmon += nprodnew;
898 return _set_prodmon_exp( ++kvar, iexp, iord, iprodexp, nprodmon );
901 template <
typename T>
inline void
902 CModel<T>::_set_bndvar
903 (
const unsigned int ivar,
const T&X )
907 #ifdef MC__CMODEL_DEBUG
908 mc::display( 1, _nvar, _bndvar, 1,
"_bndvar", std::cout );
912 template <
typename T>
inline T
914 (
const unsigned int iord,
const T&X )
916 assert( Op<T>::l(X) >= -1. && Op<T>::u(X) <= 1. );
920 case 2:
return 2.*Op<T>::sqr(X)-1.;
922 double XL = Op<T>::l(X), XU = Op<T>::u(X), TL, TU;
923 unsigned kL = iord - std::ceil(iord*std::acos(XL)/mc::PI);
924 unsigned kU = iord - std::floor(iord*std::acos(XU)/mc::PI);
925 #ifdef MC__CMODEL_DEBUG
926 std::cout <<
"iord: " << iord <<
" X: " << X
927 <<
" kL: " << kL <<
" kU: " << kU << std::endl;
931 TL = std::cos(iord*std::acos(XL));
932 TU = std::cos(iord*std::acos(XU));
933 return( TL<=TU? Op<T>::zeroone()*(TU-TL)+TL: Op<T>::zeroone()*(TL-TU)+TU );
935 TL = std::cos(iord*std::acos(XL));
936 TU = std::cos(iord*std::acos(XU));
937 if( (iord%2 && kL%2) || (!(iord%2) && !(kL%2)) ){
938 if( kL%2 )
return( Op<T>::zeroone()*((TU>TL?TU:TL)+1.)-1. );
939 else return( Op<T>::zeroone()*((TU>TL?TL:TU)-1.)+1. );
942 return Op<T>::zeroone();
948 template <
typename T>
inline CVar<T>
950 (
const CVar<T>&CV,
const int n )
const
952 if( n == 0 )
return 1.;
953 else if( n == 1 )
return CV;
954 return n%2 ? sqr( _intpow( CV, n/2 ) ) * CV : sqr( _intpow( CV, n/2 ) );
957 template <
typename T>
inline void
958 CModel<T>::_interpolation
959 (
double*coefmon,
const unsigned nord,
const T&X, puniv f )
961 double b( Op<T>::mid(X) ), a( Op<T>::u(X)-b ), x[nord+1], fx[nord+1];
962 double mulconst( PI/(2.*
double(nord+1)) );
963 for(
unsigned int i(0); i<=nord; i++ ){
964 x[i] = std::cos(mulconst*(2.*
double(i)+1.));
965 fx[i] = f( a*x[i]+b );
973 coefmon[0] = 0.5 * ( fx[0] + fx[1] );
974 coefmon[1] = ( fx[1] - fx[0] ) / ( x[1] - x[0] );
977 for(
unsigned int i(0); i<=nord; i++ ){
978 double mulconst2( std::cos(mulconst*
double(i)) ),
979 mulconst3( 4*std::pow(mulconst2,2)-2 ),
982 b1 = fx[nord-1] + mulconst3*b0;
983 for(
unsigned int j=nord-2; j>1; j-=2 ){
984 b0 = fx[j] + mulconst3*b1 - b0;
985 b1 = fx[j-1] + mulconst3*b0 - b1;
988 b0 = fx[0] + mulconst3*b1 - b0 - b1;
990 b0 = fx[1] + mulconst3*b1 - b0;
991 b0 = fx[0] + mulconst3*b0 - b1 - b0;
993 coefmon[i] = 2./double(nord+1)*mulconst2*b0;
1000 template <
typename T>
inline CVar<T>
1001 CModel<T>::_composition
1002 (
const double* coefmon,
const unsigned nord,
const CVar<T>& CVI )
1012 CV1 = coefmon[0] + 0.5*coefmon[1]*CVI;
1015 CV1 = coefmon[nord];
1016 CV2 = coefmon[nord-1] + CVI*CV1;
1017 for(
unsigned i=nord-2; i>1; i-=2 ){
1018 CV1 = coefmon[i] + CVI*CV2 - CV1;
1019 CV2 = coefmon[i-1] + CVI*CV1 - CV2;
1022 CV1 = coefmon[0] + 0.5*CVI*CV2 - CV1;
1025 CV1 = coefmon[1] + CVI*CV2 - CV1;
1026 CV1 = coefmon[0] + 0.5*CVI*CV1 - CV2;
1035 template <
typename T>
inline CVar<T>&
1037 (
const CVar<T>&CV )
1041 #ifdef MC__CMODEL_CHECK_PMODEL
1042 if( _CM !=
dynamic_cast< CModel<T>*
>( PolyVar<T>::_PM ) ) assert(
false );
1047 template <
typename T>
inline
1057 template <
typename T>
inline CVar<T>&
1061 if( _CM ){ _CM = 0; _resize( _CM ); }
1068 template <
typename T>
inline
1078 template <
typename T>
inline CVar<T>&
1082 if( _CM ){ _CM = 0; _resize( _CM ); }
1089 template <
typename T>
inline
1091 ( CModel<T>*CM,
const double d )
1092 : PolyVar<T>( CM ), _CM( CM )
1101 template <
typename T>
inline
1103 ( CModel<T>*CM,
const T&B )
1104 : PolyVar<T>( CM ), _CM( CM )
1107 for(
unsigned int i=0; i<
nmon(); i++ )
_coefmon[i] = 0.;
1108 for(
unsigned int i=0; i<=
nord(); i++)
_bndord[i] = 0.;
1115 template <
typename T>
template <
typename U>
inline
1121 _coefmon[0] = CVtrunc._coefmon[0];
1122 CVtrunc._coefmon[0] = 0. ;
1123 for(
unsigned int i=1; CM && i<nmon(); i++ ){
1124 if( CVtrunc.CM && i < CVtrunc.nmon() ){
1125 _coefmon[i] = CVtrunc._coefmon[i];
1126 CVtrunc._coefmon[i] = 0.;
1131 CVtrunc._bndord_uptd =
false;
1132 *_bndrem = T( CVtrunc.B() );
1133 _bndord_uptd =
false;
1137 template <
typename T>
template <
typename U>
inline
1144 _coefmon[0] = CVtrunc._coefmon[0];
1145 CVtrunc._coefmon[0] = 0. ;
1146 for(
unsigned int i=1; CM && i<nmon(); i++ ){
1147 if( CVtrunc.CM && i < CVtrunc.nmon() ){
1148 _coefmon[i] = CVtrunc._coefmon[i];
1149 CVtrunc._coefmon[i] = 0.;
1154 CVtrunc._bndord_uptd =
false;
1155 *_bndrem = (*method)( CVtrunc.B() );
1156 _bndord_uptd =
false;
1160 template <
typename T>
template <
typename U>
inline
1167 _coefmon[0] = CVtrunc._coefmon[0];
1168 CVtrunc._coefmon[0] = 0. ;
1169 for(
unsigned int i=1; CM && i<nmon(); i++ ){
1170 if( CVtrunc.CM && i < CVtrunc.nmon() ){
1171 _coefmon[i] = CVtrunc._coefmon[i];
1172 CVtrunc._coefmon[i] = 0.;
1177 CVtrunc._bndord_uptd =
false;
1178 *_bndrem = (CVtrunc.B().*method)();
1179 _bndord_uptd =
false;
1183 template <
typename T>
inline CVar<T>&
1185 (
const unsigned int ivar,
const T&X )
1190 _CM->_set_bndvar( ivar, X );
1194 for(
unsigned int i=1; i<nmon(); i++ ) _coefmon[i] = 0.;
1195 if( nord() > 0 ) _coefmon[nvar()-ivar] =
Op<T>::diam(X)/2.;
1198 _bndord[0] = _coefmon[0];
1200 _bndord[1] = X-_coefmon[0];
1201 for(
unsigned int i=2; i<nord()+2; i++) _bndord[i] = 0.;
1205 *_bndrem = X-_coefmon[0];
1206 _set_bndpol( _coefmon[0] );
1208 _bndord_uptd =
true;
1213 template <
typename T>
inline
1221 template <
typename T>
inline void
1224 if( !_CM || _bndord_uptd )
return;
1225 _bndord[0] = _coefmon[0];
1226 for(
unsigned int i=1; i<=nord(); i++ ){
1228 for(
unsigned int j=_posord(i); j<_posord(i+1); j++ )
1229 _bndord[i] += _coefmon[j] * T(-1.,1.);
1231 _bndord_uptd =
true;
1234 template <
typename T>
inline T
1235 CVar<T>::_polybound_eigen()
const
1237 static const double TOL = 1e-8;
1239 T bndpol = _coefmon[0];
1240 if( nord() == 1 ) bndpol += _bndord[1];
1242 else if( nord() > 1 ){
1243 T bndmon = Op<T>::zeroone()*2.-1.;
1244 double*U =
new double[nvar()*nvar()];
1245 for(
unsigned int i=_posord(2); i<_posord(3); i++ ){
1246 unsigned int i1=0, i2=nvar();
1247 const unsigned int*iexp=_expmon(i);
1248 for( ; i1<nvar(); i1++ )
if( iexp[i1] )
break;
1249 if( iexp[i1] == 2 ){
1250 U[nvar()*i1+i1] = 2.*_coefmon[i];
1251 bndpol -= _coefmon[i];
1254 for( i2=i1+1; i2<nvar(); i2++ )
if( iexp[i2] )
break;
1255 U[nvar()*i1+i2] = 0.;
1256 U[nvar()*i2+i1] = _coefmon[i]/2.;
1258 #ifdef MC__CVAR_DEBUG_EIGEN
1259 display( nvar(), nvar(), U, nvar(),
"Matrix U", std::cout );
1261 double*D = mc::dsyev_wrapper( nvar(), U,
true );
1267 for(
unsigned int i=0; i<nvar(); i++ ){
1270 for(
unsigned int k=0; k<nvar(); k++ ){
1271 linaux += U[i*nvar()+k] * _coefmon[nvar()-k];
1272 bndaux += U[i*nvar()+k] * bndmon;
1274 #ifdef MC__CVAR_DEBUG_EIGEN
1275 std::cout << i <<
": LINAUX = " << linaux
1276 <<
" BNDAUX = " << bndaux << std::endl;
1278 if( std::fabs(D[i]) > TOL )
1279 bndpol += D[i] * Op<T>::sqr( linaux/D[i]/2. + bndaux )
1280 - linaux*linaux/D[i]/4.;
1282 bndpol += linaux * bndaux + D[i] * Op<T>::sqr( bndaux );
1283 #ifdef MC__CVAR_DEBUG_EIGEN
1284 std::cout <<
"BNDPOL: " << bndpol << std::endl;
1290 #ifdef MC__CVAR_DEBUG_EIGEN
1291 int tmp; std::cin >> tmp;
1294 for(
unsigned int i=3; i<=nord(); i++ ) bndpol += _bndord[i];
1298 template <
typename T>
inline T
1299 CVar<T>::_polybound_LSB()
const
1301 static const double TOL = 1e-8;
1303 T bndpol = _coefmon[0];
1304 if( nord() == 1 ) bndpol += _bndord[1];
1306 else if( nord() > 1 ){
1307 T bndmon = Op<T>::zeroone()*2.-1.;
1308 for(
unsigned int i=_posord(2); i<_posord(3); i++ ){
1310 const unsigned int*iexp=_expmon(i);
1311 for(
unsigned int j=0; j<nvar(); j++ ){
1312 k = ( iexp[j]==1? nvar(): j );
1313 if( iexp[j] )
break;
1317 bndpol += _coefmon[i] * bndmon;
1321 const double ai = _coefmon[nvar()-k], aii = _coefmon[i];
1322 if( std::fabs(aii) > TOL )
1323 bndpol += (2.*aii)*Op<T>::sqr(bndmon+ai/(aii*4.))-aii-ai*ai/8./aii;
1325 bndpol += ai*bndmon+aii*bndmon;
1329 for(
unsigned int i=3; i<=nord(); i++ ) bndpol += _bndord[i];
1333 template <
typename T>
inline T
1334 CVar<T>::_polybound_bernstein()
const
1408 template <
typename T>
inline T
1409 CVar<T>::_polybound_naive()
const
1411 T bndpol = _coefmon[0];
1412 for(
unsigned int i=1; i<=nord(); i++ ) bndpol += _bndord[i];
1416 template <
typename T>
inline T
1418 (
const int type )
const
1420 if( !_CM )
return _coefmon[0];
1425 return _polybound_naive();
1427 return _polybound_bernstein();
1429 return _polybound_eigen();
1431 T bndpol, bndpol_LSB = _polybound_LSB(), bndpol_eigen = _polybound_eigen();
1432 if( !Op<T>::inter( bndpol, bndpol_LSB, bndpol_eigen ) )
1434 return Op<T>::diam(bndpol_LSB)<Op<T>::diam(bndpol_eigen)? bndpol_LSB: bndpol_eigen;
1438 return _polybound_LSB();
1442 template <
typename T>
inline double
1444 (
const double*x )
const
1446 if( !_CM )
return _coefmon[0];
1448 static const double TOL = machprec()*1e2;
1450 for(
unsigned k=0; k<nvar(); k++ ){
1452 xs[k] = ( dXk>TOL? 2.*(x[k]-
Op<T>::l(_CM->_bndvar[k]))/dXk-1.
1455 double Pval = _coefmon[0];
1456 for(
unsigned int i=1; i<nmon(); i++ ){
1457 const unsigned int *iexp = _expmon(i);
1459 for(
unsigned int k=0; k<nvar(); k++ ){
1460 if( !iexp[k] )
continue;
1461 if( iexp[k] == 1 ) valmon *= xs[k];
1462 else if( iexp[k] == 2 ) valmon *= 2*xs[k]*xs[k]-1;
1463 else valmon *= std::cos(iexp[k]*std::acos(xs[k]));
1465 Pval += _coefmon[i] * valmon;
1470 template <
typename T>
inline double
1473 const double coefconst = _coefmon[0];
1474 if( reset ) *
this -= coefconst;
1478 template <
typename T>
inline double*
1481 if( !nvar() || !nord() )
return 0;
1483 double*plin =
new double[nvar()];
1484 for(
unsigned int i=0; i<nvar(); i++ )
1485 plin[i] = ( isequal(
Op<T>::diam(_CM->bndvar()[i]), 0. )? 0.:
1486 _coefmon[nvar()-i] /
Op<T>::diam(_CM->bndvar()[i]) * 2. );
1490 template <
typename T>
inline double
1492 (
const unsigned int ivar,
const bool reset )
1494 if( ivar>=nvar() || !nord() )
return 0.;
1495 const bool zerorange = isequal(
Op<T>::diam(_CM->bndvar()[ivar]), 0. );
1496 const double coeflin = ( zerorange? 0.: _coefmon[nvar()-ivar] /
Op<T>::diam(_CM->bndvar()[ivar]) * 2. );
1497 if( !zerorange && reset ){ _coefmon[nvar()-ivar] = 0.; _bndord_uptd =
false; _unset_bndpol(); }
1501 template <
typename T>
inline std::ostream&
1503 ( std::ostream&out,
const CVar<T>&CV )
1506 << std::scientific << std::setprecision(5)
1511 out <<
" a0 = " << std::right << std::setw(12) << CV._coefmon[0]
1513 <<
" R = " << *(CV._bndrem) << std::endl;
1518 out << std::setprecision(CV._CM->options.DISPLAY_DIGITS);
1519 for(
unsigned int i=0; i<CV.nmon(); i++ ){
1520 out <<
" a" << std::left << std::setw(4) << i <<
" = "
1521 << std::right << std::setw(CV._CM->options.DISPLAY_DIGITS+7)
1522 << CV._coefmon[i] <<
" ";
1523 for(
unsigned int k=0; k<CV.nvar(); k++ )
1524 out << std::setw(3) << CV._expmon(i)[k];
1528 out << std::right <<
" R = " << *(CV._bndrem)
1533 out << std::right <<
" B = " << CV.B()
1539 template <
typename T>
inline CVar<T>
1541 (
const CVar<T>&CV )
1546 template <
typename T>
template <
typename U>
inline CVar<T>&
1547 CVar<T>::operator +=
1548 (
const CVar<U>&CV )
1551 _coefmon[0] += CV._coefmon[0];
1552 if( _CM && _bndord_uptd ) _bndord[0] += CV._coefmon[0];
1553 *_bndrem += *(CV._bndrem);
1554 if( _bndpol ) *_bndpol += CV._coefmon[0];
1558 *
this = CV; *
this += CV2;
1563 for(
unsigned int i=0; i<nmon(); i++ )
1564 _coefmon[i] += CV._coefmon[i];
1565 if( CV._bndord_uptd )
1566 for(
unsigned int i=0; _bndord_uptd && i<=nord(); i++ )
1567 _bndord[i] += CV._bndord[i];
1568 else _bndord_uptd =
false;
1569 *_bndrem += *(CV._bndrem);
1570 if( _bndpol && CV._bndpol ) *_bndpol += *(CV._bndpol);
1571 else _unset_bndpol();
1577 template <
typename T,
typename U>
inline CVar<T>
1579 (
const CVar<T>&CV1,
const CVar<U>&CV2 )
1586 template <
typename T>
inline CVar<T>&
1587 CVar<T>::operator +=
1591 if( _CM && _bndord_uptd ) _bndord[0] += c;
1592 if( _bndpol ) *_bndpol += c;
1597 template <
typename T>
inline CVar<T>
1599 (
const CVar<T>&CV1,
const double c )
1606 template <
typename T>
inline CVar<T>
1608 (
const double c,
const CVar<T>&CV2 )
1615 template <
typename T>
template <
typename U>
inline CVar<T>&
1616 CVar<T>::operator +=
1624 template <
typename T,
typename U>
inline CVar<T>
1626 (
const CVar<T>&CV1,
const U&I )
1633 template <
typename T,
typename U>
inline CVar<T>
1635 (
const U&I,
const CVar<T>&CV2 )
1642 template <
typename T>
inline CVar<T>
1644 (
const CVar<T>&CV )
1648 CV2._coefmon[0] = -CV._coefmon[0];
1649 *CV2._bndrem = - *CV._bndrem;
1650 if( CV._bndpol ) CV2._set_bndpol( - *CV._bndpol );
1653 CVar<T>& CV2 = *CV._CV();
1654 CV2._unset_bndpol(); CV2._bndord_uptd =
false;
1655 for(
unsigned int i=0; i<CV.nmon(); i++ ) CV2._coefmon[i] = -CV._coefmon[i];
1656 *CV2._bndrem = - *CV._bndrem;
1657 if( CV._bndord_uptd ){
1658 for(
unsigned int i=0; i<=CV.nord(); i++ ) CV2._bndord[i] = -CV._bndord[i];
1659 CV2._bndord_uptd =
true;
1661 if( CV._bndpol ) CV2._set_bndpol( - *CV._bndpol );
1666 template <
typename T>
template <
typename U>
inline CVar<T>&
1667 CVar<T>::operator -=
1668 (
const CVar<U>&CV )
1671 _coefmon[0] -= CV._coefmon[0];
1672 if( _CM && _bndord_uptd ) _bndord[0] -= CV._coefmon[0];
1673 *_bndrem -= *(CV._bndrem);
1674 if( _bndpol ) *_bndpol -= CV._coefmon[0];
1678 *
this = -CV; *
this += CV2;
1683 for(
unsigned int i=0; i<nmon(); i++ )
1684 _coefmon[i] -= CV._coefmon[i];
1685 if( CV._bndord_uptd )
1686 for(
unsigned int i=0; _bndord_uptd && i<=nord(); i++ )
1687 _bndord[i] -= CV._bndord[i];
1688 else _bndord_uptd =
false;
1689 *_bndrem -= *(CV._bndrem);
1690 if( _bndpol && CV._bndpol ) *_bndpol -= *(CV._bndpol);
1691 else _unset_bndpol();
1697 template <
typename T,
typename U>
inline CVar<T>
1699 (
const CVar<T>&CV1,
const CVar<U>&CV2 )
1706 template <
typename T>
inline CVar<T>&
1707 CVar<T>::operator -=
1711 if( _CM && _bndord_uptd ) _bndord[0] -= c;
1712 if( _bndpol ) *_bndpol -= c;
1717 template <
typename T>
inline CVar<T>
1719 (
const CVar<T>&CV1,
const double c )
1726 template <
typename T>
inline CVar<T>
1728 (
const double c,
const CVar<T>&CV2 )
1730 CVar<T> CV3( -CV2 );
1735 template <
typename T>
template <
typename U>
inline CVar<T>&
1736 CVar<T>::operator -=
1744 template <
typename T,
typename U>
inline CVar<T>
1746 (
const CVar<T>&CV1,
const U&I )
1753 template <
typename T,
typename U>
inline CVar<T>
1755 (
const U&I,
const CVar<T>&CV2 )
1757 CVar<T> CV3( -CV2 );
1762 template <
typename T>
inline CVar<T>&
1763 CVar<T>::operator *=
1764 (
const CVar<T>&CV )
1766 CVar<T> CV2( *
this );
1771 template <
typename T>
inline CVar<T>
1773 (
const CVar<T>&CV1,
const CVar<T>&CV2 )
1775 if( !CV2._CM )
return( CV1 * CV2._coefmon[0] + CV1 * *(CV2._bndrem) );
1776 else if( !CV1._CM )
return( CV2 * CV1._coefmon[0] + CV2 * *(CV1._bndrem) );
1777 else if( &CV1 == &CV2 )
return sqr(CV1);
1779 if( CV1._CM != CV2._CM )
1781 CVar<T>& CV3 = *CV1._CV();
1782 for(
unsigned int i=0; i<CV3.nmon(); i++ ) CV3._coefmon[i] = 0.;
1783 *(CV3._bndrem) = 0.;
1784 T bndmon = Op<T>::zeroone()*2.-1.;
1787 for(
unsigned int i=0; i<CV3.nmon(); i++ ){
1788 for(
unsigned int j=0; j<i; j++ ){
1789 const unsigned int*prodij = CV3._prodmon(i,j);
1790 for(
unsigned int k=0; k<prodij[1]; k++ )
1791 CV3._coefmon[prodij[2+k]] += ( CV1._coefmon[i] * CV2._coefmon[j]
1792 + CV1._coefmon[j] * CV2._coefmon[i] ) / (double)prodij[0];
1793 *(CV3._bndrem) += bndmon * ( ( CV1._coefmon[i] * CV2._coefmon[j]
1794 + CV1._coefmon[j] * CV2._coefmon[i] )
1795 * ( 1. - (double)prodij[1] / (
double)prodij[0] ) );
1797 const unsigned int*prodii = CV3._prodmon(i,i);
1798 for(
unsigned int k=0; k<prodii[1]; k++ )
1799 CV3._coefmon[prodii[2+k]] += CV1._coefmon[i] * CV2._coefmon[i]
1800 / (
double)prodii[0];
1801 *(CV3._bndrem) += bndmon * ( CV1._coefmon[i] * CV2._coefmon[i]
1802 * ( 1. - (
double)prodii[1] / (
double)prodii[0] ) );
1806 T P1 = CV1._polybound(), P2 = CV2._polybound();
1812 T R1 = *(CV3._bndrem) + ( P1 + *(CV1._bndrem) ) * *(CV2._bndrem) + P2 * *(CV1._bndrem);
1813 T R2 = *(CV3._bndrem) + P1 * *(CV2._bndrem) + ( P2 + *(CV2._bndrem) ) * *(CV1._bndrem);
1814 if( !Op<T>::inter( *(CV3._bndrem), R1, R2) )
1815 *(CV3._bndrem) = ( Op<T>::diam(R1)<Op<T>::diam(R2)? R1: R2 );
1818 CV3._unset_bndpol();
1819 CV3._bndord_uptd =
false;
1824 template <
typename T>
inline CVar<T>
1826 (
const CVar<T>&CV )
1830 CV2._coefmon[0] *= CV2._coefmon[0];
1831 *(CV2._bndrem) *= 2. + *(CV2._bndrem);
1832 CV2._unset_bndpol();
1836 CVar<T>& CV2 = *CV._CV();
1837 for(
unsigned int i=0; i<CV2.nmon(); i++ ) CV2._coefmon[i] = 0.;
1838 *(CV2._bndrem) = 0.;
1839 T bndmon = Op<T>::zeroone()*2.-1.;
1842 for(
unsigned int i=0; i<CV2.nmon(); i++ ){
1843 for(
unsigned int j=0; j<i; j++ ){
1844 const unsigned int*prodij = CV2._prodmon(i,j);
1845 for(
unsigned int k=0; k<prodij[1]; k++ )
1846 CV2._coefmon[prodij[2+k]] += 2. * CV._coefmon[i] * CV._coefmon[j]
1847 / (
double)prodij[0];
1848 *(CV2._bndrem) += bndmon * ( 2. * CV._coefmon[i] * CV._coefmon[j]
1849 * ( 1. - (
double)prodij[1] / (
double)prodij[0] ) );
1851 const unsigned int*prodii = CV2._prodmon(i,i);
1852 for(
unsigned int k=0; k<prodii[1]; k++ )
1853 CV2._coefmon[prodii[2+k]] += CV._coefmon[i] * CV._coefmon[i]
1854 / (
double)prodii[0];
1855 *(CV2._bndrem) += bndmon * ( CV._coefmon[i] * CV._coefmon[i]
1856 * ( 1. - (
double)prodii[1] / (
double)prodii[0] ) );
1862 T PB = CV._polybound();
1863 *(CV2._bndrem) += ( 2. * PB + *(CV._bndrem) ) * *(CV._bndrem);
1866 CV2._unset_bndpol();
1867 CV2._bndord_uptd =
false;
1872 template <
typename T>
inline CVar<T>&
1873 CVar<T>::operator *=
1881 for(
unsigned int i=0; i<nmon(); i++ ) _coefmon[i] *= c;
1882 for(
unsigned int i=0; _bndord_uptd && i<=nord(); i++ ) _bndord[i] *= c;
1885 if( _bndpol ) *_bndpol *= c;
1889 template <
typename T>
inline CVar<T>
1891 (
const CVar<T>&CV1,
const double c )
1898 template <
typename T>
inline CVar<T>
1900 (
const double c,
const CVar<T>&CV2 )
1907 template <
typename T>
inline CVar<T>&
1908 CVar<T>::operator *=
1912 *(_bndrem) += _coefmon[0];
1917 const double Imid = Op<T>::mid(I);
1919 for(
unsigned int i=0; i<nmon(); i++ ) _coefmon[i] *= Imid;
1920 for(
unsigned int i=0; _bndord_uptd && i<=nord(); i++ ) _bndord[i] *= Imid;
1922 *_bndrem += (I-Imid)*Icur;
1930 template <
typename T>
inline CVar<T>
1932 (
const CVar<T>&CV1,
const T&I )
1939 template <
typename T>
inline CVar<T>
1941 (
const T&I,
const CVar<T>&CV2 )
1948 template <
typename T>
inline CVar<T>&
1949 CVar<T>::operator /=
1950 (
const CVar<T>&CV )
1956 template <
typename T>
inline CVar<T>
1958 (
const CVar<T>&CV1,
const CVar<T>&CV2 )
1960 return CV1 * inv(CV2);
1963 template <
typename T>
inline CVar<T>&
1964 CVar<T>::operator /=
1967 if( isequal( c, 0. ) )
1973 template <
typename T>
inline CVar<T>
1975 (
const CVar<T>&CV,
const double c )
1977 if ( isequal( c, 0. ))
1982 template <
typename T>
inline CVar<T>
1984 (
const double c,
const CVar<T>&CV )
2047 template <
typename T>
inline CVar<T>
2049 (
const CVar<T>&CV )
2052 return CVar<T>( Op<T>::inv(CV._coefmon[0] + *(CV._bndrem)) );
2053 if ( Op<T>::l(CV.B()) <= 0. && Op<T>::u(CV.B()) >= 0. )
2056 CVar<T> CVI( CV._CM, 0. ), CV2( CV._CM, 0. );
2058 double* coefmon = CV._coefinterp();
2059 CV._interpolation( coefmon, mc::inv );
2061 double b(Op<T>::mid(CV.B())), a(Op<T>::u(CV.B())-b), rem, ub(0), lb(0);
2062 for (
unsigned i(0); i<=CV.nord(); i++) {
2064 lb += std::pow(-1.,i)*coefmon[i];
2066 rem = std::max(std::fabs(mc::inv(a+b)-ub), std::fabs(mc::inv(b-a)-lb));
2068 CVI = CV._rescale(a,b);
2069 CV2 = CVI._composition( coefmon );
2070 CV2 += T(-rem, rem);
2075 template <
typename T>
inline CVar<T>
2077 (
const CVar<T>&CV )
2080 return CVar<T>( Op<T>::sqrt(CV._coefmon[0] + *(CV._bndrem)) );
2081 if ( Op<T>::l(CV.B()) < 0. )
2084 CVar<T> CVI( CV._CM, 0. ), CV2( CV._CM, 0. );
2086 double* coefmon = CV._coefinterp();
2087 CV._interpolation( coefmon, std::sqrt );
2089 double b(Op<T>::mid(CV.B())), a(Op<T>::u(CV.B())-b), rem, ub(0), lb(0);
2090 for (
unsigned i(0); i<=CV.nord(); i++) {
2092 lb += std::pow(-1.,i)*coefmon[i];
2094 rem = std::max(std::sqrt(a+b)-ub, std::sqrt(b-a)-lb);
2096 CVI = CV._rescale(a,b);
2097 CV2 = CVI._composition( coefmon );
2098 CV2 += T(-rem, rem);
2103 template <
typename T>
inline CVar<T>
2105 (
const CVar<T>&CV )
2108 return CVar<T>( Op<T>::exp(CV._coefmon[0] + *(CV._bndrem)) );
2110 CVar<T> CVI( CV._CM, 0. ), CV2( CV._CM, 0. );
2112 double* coefmon = CV._coefinterp();
2113 CV._interpolation( coefmon, std::exp );
2115 double b(Op<T>::mid(CV.B())), a(Op<T>::u(CV.B())-b), rem, ub(0), lb(0);
2116 for (
unsigned i(0); i<=CV.nord(); i++) {
2118 lb += std::pow(-1.,i)*coefmon[i];
2120 rem = std::max(std::exp(a+b)-ub, std::exp(b-a)-lb);
2122 CVI = CV._rescale(a,b);
2123 CV2 = CVI._composition( coefmon );
2124 CV2 += T(-rem, rem);
2130 template <
typename T>
inline CVar<T>
2132 (
const CVar<T>&CV )
2135 return CVar<T>( Op<T>::log(CV._coefmon[0] + *(CV._bndrem)) );
2136 if ( Op<T>::l(CV.B()) <= 0. )
2139 CVar<T> CVI( CV._CM, 0. ), CV2( CV._CM, 0. );
2141 double* coefmon = CV._coefinterp();
2142 CV._interpolation( coefmon, std::log );
2144 double b(Op<T>::mid(CV.B())), a(Op<T>::u(CV.B())-b), rem, ub(0), lb(0);
2145 for (
unsigned i(0); i<=CV.nord(); i++) {
2147 lb += std::pow(-1.,i)*coefmon[i];
2149 rem = std::max(std::fabs(std::log(a+b)-ub), std::fabs(std::log(b-a)-lb));
2151 CVI = CV._rescale(a,b);
2152 CV2 = CVI._composition( coefmon );
2153 CV2 += T(-rem, rem);
2159 template <
typename T>
inline CVar<T>
2161 (
const CVar<T>&CV )
2163 return CV * log( CV );
2166 template <
typename T>
inline CVar<T>
2168 (
const CVar<T>&CV,
const int n )
2171 return CVar<T>( Op<T>::pow(CV._coefmon[0] + *(CV._bndrem), n) );
2173 if( n < 0 )
return pow( inv( CV ), -n );
2174 CVar<T> CV2( CV._CM->_intpow( CV, n ) );
2179 template <
typename T>
inline CVar<T>
2181 (
const CVar<T> &CV,
const double a )
2183 return exp( a * log( CV ) );
2186 template <
typename T>
inline CVar<T>
2188 (
const CVar<T> &CV1,
const CVar<T> &CV2 )
2190 return exp( CV2 * log( CV1 ) );
2193 template <
typename T>
inline CVar<T>
2195 (
const double a,
const CVar<T> &CV )
2197 return exp( CV * std::log( a ) );
2200 template <
typename T>
inline CVar<T>
2202 (
const unsigned int n,
const CVar<T>*CV,
const int*k)
2208 return pow( CV[0], k[0] );
2210 return pow( CV[0], k[0] ) * monomial( n-1, CV+1, k+1 );
2213 template <
typename T>
inline CVar<T>
2215 (
const CVar<T> &CV )
2218 return CVar<T>( Op<T>::cos(CV._coefmon[0] + *(CV._bndrem)) );
2220 CVar<T> CVI( CV._CM, 0. ), CV2( CV._CM, 0. );
2222 double* coefmon = CV._coefinterp();
2223 CV._interpolation( coefmon, std::cos );
2225 double b(Op<T>::mid(CV.B())), a(Op<T>::u(CV.B())-b), rem, fact(1);
2226 for (
unsigned i(1); i<=CV.nord()+1; i++) fact *=
double(i);
2227 rem = 4.*std::pow(a/2.,
double(CV.nord()+1))/fact;
2229 CVI = CV._rescale(a,b);
2230 CV2 = CVI._composition( coefmon );
2231 CV2 += T(-rem, rem);
2237 template <
typename T>
inline CVar<T>
2239 (
const CVar<T> &CV )
2241 return cos( CV - PI/2. );
2244 template <
typename T>
inline CVar<T>
2246 (
const CVar<T> &CV )
2249 return CVar<T>( Op<T>::acos(CV._coefmon[0] + *(CV._bndrem)) );
2250 if ( Op<T>::l(CV.B()) < -1. && Op<T>::u(CV.B()) > 1. )
2253 CVar<T> CVI( CV._CM, 0. ), CV2( CV._CM, 0. );
2257 double coefmon[CV.nord()+1];
2258 double b(Op<T>::mid(CV.B())), a(Op<T>::u(CV.B())-b), rem, ub(-4.*a/PI);
2259 coefmon[0] = 0.5*PI*a+b;
2261 for (
unsigned i(3); i<=CV.nord(); i+=2) {
2263 coefmon[i] = coefmon[1]/std::pow(
double(i),2.);
2266 if (CV.nord()%2==0) coefmon[CV.nord()] = 0.;
2269 CVI = CV._rescale(a,b);
2270 CV2 = CVI._composition( coefmon );
2271 CV2 += T(-rem, rem);
2277 template <
typename T>
inline CVar<T>
2279 (
const CVar<T> &CV )
2281 return PI/2. - acos( CV );
2284 template <
typename T>
inline CVar<T>
2286 (
const CVar<T> &CV )
2288 return sin( CV ) / cos( CV );
2291 template <
typename T>
inline CVar<T>
2293 (
const CVar<T> &CV )
2295 return asin( CV / sqrt( sqr( CV ) + 1. ) );
2298 template <
typename T>
inline CVar<T>
2300 (
const CVar<T> &CV )
2303 return CVar<T>( Op<T>::fabs(CV._coefmon[0] + *(CV._bndrem)) );
2305 return sqrt( sqr( CV ) );
2330 template <
typename T>
inline CVar<T>
2332 (
const CVar<T>&CV1,
const CVar<T>&CV2 )
2335 if( !CV1._CM && !CV2._CM ){
2336 T R1 = CV1._coefmon[0] + *(CV1._bndrem);
2337 T R2 = CV2._coefmon[0] + *(CV2._bndrem);
2338 return Op<T>::hull(R1, R2);
2343 return hull( CV2, CV1 );
2346 else if( !CV2._CM ){
2347 CVar<T> CVR = CV1.P();
2348 return CVR + Op<T>::hull( CV1.R(), CV2._coefmon[0]+*(CV2._bndrem)-CVR.B() );
2352 else if( CV1._CM != CV2._CM )
2356 CVar<T> CV1C( CV1 ), CV2C( CV2 );
2357 const double eta = CV1._CM->options.REF_POLY;
2358 T R1C = CV1C.
C().R(), R2C = CV2C.C().R();
2361 T BCVD = (CV1C-CV2C).B();
2362 return (1.-eta)*CV1C + eta*CV2C + Op<T>::hull( R1C+eta*BCVD, R2C+(eta-1.)*BCVD );
2365 template <
typename T>
inline bool
2367 ( CVar<T>&CVR,
const CVar<T>&CV1,
const CVar<T>&CV2 )
2370 if( !CV1._CM && !CV2._CM ){
2371 T R1 = CV1._coefmon[0] + CV1._bndord[0];
2372 T R2 = CV2._coefmon[0] + CV2._bndord[0];
2374 bool flag = Op<T>::inter(RR, R1, R2);
2381 return inter( CVR, CV2, CV1 );
2384 else if( !CV2._CM ){
2385 T R1 = CV1.R(), B2 = CV2.B();
2387 if( !Op<T>::inter(*(CVR._bndrem), R1, B2-CVR.B()) )
2394 else if( CV1._CM != CV2._CM )
2398 CVar<T> CV1C( CV1 ), CV2C( CV2 );
2399 const double eta = CV1._CM->options.REF_POLY;
2400 T R1C = CV1C.
C().R(), R2C = CV2C.C().R();
2403 CVR = (1.-eta)*CV1C + eta*CV2C;
2406 if( !Op<T>::inter( *(CVR._bndrem), R1C+eta*BCVD, R2C+(eta-1.)*BCVD ) )
2420 template <>
template<
typename T>
struct Op< mc::
CVar<T> >
2423 static CV point(
const double c ) {
return CV(c); }
2425 static void I(CV& x,
const CV&y) { x = y; }
2426 static double l(
const CV& x) {
return mc::Op<T>::l(x.
B()); }
2427 static double u(
const CV& x) {
return mc::Op<T>::u(x.
B()); }
2431 static CV inv (
const CV& x) {
return mc::inv(x); }
2432 static CV sqr (
const CV& x) {
return mc::sqr(x); }
2433 static CV sqrt(
const CV& x) {
return mc::sqrt(x); }
2434 static CV log (
const CV& x) {
return mc::log(x); }
2435 static CV xlog(
const CV& x) {
return x*mc::log(x); }
2436 static CV fabs(
const CV& x) {
return mc::fabs(x); }
2437 static CV exp (
const CV& x) {
return mc::exp(x); }
2438 static CV sin (
const CV& x) {
return mc::sin(x); }
2439 static CV cos (
const CV& x) {
return mc::cos(x); }
2440 static CV tan (
const CV& x) {
return mc::tan(x); }
2441 static CV asin(
const CV& x) {
return mc::asin(x); }
2442 static CV acos(
const CV& x) {
return mc::acos(x); }
2443 static CV atan(
const CV& x) {
return mc::atan(x); }
2448 static CV hull(
const CV& x,
const CV& y) {
return mc::hull(x,y); }
2449 static CV min (
const CV& x,
const CV& y) {
return mc::Op<T>::min(x.
B(),y.
B()); }
2450 static CV max (
const CV& x,
const CV& y) {
return mc::Op<T>::max(x.
B(),y.
B()); }
2451 static CV arh (
const CV& x,
const double k) {
return mc::exp(-k/x); }
2452 template <
typename X,
typename Y>
static CV pow(
const X& x,
const Y& y) {
return mc::pow(x,y); }
2453 static CV monomial (
const unsigned int n,
const T* x,
const int* k) {
return mc::monomial(n,x,k); }
2454 static bool inter(CV& xIy,
const CV& x,
const CV& y) {
return mc::inter(xIy,x,y); }
2455 static bool eq(
const CV& x,
const CV& y) {
return mc::Op<T>::eq(x.
B(),y.
B()); }
2456 static bool ne(
const CV& x,
const CV& y) {
return mc::Op<T>::ne(x.
B(),y.
B()); }
2457 static bool lt(
const CV& x,
const CV& y) {
return mc::Op<T>::lt(x.
B(),y.
B()); }
2458 static bool le(
const CV& x,
const CV& y) {
return mc::Op<T>::le(x.
B(),y.
B()); }
2459 static bool gt(
const CV& x,
const CV& y) {
return mc::Op<T>::gt(x.
B(),y.
B()); }
2460 static bool ge(
const CV& x,
const CV& y) {
return mc::Op<T>::ge(x.
B(),y.
B()); }
Options of mc::CModel.
Definition: cmodel.hpp:300
Chebyshev model bound does not intersect with bound in template parameter arithmetic.
Definition: cmodel.hpp:259
Lin & Stadtherr range bounder.
Definition: cmodel.hpp:329
~CVar()
Destructor of Chebyshev variable.
Definition: cmodel.hpp:604
double REF_POLY
Scalar in related to the choice of the polynomial part in the overloaded functions mc::inter and mc:...
Definition: cmodel.hpp:343
Options()
Constructor of mc::CModel::Options.
Definition: cmodel.hpp:303
Operation between Chebyshev variables linked to different Chebyshev models.
Definition: cmodel.hpp:260
Failed to construct Chebyshev variable.
Definition: cmodel.hpp:258
unsigned int nmon() const
Total number of monomial terms in polynomial model.
Definition: polymodel.hpp:463
int ierr()
Error flag.
Definition: cmodel.hpp:266
C++ base class for the computation of polynomial models for factorable functions: Environment...
Definition: polymodel.hpp:36
std::pair< unsigned int, const double * > coefmon() const
Get pair of size of, and const pointer to, array of (possibly scaled) monomial coefficients in multiv...
Definition: polymodel.hpp:870
Division by zero scalar.
Definition: cmodel.hpp:252
CVar< T > P() const
Shortcut to mc::CVar::polynomial.
Definition: cmodel.hpp:652
Exceptions of mc::CModel.
Definition: cmodel.hpp:247
virtual void _center()
Center remainder error term _bndrem
Definition: polymodel.hpp:850
unsigned int DISPLAY_DIGITS
Number of digits in output stream for Chebyshev model coefficients.
Definition: cmodel.hpp:345
unsigned INTERP_EXTRA
Extra terms in chebyshev interpolation of univariates: 0-Chebyshev interpolation of order NORD; extra...
Definition: cmodel.hpp:335
T * _bndrem
Pointer to remainder bound of variable (possibly NULL if not computed)
Definition: polymodel.hpp:443
Eigenvalue decomposition-based bounder.
Definition: cmodel.hpp:330
Naive polynomial range bounder.
Definition: cmodel.hpp:328
Log operation with non-positive numbers in range.
Definition: cmodel.hpp:254
Exceptions(TYPE ierr)
Constructor for error ierr
Definition: cmodel.hpp:264
Hybrid LSB + EIGEN range bounder.
Definition: cmodel.hpp:332
C++ class for the computation of Chebyshev models of factorable function - Chebyshev model environmen...
Definition: cmodel.hpp:218
double * linear() const
Get pointer to array of size nvar with coefficients of linear term in Chebyshev variable.
Definition: cmodel.hpp:1479
~CModel()
Destructor of Chebyshev model environment.
Definition: cmodel.hpp:239
CVar< T > & center()
Center remainder term of Chebyshev variable.
Definition: cmodel.hpp:657
Bernstein range bounder.
Definition: cmodel.hpp:331
Inverse operation with zero in range.
Definition: cmodel.hpp:253
std::string what()
Error description.
Definition: cmodel.hpp:268
virtual T B() const
Shortcut to mc::PolyVar::bound.
Definition: polymodel.hpp:651
virtual PolyVar< T > & set(PolyModel *env)
Set polynomial model environment in variable as env
Definition: polymodel.hpp:573
Feature not yet implemented in mc::CModel.
Definition: cmodel.hpp:261
BOUNDER BOUNDER_TYPE
Chebyshev model range bounder - See How are the options set for the computation of a Chebyshev model...
Definition: cmodel.hpp:337
C++ base class for the computation of polynomial models for factorable functions: Variable...
Definition: polymodel.hpp:425
BOUNDER
Chebyshev model range bounder option.
Definition: cmodel.hpp:327
virtual T B(const int type) const
Shortcut to mc::PolyVar::bound.
Definition: polymodel.hpp:645
Maximum size of polynomial model reached (monomials indexed as unsigned int)
Definition: polymodel.hpp:103
unsigned int nord() const
Order of polynomial model.
Definition: polymodel.hpp:451
CVar< T > & C()
Shortcut to mc::CVar::center.
Definition: cmodel.hpp:661
virtual void _set_bndpol(const T &bndpol)
Set polynomial bound in variable as bndpol
Definition: polymodel.hpp:841
bool _bndord_uptd
Whether the bounds in bndord are up-to-date.
Definition: polymodel.hpp:440
unsigned int nord() const
Order of polynomial model environment.
Definition: polymodel.hpp:62
T bound() const
Retreive bound on variable using default bounder.
Definition: polymodel.hpp:620
TYPE
Enumeration type for CModel exception handling.
Definition: cmodel.hpp:251
unsigned int BOUNDER_ORDER
Order of Bernstein polynomial for Chebyshev model range bounding (no less than Chebyshev model order!...
Definition: cmodel.hpp:339
PolyModel(const unsigned int nvar, const unsigned int nord)
Constructor of polynomial model environment for nvar variables and order nord
Definition: polymodel.hpp:46
C++ class for Chebyshev model computation of factorable function - Chebyshev model propagation...
Definition: cmodel.hpp:207
double constant(const bool reset=false)
Get coefficient of constant term in Chebyshev variable. The value of this coefficient is reset to 0 i...
Definition: cmodel.hpp:1471
CModel< T > * env() const
Get pointer to linked Chebyshev model environment.
Definition: cmodel.hpp:567
double * _coefmon
Array of size _nmon with monomial coefficients of variable.
Definition: polymodel.hpp:434
Square-root operation with negative numbers in range.
Definition: cmodel.hpp:255
const T * bndvar() const
Get const pointer to array of size _nvar with original variable bounds.
Definition: cmodel.hpp:243
CVar< T > polynomial() const
Return new Chebyshev variable with same multivariate polynomial part but zero remainder.
Definition: cmodel.hpp:646
T * _bndord
Array of size _nord+2 with bounds for all terms of degrees iord=0,...,_nord as well as the remainder ...
Definition: polymodel.hpp:437
Failed to compute eigenvalue decomposition in range bounder CModel::Options::EIGEN.
Definition: cmodel.hpp:257
unsigned int nvar() const
Number of variables in polynomial model environment.
Definition: polymodel.hpp:56
static const std::string BOUNDER_NAME[5]
Array of Chebyshev model range bounder names (for display)
Definition: cmodel.hpp:341
Sine/Cosine inverse operation with range outside [-1,1].
Definition: cmodel.hpp:256
CVar< T > & set(CModel< T > *CM, const unsigned int ix, const T &X)
Set Chebyshev variable with index ix (starting from 0) and bounded by X
Definition: cmodel.hpp:627
C++ structure to allow usage of various template parameters in the types mc::McCormick, mc::TModel, mc::TVar, and mc::SpecBnd of MC++ _ Specialization of this structure is required for the template parameters can be found in the header files defining the types mc::McCormick, mc::TModel, mc::TVar, and mc::SpecBnd.
Definition: mcop.hpp:13