524 #ifndef MC__FFUNC_HPP
525 #define MC__FFUNC_HPP
537 #include <sys/time.h>
539 #include "mcfadbad.hpp"
540 #include "mcfunc.hpp"
541 #include "mclapack.hpp"
544 #undef MC__FFUNC_DEBUG
545 #undef MC__FFUNC_DEBUG_TAD
546 #undef MC__FFUNC_DEBUG_DEPMAP
547 #undef MC__FFUNC_CPU_EVAL
587 {
t =
INT; n = i;
return *
this; }
591 {
t =
REAL; x = d;
return *
this; }
595 {
t = num.t;
t==
REAL? x=num.x: n=num.n;
return *
this; }
609 if( Num1->t != Num2->t )
return false;
611 case FFNum::INT:
return Num1->n==Num2->n?
true:
false;
612 case FFNum::REAL:
return isequal( Num1->x, Num2->x );
628 if( Num1->t < Num2->t )
return true;
629 if( Num1->t > Num2->t )
return false;
631 case FFNum::INT:
return Num1->n<Num2->n?
true:
false;
632 case FFNum::REAL:
return !isequal( Num1->x, Num2->x ) && Num1->x<Num2->x?
true:
false;
649 friend std::ostream& operator<< ( std::ostream&,
const FFGraph& );
650 friend std::ostream& operator<< ( std::ostream&,
const FFOp& );
653 friend std::ostream& operator<< ( std::ostream&,
const FFVar& );
656 template <
typename V>
friend FFVar operator+ (
const V&,
const FFVar& );
657 template <
typename V>
friend FFVar operator+ (
const FFVar&,
const V& );
660 template <
typename V>
friend FFVar operator- (
const V&,
const FFVar& );
661 template <
typename V>
friend FFVar operator- (
const FFVar&,
const V& );
663 template <
typename V>
friend FFVar operator* (
const V&,
const FFVar& );
664 template <
typename V>
friend FFVar operator* (
const FFVar&,
const V& );
666 template <
typename V>
friend FFVar operator/ (
const V&,
const FFVar& );
667 template <
typename V>
friend FFVar operator/ (
const FFVar&,
const V& );
669 friend FFVar max (
const unsigned int,
const FFVar* );
670 template <
typename V>
friend FFVar max (
const V&,
const FFVar& );
671 template <
typename V>
friend FFVar max (
const FFVar&,
const V& );
673 friend FFVar min (
const unsigned int,
const FFVar* );
674 template <
typename V>
friend FFVar min (
const V&,
const FFVar& );
675 template <
typename V>
friend FFVar min (
const FFVar&,
const V& );
693 friend FFVar pow (
const FFVar&,
const double );
695 friend FFVar pow (
const double,
const FFVar& );
701 FFVar& operator= (
const int );
702 FFVar& operator= (
const double );
703 template <
typename V>
FFVar& operator+= (
const V& );
704 template <
typename V>
FFVar& operator-= (
const V& );
705 template <
typename V>
FFVar& operator*= (
const V& );
706 template <
typename V>
FFVar& operator/= (
const V& );
708 typedef std::list< FFOp* > t_Ops;
711 typedef typename std::pair< FFOp*, t_Ops > pt_Ops;
716 static const long NOREF = -33;
755 { *
this =
FFVar( dag );
761 : _dag( 0 ), _id(
CINT,
NOREF ), _num( i ), _dep( i ), _val( 0 )
767 : _dag( 0 ), _id(
CREAL,
NOREF ), _num( d ), _dep( d ), _val( 0 )
773 : _dag( Var._dag ), _id( Var._id ), _num( Var._num ), _dep( Var._dep ),
774 _val( Var._val ), _ops( Var._ops )
793 const std::pair<TYPE,long>
id()
const
798 std::pair<TYPE,long>&
id()
836 {
delete static_cast<U*
>( _val ); _val = 0; }
840 {
return _name(_id); }
846 static std::string _name
847 (
const std::pair<TYPE,long>
id )
849 std::ostringstream ovar;
850 id.first==
VAR? ovar<<
"X": ovar<<
"Z";
869 if( Var1->_id.first < Var2->_id.first )
return true;
870 if( Var1->_id.first > Var2->_id.first )
return false;
872 switch( Var1->_id.first ){
875 if( Var1->_id.second < Var2->_id.second )
return true;
876 if( Var1->_id.second > Var2->_id.second )
return false;
880 return ltNum( &Var1->_num, &Var2->_num );
903 PLUS, NEG, MINUS, TIMES, SCALE, DIV,
904 EXP, LOG, SQRT, SQR, IPOW, POW, SIN, COS, TAN, ASIN, ACOS, ATAN,
905 FABS, ERF, FSTEP, MINF, MAXF
926 ( std::list<const FFOp*>&Ops )
const;
929 (
const U& U_dum )
const;
932 (
const U& U_dum,
const std::vector<const FFVar*>&vDep,
933 const std::vector<const FFVar*>&vIndep )
const;
936 ( std::ostream&os )
const;
939 ( std::ostream&os )
const;
942 ( std::ostream&os,
const std::string&fname,
const bool unary,
943 const unsigned int fontsize,
const bool dotted=
false )
const;
946 ( std::ostream&os,
const bool constant,
const unsigned int fontsize )
const;
949 (
const U& U_dum )
const;
956 (
const bool visited=
true )
const
957 { _visited = visited; }
971 mutable bool _visited;
984 (
const FFOp*Op1,
const FFOp*Op2 )
const
987 if( Op1->type < Op2->type )
return true;
988 if( Op1->type > Op2->type )
return false;
992 if( !Op1->plop )
return ltVar( Op1->pres, Op2->pres );
993 if( ltVar( Op1->plop, Op2->plop ) )
return true;
994 if( ltVar( Op2->plop, Op1->plop ) )
return false;
995 if( Op1->prop )
return ltVar( Op1->prop, Op2->prop );
1009 (
const FFOp*Op1,
const FFOp*Op2 )
const
1010 {
return ( Op1->type < Op2->type ); }
1027 template <
typename V>
friend FFVar operator+ (
const V&,
const FFVar& );
1028 template <
typename V>
friend FFVar operator+ (
const FFVar&,
const V& );
1031 template <
typename V>
friend FFVar operator- (
const V&,
const FFVar& );
1032 template <
typename V>
friend FFVar operator- (
const FFVar&,
const V& );
1034 template <
typename V>
friend FFVar operator* (
const V&,
const FFVar& );
1035 template <
typename V>
friend FFVar operator* (
const FFVar&,
const V& );
1037 template <
typename V>
friend FFVar operator/ (
const V&,
const FFVar& );
1038 template <
typename V>
friend FFVar operator/ (
const FFVar&,
const V& );
1040 friend FFVar max (
const unsigned int,
const FFVar* );
1041 template <
typename V>
friend FFVar max (
const V&,
const FFVar& );
1042 template <
typename V>
friend FFVar max (
const FFVar&,
const V& );
1044 friend FFVar min (
const unsigned int,
const FFVar* );
1045 template <
typename V>
friend FFVar min (
const V&,
const FFVar& );
1046 template <
typename V>
friend FFVar min (
const FFVar&,
const V& );
1063 friend FFVar pow (
const FFVar&,
const int );
1064 friend FFVar pow (
const FFVar&,
const double );
1066 friend FFVar pow (
const double,
const FFVar& );
1069 friend std::ostream& operator<< ( std::ostream&,
const FFGraph& );
1076 typedef std::set< FFVar*, lt_FFVar > t_Vars;
1077 typedef std::set< FFOp*, lt_FFOp > t_Ops;
1078 typedef typename t_Vars::iterator it_Vars;
1079 typedef typename t_Vars::const_iterator cit_Vars;
1080 typedef typename t_Ops::iterator it_Ops;
1081 typedef typename t_Ops::const_iterator cit_Ops;
1131 return "Invalid mc::FFGraph passed for initilization of an mc:FFVar object";
1133 return "Operation between mc::FFVar objects linked to different mc::FFGraph objects";
1135 return "Missing independent variable for evaluating a given subgraph using FFGraph::eval";
1137 return "Exception thrown during subgraph evaluation";
1139 return "Feature not yet implemented in mc::FFGraph";
1141 return "Undocumented error in mc::FFGraph";
1179 (
const unsigned int nDep,
const FFVar*pDep )
const;
1183 (
const std::vector<const FFVar*>&vDep )
const;
1187 (
const unsigned nDep,
const FFVar*
const pDep,
const unsigned nIndep,
1188 const FFVar*
const pIndep );
1192 ( std::list<const FFOp*>&opDep,
const unsigned nDep,
const FFVar*
const pDep,
1193 const unsigned nIndep,
const FFVar*
const pIndep );
1197 (
const std::vector<const FFVar*>&vDep,
const std::vector<const FFVar*>&vIndep ) ;
1201 ( std::list<const FFOp*>&opDep,
const std::vector<const FFVar*>&vDep,
const std::vector<const FFVar*>&vIndep ) ;
1205 (
const std::list<const FFOp*>&Ops, std::ostream&os=std::cout );
1209 (
const unsigned int nDep,
const FFVar*pDep, std::ostream&os=std::cout )
const;
1213 (
const std::vector<const FFVar*>&vDep, std::ostream&os=std::cout )
const;
1216 std::vector<const FFVar*>
FAD
1217 (
const std::vector<const FFVar*>&vDep,
const std::vector<const FFVar*>&vIndep );
1221 (
const unsigned nDep,
const FFVar*
const pDep,
const unsigned nIndep,
1222 const FFVar*
const pIndep,
const bool transp=
false );
1225 std::vector<const FFVar*>
BAD
1226 (
const std::vector<const FFVar*>&vDep,
const std::vector<const FFVar*>&vIndep );
1230 (
const unsigned nDep,
const FFVar*
const pDep,
const unsigned nIndep,
1231 const FFVar*
const pIndep,
const bool transp=
false );
1234 std::vector<const FFVar*>
TAD
1235 (
const unsigned int ordermax,
const std::vector<const FFVar*>&vDep,
1236 const std::vector<const FFVar*>&vVar,
const FFVar*
const pIndep=0 );
1240 (
const unsigned int ordermax,
const unsigned nDep,
const FFVar*
const pDep,
1241 const unsigned nVar,
const FFVar*
const pVar,
const FFVar*
const pIndep=0 );
1244 std::vector<const FFVar*>
compose
1245 (
const std::vector<const FFVar*>&vDepOut,
1246 const std::vector< std::pair<const FFVar*,const FFVar*> >&vDepIn );
1250 (
const unsigned nDepOut,
const FFVar*pDepOut,
const unsigned nDepIn,
1254 template <
typename U> std::vector<U>
eval
1255 (
const std::vector<const FFVar*>&vDep,
1256 const std::vector< std::pair<const FFVar*,U> >&vVar );
1259 template <
typename U> std::vector<U>
eval
1260 ( std::list<const FFOp*>&opDep,
const std::vector<const FFVar*>&vDep,
1261 const std::vector< std::pair<const FFVar*,U> >&vVar );
1264 template <
typename U> std::vector<U>
eval
1265 ( std::list<const FFOp*>&opDep, U*opRes,
const std::vector<const FFVar*>&vDep,
1266 const std::vector< std::pair<const FFVar*,U> >&vVar );
1269 template <
typename U>
void eval
1270 (
const unsigned nDep,
const FFVar*pDep, U*vDep,
1271 const unsigned nVar,
const FFVar*pVar, U*vVar,
const bool add=
false );
1274 template <
typename U>
void eval
1275 ( std::list<const FFOp*>&opDep,
const unsigned nDep,
const FFVar*pDep,
1276 U*vDep,
const unsigned nVar,
const FFVar*pVar, U*vVar,
const bool add=
false );
1279 template <
typename U>
void eval
1280 ( std::list<const FFOp*>&opDep, U*opRes,
const unsigned nDep,
const FFVar*pDep,
1281 U*vDep,
const unsigned nVar,
const FFVar*pVar, U*vVar,
const bool add=
false );
1285 { timeval time; gettimeofday(&time, 0) ;
1286 return time.tv_sec + time.tv_usec*1e-6; }
1297 { it_Ops ito =
_Ops.begin();
1298 for( ; ito !=
_Ops.end(); ++ito )
delete *ito;
1303 { it_Ops ito =
_Ops.begin();
1304 for( ; ito !=
_Ops.end(); ++ito ) (*ito)->flag(
false ); }
1315 template <
typename U>
static FFVar&
1320 template <
typename U>
static FFVar&
1342 { it_Vars itv =
_Vars.begin();
1343 for( ; itv !=
_Vars.end(); ++itv )
delete *itv;
1371 inline std::ostream&
1373 ( std::ostream&out,
const FFNum&Num )
1377 out << Num.n <<
"(I)";
break;
1379 out << Num.x <<
"(D)";
break;
1389 _id( VAR, _dag->_nvar++ ), _num( 0./0. ), _dep(), _val( 0 )
1394 _dep.indep(_id.second);
1398 FFOp* pOp =
new FFOp( FFOp::VAR, 0, 0, pVar );
1399 _dag->_Ops.insert( pOp );
1400 pVar->_ops.first = _ops.first = pOp;
1401 _dag->_append_var( pVar );
1435 : _dag( dag ), _id( AUX, dag->_naux++ ), _num( 0./0. ), _dep(dep), _val ( 0 )
1436 { _ops.first = op; }
1439 ( FFGraph*dag,
const pt_idVar&
id )
1440 : _dag( dag ), _id( id ), _num( 0 ), _dep(), _val( 0 )
1443 inline std::ostream&
1445 ( std::ostream&out,
const FFVar&Var)
1456 if(
this == &Var )
return *
this;
1470 _id = std::make_pair(CINT,NOREF);
1476 _ops.second.clear();
1484 _id = std::make_pair(CREAL,NOREF);
1490 _ops.second.clear();
1501 template <
typename U>
inline FFVar&
1505 FFVar VarNew = *
this + Var;
1512 (
const FFVar&Var1,
const FFVar&Var2 )
1514 if( &Var1 == &Var2 )
return( 2. * Var1 );
1518 switch( Var1._num.t ){
1520 switch( Var2._num.t ){
1521 case FFNum::INT:
return( Var1._num.n + Var2._num.n );
1522 case FFNum::REAL:
return( Var1._num.n + Var2._num.x );
1525 switch( Var2._num.t ){
1526 case FFNum::INT:
return( Var1._num.x + Var2._num.n );
1527 case FFNum::REAL:
return( Var1._num.x + Var2._num.x );
1532 switch( Var1._num.t ){
1533 case FFNum::INT:
return( Var2 + Var1._num.n );
1538 switch( Var2._num.t ){
1539 case FFNum::INT:
return( Var1 + Var2._num.n );
1549 template <
typename U>
inline FFVar
1551 (
const U&Cst1,
const FFVar&Var2 )
1554 if( Cst1 == 0. )
return Var2;
1558 switch( Var2._num.t ){
1559 case FFNum::INT:
return( Cst1 + Var2._num.n );
1570 template <
typename U>
inline FFVar
1572 (
const FFVar&Var1,
const U&Cst2 )
1574 return( Cst2 + Var1 );
1583 switch( Var._num.
t ){
1594 template <
typename U>
inline FFVar&
1598 FFVar VarNew = *
this - Var;
1605 (
const FFVar&Var1,
const FFVar&Var2 )
1607 if( &Var1 == &Var2 )
return double(0);
1612 switch( Var1._num.t ){
1614 switch( Var2._num.t ){
1615 case FFNum::INT:
return( Var1._num.n - Var2._num.n );
1616 case FFNum::REAL:
return( Var1._num.n - Var2._num.x );
1619 switch( Var2._num.t ){
1620 case FFNum::INT:
return( Var1._num.x - Var2._num.n );
1621 case FFNum::REAL:
return( Var1._num.x - Var2._num.x );
1627 switch( Var1._num.t ){
1628 case FFNum::INT:
return( (
double)Var1._num.n - Var2 );
1634 switch( Var2._num.t ){
1635 case FFNum::INT:
return( Var1 - (
double)Var2._num.n );
1645 template <
typename U>
inline FFVar
1647 (
const FFVar&Var1,
const U&Cst2 )
1652 if( Cst2 == 0. )
return Var1;
1656 switch( Var1._num.t ){
1657 case FFNum::INT:
return( Var1._num.n - Cst2 );
1668 template <
typename U>
inline FFVar
1670 (
const U&Cst1,
const FFVar&Var2 )
1673 if( Cst1 == 0. )
return -Var2;
1677 switch( Var2._num.t ){
1678 case FFNum::INT:
return( Cst1 - Var2._num.n );
1689 template <
typename U>
inline FFVar&
1693 FFVar VarNew = *
this * Var;
1700 (
const FFVar&Var1,
const FFVar&Var2 )
1702 if( &Var1 == &Var2 )
return sqr(Var1);
1706 switch( Var1._num.t ){
1708 switch( Var2._num.t ){
1709 case FFNum::INT:
return( Var1._num.n * Var2._num.n );
1710 case FFNum::REAL:
return( Var1._num.n * Var2._num.x );
1713 switch( Var2._num.t ){
1714 case FFNum::INT:
return( Var1._num.x * Var2._num.n );
1715 case FFNum::REAL:
return( Var1._num.x * Var2._num.x );
1721 switch( Var1._num.t ){
1722 case FFNum::INT:
return( (
double)Var1._num.n * Var2 );
1728 switch( Var2._num.t ){
1729 case FFNum::INT:
return( Var1 * (
double)Var2._num.n );
1739 template <
typename U>
inline FFVar
1741 (
const FFVar&Var1,
const U&Cst2 )
1743 return( Cst2 * Var1 );
1746 template <
typename U>
inline FFVar
1748 (
const U&Cst1,
const FFVar&Var2 )
1751 if( Cst1 == 0. )
return double(0);
1753 if( Cst1 == 1. )
return Var2;
1755 if( Cst1 == -1. )
return -Var2;
1759 switch( Var2._num.t ){
1760 case FFNum::INT:
return( Cst1 * Var2._num.n );
1771 template <
typename U>
inline FFVar&
1775 FFVar VarNew = *
this / Var;
1782 (
const FFVar&Var1,
const FFVar&Var2 )
1784 if( &Var1 == &Var2 )
return double(1);
1788 switch( Var1._num.t ){
1790 switch( Var2._num.t ){
1791 case FFNum::INT:
return( Var1._num.n / Var2._num.n );
1792 case FFNum::REAL:
return( Var1._num.n / Var2._num.x );
1795 switch( Var2._num.t ){
1796 case FFNum::INT:
return( Var1._num.x / Var2._num.n );
1797 case FFNum::REAL:
return( Var1._num.x / Var2._num.x );
1803 switch( Var1._num.t ){
1804 case FFNum::INT:
return( Var1._num.n / Var2 );
1810 switch( Var2._num.t ){
1811 case FFNum::INT:
return( Var1 / Var2._num.n );
1821 template <
typename U>
inline FFVar
1823 (
const FFVar&Var1,
const U&Cst2 )
1825 return( ( 1 / Cst2 ) * Var1 );
1828 template <
typename U>
inline FFVar
1830 (
const U&Cst1,
const FFVar&Var2 )
1833 if( Cst1 == 0. )
return int(0);
1837 switch( Var2._num.t ){
1838 case FFNum::INT:
return( Cst1 / Var2._num.n );
1858 (
const FFVar&Var1,
const FFVar&Var2 )
1860 if( &Var1 == &Var2 )
return Var1;
1864 switch( Var1._num.t ){
1866 switch( Var2._num.t ){
1867 case FFNum::INT:
return( Var1._num.n>Var2._num.n? Var1._num.n: Var2._num.n );
1868 case FFNum::REAL:
return( std::max((
double)Var1._num.n,Var2._num.x) );
1871 switch( Var2._num.t ){
1872 case FFNum::INT:
return( std::max(Var1._num.x,(
double)Var2._num.n) );
1873 case FFNum::REAL:
return( std::max(Var1._num.x,Var2._num.x) );
1879 switch( Var1._num.t ){
1880 case FFNum::INT:
return( max((
double)Var1._num.n,Var2) );
1881 case FFNum::REAL:
return( max(Var1._num.x,Var2) );
1886 switch( Var2._num.t ){
1887 case FFNum::INT:
return( max((
double)Var2._num.n,Var1) );
1888 case FFNum::REAL:
return( max(Var2._num.x,Var1) );
1897 template <
typename U>
inline FFVar
1899 (
const FFVar&Var1,
const U&Cst2 )
1901 return( max( Cst2, Var1 ) );
1904 template <
typename U>
inline FFVar
1906 (
const U&Cst1,
const FFVar&Var2 )
1910 switch( Var2._num.t ){
1911 case FFNum::INT:
return( std::max(Cst1,(
double)Var2._num.n) );
1912 case FFNum::REAL:
return( std::max(Cst1,Var2._num.x) );
1924 (
const unsigned nVar,
const FFVar*pVar )
1926 if( nVar<=0 || !pVar )
return( 0 );
1928 FFVar VarR = pVar[0];
1929 for(
unsigned int i=1; i<nVar; i++ ) VarR = max( VarR, pVar[i] );
1935 (
const FFVar&Var1,
const FFVar&Var2 )
1937 if( &Var1 == &Var2 )
return Var1;
1941 switch( Var1._num.t ){
1943 switch( Var2._num.t ){
1944 case FFNum::INT:
return( Var1._num.n<Var2._num.n? Var1._num.n: Var2._num.n );
1945 case FFNum::REAL:
return( std::min((
double)Var1._num.n,Var2._num.x) );
1948 switch( Var2._num.t ){
1949 case FFNum::INT:
return( std::min(Var1._num.x,(
double)Var2._num.n) );
1950 case FFNum::REAL:
return( std::min(Var1._num.x,Var2._num.x) );
1956 switch( Var1._num.t ){
1957 case FFNum::INT:
return( min((
double)Var1._num.n,Var2) );
1958 case FFNum::REAL:
return( min(Var1._num.x,Var2) );
1963 switch( Var2._num.t ){
1964 case FFNum::INT:
return( min((
double)Var2._num.n,Var1) );
1965 case FFNum::REAL:
return( min(Var2._num.x,Var1) );
1974 template <
typename U>
inline FFVar
1976 (
const FFVar&Var1,
const U&Cst2 )
1978 return( min( Cst2, Var1 ) );
1981 template <
typename U>
inline FFVar
1983 (
const U&Cst1,
const FFVar&Var2 )
1987 switch( Var2._num.t ){
1988 case FFNum::INT:
return( std::min(Cst1,(
double)Var2._num.n) );
1989 case FFNum::REAL:
return( std::min(Cst1,Var2._num.x) );
2001 (
const unsigned nVar,
const FFVar*pVar )
2003 if( nVar<=0 || !pVar )
return( 0 );
2005 FFVar VarR = pVar[0];
2006 for(
unsigned int i=1; i<nVar; i++ ) VarR = min( VarR, pVar[i] );
2016 switch( Var._num.t ){
2017 case FFNum::INT:
return( std::exp( Var._num.n ) );
2018 case FFNum::REAL:
return( std::exp( Var._num.x ) );
2033 switch( Var._num.t ){
2034 case FFNum::INT:
return( std::log( Var._num.n ) );
2035 case FFNum::REAL:
return( std::log( Var._num.x ) );
2050 switch( Var._num.t ){
2051 case FFNum::INT:
return( mc::sqr( Var._num.n ) );
2052 case FFNum::REAL:
return( mc::sqr( Var._num.x ) );
2067 switch( Var._num.t ){
2068 case FFNum::INT:
return( std::sqrt( Var._num.n ) );
2069 case FFNum::REAL:
return( std::sqrt( Var._num.x ) );
2084 switch( Var._num.t ){
2085 case FFNum::INT:
return( std::fabs( Var._num.n ) );
2086 case FFNum::REAL:
return( std::fabs( Var._num.x ) );
2097 (
const FFVar&Var,
const int iExp )
2101 switch( Var._num.t ){
2102 case FFNum::INT:
return( std::pow( Var._num.n, iExp ) );
2103 case FFNum::REAL:
return( std::pow( Var._num.x, iExp ) );
2108 if( iExp == 0 )
return( 1. );
2109 if( iExp == 1 )
return Var;
2110 if( iExp == 2 )
return sqr(Var);
2120 (
const FFVar&Var1,
const double Cst2 )
2122 return exp( Cst2 * log( Var1 ) );
2127 (
const FFVar&Var1,
const FFVar&Var2 )
2131 return pow( Var1, Var2._num.n );
2133 return exp( Var2 * log( Var1 ) );
2138 (
const double Cst1,
const FFVar&Var2 )
2142 return std::pow( Cst1, Var2._num.n );
2144 return exp( Var2 * std::log( Cst1 ) );
2153 switch( Var._num.t ){
2154 case FFNum::INT:
return( std::cos( Var._num.n ) );
2155 case FFNum::REAL:
return( std::cos( Var._num.x ) );
2170 switch( Var._num.t ){
2171 case FFNum::INT:
return( std::sin( Var._num.n ) );
2172 case FFNum::REAL:
return( std::sin( Var._num.x ) );
2187 switch( Var._num.t ){
2188 case FFNum::INT:
return( std::tan( Var._num.n ) );
2189 case FFNum::REAL:
return( std::tan( Var._num.x ) );
2205 switch( Var._num.t ){
2206 case FFNum::INT:
return( std::asin( Var._num.n ) );
2207 case FFNum::REAL:
return( std::asin( Var._num.x ) );
2222 switch( Var._num.t ){
2223 case FFNum::INT:
return( std::acos( Var._num.n ) );
2224 case FFNum::REAL:
return( std::acos( Var._num.x ) );
2239 switch( Var._num.t ){
2240 case FFNum::INT:
return( std::atan( Var._num.n ) );
2241 case FFNum::REAL:
return( std::atan( Var._num.x ) );
2256 switch( Var._num.t ){
2257 case FFNum::INT:
return( ::erf( Var._num.n ) );
2271 return ( 1. - erf( Var ) );
2280 switch( Var._num.t ){
2281 case FFNum::INT:
return( mc::fstep( Var._num.n ) );
2282 case FFNum::REAL:
return( mc::fstep( Var._num.x ) );
2295 return ( fstep( -Var ) );
2304 type( top ), pres( res ), _visited(
false)
2308 || ( top != PLUS && top != TIMES && top != SCALE )
2310 { plop = lop; prop = rop; }
2312 { plop = rop; prop = lop; }
2315 inline std::ostream&
2317 ( std::ostream&out,
const FFOp&
Op)
2320 case FFOp::CNST: out <<
Op.pres->num() <<
"\t";
break;
2321 case FFOp::VAR: out <<
"VARIABLE";
break;
2322 case FFOp::PLUS: out << FFVar::_name(
Op.plop->id() ) <<
" + " << FFVar::_name(
Op.prop->id() ) <<
"\t";
break;
2323 case FFOp::NEG: out <<
"- " << FFVar::_name(
Op.plop->id() ) <<
"\t" ;
break;
2324 case FFOp::MINUS: out << FFVar::_name(
Op.plop->id() ) <<
" - " << FFVar::_name(
Op.prop->id() ) <<
"\t";
break;
2326 case FFOp::SCALE: out << FFVar::_name(
Op.plop->id() ) <<
" * " << FFVar::_name(
Op.prop->id() ) <<
"\t";
break;
2327 case FFOp::DIV: out << FFVar::_name(
Op.plop->id() ) <<
" / " << FFVar::_name(
Op.prop->id() ) <<
"\t";
break;
2328 case FFOp::MINF: out <<
"MIN( " << FFVar::_name(
Op.plop->id() ) <<
", " << FFVar::_name(
Op.prop->id() ) <<
" )";
break;
2329 case FFOp::MAXF: out <<
"MAX( " << FFVar::_name(
Op.plop->id() ) <<
", " << FFVar::_name(
Op.prop->id() ) <<
" )";
break;
2330 case FFOp::EXP: out <<
"EXP( " << FFVar::_name(
Op.plop->id() ) <<
" )\t";
break;
2331 case FFOp::LOG: out <<
"LOG( " << FFVar::_name(
Op.plop->id() ) <<
" )\t";
break;
2332 case FFOp::SQR: out <<
"SQR( " << FFVar::_name(
Op.plop->id() ) <<
" )\t";
break;
2333 case FFOp::SQRT: out <<
"SQRT( " << FFVar::_name(
Op.plop->id() ) <<
" )\t";
break;
2334 case FFOp::FABS: out <<
"FABS( " << FFVar::_name(
Op.plop->id() ) <<
" )\t";
break;
2335 case FFOp::IPOW: out <<
"POW( " << FFVar::_name(
Op.plop->id() ) <<
", " << FFVar::_name(
Op.prop->id() ) <<
" )";
break;
2336 case FFOp::COS: out <<
"COS( " << FFVar::_name(
Op.plop->id() ) <<
" )\n";
break;
2337 case FFOp::SIN: out <<
"SIN( " << FFVar::_name(
Op.plop->id() ) <<
" )\n";
break;
2338 case FFOp::TAN: out <<
"TAN( " << FFVar::_name(
Op.plop->id() ) <<
" )\n";
break;
2339 case FFOp::ASIN: out <<
"ASIN( " << FFVar::_name(
Op.plop->id() ) <<
" )\n";
break;
2340 case FFOp::ACOS: out <<
"ACOS( " << FFVar::_name(
Op.plop->id() ) <<
" )\n";
break;
2341 case FFOp::ATAN: out <<
"ATAN( " << FFVar::_name(
Op.plop->id() ) <<
" )\n";
break;
2342 case FFOp::ERF: out <<
"ERF( " << FFVar::_name(
Op.plop->id() ) <<
" )\n";
break;
2343 case FFOp::FSTEP: out <<
"FSTEP( " << FFVar::_name(
Op.plop->id() ) <<
" )\n";
break;
2351 ( std::list<const FFOp*>&Ops )
const
2353 if( _visited )
return;
2357 if( plop && plop->ops().first ) plop->ops().first->propagate_subgraph( Ops );
2358 if( prop && prop->ops().first ) prop->ops().first->propagate_subgraph( Ops );
2359 Ops.push_back(
this );
2362 template <
typename U>
inline void
2364 (
const U& U_dum )
const
2366 if( _visited )
return;
2369 if( plop && plop->ops().first ) plop->ops().first->reset_val_subgraph( U_dum );
2370 if( prop && prop->ops().first ) prop->ops().first->reset_val_subgraph( U_dum );
2371 if( pres && pres->val() ) pres->reset_val( U_dum );
2374 template <
typename U>
inline void
2376 (
const U& U_dum,
const std::vector<const FFVar*>&vDep,
2377 const std::vector<const FFVar*>&vIndep )
const
2379 if( _visited )
return;
2382 if( plop && plop->ops().first ) plop->ops().first->reset_val_subgraph( U_dum, vDep, vIndep );
2383 if( prop && prop->ops().first ) prop->ops().first->reset_val_subgraph( U_dum, vDep, vIndep );
2384 if( pres && pres->val() ){
2386 typename std::vector<const FFVar*>::const_iterator iti = vIndep.begin();
2387 for( ; iti!=vIndep.end(); ++iti )
if( pres->id() == (*iti)->id() )
return;
2389 typename std::vector<const FFVar*>::const_iterator itd = vDep.begin();
2390 for( ; itd!=vDep.end(); ++itd )
if( pres->id() == (*itd)->id() )
return;
2391 pres->reset_val( U_dum );
2395 template <
typename U>
inline void
2397 (
const U& U_dum )
const
2406 switch( pres->num().t ){
2407 case FFNum::INT: pres->val() =
new U( pres->num().n );
return;
2408 case FFNum::REAL: pres->val() =
new U( pres->num().x );
return;
2413 pres->val() =
new U( *static_cast<U*>( plop->val() )
2414 + *static_cast<U*>( prop->val() ) );
2415 #ifdef MC__FFUNC_DEBUG_EVAL
2416 std::cout <<
"FFOp::PLUS:" << std::endl;
2417 std::cout <<
"plop: " << plop <<
" plop->val(): " << plop->val() << std::endl;
2418 std::cout <<
"prop: " << prop <<
" prop->val(): " << prop->val() << std::endl;
2419 std::cout <<
"pres: " << pres <<
" pres->val(): " << pres->val() << std::endl;
2425 pres->val() =
new U( - *static_cast<U*>( plop->val() ) );
2430 pres->val() =
new U( *static_cast<U*>( plop->val() )
2431 - *static_cast<U*>( prop->val() ) );
2437 pres->val() =
new U( *static_cast<U*>( plop->val() )
2438 * *static_cast<U*>( prop->val() ) );
2439 #ifdef MC__FFUNC_DEBUG_EVAL
2440 std::cout <<
"FFOp::TIMES:" << std::endl;
2441 std::cout <<
"plop: " << plop <<
" plop->val(): " << plop->val() << std::endl;
2442 std::cout <<
"prop: " << prop <<
" prop->val(): " << prop->val() << std::endl;
2443 std::cout <<
"pres: " << pres <<
" pres->val(): " << pres->val() << std::endl;
2449 pres->val() =
new U( *static_cast<U*>( plop->val() )
2450 / *static_cast<U*>( prop->val() ) );
2455 pres->val() =
new U(
Op<U>::pow( *static_cast<U*>( plop->val() ),
2461 pres->val() =
new U(
Op<U>::exp( *static_cast<U*>( plop->val() ) ) );
2466 pres->val() =
new U(
Op<U>::log( *static_cast<U*>( plop->val() ) ) );
2471 pres->val() =
new U(
Op<U>::sqr( *static_cast<U*>( plop->val() ) ) );
2472 #ifdef MC__FFUNC_DEBUG_EVAL
2473 std::cout <<
"FFOp::SQR:" << std::endl;
2474 std::cout <<
"plop: " << plop <<
" plop->val(): " << plop->val() << std::endl;
2475 std::cout <<
"pres: " << pres <<
" pres->val(): " << pres->val() << std::endl;
2481 pres->val() =
new U(
Op<U>::sqrt( *static_cast<U*>( plop->val() ) ) );
2486 pres->val() =
new U(
Op<U>::cos( *static_cast<U*>( plop->val() ) ) );
2491 pres->val() =
new U(
Op<U>::sin( *static_cast<U*>( plop->val() ) ) );
2496 pres->val() =
new U(
Op<U>::tan( *static_cast<U*>( plop->val() ) ) );
2501 pres->val() =
new U(
Op<U>::acos( *static_cast<U*>( plop->val() ) ) );
2506 pres->val() =
new U(
Op<U>::asin( *static_cast<U*>( plop->val() ) ) );
2511 pres->val() =
new U(
Op<U>::atan( *static_cast<U*>( plop->val() ) ) );
2516 pres->val() =
new U(
Op<U>::erf( *static_cast<U*>( plop->val() ) ) );
2521 pres->val() =
new U(
Op<U>::fabs( *static_cast<U*>( plop->val() ) ) );
2526 pres->val() =
new U(
Op<U>::fstep( *static_cast<U*>( plop->val() ) ) );
2531 pres->val() =
new U(
Op<U>::min( *static_cast<U*>( plop->val() ),
2532 *static_cast<U*>( prop->val() ) ) );
2537 pres->val() =
new U(
Op<U>::max( *static_cast<U*>( plop->val() ),
2538 *static_cast<U*>( prop->val() ) ) );
2546 template <
typename U>
inline void
2556 switch( pres->num().t ){
2557 case FFNum::INT: *pUres = pres->num().n;
break;
2563 *pUres = *
static_cast<U*
>( plop->val() ) + *static_cast<U*>( prop->val() );
2567 *pUres = - *
static_cast<U*
>( plop->val() );
2571 *pUres = *
static_cast<U*
>( plop->val() ) - *static_cast<U*>( prop->val() );
2576 *pUres = *
static_cast<U*
>( plop->val() ) * *static_cast<U*>( prop->val() );
2580 *pUres = *
static_cast<U*
>( plop->val() ) / *static_cast<U*>( prop->val() );
2584 *pUres =
Op<U>::pow( *static_cast<U*>( plop->val() ), prop->num().n );
2588 *pUres =
Op<U>::exp( *static_cast<U*>( plop->val() ) );
2592 *pUres =
Op<U>::log( *static_cast<U*>( plop->val() ) );
2596 *pUres =
Op<U>::sqr( *static_cast<U*>( plop->val() ) );
2600 *pUres =
Op<U>::sqrt( *static_cast<U*>( plop->val() ) );
2604 *pUres =
Op<U>::cos( *static_cast<U*>( plop->val() ) );
2608 *pUres =
Op<U>::sin( *static_cast<U*>( plop->val() ) );
2612 *pUres =
Op<U>::tan( *static_cast<U*>( plop->val() ) );
2616 *pUres =
Op<U>::acos( *static_cast<U*>( plop->val() ) );
2620 *pUres =
Op<U>::asin( *static_cast<U*>( plop->val() ) );
2624 *pUres =
Op<U>::atan( *static_cast<U*>( plop->val() ) );
2628 *pUres =
Op<U>::erf( *static_cast<U*>( plop->val() ) );
2632 *pUres =
Op<U>::fabs( *static_cast<U*>( plop->val() ) );
2636 *pUres =
Op<U>::fstep( *static_cast<U*>( plop->val() ) );
2640 *pUres =
Op<U>::min( *static_cast<U*>( plop->val() ), *static_cast<U*>( prop->val() ) );
2644 *pUres =
Op<U>::max( *static_cast<U*>( plop->val() ), *static_cast<U*>( prop->val() ) );
2651 pres->val() = pUres;
2657 ( std::ostream&os )
const
2659 if( _visited )
return;
2662 if( plop && plop->ops().first ) plop->ops().first->generate_dot_script( os );
2663 if( prop && prop->ops().first ) prop->ops().first->generate_dot_script( os );
2664 append_dot_script( os );
2669 ( std::ostream&os )
const
2671 std::ostringstream var_color; var_color <<
"red";
2672 std::ostringstream aux_color; aux_color <<
"blue";
2673 std::ostringstream op_color; op_color <<
"black";
2675 case FFOp::VAR:
return append_dot_script_variable( os,
false, 14 );
2676 case FFOp::CNST:
return append_dot_script_variable( os,
true, 14 );
2677 case FFOp::PLUS:
return append_dot_script_factor( os,
" + ",
false, 18 );
2678 case FFOp::NEG:
return append_dot_script_factor( os,
" - ",
true, 18 );
2679 case FFOp::MINUS:
return append_dot_script_factor( os,
" - ",
false, 18 );
2680 case FFOp::SCALE:
return append_dot_script_factor( os,
" x ",
false, 18 );
2681 case FFOp::TIMES:
return append_dot_script_factor( os,
" x ",
false, 18 );
2682 case FFOp::DIV:
return append_dot_script_factor( os,
" / ",
false, 18 );
2683 case FFOp::MINF:
return append_dot_script_factor( os,
"min",
false, 14 );
2684 case FFOp::MAXF:
return append_dot_script_factor( os,
"max",
false, 14 );
2685 case FFOp::IPOW:
return append_dot_script_factor( os,
"pow",
false, 14,
true );
2686 case FFOp::EXP:
return append_dot_script_factor( os,
"exp",
true, 14 );
2687 case FFOp::LOG:
return append_dot_script_factor( os,
"log",
true, 14 );
2688 case FFOp::FABS:
return append_dot_script_factor( os,
"fabs",
true, 14 );
2689 case FFOp::SQR:
return append_dot_script_factor( os,
"sqr",
true, 14 );
2690 case FFOp::SQRT:
return append_dot_script_factor( os,
"sqrt",
true, 14 );
2691 case FFOp::COS:
return append_dot_script_factor( os,
"cos",
true, 14 );
2692 case FFOp::SIN:
return append_dot_script_factor( os,
"sin",
true, 14 );
2693 case FFOp::TAN:
return append_dot_script_factor( os,
"tan",
true, 14 );
2694 case FFOp::ACOS:
return append_dot_script_factor( os,
"acos",
true, 14 );
2695 case FFOp::ASIN:
return append_dot_script_factor( os,
"asin",
true, 14 );
2696 case FFOp::ATAN:
return append_dot_script_factor( os,
"atan",
true, 14 );
2697 case FFOp::ERF:
return append_dot_script_factor( os,
"erf",
true, 14 );
2698 case FFOp::FSTEP:
return append_dot_script_factor( os,
"fstep",
true, 14 );
2699 default: os <<
"/* a factor was not displayed */\n";
2706 ( std::ostream&os,
const std::string&fname,
const bool unary,
2707 const unsigned int fontsize,
const bool dotted )
const
2709 std::ostringstream op_color; op_color <<
"black";
2711 os <<
" " << pres->name() <<
" [shape=record,fontname=\"Arial\",color="
2712 << op_color.str().c_str() <<
",label=\"<f0> " << fname.c_str() <<
"|<f1> "
2713 << pres->name() <<
"\"];\n";
2715 os <<
" " << plop->name() <<
" -> " << pres->name() <<
" [arrowsize=0.7];\n";
2717 os <<
" " << prop->name() <<
" -> " << pres->name() <<
" [arrowsize=0.7"
2718 << (dotted?
",style=dotted];\n":
"];\n");
2725 ( std::ostream&os,
const bool constant,
const unsigned int fontsize )
const
2727 std::ostringstream var_color; var_color <<
"red";
2728 std::ostringstream cst_color; cst_color <<
"blue";
2731 os <<
" " << pres->name() <<
" [shape=record,fontname=\"Arial\",color="
2732 << cst_color.str().c_str() <<
",label=\"<f0> " << pres->num() <<
"|<f1> "
2733 << pres->name() <<
"\"];\n";
2735 os <<
" " << pres->name() <<
" [shape=ellipse,fontname=\"Arial\",color="
2736 << (var_color.str().c_str()) <<
"];\n";
2745 case FFOp::PLUS:
case FFOp::MINUS:
case FFOp::TIMES:
case FFOp::DIV:
2746 case FFOp::MINF:
case FFOp::MAXF:
2748 case FFOp::NEG:
case FFOp::SCALE:
case FFOp::IPOW:
case FFOp::EXP:
2749 case FFOp::LOG:
case FFOp::FABS:
case FFOp::SQR:
case FFOp::SQRT:
2750 case FFOp::COS:
case FFOp::SIN:
case FFOp::TAN:
case FFOp::ACOS:
2751 case FFOp::ASIN:
case FFOp::ATAN:
case FFOp::ERF:
case FFOp::FSTEP:
2759 inline std::ostream&
2761 ( std::ostream&out,
const FFGraph&dag)
2763 typename FFGraph::t_Vars Vars = dag.
_Vars;
2764 typename FFGraph::it_Vars itv = Vars.begin();
2766 out << ( dag.
_nvar?
"\nDAG VARIABLES:\n":
"\nNO DAG VARIABLES\n" );
2767 for( ; itv!=Vars.end() && (*itv)->_id.first<=
FFVar::VAR; ++itv ){
2769 out <<
" " << **itv;
2771 typename FFVar::t_Ops Ops = (*itv)->_ops.second;
2772 typename FFVar::t_Ops::iterator ito = Ops.begin();
2773 for( ; ito!=Ops.end(); ++ito ) out <<
" " << *(*ito)->pres;
2774 out <<
" }" << std::endl;
2777 out << ( dag.
_naux?
"\nDAG INTERMEDIATES:\n":
"\nNO DAG INTERMEDIATES\n" );
2778 for( ; itv!=Vars.end(); ++itv ){
2780 out <<
" " << **itv;
2781 if( (*itv)->_ops.first ) out <<
"\t" <<
"<= " << *((*itv)->_ops.first);
2783 typename FFVar::t_Ops Ops = (*itv)->_ops.second;
2784 typename FFVar::t_Ops::iterator ito = Ops.begin();
2785 for( ; ito!=Ops.end(); ++ito ) out <<
" " << *(*ito)->pres;
2786 out <<
" }" << std::endl;
2796 if( Var1._dag != Var2._dag )
throw Exceptions( Exceptions::DAG );
2798 FFVar *pVar1 = Var1._ops.first->pres, *pVar2 = Var2._ops.first->pres;
2802 pVar1->_ops.second.push_back( pOp );
2803 pVar2->_ops.second.push_back( pOp );
2808 template <
typename U>
inline FFVar&
2813 FFVar *pVar2 = Var2._ops.first->pres;
2815 FFVar *pVar1 = pCst1->_ops.first->pres;
2819 pVar1->_ops.second.push_back( pOp );
2820 pVar2->_ops.second.push_back( pOp );
2825 template <
typename U>
inline FFVar&
2830 FFVar *pVar1 = Var1._ops.first->pres;
2832 FFVar *pVar2 = pCst2->_ops.first->pres;
2836 pVar1->_ops.second.push_back( pOp );
2837 pVar2->_ops.second.push_back( pOp );
2847 FFVar *pVar = Var._ops.first->pres;
2851 pVar->_ops.second.push_back( pOp );
2860 FFOp* op =
new FFOp( top, lop, rop );
2861 typename FFGraph::it_Ops itop = _Ops.find( op );
2862 if( itop!=_Ops.end() ){
delete op;
return *itop; }
2871 typename FFGraph::it_Ops itop = _Ops.find( op );
2872 if( itop==_Ops.end() )
return false;
2882 pOp->
pres =
new FFVar(
this, dep, pOp );
2883 _append_aux( pOp->
pres );
2893 it_Vars iAux = _Vars.find( pAux );
2894 if( iAux!=_Vars.end() ){
delete pAux;
return *iAux; }
2897 _append_aux( pAux, FFOp::CNST );
2907 it_Vars iAux = _Vars.find( pAux );
2908 if( iAux!=_Vars.end() ){
delete pAux;
return *iAux; }
2911 _append_aux( pAux, FFOp::CNST );
2919 FFOp*pOp =
new FFOp( tOp, 0, 0, pAux );
2922 pAux->
ops().first = pOp;
2923 pAux->
id().second = _naux++;
2924 _append_aux( pAux );
2931 _Vars.insert( pAux );
2938 _Vars.insert( pVar );
2946 it_Vars iVar = _Vars.find( pVar );
2948 return( iVar==_Vars.end()? 0: *iVar );
2951 inline std::list<const FFOp*>
2953 (
const unsigned int nDep,
const FFVar*pDep )
const
2955 std::list<const FFOp*> Ops;
2956 _reset_operations();
2957 for(
unsigned int i=0; i<nDep; i++ ){
2958 if( !pDep[i].ops().first )
continue;
2959 pDep[i].
ops().first->propagate_subgraph( Ops );
2964 inline std::list<const FFOp*>
2966 (
const std::vector<const FFVar*>&vDep )
const
2970 std::list<const FFOp*> Ops;
2971 _reset_operations();
2972 typename std::vector<const FFVar*>::const_iterator it = vDep.begin();
2973 for( ; it!=vDep.end(); ++it ){
2974 if( !(*it)->ops().first )
continue;
2975 (*it)->ops().first->propagate_subgraph( Ops );
2982 (
const std::list<const FFOp*>&Ops, std::ostream&os )
2984 os << ( !Ops.empty()?
"\nFACTORS IN SUBGRAPH:\n":
"\nNO FACTORS IN SUBGRAPH\n" );
2985 typename std::list<const FFOp*>::const_iterator ito = Ops.begin();
2986 for( ; ito!=Ops.end(); ++ito )
2987 os <<
" " << *(*ito)->pres <<
"\t" <<
"<= " << **ito << std::endl;
2992 (
const unsigned int nDep,
const FFVar*pDep, std::ostream&os )
const
2994 _reset_operations();
2995 os <<
"\ndigraph G {\n";
2996 for(
unsigned int i=0; i<nDep; i++ ){
2997 if( !pDep[i].ops().first )
continue;
2998 pDep[i].
ops().first->generate_dot_script( os );
3005 (
const std::vector<const FFVar*>&vDep, std::ostream&os )
const
3009 _reset_operations();
3010 os <<
"\ndigraph G {\nnode [shape=record];\n";
3011 typename std::vector<const FFVar*>::const_iterator it = vDep.begin();
3012 for( ; it!=vDep.end(); ++it ){
3013 if( !(*it)->ops().first )
continue;
3014 (*it)->ops().first->generate_dot_script( os );
3021 (
const unsigned nDep,
const FFVar*
const pDep,
const unsigned nIndep,
3022 const FFVar*
const pIndep,
const bool transp )
3024 if( !nDep || !nIndep )
return 0;
3025 assert( pDep && pIndep );
3027 std::vector<const FFVar*> vDep, vIndep;
3028 for(
unsigned i=0; i<nDep; i++ ) vDep.push_back( pDep+i );
3029 for(
unsigned i=0; i<nIndep; i++ ) vIndep.push_back( pIndep+i );
3031 std::vector<const FFVar*> vDep_F = FAD( vDep, vIndep );
3033 typename std::vector<const FFVar*>::const_iterator it = vDep_F.begin();
3035 for(
unsigned k=0; it!=vDep_F.end(); ++it, k++ ) pDep_F[k] = **it;
3037 for(
unsigned i=0; it!=vDep_F.end(); i++ )
3038 for(
unsigned j=0; j<nIndep; ++it, j++ ) pDep_F[i+j*nDep] = **it;
3043 inline std::vector<const FFVar*>
3045 (
const std::vector<const FFVar*>&vDep,
const std::vector<const FFVar*>&vIndep )
3048 if( !vIndep.size() || !vDep.size() )
return std::vector<const FFVar*>();
3052 it_Vars itv = _Vars.begin();
3053 for( ; itv!=_Vars.end() && (*itv)->_id.first<=
FFVar::VAR; ++itv ){
3054 fadbad::F<mc::FFVar>* pX_F =
new fadbad::F<mc::FFVar>( **itv );
3055 typename std::vector<const FFVar*>::const_iterator iti = vIndep.begin();
3056 for(
unsigned int i=0; iti!=vIndep.end(); ++iti, i++ )
3057 if( (*itv)->id().second == (*iti)->id().second )
3058 pX_F->diff( i, vIndep.size() );
3060 (*itv)->val() = pX_F;
3067 std::list<const FFOp*> opDep = subgraph( vDep );
3068 typename std::list<const FFOp*>::iterator ito = opDep.begin();
3069 for( ; ito!=opDep.end(); ++ito ) (*ito)->evaluate( fadbad::F<mc::FFVar>() );
3072 std::vector<const FFVar*> vDep_F;
3073 typename std::vector<const FFVar*>::const_iterator itd = vDep.begin();
3074 for( ; itd!=vDep.end(); ++itd ){
3076 FFVar* pF = _find_var( (*itd)->id() );
3077 typename std::vector<const FFVar*>::const_iterator iti = vIndep.begin();
3079 for(
unsigned int i=0; iti!=vIndep.end(); ++iti, i++ ){
3081 vDep_F.push_back( _add_constant( 0. ) );
continue;
3085 fadbad::F<mc::FFVar>* pF_F =
static_cast<fadbad::F<mc::FFVar>*
>( pF->
val() );
3086 const FFVar* pdFdX = _find_var( pF_F->deriv(i).id() );
3088 const FFNum& num = pF_F->deriv(i).num();
3090 case FFNum::INT: vDep_F.push_back( _add_constant( num.n ) );
continue;
3091 case FFNum::REAL: vDep_F.push_back( _add_constant( num.x ) );
continue;
3094 else vDep_F.push_back( pdFdX );
3099 itv = _Vars.begin();
3100 for( ; itv!=_Vars.end() && (*itv)->_id.first<=
FFVar::VAR; ++itv )
3101 (*itv)->reset_val( fadbad::F<mc::FFVar>() );
3103 _reset_operations();
3105 for( ; itd!=vDep.end(); ++itd ){
3106 if( !(*itd)->ops().first )
continue;
3107 (*itd)->ops().first->reset_val_subgraph( fadbad::F<mc::FFVar>() );
3115 (
const unsigned nDep,
const FFVar*
const pDep,
const unsigned nIndep,
3116 const FFVar*
const pIndep,
const bool transp )
3118 if( !nDep || !nIndep )
return 0;
3119 assert( pDep && pIndep );
3121 std::vector<const FFVar*> vDep, vIndep;
3122 for(
unsigned i=0; i<nDep; i++ ) vDep.push_back( pDep+i );
3123 for(
unsigned i=0; i<nIndep; i++ ) vIndep.push_back( pIndep+i );
3125 std::vector<const FFVar*> vDep_B = BAD( vDep, vIndep );
3127 typename std::vector<const FFVar*>::const_iterator it = vDep_B.begin();
3129 for(
unsigned k=0; it!=vDep_B.end(); ++it, k++ ) pDep_B[k] = **it;
3131 for(
unsigned i=0; it!=vDep_B.end(); i++ )
3132 for(
unsigned j=0; j<nIndep; ++it, j++ ) pDep_B[i+j*nDep] = **it;
3137 inline std::vector<const FFVar*>
3139 (
const std::vector<const FFVar*>&vDep,
const std::vector<const FFVar*>&vIndep )
3142 if( !vIndep.size() || !vDep.size() )
return std::vector<const FFVar*>();
3146 it_Vars itv = _Vars.begin();
3147 for( ; itv!=_Vars.end() && (*itv)->_id.first<=
FFVar::VAR; ++itv ){
3148 fadbad::B<mc::FFVar>* pX_B =
new fadbad::B<mc::FFVar>( **itv );
3150 (*itv)->val() = pX_B;
3158 std::list<const FFOp*> opDep = subgraph( vDep );
3159 typename std::list<const FFOp*>::iterator ito = opDep.begin();
3160 for( ; ito!=opDep.end(); ++ito ) (*ito)->evaluate( fadbad::B<mc::FFVar>() );
3164 _reset_operations();
3165 typename std::vector<const FFVar*>::const_iterator itd = vDep.begin();
3166 for( ; itd!=vDep.end(); ++itd ){
3167 if( !(*itd)->ops().first )
continue;
3168 (*itd)->ops().first->reset_val_subgraph( fadbad::B<mc::FFVar>(), vDep, vIndep );
3173 for(
unsigned j=0; itd!=vDep.end(); ++itd, j++ ){
3175 FFVar* pF = _find_var( (*itd)->id() );
3178 fadbad::B<mc::FFVar>* pF_B =
static_cast<fadbad::B<mc::FFVar>*
>( pF->
val() );
3179 pF_B->diff( j, vDep.size() );
3184 std::vector<const FFVar*> vDep_B;
3186 for(
unsigned j=0; itd!=vDep.end(); ++itd, j++ ){
3188 FFVar* pF = _find_var( (*itd)->id() );
3189 typename std::vector<const FFVar*>::const_iterator iti = vIndep.begin();
3191 for( ; iti!=vIndep.end(); ++iti ){
3193 vDep_B.push_back( _add_constant( 0. ) ); std::cout <<
"here: 1!\n\n\n";
continue;
3196 FFVar* pX = _find_var( (*iti)->id() );
3199 fadbad::B<mc::FFVar>* pX_B =
static_cast<fadbad::B<mc::FFVar>*
>( pX->
val() );
3200 FFVar* dXj = &pX_B->d(j);
3201 const FFVar* pdFdX = _find_var( dXj->id() );
3205 switch( dXj->num().t ){
3206 case FFNum::INT: vDep_B.push_back( _add_constant( dXj->num().n ) );
continue;
3207 case FFNum::REAL: vDep_B.push_back( _add_constant( dXj->num().x ) );
continue;
3210 else vDep_B.push_back( pdFdX );
3215 itv = _Vars.begin();
3216 for( ; itv!=_Vars.end() && (*itv)->_id.first<=
FFVar::VAR; ++itv )
3217 (*itv)->reset_val( fadbad::B<mc::FFVar>() );
3220 for( ; itd!=vDep.end(); ++itd )
3221 _find_var( (*itd)->id() )->reset_val( fadbad::B<mc::FFVar>() );
3228 (
const unsigned int ordermax,
const unsigned nDep,
const FFVar*
const pDep,
3229 const unsigned nVar,
const FFVar*
const pVar,
const FFVar*
const pIndep )
3231 if( !nDep || !nVar )
return 0;
3232 assert( pDep && pVar );
3234 std::vector<const FFVar*> vDep, vVar;
3235 for(
unsigned i=0; i<nDep; i++ ) vDep.push_back( pDep+i );
3236 for(
unsigned i=0; i<nVar; i++ ) vVar.push_back( pVar+i );
3238 std::vector<const FFVar*> vDep_T = TAD( ordermax, vDep, vVar, pIndep );
3240 typename std::vector<const FFVar*>::const_iterator it = vDep_T.begin();
3241 for(
unsigned k=0; it!=vDep_T.end(); ++it, k++ ) pDep_T[k] = **it;
3246 inline std::vector<const FFVar*>
3248 (
const unsigned int ordermax,
const std::vector<const FFVar*>&vDep,
3249 const std::vector<const FFVar*>&vVar,
const FFVar*
const pIndep )
3252 if( !vVar.size() || !vDep.size() || vVar.size() != vDep.size() )
3253 return std::vector<const FFVar*>();
3255 std::vector<const FFVar*> vDep_T;
3258 fadbad::T<mc::FFVar>** pX_T =
new fadbad::T<mc::FFVar>*[ vVar.size() ];
3259 it_Vars itv = _Vars.begin();
3260 for( ; itv!=_Vars.end() && (*itv)->_id.first<=
FFVar::VAR; ++itv ){
3261 fadbad::T<mc::FFVar>* pXi_T =
new fadbad::T<mc::FFVar>( **itv );
3262 typename std::vector<const FFVar*>::const_iterator iti = vVar.begin();
3264 if( pIndep && (*itv)->
id().second == pIndep->
id().second )
3267 for(
unsigned int i=0; iti!=vVar.end(); ++iti, i++ ){
3268 if( (*itv)->id().second == (*iti)->id().second ){
3270 vDep_T.push_back( *itv );
3271 #ifdef MC__FFUNC_DEBUG_TAD
3272 std::cout <<
"FFGraph::TAD *** f(" << i <<
")[0] = "
3273 << **itv <<
" (" << *itv <<
")\n";
3278 (*itv)->val() = pXi_T;
3285 std::list<const FFOp*> opDep = subgraph( vDep );
3286 typename std::list<const FFOp*>::iterator ito = opDep.begin();
3287 for( ; ito!=opDep.end(); ++ito ) (*ito)->evaluate( fadbad::T<mc::FFVar>() );
3290 fadbad::T<mc::FFVar>** pF_T =
new fadbad::T<mc::FFVar>*[ vDep.size() ];
3291 typename std::vector<const FFVar*>::const_iterator itd = vDep.begin();
3292 for(
unsigned j=0; itd!=vDep.end(); ++itd, j++ ){
3293 FFVar*pF = _find_var( (*itd)->id() );
3294 pF_T[j] = ( pF?
static_cast<fadbad::T<mc::FFVar>*
>( pF->
val() ): 0 );
3298 for(
unsigned int q=0; q<ordermax; q++ ){
3300 for(
unsigned j=0; itd!=vDep.end(); ++itd, j++ ){
3303 vDep_T.push_back( _add_constant( 0. ) );
continue;
3308 mc::FFVar Xjq = (*pF_T[j])[q]/
double(q+1);
3310 FFVar*pXjq = _find_var( Xjq.
id() );
3311 if( !pXjq )
switch( Xjq.
num().
t ){
3313 (*pX_T[j])[q+1] = Xjq.
num().n;
3314 vDep_T.push_back( _add_constant( Xjq.
num().n ) );
3317 (*pX_T[j])[q+1] = Xjq.
num().x;
3318 vDep_T.push_back( _add_constant( Xjq.
num().x ) );
3322 (*pX_T[j])[q+1] = *pXjq;
3323 vDep_T.push_back( pXjq );
3325 #ifdef MC__FFUNC_DEBUG_TAD
3326 std::cout <<
"FFGraph::TAD *** f(" << j <<
")[" << q+1 <<
"] = "
3327 << *pXjq <<
" (" << pXjq <<
")\n";
3333 itv = _Vars.begin();
3334 for( ; itv!=_Vars.end() && (*itv)->_id.first<=
FFVar::VAR; ++itv )
3335 (*itv)->
reset_val( fadbad::T<mc::FFVar>() );
3337 _reset_operations();
3339 for( ; itd!=vDep.end(); ++itd ){
3340 if( !(*itd)->ops().first )
continue;
3341 (*itd)->ops().first->reset_val_subgraph( fadbad::T<mc::FFVar>() );
3352 (
const unsigned nDepOut,
const FFVar*pDepOut,
const unsigned nDepIn,
3355 if( !nDepOut || !nDepIn )
return pDepOut;
3356 assert( pDepOut && pVarOut && pDepIn );
3358 std::vector<const FFVar*> vDepOut;
3359 std::vector< std::pair<const FFVar*,const FFVar*> > vDepIn;
3360 for(
unsigned i=0; i<nDepOut; i++ ) vDepOut.push_back( pDepOut+i );
3361 for(
unsigned i=0; i<nDepIn; i++ ) vDepIn.push_back( std::make_pair(pVarOut+i,pDepIn+i) );
3363 std::vector<const FFVar*> vDepComp = compose( vDepOut, vDepIn );
3365 FFVar* pDepComp =
new FFVar[ vDepComp.size() ];
3366 typename std::vector<const FFVar*>::const_iterator it = vDepComp.begin();
3367 for(
unsigned k=0; it!=vDepComp.end(); ++it, k++ ) pDepComp[k] = **it;
3372 inline std::vector<const FFVar*>
3374 (
const std::vector<const FFVar*>&vDepOut,
3375 const std::vector< std::pair<const FFVar*,const FFVar*> >&vDepIn )
3378 if( !vDepIn.size() || !vDepOut.size() )
return vDepOut;
3381 std::vector< std::pair<const FFVar*,FFVar> > vIndep;
3382 it_Vars itv = _Vars.begin();
3383 for( ; itv!=_Vars.end() && (*itv)->_id.first<=
FFVar::VAR; ++itv ){
3384 typename std::vector< std::pair<const FFVar*,const FFVar*> >::const_iterator iti = vDepIn.begin();
3387 for( ; !match && iti!=vDepIn.end(); ++iti )
3388 if( (*itv)->id().second == (*iti).first->id().second ){
3389 FFVar DepIn = *(*iti).second;
3390 vIndep.push_back( std::make_pair( (*iti).first, DepIn ) );
3391 #ifdef MC__FFUNC_DEBUG_COMPOSE
3392 std::cout << *(*iti).first <<
" <-> " << DepIn << std::endl;
3398 vIndep.push_back( std::make_pair( *itv, **itv ) );
3399 #ifdef MC__FFUNC_DEBUG_COMPOSE
3400 std::cout << **itv <<
" <-> " << **itv << std::endl;
3405 std::vector<FFVar> vDepComp = eval( vDepOut, vIndep );
3406 std::vector<const FFVar*> vDepNew;
3407 typename std::vector<FFVar>::iterator itd = vDepComp.begin();
3408 for( ; itd!=vDepComp.end(); ++itd ){
3409 FFVar* pF = _find_var( (*itd).id() );
3411 const FFNum& num = (*itd).num();
3413 case FFNum::INT: vDepNew.push_back( _add_constant( num.n ) );
continue;
3414 case FFNum::REAL: vDepNew.push_back( _add_constant( num.x ) );
continue;
3417 else vDepNew.push_back( pF );
3422 template <
typename U>
inline std::vector<U>
3424 (
const std::vector<const FFVar*>&vDep,
3425 const std::vector< std::pair<const FFVar*,U> >&vVar )
3428 if( !vDep.size() )
return std::vector<U>();
3431 std::list<const FFOp*> opDep = subgraph( vDep );
3433 return eval( opDep, vDep, vVar );
3436 template <
typename U>
inline std::vector<U>
3438 ( std::list<const FFOp*>&opDep,
const std::vector<const FFVar*>&vDep,
3439 const std::vector< std::pair<const FFVar*,U> >&vVar )
3442 if( !vDep.size() )
return std::vector<U>();
3443 #ifdef MC__FFUNC_CPU_EVAL
3448 #ifdef MC__FFUNC_CPU_EVAL
3449 cputime = -cpuclock();
3451 typename std::vector< std::pair<const FFVar*,U> >::const_iterator iti = vVar.begin();
3452 for( ; iti!=vVar.end(); ++iti ){
3453 FFVar* pF = _find_var( (*iti).first->id() );
3455 pF->
val() =
new U( (*iti).second );
3456 #ifdef MC__FFUNC_DEBUG_EVAL
3457 std::cout << (*iti).first <<
" " << (*iti).second << std::endl;
3461 #ifdef MC__FFUNC_CPU_EVAL
3462 cputime += cpuclock();
3463 std::cout <<
"\nIndep. init. time: " << std::fixed << cputime << std::endl;
3469 std::vector<U> vDep_U;
3470 bool rethrow =
false;
3472 #ifdef MC__FFUNC_CPU_EVAL
3473 cputime = -cpuclock();
3476 typename std::list<const FFOp*>::iterator ito = opDep.begin();
3477 for( ; ito!=opDep.end(); ++ito ) (*ito)->evaluate( U() );
3478 #ifdef MC__FFUNC_CPU_EVAL
3479 cputime += cpuclock();
3480 std::cout <<
"Evaluation time: " << std::fixed << cputime << std::endl;
3484 #ifdef MC__FFUNC_CPU_EVAL
3485 cputime = -cpuclock();
3487 typename std::vector<const FFVar*>::const_iterator itd = vDep.begin();
3488 for( ; itd!=vDep.end(); ++itd ){
3490 FFVar* pF = _find_var( (*itd)->id() );
3492 if( pF ) vDep_U.push_back( U( *static_cast<U*>( pF->
val() ) ) );
3493 else switch( (*itd)->num().t ){
3495 vDep_U.push_back( (*itd)->num().n );
3498 vDep_U.push_back( (*itd)->num().x );
3502 #ifdef MC__FFUNC_CPU_EVAL
3503 cputime += cpuclock();
3504 std::cout <<
"Dep. collect. time: " << std::fixed << cputime << std::endl;
3512 #ifdef MC__FFUNC_CPU_EVAL
3513 cputime = -cpuclock();
3516 for( ; iti!=vVar.end(); ++iti ){
3517 FFVar* pF = _find_var( (*iti).first->id() );
3524 typename std::list<const FFOp*>::iterator ito = opDep.begin();
3525 for( ; ito!=opDep.end(); ++ito ) (*ito)->flag(
false );
3526 typename std::vector<const FFVar*>::const_iterator itd = vDep.begin();
3527 for( ; itd!=vDep.end(); ++itd ){
3528 if( !(*itd)->ops().first )
continue;
3529 (*itd)->ops().first->reset_val_subgraph( U() );
3531 #ifdef MC__FFUNC_CPU_EVAL
3532 cputime += cpuclock();
3533 std::cout <<
"Clean-up time: " << std::fixed << cputime << std::endl;
3540 template <
typename U>
inline std::vector<U>
3542 ( std::list<const FFOp*>&opDep, U*opRes,
const std::vector<const FFVar*>&vDep,
3543 const std::vector< std::pair<const FFVar*,U> >&vVar )
3546 if( !vDep.size() )
return std::vector<U>();
3547 assert( opDep.size() && opRes );
3550 #ifdef MC__FFUNC_CPU_EVAL
3551 double cputime = -cpuclock();
3553 typename std::list<const FFOp*>::iterator ito = opDep.begin();
3554 for( U*pUres=opRes; ito!=opDep.end(); ++ito, pUres++ ){
3556 if( (*ito)->type == FFOp::VAR ){
3558 typename std::vector< std::pair<const FFVar*,U> >::const_iterator iti = vVar.begin();
3559 for( ; iti!=vVar.end(); ++iti ){
3560 if( (*ito)->pres->id() == (*iti).first->id() ){
3562 *pUres = (*iti).second;
3568 (*ito)->evaluate( pUres );
3570 #ifdef MC__FFUNC_CPU_EVAL
3571 cputime += cpuclock();
3572 std::cout <<
"\nEvaluation time: " << std::fixed << cputime << std::endl;
3576 #ifdef MC__FFUNC_CPU_EVAL
3577 cputime = -cpuclock();
3579 std::vector<U> vDep_U;
3580 typename std::vector<const FFVar*>::const_iterator itd = vDep.begin();
3581 for( ; itd!=vDep.end(); ++itd ){
3583 FFVar* pF = _find_var( (*itd)->id() );
3585 if( pF ) vDep_U.push_back( U( *static_cast<U*>( pF->
val() ) ) );
3586 else switch( (*itd)->num().t ){
3588 vDep_U.push_back( (*itd)->num().n );
3591 vDep_U.push_back( (*itd)->num().x );
3595 #ifdef MC__FFUNC_CPU_EVAL
3596 cputime += cpuclock();
3597 std::cout <<
"Dep. collect. time: " << std::fixed << cputime << std::endl;
3603 template <
typename U>
inline void
3605 (
const unsigned nDep,
const FFVar*pDep, U*vDep,
const unsigned nVar,
3606 const FFVar*pVar, U*vVar,
const bool add )
3612 std::list<const FFOp*> opDep = subgraph( nDep, pDep );
3614 return eval( opDep, nDep, pDep, vDep, nVar, pVar, vVar, add );
3617 template <
typename U>
inline void
3619 ( std::list<const FFOp*>&opDep,
const unsigned nDep,
const FFVar*pDep,
3620 U*vDep,
const unsigned nVar,
const FFVar*pVar, U*vVar,
const bool add )
3624 assert( pDep && vDep );
3625 assert( !nVar || ( pVar && vVar ) );
3626 #ifdef MC__FFUNC_CPU_EVAL
3631 #ifdef MC__FFUNC_CPU_EVAL
3632 cputime = -cpuclock();
3634 for(
unsigned int i=0; i<nVar; i++ ){
3635 FFVar* pF = _find_var( pVar[i].
id() );
3637 pF->
val() =
new U( vVar[i] );
3638 #ifdef MC__FFUNC_DEBUG_EVAL
3639 std::cout << pVar[i] <<
" " << vVar[i] << std::endl;
3643 #ifdef MC__FFUNC_CPU_EVAL
3644 cputime += cpuclock();
3645 std::cout <<
"\nIndep. init. time: " << std::fixed << cputime << std::endl;
3651 bool rethrow =
false;
3653 #ifdef MC__FFUNC_CPU_EVAL
3654 cputime = -cpuclock();
3657 typename std::list<const FFOp*>::iterator ito = opDep.begin();
3658 for( ; ito!=opDep.end(); ++ito ) (*ito)->evaluate( U() );
3659 #ifdef MC__FFUNC_CPU_EVAL
3660 cputime += cpuclock();
3661 std::cout <<
"Evaluation time: " << std::fixed << cputime << std::endl;
3665 #ifdef MC__FFUNC_CPU_EVAL
3666 cputime = -cpuclock();
3668 for(
unsigned i=0; i<nDep; i++ ){
3670 FFVar* pF = _find_var( pDep[i].
id() );
3672 if( !add && pF ) vDep[i] = *
static_cast<U*
>( pF->
val() );
3673 else if( pF ) vDep[i] += *
static_cast<U*
>( pF->
val() );
3674 else if( !add )
switch( pDep[i].num().t ){
3676 vDep[i] = pDep[i].
num().n;
3679 vDep[i] = pDep[i].
num().x;
3682 else switch( pDep[i].num().t ){
3684 vDep[i] += pDep[i].
num().n;
3687 vDep[i] += pDep[i].
num().x;
3691 #ifdef MC__FFUNC_CPU_EVAL
3692 cputime += cpuclock();
3693 std::cout <<
"Dep. collect. time: " << std::fixed << cputime << std::endl;
3701 #ifdef MC__FFUNC_CPU_EVAL
3702 cputime = -cpuclock();
3704 for(
unsigned int i=0; i<nVar; i++ ){
3705 FFVar* pF = _find_var( pVar[i].
id() );
3712 typename std::list<const FFOp*>::iterator ito = opDep.begin();
3713 for( ; ito!=opDep.end(); ++ito ) (*ito)->flag(
false );
3714 for(
unsigned i=0; i<nDep; i++ ){
3715 if( !pDep[i].ops().first )
continue;
3716 pDep[i].
ops().first->reset_val_subgraph( U() );
3718 #ifdef MC__FFUNC_CPU_EVAL
3719 cputime += cpuclock();
3720 std::cout <<
"Clean-up time: " << std::fixed << cputime << std::endl;
3727 template <
typename U>
inline void
3729 ( std::list<const FFOp*>&opDep, U*opRes,
const unsigned nDep,
const FFVar*pDep,
3730 U*vDep,
const unsigned nVar,
const FFVar*pVar, U*vVar,
const bool add )
3734 assert( opDep.size() && opRes );
3735 assert( pDep && vDep );
3736 assert( !nVar || ( pVar && vVar ) );
3737 #ifdef MC__FFUNC_CPU_EVAL
3742 #ifdef MC__FFUNC_CPU_EVAL
3743 double cputime = -cpuclock();
3745 typename std::list<const FFOp*>::iterator ito = opDep.begin();
3746 for( U*pUres=opRes; ito!=opDep.end(); ++ito, pUres++ ){
3748 if( (*ito)->type == FFOp::VAR ){
3750 for(
unsigned i=0; i<nVar; i++ ){
3751 if( (*ito)->pres->id() == pVar[i].
id() ){
3759 (*ito)->evaluate( pUres );
3761 #ifdef MC__FFUNC_CPU_EVAL
3762 cputime += cpuclock();
3763 std::cout <<
"\nEvaluation time: " << std::fixed << cputime << std::endl;
3767 #ifdef MC__FFUNC_CPU_EVAL
3768 cputime = -cpuclock();
3770 for(
unsigned i=0; i<nDep; i++ ){
3772 FFVar* pF = _find_var( pDep[i].
id() );
3774 if( !add && pF ) vDep[i] = *
static_cast<U*
>( pF->
val() );
3775 else if( pF ) vDep[i] += *
static_cast<U*
>( pF->
val() );
3776 else if( !add )
switch( pDep[i].num().t ){
3778 vDep[i] = pDep[i].
num().n;
3781 vDep[i] = pDep[i].
num().x;
3784 else switch( pDep[i].num().t ){
3786 vDep[i] += pDep[i].
num().n;
3789 vDep[i] += pDep[i].
num().x;
3793 #ifdef MC__FFUNC_CPU_EVAL
3794 cputime += cpuclock();
3795 std::cout <<
"Dep. collect. time: " << std::fixed << cputime << std::endl;
3801 inline CPPL::dssmatrix
3803 (
const unsigned nDep,
const FFVar*
const pDep,
const unsigned nIndep,
3804 const FFVar*
const pIndep )
3807 std::list<const FFOp*> opDep = subgraph( nDep, pDep );
3808 #ifdef MC__FFUNC_DEBUG_DEPMAP
3812 return depmap( opDep, nDep, pDep, nIndep, pIndep );
3815 inline CPPL::dssmatrix
3817 ( std::list<const FFOp*>&opDep,
const unsigned nDep,
const FFVar*
const pDep,
3818 const unsigned nIndep,
const FFVar*
const pIndep )
3820 std::vector<const FFVar*> vDep, vIndep;
3821 for(
unsigned i=0; i<nDep; i++ ) vDep.push_back( pDep+i );
3822 for(
unsigned i=0; i<nIndep; i++ ) vIndep.push_back( pIndep+i );
3824 return depmap( opDep, vDep, vIndep );
3827 inline CPPL::dssmatrix
3829 (
const std::vector<const FFVar*>&vDep,
const std::vector<const FFVar*>&vIndep )
3832 std::list<const FFOp*> opDep = subgraph( vDep );
3833 #ifdef MC__FFUNC_DEBUG_DEPMAP
3837 return depmap( opDep, vDep, vIndep );
3840 inline CPPL::dssmatrix
3842 ( std::list<const FFOp*>&opDep,
const std::vector<const FFVar*>&vDep,
3843 const std::vector<const FFVar*>&vIndep )
3846 bool contains_product =
false;
3848 std::map< const FFVar* , long > aux_map;
3849 long vindex = 0 , prod_index = 0;
3851 for (std::vector<const FFVar*>::const_iterator i=vIndep.begin(); i!=vIndep.end(); ++i ){
3852 aux_map[ _find_var((*i)->_id) ] = vindex;
3856 for(std::list<const FFOp*>::const_iterator i=opDep.begin(); i!=opDep.end(); ++i)
3857 switch((*i) -> pres ->id().first){
3859 if( (*i)->type == mc::FFOp::TIMES && !contains_product ){
3860 contains_product =
true;
3861 prod_index = vindex;
3864 aux_map[ (*i)->pres ] = vindex;
3872 #ifdef MC__FFUNC_DEBUG_DEPMAP
3873 std::cout <<
"AUX MAP: " << std::endl;
3874 for( std::map<const FFVar*,long>::const_iterator i=aux_map.begin(); i!=aux_map.end(); ++i )
3875 std::cout << *(i->first) <<
" , " << i->second << std::endl;
3878 ndepmap = aux_map.size();
3879 if( contains_product ) ndepmap += 6;
3880 CPPL::dssmatrix depmap(ndepmap);
3883 for(
unsigned long i=0 ; i<vIndep.size(); ++i ){
3884 for(
unsigned long j=i ; j<vIndep.size(); ++j ) depmap.put( i, j, 1 );
3885 depmap.put( i, i, 1 );
3889 for( std::vector<const FFVar*>::const_iterator i_it=vDep.begin(); i_it!=vDep.end(); ++i_it ){
3890 long i = aux_map.find( _find_var((*i_it)->_id) )->second;
3891 for( std::vector<const FFVar*>::const_iterator j_it = i_it ; j_it != vDep.end(); ++j_it ){
3892 long j = aux_map.find( _find_var((*j_it)->_id) )->second;
3893 depmap.put( i, j, 1 );
3895 depmap.put( i, i, 1);
3898 long idep = ndepmap - 1;
3899 contains_product =
false;
3900 for(std::list<const FFOp*>::const_reverse_iterator i_it=opDep.rbegin(); i_it!=opDep.rend(); ++i_it){
3901 if( (*i_it)->pres->id().first ==
FFVar::AUX ){
3902 if( !(*i_it)->is_univariate() ){
3905 k = aux_map.find((*i_it)->plop)->second;
3907 l = aux_map.find((*i_it)->prop)->second;
3910 if( k != -1 && l != -1 ) depmap.put(k,l,1);
3911 for(
long j=0; j<idep ; ++j ){
3912 if( depmap.isListed( idep, j ) ){
3913 if( k != -1 ) depmap.put( j, k, 1 );
3914 if( l != -1 ) depmap.put( j, l, 1 ) ;
3917 if( k != -1 ) depmap.put( k, k ,1 );
3918 if( l != -1 ) depmap.put( l, l ,1 );
3919 #ifdef MC__FFUNC_DEBUG_DEPMAP
3920 std::cout <<
" Row Info: \n";
3921 std::cout <<
" Operation : " << *((*i_it)->pres) <<
" = " <<*(*i_it) << std::endl;
3922 std::cout <<
"i = " << idep <<
" k = " << k <<
" l = " << l << std::endl;
3924 if( (*i_it)->type == FFOp::TIMES && ( idep == prod_index+6 ) )
3930 k = aux_map.find((*i_it)->plop)->second;
3933 for(
long j=0; j<idep; ++j )
3934 if( depmap.isListed( idep, j ) && k != -1 ) depmap.put( j, k, 1 );
3935 if( k != -1 ) depmap.put( k, k, 1 );
3936 #ifdef MC__FFUNC_DEBUG_DEPMAP
3937 std::cout <<
" Row Info: \n";
3938 std::cout <<
" Operation : " << *((*i_it)->pres) <<
" = " <<*(*i_it) << std::endl;
3939 std::cout <<
"i = " << idep <<
" k = " << k <<
" l = " << -1 << std::endl;
3958 static FV point(
const double c ) {
return FV(c); }
3960 static void I(
FV& x,
const FV&y) { x = y; }
3966 static FV inv (
const FV& x) {
return mc::inv(x); }
3967 static FV sqr (
const FV& x) {
return mc::sqr(x); }
3968 static FV sqrt(
const FV& x) {
return mc::sqrt(x); }
3969 static FV log (
const FV& x) {
return mc::log(x); }
3970 static FV xlog(
const FV& x) {
return x*mc::log(x); }
3971 static FV fabs(
const FV& x) {
return mc::fabs(x); }
3972 static FV exp (
const FV& x) {
return mc::exp(x); }
3973 static FV sin (
const FV& x) {
return mc::sin(x); }
3974 static FV cos (
const FV& x) {
return mc::cos(x); }
3975 static FV tan (
const FV& x) {
return mc::tan(x); }
3976 static FV asin(
const FV& x) {
return mc::asin(x); }
3977 static FV acos(
const FV& x) {
return mc::acos(x); }
3978 static FV atan(
const FV& x) {
return mc::atan(x); }
3979 static FV erf (
const FV& x) {
return mc::erf(x); }
3980 static FV erfc(
const FV& x) {
return mc::erfc(x); }
3981 static FV fstep(
const FV& x) {
return mc::fstep(x); }
3982 static FV bstep(
const FV& x) {
return mc::bstep(x); }
3984 static FV min (
const FV& x,
const FV& y) {
return mc::min(x,y); }
3985 static FV max (
const FV& x,
const FV& y) {
return mc::max(x,y); }
3986 static FV arh (
const FV& x,
const double k) {
return mc::exp(-k/x); }
3987 template <
typename X,
typename Y>
static FV pow(
const X& x,
const Y& y) {
return mc::pow(x,y); }
4003 template <>
struct Op<mc::FFVar>{
4004 typedef double Base;
4006 static Base myInteger(
const int i ) {
return Base(i); }
4007 static Base myZero() {
return myInteger(0); }
4008 static Base myOne() {
return myInteger(1);}
4009 static Base myTwo() {
return myInteger(2); }
4010 static double myPI() {
return mc::PI; }
4011 static FV myPos(
const FV& x ) {
return x; }
4012 static FV myNeg(
const FV& x ) {
return -x; }
4013 template <
typename U>
static FV& myCadd(
FV& x,
const U& y ) {
return x+=y; }
4014 template <
typename U>
static FV& myCsub(
FV& x,
const U& y ) {
return x-=y; }
4015 template <
typename U>
static FV& myCmul(
FV& x,
const U& y ) {
return x*=y; }
4016 template <
typename U>
static FV& myCdiv(
FV& x,
const U& y ) {
return x/=y; }
4017 static FV myInv(
const FV& x ) {
return mc::inv( x ); }
4018 static FV mySqr(
const FV& x ) {
return mc::pow( x, 2 ); }
4019 template <
typename X,
typename Y>
static FV myPow(
const X& x,
const Y& y ) {
return mc::pow( x, y ); }
4020 static FV mySqrt(
const FV& x ) {
return mc::sqrt( x ); }
4021 static FV myLog(
const FV& x ) {
return mc::log( x ); }
4022 static FV myExp(
const FV& x ) {
return mc::exp( x ); }
4023 static FV mySin(
const FV& x ) {
return mc::sin( x ); }
4024 static FV myCos(
const FV& x ) {
return mc::cos( x ); }
4025 static FV myTan(
const FV& x ) {
return mc::tan( x ); }
4026 static FV myAsin(
const FV& x ) {
return mc::asin( x ); }
4027 static FV myAcos(
const FV& x ) {
return mc::acos( x ); }
4028 static FV myAtan(
const FV& x ) {
return mc::atan( x ); }
4029 static bool myEq(
const FV& x,
const FV& y ) {
throw std::runtime_error(
"fadbad::Op<FFVar>::myEq -- operation not permitted"); }
4030 static bool myNe(
const FV& x,
const FV& y ) {
throw std::runtime_error(
"fadbad::Op<FFVar>::myNe -- operation not permitted"); }
4031 static bool myLt(
const FV& x,
const FV& y ) {
throw std::runtime_error(
"fadbad::Op<FFVar>::myLt -- operation not permitted"); }
4032 static bool myLe(
const FV& x,
const FV& y ) {
throw std::runtime_error(
"fadbad::Op<FFVar>::myLe -- operation not permitted"); }
4033 static bool myGt(
const FV& x,
const FV& y ) {
throw std::runtime_error(
"fadbad::Op<FFVar>::myGt -- operation not permitted"); }
4034 static bool myGe(
const FV& x,
const FV& y ) {
throw std::runtime_error(
"fadbad::Op<FFVar>::myGe -- operation not permitted"); }
C++ structure for comparing operations in a factorable program for ordering in set FFGraph::_Ops...
Definition: ffunc.hpp:980
void flag(const bool visited=true) const
Flag operation as visited or not.
Definition: ffunc.hpp:956
FFVar * prop
Pointer to right operand.
Definition: ffunc.hpp:922
Error due to a invalid FFGraph pointer in initialization of FFVar.
Definition: ffunc.hpp:1116
unsigned long _nvar
Number of original variables in DAG.
Definition: ffunc.hpp:1086
Error due to a missing independent variable for evaluating a given subgraph using FFGraph::eval...
Definition: ffunc.hpp:1118
void evaluate(const U &U_dum) const
Evaluate operation in U arithmetic, dynamically allocating the result.
Definition: ffunc.hpp:2397
void *& val()
Get pointer to value field.
Definition: ffunc.hpp:830
Real constant.
Definition: ffunc.hpp:723
void append_dot_script_factor(std::ostream &os, const std::string &fname, const bool unary, const unsigned int fontsize, const bool dotted=false) const
Append script for factor fname using DOT to os
Definition: ffunc.hpp:2706
pt_Ops & ops()
Get pointer to defining operation.
Definition: ffunc.hpp:818
void _reset_operations() const
Reset all operations in set _Ops
Definition: ffunc.hpp:1302
TYPE
Enumeration type for variables in factorable function.
Definition: ffunc.hpp:719
void dot_script(const unsigned int nDep, const FFVar *pDep, std::ostream &os=std::cout) const
Generate script for DAG visualization of factors *F using DOT.
Definition: ffunc.hpp:2992
static FFVar & _insert_binary_operation(const typename FFOp::TYPE top, const FFDep &dep, const FFVar &Var1, const FFVar &Var2)
Looks for the binary operation of type top with left and right operands Var1, Var2 in set _Ops and ad...
Definition: ffunc.hpp:2794
void _append_aux(FFVar *pAux, typename FFOp::TYPE tOp)
Appends the auxiliary variable pAux and define it in _Ops with type tOp
Definition: ffunc.hpp:2917
const std::pair< TYPE, long > id() const
Get variable identifier.
Definition: ffunc.hpp:794
Exceptions(TYPE ierr)
Constructor for error ierr
Definition: ffunc.hpp:1124
Error due to calling a function/feature not yet implemented in MC++.
Definition: ffunc.hpp:1121
void reset_val(const U &U_dum)
Get pointer to value field.
Definition: ffunc.hpp:835
Structure comparing values of scalars in factorable functions for strict inequality.
Definition: ffunc.hpp:622
const bool stat() const
Retreive operation status (visited or not)
Definition: ffunc.hpp:959
Structure comparing variable identifiers in a factorable function for ordering in set FFGraph::_Vars...
Definition: ffunc.hpp:862
FFVar * plop
Pointer to left operand.
Definition: ffunc.hpp:920
const pt_Ops ops() const
Get const pointer to defining operation.
Definition: ffunc.hpp:814
std::vector< const FFVar * > FAD(const std::vector< const FFVar * > &vDep, const std::vector< const FFVar * > &vIndep)
Expand DAG with derivatives of dependents vDep with respect to independents vIndep using fadbad::F – ...
Definition: ffunc.hpp:3045
unsigned long nvar() const
Number of original variables in DAG.
Definition: ffunc.hpp:1162
Real value.
Definition: ffunc.hpp:565
FFOp(TYPE top, FFVar *lop=0, FFVar *rop=0, FFVar *res=0)
Constructor.
Definition: ffunc.hpp:2303
const FFDep & dep() const
Get const reference to variable dependencies.
Definition: ffunc.hpp:806
Class defining operations in a factorable function.
Definition: ffunc.hpp:892
FFOp * _insert_operation(const typename FFOp::TYPE top, FFVar *lop, FFVar *rop=0)
Looks for the operation of type top with left and right operands lop, rop in set _Ops and adds it if ...
Definition: ffunc.hpp:2858
std::list< const FFOp * > subgraph(const unsigned int nDep, const FFVar *pDep) const
Extract list of operations corresponding to nDep dependents in array pDep
Definition: ffunc.hpp:2953
C++ class for evaluation of the sparsity pattern of a factorable function.
Definition: ffdep.hpp:90
t_Ops _Ops
Set of operations in DAG.
Definition: ffunc.hpp:1095
bool is_univariate() const
Return whether or not operation is univariate.
Definition: ffunc.hpp:2742
std::vector< const FFVar * > compose(const std::vector< const FFVar * > &vDepOut, const std::vector< std::pair< const FFVar *, const FFVar * > > &vDepIn)
Compose the dependents in vDepOut with those in vDepIn – This function creates the subgraph for the o...
Definition: ffunc.hpp:3374
Integer value.
Definition: ffunc.hpp:564
Error during subgraph evaluation using FFGraph::eval.
Definition: ffunc.hpp:1119
Error due to an operation between variables linked to different DAGs.
Definition: ffunc.hpp:1117
~FFOp()
Destructor.
Definition: ffunc.hpp:912
static void output(const std::list< const FFOp * > &Ops, std::ostream &os=std::cout)
Output list of nodes in Ops to os
Definition: ffunc.hpp:2982
unsigned long _naux
Number of auxiliary variables in DAG.
Definition: ffunc.hpp:1089
void _clear_operations()
Erase all operations in set _Ops
Definition: ffunc.hpp:1296
Structure comparing values of scalars in factorable functions for equality.
Definition: ffunc.hpp:603
Integer constant.
Definition: ffunc.hpp:722
void append_dot_script(std::ostream &os) const
Append script for current operation using DOT to os
Definition: ffunc.hpp:2669
FFDep & dep()
Get reference to variable dependencies.
Definition: ffunc.hpp:810
void append_dot_script_variable(std::ostream &os, const bool constant, const unsigned int fontsize) const
Append script for variable/contant using DOT to os
Definition: ffunc.hpp:2725
std::string name() const
Get variable name.
Definition: ffunc.hpp:839
FFVar * _find_var(const typename FFVar::pt_idVar &id)
Search for the variable with identify id in _Vars
Definition: ffunc.hpp:2943
FFGraph *& dag()
Get pointer to factorable function dag.
Definition: ffunc.hpp:826
void _clear_variables()
Erase all variables in _Vars.
Definition: ffunc.hpp:1341
virtual ~FFGraph()
Destructor.
Definition: ffunc.hpp:1107
const FFGraph * dag() const
Get const pointer to factorable function.
Definition: ffunc.hpp:822
std::string what()
Error description.
Definition: ffunc.hpp:1128
Auxiliary variable.
Definition: ffunc.hpp:721
virtual void _append_var(FFVar *pVar)
Appends new original variable.
Definition: ffunc.hpp:2936
void propagate_subgraph(std::list< const FFOp * > &Ops) const
Propagate subset of operations participating in subgraph.
Definition: ffunc.hpp:2351
std::vector< const FFVar * > TAD(const unsigned int ordermax, const std::vector< const FFVar * > &vDep, const std::vector< const FFVar * > &vVar, const FFVar *const pIndep=0)
Expand DAG with Taylor coefficients of dependents vDep with respect to independents vIndep using fadb...
Definition: ffunc.hpp:3248
C++ class representing the DAG of factorable functions.
Definition: ffunc.hpp:1019
void generate_dot_script(std::ostream &os) const
Propagate script for DAG using DOT and display to os
Definition: ffunc.hpp:2657
void reset_val_subgraph(const U &U_dum) const
Reset mc::FFVar::_val field in subgraph.
Definition: ffunc.hpp:2364
TYPE
Enumeration type for exception handling.
Definition: ffunc.hpp:1115
static double cpuclock()
Return current clock time.
Definition: ffunc.hpp:1284
Structure defining the numeric field of a factorable program variable.
Definition: ffunc.hpp:560
TYPE
Enumeration type for unary and binary operations.
Definition: ffunc.hpp:901
Internal error.
Definition: ffunc.hpp:1120
unsigned long naux() const
Number of auxiliary variables in DAG.
Definition: ffunc.hpp:1166
Exceptions of mc::FFGraph.
Definition: ffunc.hpp:1111
std::vector< const FFVar * > BAD(const std::vector< const FFVar * > &vDep, const std::vector< const FFVar * > &vIndep)
Expand DAG with derivatives of dependents vDep with respect to independents vIndep using fadbad::B – ...
Definition: ffunc.hpp:3139
CPPL::dssmatrix depmap(const unsigned nDep, const FFVar *const pDep, const unsigned nIndep, const FFVar *const pIndep)
Create dependency map corresponding to nDep dependents in array pDep and nIndep independents in array...
Definition: ffunc.hpp:3803
static FFVar & _insert_unary_operation(const typename FFOp::TYPE top, const FFDep &dep, const FFVar &Var)
Looks for the unary operation of type top with operand Var1, Var2 in set _Ops and adds it if not foun...
Definition: ffunc.hpp:2844
TYPE
Enumeration type for numeric variables in factorable function.
Definition: ffunc.hpp:563
const bool & stat()
Retreive/set operation status (visited or not)
Definition: ffunc.hpp:962
FFVar * _add_auxiliary(const FFDep &dep, FFOp *pOp)
Adds the auxiliary variable with dependency dep from operation op
Definition: ffunc.hpp:2880
FFNum(const int i=0)
Constructor for an integer variable.
Definition: ffunc.hpp:576
std::pair< TYPE, long > pt_idVar
Typedef for variable identifier in factorable function.
Definition: ffunc.hpp:726
FFVar(FFGraph *dag)
Constructor for variable in DAG *dag
Definition: ffunc.hpp:1387
FFNum(const double d)
Constructor for a real variable.
Definition: ffunc.hpp:580
const FFNum & num() const
Get const reference to variable numeric field.
Definition: ffunc.hpp:802
FFVar * _add_constant(const double x)
Looks for the real constant x and adds it if not found.
Definition: ffunc.hpp:2889
FFGraph()
Default Constructor.
Definition: ffunc.hpp:1102
t_Vars _Vars
Set of variables in DAG.
Definition: ffunc.hpp:1092
TYPE t
Variable type.
Definition: ffunc.hpp:568
FFVar * pres
Pointer to operation result.
Definition: ffunc.hpp:918
std::pair< TYPE, long > & id()
Get reference to variable identifier.
Definition: ffunc.hpp:798
bool _remove_operation(FFOp *op)
Erase operation op in set _Ops
Definition: ffunc.hpp:2869
Original variable.
Definition: ffunc.hpp:720
static const long NOREF
Index for 'free' variables in factorable function.
Definition: ffunc.hpp:717
const t_Vars & Vars() const
Reference to set of (all) variables in factorable function.
Definition: ffunc.hpp:1170
FFVar & set(FFGraph *dag)
Attach variable to DAG *dag.
Definition: ffunc.hpp:754
int ierr()
Inline function returning the error flag.
Definition: ffunc.hpp:1126
TYPE type
Type of operation.
Definition: ffunc.hpp:916
std::vector< U > eval(const std::vector< const FFVar * > &vDep, const std::vector< std::pair< const FFVar *, U > > &vVar)
Evaluate the dependents in vDep in U arithmetic for the variable values specified in vVar – This func...
Definition: ffunc.hpp:3424
Class defining variables in a factorable function.
Definition: ffunc.hpp:643
C++ structure for comparing operations in a factorable program.
Definition: ffunc.hpp:1005
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
void clear()
Clear DAG (all variables and operations)
Definition: ffunc.hpp:1174