26 #ifndef CASADI_CALCULUS_HPP
27 #define CASADI_CALCULUS_HPP
34 #include "casadi_common.hpp"
44 const double pi = M_PI;
46 const double pi = 3.14159265358979323846;
50 const double inf = std::numeric_limits<double>::infinity();
53 const double nan = std::numeric_limits<double>::quiet_NaN();
56 const double eps = std::numeric_limits<double>::epsilon();
219 #define NUM_BUILT_IN_OPS (OP_KRON_CONTRACT+1)
249 using std::remainder;
270 inline double sign(
double x) {
return x<0 ? -1 : x>0 ? 1 : x;}
278 inline double constpow(
double x,
double y) {
return pow(x, y);}
280 std::ios::fmtflags f(
uout().flags());
281 uout() <<
"|> " << y <<
" : ";
282 uout() << std::setprecision(std::numeric_limits<double>::digits10 + 1) << std::scientific;
283 uout() << x << std::endl;
287 inline bool is_equal(
double x,
double y, casadi_int depth=0) {
return x==y;}
291 inline casadi_int
casadi_max(casadi_int x, casadi_int y) {
return std::max(x, y);}
292 inline casadi_int
casadi_min(casadi_int x, casadi_int y) {
return std::min(x, y);}
296 inline double if_else(
double x,
double y,
double z) {
return x==0 ? z : y;}
305 return x==-1 ? -
inf :
nan;
307 double z = sqrt(-log((1.0+x)/2.0));
308 return -(((1.641345311*z+3.429567803)*z-1.624906493)*z-1.970840454)/
309 ((1.637067800*z+3.543889200)*z+1.0);
314 y = x*(((-0.140543331*z+0.914624893)*z-1.645349621)*z+0.886226899)/
315 ((((-0.329097515*z+0.012229801)*z+1.442710462)*z-2.118377725)*z+1.0);
317 double z = sqrt(-log((1.0-x)/2.0));
318 y = (((1.641345311*z+3.429567803)*z-1.624906493)*z-1.970840454)/
319 ((1.637067800*z+3.543889200)*z+1.0);
323 y = y - (erf(y) - x) / (2.0/sqrt(
pi) * exp(-y*y));
324 y = y - (erf(y) - x) / (2.0/sqrt(
pi) * exp(-y*y));
341 template<casadi_
int I>
344 template<
typename T>
static inline void fcn(
const T& x, T& f);
347 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d);
350 template<casadi_
int I>
353 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) {
357 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
361 template<casadi_
int I>
364 template<
typename T>
static inline T fcn(
const T& x,
const T& y) {
372 template<casadi_
int I>
375 template<
typename T>
static inline void derf(
const T& x,
const T& y, T& f, T* d) {
394 template<casadi_
int I>
397 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f, casadi_int n) {
402 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d,
410 template<casadi_
int I>
413 template<
typename T>
static inline void fcn(
const T* x,
const T* y, T* f, casadi_int n) {
414 for (casadi_int i=0; i<n; ++i) {
420 template<
typename T>
static inline void der(
const T* x,
const T* y,
421 const T* f, T* d, casadi_int n) {
422 for (casadi_int i=0; i<n; ++i, d+=2) {
429 template<casadi_
int I>
432 template<
typename T>
static inline void fcn(
const T* x,
const T& y, T* f, casadi_int n) {
433 for (casadi_int i=0; i<n; ++i) {
439 template<
typename T>
static inline void der(
const T* x,
const T& y,
440 const T* f, T* d, casadi_int n) {
441 for (casadi_int i=0; i<n; ++i, d+=2) {
448 template<casadi_
int I>
451 template<
typename T>
static inline void fcn(
const T& x,
const T* y, T* f, casadi_int n) {
452 for (casadi_int i=0; i<n; ++i) {
458 template<
typename T>
static inline void der(
const T& x,
const T* y,
459 const T* f, T* d, casadi_int n) {
460 for (casadi_int i=0; i<n; ++i, d+=2) {
602 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = x;}
603 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = 1; }
610 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x+y;}
611 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
619 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x-y;}
620 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
628 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x*y;}
629 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
637 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x/y;}
638 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
639 d[0]=1/y; d[1]=-f/y;}
646 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = -x;}
647 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0]=-1;}
654 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = exp(x);}
655 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0]=f;}
662 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = log(x);}
663 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0]=1/x;}
670 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = pow(x, y);}
672 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
673 d[0]=y*pow(x, y-1); d[1]=log(x)*f;}
680 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = pow(x, y);}
681 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
682 d[0]=y*pow(x, y-1); d[1]=0;}
689 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = sqrt(x);}
690 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0]=1/(
twice(f));}
697 template<
typename T>
static inline void fcn(
const T& x, T& f) { f =
sq(x);}
698 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0]=
twice(x);}
704 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = 2.*x;}
705 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = 2; }
712 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = sin(x);}
713 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0]=cos(x);}
720 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = cos(x);}
721 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0]=-sin(x);}
728 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = tan(x);}
729 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d)
730 { d[0] = 1/
sq(cos(x));}
737 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = asin(x);}
738 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0]=1/sqrt(1-x*x);}
745 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = acos(x);}
746 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d)
747 { d[0]=-1/sqrt(1-x*x);}
754 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = atan(x);}
755 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = 1/(1+x*x);}
762 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x < y;}
763 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
771 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x <= y;}
772 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
780 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = floor(x);}
781 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = 0;}
788 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = ceil(x);}
789 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = 0;}
795 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = fmod(x, y);}
796 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
797 d[0]=1; d[1]=(f-x)/y;}
803 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) {
804 f = remainder(x, y);}
805 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
806 d[0]=1; d[1]=(f-x)/y;}
812 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x==y;}
813 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
820 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x!=y;}
821 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
829 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = !x;}
830 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = 0;}
836 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x && y;}
837 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
844 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x || y;}
845 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
852 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = erf(x);}
853 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) {
854 d[0] = (2/sqrt(
pi))*exp(-x*x);}
860 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = fabs(x);}
861 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) {
868 template<
typename T>
static inline void fcn(
const T& x, T& f) { f =
sign(x);}
869 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0]=0;}
875 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = copysign(x, y);}
876 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
877 T e = 1; d[0]=copysign(e, y); d[1]=0;}
883 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = fmin(x, y);}
884 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
894 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = fmax(x, y);}
895 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
905 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = 1./x;}
906 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = -f*f; }
912 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = sinh(x);}
913 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = cosh(x); }
919 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = cosh(x);}
920 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = sinh(x); }
926 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = tanh(x);}
927 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = 1-f*f; }
933 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = asinh(x);}
934 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) {
935 d[0] = 1/sqrt(1+x*x); }
941 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = acosh(x);}
942 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) {
943 d[0] = 1/sqrt(x-1)/sqrt(x+1); }
949 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = atanh(x);}
950 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) { d[0] = 1/(1-x*x); }
956 template<
typename T>
static inline void fcn(
const T& x, T& f) { f =
erfinv(x);}
957 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) {
958 d[0] = (sqrt(
pi)/2)*exp(f*f); }
964 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = log1p(x);}
965 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) {
972 template<
typename T>
static inline void fcn(
const T& x, T& f) { f = expm1(x);}
973 template<
typename T>
static inline void der(
const T& x,
const T& f, T* d) {
980 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) {f =
printme(x, y); }
981 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
989 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = atan2(x, y);}
990 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
991 T t = x*x+y*y; d[0]=y/t; d[1]=-x/t;}
998 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) {
1000 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
1007 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = x;}
1008 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
1009 d[0] = 1; d[1] = 0; }
1015 template<
typename T>
static inline void fcn(
const T& x,
const T& y, T& f) { f = hypot(x, y);}
1016 template<
typename T>
static inline void der(
const T& x,
const T& y,
const T& f, T* d) {
1017 d[0] = x/f; d[1] = y/f; }
1020 template<
template<casadi_
int>
class F,
typename T>
1023 case OP_ASSIGN:
return F<OP_ASSIGN>::check;
1024 case OP_ADD:
return F<OP_ADD>::check;
1025 case OP_SUB:
return F<OP_SUB>::check;
1026 case OP_MUL:
return F<OP_MUL>::check;
1027 case OP_DIV:
return F<OP_DIV>::check;
1028 case OP_NEG:
return F<OP_NEG>::check;
1029 case OP_EXP:
return F<OP_EXP>::check;
1030 case OP_LOG:
return F<OP_LOG>::check;
1031 case OP_POW:
return F<OP_POW>::check;
1033 case OP_SQRT:
return F<OP_SQRT>::check;
1034 case OP_SQ:
return F<OP_SQ>::check;
1035 case OP_TWICE:
return F<OP_TWICE>::check;
1036 case OP_SIN:
return F<OP_SIN>::check;
1037 case OP_COS:
return F<OP_COS>::check;
1038 case OP_TAN:
return F<OP_TAN>::check;
1039 case OP_ASIN:
return F<OP_ASIN>::check;
1040 case OP_ACOS:
return F<OP_ACOS>::check;
1041 case OP_ATAN:
return F<OP_ATAN>::check;
1042 case OP_LT:
return F<OP_LT>::check;
1043 case OP_LE:
return F<OP_LE>::check;
1044 case OP_EQ:
return F<OP_EQ>::check;
1045 case OP_NE:
return F<OP_NE>::check;
1046 case OP_NOT:
return F<OP_NOT>::check;
1047 case OP_AND:
return F<OP_AND>::check;
1048 case OP_OR:
return F<OP_OR>::check;
1049 case OP_FLOOR:
return F<OP_FLOOR>::check;
1050 case OP_CEIL:
return F<OP_CEIL>::check;
1051 case OP_FMOD:
return F<OP_FMOD>::check;
1053 case OP_FABS:
return F<OP_FABS>::check;
1054 case OP_SIGN:
return F<OP_SIGN>::check;
1057 case OP_ERF:
return F<OP_ERF>::check;
1058 case OP_FMIN:
return F<OP_FMIN>::check;
1059 case OP_FMAX:
return F<OP_FMAX>::check;
1060 case OP_INV:
return F<OP_INV>::check;
1061 case OP_SINH:
return F<OP_SINH>::check;
1062 case OP_COSH:
return F<OP_COSH>::check;
1063 case OP_TANH:
return F<OP_TANH>::check;
1064 case OP_ASINH:
return F<OP_ASINH>::check;
1065 case OP_ACOSH:
return F<OP_ACOSH>::check;
1066 case OP_ATANH:
return F<OP_ATANH>::check;
1067 case OP_ATAN2:
return F<OP_ATAN2>::check;
1068 case OP_CONST:
return F<OP_CONST>::check;
1069 case OP_INPUT:
return F<OP_INPUT>::check;
1070 case OP_OUTPUT:
return F<OP_OUTPUT>::check;
1072 case OP_CALL:
return F<OP_CALL>::check;
1073 case OP_FIND:
return F<OP_FIND>::check;
1074 case OP_LOW:
return F<OP_LOW>::check;
1075 case OP_MAP:
return F<OP_MAP>::check;
1076 case OP_MTIMES:
return F<OP_MTIMES>::check;
1077 case OP_SOLVE:
return F<OP_SOLVE>::check;
1080 case OP_INVERSE:
return F<OP_INVERSE>::check;
1081 case OP_DOT:
return F<OP_DOT>::check;
1082 case OP_BILIN:
return F<OP_BILIN>::check;
1083 case OP_RANK1:
return F<OP_RANK1>::check;
1084 case OP_HORZCAT:
return F<OP_HORZCAT>::check;
1085 case OP_VERTCAT:
return F<OP_VERTCAT>::check;
1086 case OP_DIAGCAT:
return F<OP_DIAGCAT>::check;
1090 case OP_RESHAPE:
return F<OP_RESHAPE>::check;
1092 case OP_SUBREF:
return F<OP_SUBREF>::check;
1100 case OP_PROJECT:
return F<OP_PROJECT>::check;
1102 case OP_MONITOR:
return F<OP_MONITOR>::check;
1103 case OP_DUMP:
return F<OP_DUMP>::check;
1104 case OP_NORM2:
return F<OP_NORM2>::check;
1105 case OP_NORM1:
return F<OP_NORM1>::check;
1106 case OP_NORMINF:
return F<OP_NORMINF>::check;
1107 case OP_NORMF:
return F<OP_NORMF>::check;
1108 case OP_MMIN:
return F<OP_MMIN>::check;
1109 case OP_MMAX:
return F<OP_MMAX>::check;
1112 case OP_ERFINV:
return F<OP_ERFINV>::check;
1113 case OP_PRINTME:
return F<OP_PRINTME>::check;
1114 case OP_LIFT:
return F<OP_LIFT>::check;
1116 case OP_BSPLINE:
return F<OP_BSPLINE>::check;
1118 case OP_LOG1P:
return F<OP_LOG1P>::check;
1119 case OP_EXPM1:
return F<OP_EXPM1>::check;
1120 case OP_HYPOT:
return F<OP_HYPOT>::check;
1122 case OP_KRON:
return F<OP_KRON>::check;
1128 template<
template<casadi_
int>
class F>
1130 return operation_getter<F, bool>(op);
1134 template<
typename T>
1140 static inline void fun(
unsigned char op,
const T& x,
const T& y,
T& f);
1145 static inline void fun(
unsigned char op,
const T* x,
const T* y,
T* f, casadi_int n);
1150 static inline void fun(
unsigned char op,
const T* x,
const T& y,
T* f, casadi_int n);
1155 static inline void fun(
unsigned char op,
const T& x,
const T* y,
T* f, casadi_int n);
1160 static inline void der(
unsigned char op,
const T& x,
const T& y,
const T& f,
T* d);
1165 static inline void derF(
unsigned char op,
const T& x,
const T& y,
T& f,
T* d);
1170 static inline void fun_linear(
unsigned char op,
const T*x,
const T* y,
T* f);
1175 static inline bool is_binary(
unsigned char op);
1180 static inline bool is_unary(
unsigned char op);
1185 static inline casadi_int
ndeps(
unsigned char op);
1190 static inline std::string
print(
unsigned char op,
const std::string& x,
1191 const std::string& y);
1192 static inline std::string
print(
unsigned char op,
const std::string& x);
1193 static inline std::string
name(
unsigned char op);
1194 static inline std::string
pre(
unsigned char op);
1195 static inline std::string
sep(
unsigned char op);
1196 static inline std::string
post(
unsigned char op);
1206 static inline void fun(
unsigned char op,
const casadi_int& x,
1207 const casadi_int& y, casadi_int& f) {
1210 f =
static_cast<casadi_int
>(ff);
1213 static inline void fun(
unsigned char op,
const casadi_int* x,
const casadi_int* y,
1214 casadi_int* f, casadi_int n) {
1215 for (casadi_int i=0; i<n; ++i) {
1218 *f++ =
static_cast<casadi_int
>(ff);
1222 static inline void fun(
unsigned char op,
const casadi_int* x,
const casadi_int& y,
1223 casadi_int* f, casadi_int n) {
1224 for (casadi_int i=0; i<n; ++i) {
1227 *f++ =
static_cast<casadi_int
>(ff);
1231 static inline void fun(
unsigned char op,
const casadi_int& x,
const casadi_int* y,
1232 casadi_int* f, casadi_int n) {
1233 for (casadi_int i=0; i<n; ++i) {
1236 *f++ =
static_cast<casadi_int
>(ff);
1243 static inline void der(
unsigned char op,
const casadi_int& x,
const casadi_int& y,
1244 const casadi_int& f, casadi_int* d) {
1245 double d_real[2] = {
static_cast<double>(d[0]),
static_cast<double>(d[1])};
1247 static_cast<double>(f), d_real);
1248 d[0] =
static_cast<casadi_int
>(d_real[0]);
1249 d[1] =
static_cast<casadi_int
>(d_real[1]);
1255 static inline void derF(
unsigned char op,
const casadi_int& x,
const casadi_int& y,
1256 casadi_int& f, casadi_int* d) {
1257 double d_real[2] = {
static_cast<double>(d[0]),
static_cast<double>(d[1])};
1258 double f_real =
static_cast<double>(f);
1260 f =
static_cast<casadi_int
>(f_real);
1261 d[0] =
static_cast<casadi_int
>(d_real[0]);
1262 d[1] =
static_cast<casadi_int
>(d_real[1]);
1268 static inline casadi_int
ndeps(
unsigned char op) {
1275 static inline std::string
print(
unsigned char op,
const std::string& x,
1276 const std::string& y) {
1279 static inline std::string
print(
unsigned char op,
const std::string& x) {
1282 static inline std::string
pre(
unsigned char op) {
1285 static inline std::string
name(
unsigned char op) {
1288 static inline std::string
sep(
unsigned char op) {
1291 static inline std::string
post(
unsigned char op) {
1298 template<
typename T>
1302 #define CASADI_MATH_FUN_BUILTIN_GEN(CNAME, X, Y, F, N) \
1303 case OP_ASSIGN: CNAME<OP_ASSIGN>::fcn(X, Y, F, N); break; \
1304 case OP_ADD: CNAME<OP_ADD>::fcn(X, Y, F, N); break; \
1305 case OP_SUB: CNAME<OP_SUB>::fcn(X, Y, F, N); break; \
1306 case OP_MUL: CNAME<OP_MUL>::fcn(X, Y, F, N); break; \
1307 case OP_DIV: CNAME<OP_DIV>::fcn(X, Y, F, N); break; \
1308 case OP_NEG: CNAME<OP_NEG>::fcn(X, Y, F, N); break; \
1309 case OP_EXP: CNAME<OP_EXP>::fcn(X, Y, F, N); break; \
1310 case OP_LOG: CNAME<OP_LOG>::fcn(X, Y, F, N); break; \
1311 case OP_POW: CNAME<OP_POW>::fcn(X, Y, F, N); break; \
1312 case OP_CONSTPOW: CNAME<OP_CONSTPOW>::fcn(X, Y, F, N); break; \
1313 case OP_SQRT: CNAME<OP_SQRT>::fcn(X, Y, F, N); break; \
1314 case OP_SQ: CNAME<OP_SQ>::fcn(X, Y, F, N); break; \
1315 case OP_TWICE: CNAME<OP_TWICE>::fcn(X, Y, F, N); break; \
1316 case OP_SIN: CNAME<OP_SIN>::fcn(X, Y, F, N); break; \
1317 case OP_COS: CNAME<OP_COS>::fcn(X, Y, F, N); break; \
1318 case OP_TAN: CNAME<OP_TAN>::fcn(X, Y, F, N); break; \
1319 case OP_ASIN: CNAME<OP_ASIN>::fcn(X, Y, F, N); break; \
1320 case OP_ACOS: CNAME<OP_ACOS>::fcn(X, Y, F, N); break; \
1321 case OP_ATAN: CNAME<OP_ATAN>::fcn(X, Y, F, N); break; \
1322 case OP_LT: CNAME<OP_LT>::fcn(X, Y, F, N); break; \
1323 case OP_LE: CNAME<OP_LE>::fcn(X, Y, F, N); break; \
1324 case OP_EQ: CNAME<OP_EQ>::fcn(X, Y, F, N); break; \
1325 case OP_NE: CNAME<OP_NE>::fcn(X, Y, F, N); break; \
1326 case OP_NOT: CNAME<OP_NOT>::fcn(X, Y, F, N); break; \
1327 case OP_AND: CNAME<OP_AND>::fcn(X, Y, F, N); break; \
1328 case OP_OR: CNAME<OP_OR>::fcn(X, Y, F, N); break; \
1329 case OP_IF_ELSE_ZERO: CNAME<OP_IF_ELSE_ZERO>::fcn(X, Y, F, N); break; \
1330 case OP_FLOOR: CNAME<OP_FLOOR>::fcn(X, Y, F, N); break; \
1331 case OP_CEIL: CNAME<OP_CEIL>::fcn(X, Y, F, N); break; \
1332 case OP_FMOD: CNAME<OP_FMOD>::fcn(X, Y, F, N); break; \
1333 case OP_REMAINDER: CNAME<OP_REMAINDER>::fcn(X, Y, F, N); break; \
1334 case OP_FABS: CNAME<OP_FABS>::fcn(X, Y, F, N); break; \
1335 case OP_SIGN: CNAME<OP_SIGN>::fcn(X, Y, F, N); break; \
1336 case OP_COPYSIGN: CNAME<OP_COPYSIGN>::fcn(X, Y, F, N); break; \
1337 case OP_ERF: CNAME<OP_ERF>::fcn(X, Y, F, N); break; \
1338 case OP_FMIN: CNAME<OP_FMIN>::fcn(X, Y, F, N); break; \
1339 case OP_FMAX: CNAME<OP_FMAX>::fcn(X, Y, F, N); break; \
1340 case OP_INV: CNAME<OP_INV>::fcn(X, Y, F, N); break; \
1341 case OP_SINH: CNAME<OP_SINH>::fcn(X, Y, F, N); break; \
1342 case OP_COSH: CNAME<OP_COSH>::fcn(X, Y, F, N); break; \
1343 case OP_TANH: CNAME<OP_TANH>::fcn(X, Y, F, N); break; \
1344 case OP_ASINH: CNAME<OP_ASINH>::fcn(X, Y, F, N); break; \
1345 case OP_ACOSH: CNAME<OP_ACOSH>::fcn(X, Y, F, N); break; \
1346 case OP_ATANH: CNAME<OP_ATANH>::fcn(X, Y, F, N); break; \
1347 case OP_ATAN2: CNAME<OP_ATAN2>::fcn(X, Y, F, N); break; \
1348 case OP_ERFINV: CNAME<OP_ERFINV>::fcn(X, Y, F, N); break; \
1349 case OP_LIFT: CNAME<OP_LIFT>::fcn(X, Y, F, N); break; \
1350 case OP_PRINTME: CNAME<OP_PRINTME>::fcn(X, Y, F, N); break; \
1351 case OP_LOG1P: CNAME<OP_LOG1P>::fcn(X, Y, F, N); break; \
1352 case OP_EXPM1: CNAME<OP_EXPM1>::fcn(X, Y, F, N); break; \
1353 case OP_HYPOT: CNAME<OP_HYPOT>::fcn(X, Y, F, N); break;
1355 #define CASADI_MATH_FUN_BUILTIN(X, Y, F) CASADI_MATH_FUN_BUILTIN_GEN(BinaryOperationSS, X, Y, F, 1)
1358 CASADI_MATH_FUN_BUILTIN(x, y, f)
1362 template<
typename T>
1369 template<
typename T>
1376 template<
typename T>
1384 template<
typename T>
1388 #define CASADI_MATH_DER_BUILTIN(X, Y, F, D) \
1389 case OP_ASSIGN: BinaryOperation<OP_ASSIGN>::der(X, Y, F, D); break; \
1390 case OP_ADD: BinaryOperation<OP_ADD>::der(X, Y, F, D); break; \
1391 case OP_SUB: BinaryOperation<OP_SUB>::der(X, Y, F, D); break; \
1392 case OP_MUL: BinaryOperation<OP_MUL>::der(X, Y, F, D); break; \
1393 case OP_DIV: BinaryOperation<OP_DIV>::der(X, Y, F, D); break; \
1394 case OP_NEG: BinaryOperation<OP_NEG>::der(X, Y, F, D); break; \
1395 case OP_EXP: BinaryOperation<OP_EXP>::der(X, Y, F, D); break; \
1396 case OP_LOG: BinaryOperation<OP_LOG>::der(X, Y, F, D); break; \
1397 case OP_POW: BinaryOperation<OP_POW>::der(X, Y, F, D); break; \
1398 case OP_CONSTPOW: BinaryOperation<OP_CONSTPOW>::der(X, Y, F, D); break; \
1399 case OP_SQRT: BinaryOperation<OP_SQRT>::der(X, Y, F, D); break; \
1400 case OP_SQ: BinaryOperation<OP_SQ>::der(X, Y, F, D); break; \
1401 case OP_TWICE: BinaryOperation<OP_TWICE>::der(X, Y, F, D); break; \
1402 case OP_SIN: BinaryOperation<OP_SIN>::der(X, Y, F, D); break; \
1403 case OP_COS: BinaryOperation<OP_COS>::der(X, Y, F, D); break; \
1404 case OP_TAN: BinaryOperation<OP_TAN>::der(X, Y, F, D); break; \
1405 case OP_ASIN: BinaryOperation<OP_ASIN>::der(X, Y, F, D); break; \
1406 case OP_ACOS: BinaryOperation<OP_ACOS>::der(X, Y, F, D); break; \
1407 case OP_ATAN: BinaryOperation<OP_ATAN>::der(X, Y, F, D); break; \
1408 case OP_LT: BinaryOperation<OP_LT>::der(X, Y, F, D); break; \
1409 case OP_LE: BinaryOperation<OP_LE>::der(X, Y, F, D); break; \
1410 case OP_EQ: BinaryOperation<OP_EQ>::der(X, Y, F, D); break; \
1411 case OP_NE: BinaryOperation<OP_NE>::der(X, Y, F, D); break; \
1412 case OP_NOT: BinaryOperation<OP_NOT>::der(X, Y, F, D); break; \
1413 case OP_AND: BinaryOperation<OP_AND>::der(X, Y, F, D); break; \
1414 case OP_OR: BinaryOperation<OP_OR>::der(X, Y, F, D); break; \
1415 case OP_IF_ELSE_ZERO: BinaryOperation<OP_IF_ELSE_ZERO>::der(X, Y, F, D); break; \
1416 case OP_FLOOR: BinaryOperation<OP_FLOOR>::der(X, Y, F, D); break; \
1417 case OP_CEIL: BinaryOperation<OP_CEIL>::der(X, Y, F, D); break; \
1418 case OP_FMOD: BinaryOperation<OP_FMOD>::der(X, Y, F, D); break; \
1419 case OP_REMAINDER: BinaryOperation<OP_REMAINDER>::der(X, Y, F, D); break; \
1420 case OP_FABS: BinaryOperation<OP_FABS>::der(X, Y, F, D); break; \
1421 case OP_SIGN: BinaryOperation<OP_SIGN>::der(X, Y, F, D); break; \
1422 case OP_COPYSIGN: BinaryOperation<OP_COPYSIGN>::der(X, Y, F, D); break; \
1423 case OP_ERF: BinaryOperation<OP_ERF>::der(X, Y, F, D); break; \
1424 case OP_FMIN: BinaryOperation<OP_FMIN>::der(X, Y, F, D); break; \
1425 case OP_FMAX: BinaryOperation<OP_FMAX>::der(X, Y, F, D); break; \
1426 case OP_INV: BinaryOperation<OP_INV>::der(X, Y, F, D); break; \
1427 case OP_SINH: BinaryOperation<OP_SINH>::der(X, Y, F, D); break; \
1428 case OP_COSH: BinaryOperation<OP_COSH>::der(X, Y, F, D); break; \
1429 case OP_TANH: BinaryOperation<OP_TANH>::der(X, Y, F, D); break; \
1430 case OP_ASINH: BinaryOperation<OP_ASINH>::der(X, Y, F, D); break; \
1431 case OP_ACOSH: BinaryOperation<OP_ACOSH>::der(X, Y, F, D); break; \
1432 case OP_ATANH: BinaryOperation<OP_ATANH>::der(X, Y, F, D); break; \
1433 case OP_ATAN2: BinaryOperation<OP_ATAN2>::der(X, Y, F, D); break; \
1434 case OP_ERFINV: BinaryOperation<OP_ERFINV>::der(X, Y, F, D); break; \
1435 case OP_LIFT: BinaryOperation<OP_LIFT>::der(X, Y, F, D); break; \
1436 case OP_PRINTME: BinaryOperation<OP_PRINTME>::der(X, Y, F, D); break; \
1437 case OP_LOG1P: BinaryOperation<OP_LOG1P>::der(X, Y, F, D); break; \
1438 case OP_EXPM1: BinaryOperation<OP_EXPM1>::der(X, Y, F, D); break; \
1439 case OP_HYPOT: BinaryOperation<OP_HYPOT>::der(X, Y, F, D); break;
1441 CASADI_MATH_DER_BUILTIN(x, y, f, d)
1446 template<
typename T>
1450 #define CASADI_MATH_DERF_BUILTIN(X, Y, F, D) \
1451 case OP_ASSIGN: DerBinaryOperation<OP_ASSIGN>::derf(X, Y, F, D); break; \
1452 case OP_ADD: DerBinaryOperation<OP_ADD>::derf(X, Y, F, D); break; \
1453 case OP_SUB: DerBinaryOperation<OP_SUB>::derf(X, Y, F, D); break; \
1454 case OP_MUL: DerBinaryOperation<OP_MUL>::derf(X, Y, F, D); break; \
1455 case OP_DIV: DerBinaryOperation<OP_DIV>::derf(X, Y, F, D); break; \
1456 case OP_NEG: DerBinaryOperation<OP_NEG>::derf(X, Y, F, D); break; \
1457 case OP_EXP: DerBinaryOperation<OP_EXP>::derf(X, Y, F, D); break; \
1458 case OP_LOG: DerBinaryOperation<OP_LOG>::derf(X, Y, F, D); break; \
1459 case OP_POW: DerBinaryOperation<OP_POW>::derf(X, Y, F, D); break; \
1460 case OP_CONSTPOW: DerBinaryOperation<OP_CONSTPOW>::derf(X, Y, F, D); break; \
1461 case OP_SQRT: DerBinaryOperation<OP_SQRT>::derf(X, Y, F, D); break; \
1462 case OP_SQ: DerBinaryOperation<OP_SQ>::derf(X, Y, F, D); break; \
1463 case OP_TWICE: DerBinaryOperation<OP_TWICE>::derf(X, Y, F, D); break; \
1464 case OP_SIN: DerBinaryOperation<OP_SIN>::derf(X, Y, F, D); break; \
1465 case OP_COS: DerBinaryOperation<OP_COS>::derf(X, Y, F, D); break; \
1466 case OP_TAN: DerBinaryOperation<OP_TAN>::derf(X, Y, F, D); break; \
1467 case OP_ASIN: DerBinaryOperation<OP_ASIN>::derf(X, Y, F, D); break; \
1468 case OP_ACOS: DerBinaryOperation<OP_ACOS>::derf(X, Y, F, D); break; \
1469 case OP_ATAN: DerBinaryOperation<OP_ATAN>::derf(X, Y, F, D); break; \
1470 case OP_LT: DerBinaryOperation<OP_LT>::derf(X, Y, F, D); break; \
1471 case OP_LE: DerBinaryOperation<OP_LE>::derf(X, Y, F, D); break; \
1472 case OP_EQ: DerBinaryOperation<OP_EQ>::derf(X, Y, F, D); break; \
1473 case OP_NE: DerBinaryOperation<OP_NE>::derf(X, Y, F, D); break; \
1474 case OP_NOT: DerBinaryOperation<OP_NOT>::derf(X, Y, F, D); break; \
1475 case OP_AND: DerBinaryOperation<OP_AND>::derf(X, Y, F, D); break; \
1476 case OP_OR: DerBinaryOperation<OP_OR>::derf(X, Y, F, D); break; \
1477 case OP_IF_ELSE_ZERO: DerBinaryOperation<OP_IF_ELSE_ZERO>::derf(X, Y, F, D); break; \
1478 case OP_FLOOR: DerBinaryOperation<OP_FLOOR>::derf(X, Y, F, D); break; \
1479 case OP_CEIL: DerBinaryOperation<OP_CEIL>::derf(X, Y, F, D); break; \
1480 case OP_FMOD: DerBinaryOperation<OP_FMOD>::derf(X, Y, F, D); break; \
1481 case OP_REMAINDER: DerBinaryOperation<OP_REMAINDER>::derf(X, Y, F, D); break; \
1482 case OP_FABS: DerBinaryOperation<OP_FABS>::derf(X, Y, F, D); break; \
1483 case OP_SIGN: DerBinaryOperation<OP_SIGN>::derf(X, Y, F, D); break; \
1484 case OP_COPYSIGN: DerBinaryOperation<OP_COPYSIGN>::derf(X, Y, F, D); break; \
1485 case OP_ERF: DerBinaryOperation<OP_ERF>::derf(X, Y, F, D); break; \
1486 case OP_FMIN: DerBinaryOperation<OP_FMIN>::derf(X, Y, F, D); break; \
1487 case OP_FMAX: DerBinaryOperation<OP_FMAX>::derf(X, Y, F, D); break; \
1488 case OP_INV: DerBinaryOperation<OP_INV>::derf(X, Y, F, D); break; \
1489 case OP_SINH: DerBinaryOperation<OP_SINH>::derf(X, Y, F, D); break; \
1490 case OP_COSH: DerBinaryOperation<OP_COSH>::derf(X, Y, F, D); break; \
1491 case OP_TANH: DerBinaryOperation<OP_TANH>::derf(X, Y, F, D); break; \
1492 case OP_ASINH: DerBinaryOperation<OP_ASINH>::derf(X, Y, F, D); break; \
1493 case OP_ACOSH: DerBinaryOperation<OP_ACOSH>::derf(X, Y, F, D); break; \
1494 case OP_ATANH: DerBinaryOperation<OP_ATANH>::derf(X, Y, F, D); break; \
1495 case OP_ATAN2: DerBinaryOperation<OP_ATAN2>::derf(X, Y, F, D); break; \
1496 case OP_ERFINV: DerBinaryOperation<OP_ERFINV>::derf(X, Y, F, D); break; \
1497 case OP_LIFT: DerBinaryOperation<OP_LIFT>::derf(X, Y, F, D); break; \
1498 case OP_PRINTME: DerBinaryOperation<OP_PRINTME>::derf(X, Y, F, D); break; \
1499 case OP_LOG1P: DerBinaryOperation<OP_LOG1P>::derf(X, Y, F, D); break; \
1500 case OP_EXPM1: DerBinaryOperation<OP_EXPM1>::derf(X, Y, F, D); break; \
1501 case OP_HYPOT: DerBinaryOperation<OP_HYPOT>::derf(X, Y, F, D); break;
1503 CASADI_MATH_DERF_BUILTIN(x, y, f, d)
1507 #define CASADI_MATH_BINARY_BUILTIN \
1522 case OP_REMAINDER: \
1530 #define CASADI_MATH_UNARY_BUILTIN \
1561 template<
typename T>
1564 for (
int i=0;i<3;++i) {
1565 f[i] = T::binary(op, x[i], y[i]);
1568 for (
int i=0;i<3;++i) {
1569 f[i] = T::unary(op, x[i]);
1582 bool const_argy = y[1].is_zero() && y[2].is_zero();
1588 f[2] = (x[0]+x[1]+x[2])/(y[0]+y[1]+y[2]);
1591 bool const_arg = x[1].is_zero() && x[2].is_zero();
1593 f[0] = T::unary(op, x[0]);
1595 f[2] = T::unary(op, x[0]+x[1]+x[2]);
1599 bool const_argx = x[1].is_zero() && x[2].is_zero();
1600 bool const_argy = y[1].is_zero() && y[2].is_zero();
1601 if (const_argx && const_argy) {
1602 f[0] = T::binary(op, x[0], y[0]);
1604 f[2] = T::binary(op, x[0]+x[1]+x[2], y[0]+y[1]+y[2]);
1607 casadi_error(
"Not implemented");
1611 template<
typename T>
1614 CASADI_MATH_BINARY_BUILTIN
1622 template<
typename T>
1625 CASADI_MATH_UNARY_BUILTIN
1632 template<
typename T>
1639 CASADI_MATH_BINARY_BUILTIN
1649 template<
typename T>
1652 const std::string& x,
const std::string& y) {
1653 casadi_assert_dev(ndeps(op)==2);
1654 return pre(op) + x + sep(op) + y + post(op);
1657 template<
typename T>
1660 casadi_assert_dev(ndeps(op)==1);
1661 return pre(op) + x + post(op);
1664 template<
typename T>
1668 case OP_ADD:
return "add";
1669 case OP_SUB:
return "sub";
1670 case OP_MUL:
return "mul";
1671 case OP_DIV:
return "div";
1672 case OP_NEG:
return "neg";
1673 case OP_EXP:
return "exp";
1674 case OP_LOG:
return "log";
1676 case OP_POW:
return "pow";
1678 case OP_SQ:
return "sq";
1680 case OP_SIN:
return "sin";
1681 case OP_COS:
return "cos";
1682 case OP_TAN:
return "tan";
1686 case OP_LT:
return "lt";
1687 case OP_LE:
return "le";
1688 case OP_EQ:
return "eq";
1689 case OP_NE:
return "ne";
1690 case OP_NOT:
return "not";
1691 case OP_AND:
return "and";
1692 case OP_OR:
return "or";
1701 case OP_ERF:
return "erf";
1704 case OP_INV:
return "inv";
1722 case OP_DOT:
return "dot";
1758 return "<invalid-op>";
1761 template<
typename T>
1769 case OP_NEG:
return "(-";
1771 case OP_LT:
return "(";
1772 case OP_LE:
return "(";
1773 case OP_EQ:
return "(";
1774 case OP_NE:
return "(";
1775 case OP_NOT:
return "(!";
1777 case OP_OR:
return "(";
1779 case OP_INV:
return "(1./";
1780 default:
return name(op) +
"(";
1784 template<
typename T>
1791 case OP_LT:
return "<";
1792 case OP_LE:
return "<=";
1793 case OP_EQ:
return "==";
1794 case OP_NE:
return "!=";
1795 case OP_AND:
return "&&";
1796 case OP_OR:
return "||";
1798 default:
return ",";
1802 template<
typename T>
1807 default:
return ")";
1812 template<
class T,
typename SU>
1820 if (x.is_op(
OP_MUL) && x.dep(0).is_constant() &&
1823 else if (x.is_op(
OP_MUL) && x.dep(1).is_constant() &&
1830 else if (x.is_op(
OP_NEG))
1836 if (x.is_nonnegative())
1838 else if (x.is_op(
OP_NEG))
1839 return fabs(x.dep());
1851 return fabs(x.dep());
1855 return cos(x.dep());
1857 return cos(x.dep());
1862 else if (unique && x.is_op(
OP_SUB))
1863 return x.dep(1) - x.dep(0);
1870 template<
class T,
typename SU,
typename SB>
1882 else if (y->is_zero())
1884 else if (y.is_op(
OP_NEG))
1886 else if (x.is_op(
OP_NEG))
1891 x.dep(0).is_constant() &&
static_cast<double>(x.dep(0))==0.5 &&
1892 y.dep(0).is_constant() &&
static_cast<double>(y.dep(0))==0.5 &&
1893 is_equal(y.dep(1), x.dep(1), depth))
1896 x.dep(1).is_constant() &&
static_cast<double>(x.dep(1))==2 &&
1897 y.dep(1).is_constant() &&
static_cast<double>(y.dep(1))==2 &&
1898 is_equal(y.dep(0), x.dep(0), depth))
1901 x.dep(0).is_constant() && y.dep(0).is_constant() &&
1902 static_cast<double>(x.dep(0))+
static_cast<double>(y.dep(0))==1 &&
1903 is_equal(y.dep(1), x.dep(1), depth)
1913 &&
is_equal(x.dep().dep(), y.dep().dep(), depth))
1915 else if (x.is_doubled() &&
is_equal(x.dep(0), y, depth))
1917 else if (y.is_doubled() &&
is_equal(y.dep(0), x, depth))
1920 is_equal(x.dep(0), y.dep(0), depth) && (x.dep(1)+y.dep(1)).is_one())
1930 else if (y.is_op(
OP_NEG))
1940 else if (x.is_op(
OP_NEG))
1941 return -(x.dep() + y);
1943 x.dep(0).is_constant() && y.dep(0).is_constant() &&
1944 static_cast<double>(x.dep(0))-
static_cast<double>(y.dep(0))==1 &&
1945 is_equal(y.dep(1), x.dep(1), depth)
1948 else if (x.is_doubled() &&
is_equal(x.dep(0), y, depth))
1950 else if (y.is_doubled() &&
is_equal(y.dep(0), x, depth))
1956 else if (!x.is_constant() && y.is_constant())
1958 else if (x.is_zero() || y->is_zero())
1960 else if (x.is_one())
1962 else if (y.is_one())
1964 else if (y.is_minus_one())
1966 else if (x.is_minus_one())
1968 else if (y.is_op(
OP_INV))
1970 else if (x.is_op(
OP_INV))
1972 else if (x.is_constant() && y.is_op(
OP_MUL) && y.dep(0).is_constant() &&
1973 static_cast<double>(x)*
static_cast<double>(y.dep(0))==1)
1975 else if (x.is_constant() && y.is_doubled() &&
1976 static_cast<double>(x)*2==1)
1978 else if (x.is_constant() && y.is_op(
OP_DIV) && y.dep(1).is_constant() &&
1979 static_cast<double>(x)==
static_cast<double>(y.dep(1)))
1981 else if (x.is_constant() &&
static_cast<double>(x)==2)
1983 else if (y.is_constant() &&
static_cast<double>(y)==2)
1987 else if (y.is_op(
OP_DIV) &&
1990 else if (x.is_op(
OP_NEG))
1991 return -(x.dep() * y);
1992 else if (y.is_op(
OP_NEG))
1993 return -(x * y.dep());
1994 else if (unique_x && x.is_op(
OP_ADD) && x.dep(1).is_op(
OP_DIV) &&
1995 is_equal(x.dep(1).dep(1), y, depth))
1996 return x.dep(0)*y + x.dep(1).dep(0);
1997 else if (unique_x && x.is_op(
OP_ADD) && x.dep(0).is_op(
OP_DIV) &&
1998 is_equal(x.dep(0).dep(1), y, depth))
1999 return x.dep(0).dep(0)+x.dep(1)*y;
2000 else if (unique_y && y.is_op(
OP_ADD) && y.dep(1).is_op(
OP_DIV) &&
2001 is_equal(y.dep(1).dep(1), x, depth))
2002 return x*y.dep(0) + y.dep(1).dep(0);
2003 else if (unique_y && y.is_op(
OP_ADD) && y.dep(0).is_op(
OP_DIV) &&
2004 is_equal(y.dep(0).dep(1), x, depth))
2005 return y.dep(0).dep(0) + x*y.dep(1);
2006 else if (unique_x && x.is_op(
OP_SUB) && x.dep(1).is_op(
OP_DIV) &&
2007 is_equal(x.dep(1).dep(1), y, depth))
2008 return x.dep(0)*y - x.dep(1).dep(0);
2009 else if (unique_x && x.is_op(
OP_SUB) && x.dep(0).is_op(
OP_DIV) &&
2010 is_equal(x.dep(0).dep(1), y, depth))
2011 return x.dep(0).dep(0)-x.dep(1)*y;
2012 else if (unique_y && y.is_op(
OP_SUB) && y.dep(1).is_op(
OP_DIV) &&
2013 is_equal(y.dep(1).dep(1), x, depth))
2014 return x*y.dep(0) - y.dep(1).dep(0);
2015 else if (unique_y && y.is_op(
OP_SUB) && y.dep(0).is_op(
OP_DIV) &&
2016 is_equal(y.dep(0).dep(1), x, depth))
2017 return y.dep(0).dep(0) - x*y.dep(1);
2018 else if (x.is_constant() && y.is_op(
OP_MUL) && y.dep(0).is_constant())
2019 return x*y.dep(0)*y.dep(1);
2020 else if (y.is_constant() && x.is_op(
OP_MUL) && x.dep(0).is_constant())
2021 return y*x.dep(0)*x.dep(1);
2025 return std::numeric_limits<double>::infinity();
2026 else if (x.is_zero())
2028 else if (y.is_one())
2030 else if (y.is_minus_one())
2032 else if (y.is_half())
2036 else if (x.is_doubled() && y.is_constant() &&
static_cast<double>(y)==2)
2038 else if (x.is_doubled() &&
is_equal(y, x.dep(0), depth))
2044 else if (x.is_one())
2046 else if (y.is_op(
OP_INV))
2048 else if (x.is_doubled() && y.is_doubled())
2049 return x.dep(0) / y->dep(0);
2050 else if (y.is_constant() && x.is_op(
OP_DIV) && x.dep(1).is_constant() &&
2051 static_cast<double>(y)*
static_cast<double>(x.dep(1))==1)
2053 else if (y.is_op(
OP_MUL) &&
2056 else if (y.is_doubled() &&
2059 else if (x.is_op(
OP_NEG) &&
2062 else if (y.is_op(
OP_NEG) &&
2066 is_equal(x.dep(0), y.dep(0), depth))
2069 return x.dep(1).inv();
2070 else if (x.is_op(
OP_NEG))
2071 return -(x.dep() / y);
2072 else if (y.is_op(
OP_NEG))
2073 return -(x / y.dep());
2076 if (y.is_constant()) {
2077 if (y.is_integer()) {
2078 casadi_int nn = y->to_int();
2081 }
else if (nn>100 || nn<-100) {
2084 return 1/pow(x, -nn);
2085 }
else if (nn%2 == 1) {
2086 return x*pow(x, nn-1);
2088 T rt = pow(x,
static_cast<casadi_int
>(nn/2));
2091 }
else if (y->to_double()==0.5) {
2099 if ((y-x).is_nonnegative())
2103 if (x.is_inf())
return y;
2104 if (y.is_inf())
return x;
2105 if (x.is_minus_inf() || y.is_minus_inf())
return -std::numeric_limits<double>::infinity();
2106 if (
is_equal(x, y, depth))
return x;
2109 if (x.is_minus_inf())
return y;
2110 if (y.is_minus_inf())
return x;
2111 if (x.is_inf() || y.is_inf())
return std::numeric_limits<double>::infinity();
2112 if (
is_equal(x, y, depth))
return x;
2115 if (((x)-y).is_nonnegative())
2129 }
else if (x.is_constant()) {
2130 if (
static_cast<double>(x)!=0) {
bool is_equal(double x, double y, casadi_int depth=0)
double if_else_zero(double x, double y)
Conditional assignment.
const double eps
Machine epsilon.
double if_else(double x, double y, double z)
double sign(double x)
Sign function, note that sign(nan) == nan.
casadi_int casadi_min(casadi_int x, casadi_int y)
double printme(double x, double y)
bool operation_checker(casadi_int op)
T common_simp_binary(casadi_int op, const T &x, const T &y, casadi_int depth, SU &&gen_unary, SB &&gen_binary, bool unique_x, bool unique_y, bool &hit)
const double nan
Not a number.
T common_simp_unary(casadi_int op, const T &x, casadi_int depth, SU &&gen_unary, bool unique, bool &hit)
double constpow(double x, double y)
T operation_getter(casadi_int op)
casadi_int casadi_max(casadi_int x, casadi_int y)
Operation
Enum for quick access to any node.
double simplify(double x)
const double pi
Define pi.
static T fcn(const T &x, const T &y)
Function evaluation.
Perform a binary operation on two scalars.
static void der(const T &x, const T &y, const T &f, T *d, casadi_int n)
Partial derivatives - binary function.
static void fcn(const T &x, const T &y, T &f, casadi_int n)
Function evaluation.
Perform a binary operation on a scalar and a vector.
static void der(const T &x, const T *y, const T *f, T *d, casadi_int n)
Partial derivatives - binary function.
static void fcn(const T &x, const T *y, T *f, casadi_int n)
Function evaluation.
Perform a binary operation on a vector and a scalar.
static void fcn(const T *x, const T &y, T *f, casadi_int n)
Function evaluation.
static void der(const T *x, const T &y, const T *f, T *d, casadi_int n)
Partial derivatives - binary function.
Perform a binary operation on two vectors.
static void fcn(const T *x, const T *y, T *f, casadi_int n)
Function evaluation.
static void der(const T *x, const T *y, const T *f, T *d, casadi_int n)
Partial derivatives - binary function.
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
static void der(const T &x, const T &y, const T &f, T *d)
static void fcn(const T &x, const T &y, T &f)
static void der(const T &x, const T &y, const T &f, T *d)
Partial derivatives - binary function.
static void fcn(const T &x, const T &y, T &f)
Function evaluation.
Calculate function and derivative.
static void derf(const T &x, const T &y, T &f, T *d)
Perform the operation.
static const casadi_int check
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
static void der(const T &x, const T &f, T *d)
static void fcn(const T &x, T &f)
Function evaluation.
static void der(const T &x, const T &f, T *d)
Partial derivatives.
static casadi_int ndeps(unsigned char op)
Number of dependencies.
static std::string pre(unsigned char op)
static std::string post(unsigned char op)
static void fun(unsigned char op, const casadi_int &x, const casadi_int &y, casadi_int &f)
Evaluate a built in function.
static void derF(unsigned char op, const casadi_int &x, const casadi_int &y, casadi_int &f, casadi_int *d)
Evaluate the function and the derivative function.
static void fun(unsigned char op, const casadi_int *x, const casadi_int *y, casadi_int *f, casadi_int n)
static std::string sep(unsigned char op)
static void der(unsigned char op, const casadi_int &x, const casadi_int &y, const casadi_int &f, casadi_int *d)
Evaluate a built in derivative function.
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.
static void fun(unsigned char op, const casadi_int *x, const casadi_int &y, casadi_int *f, casadi_int n)
static std::string print(unsigned char op, const std::string &x)
static void fun(unsigned char op, const casadi_int &x, const casadi_int *y, casadi_int *f, casadi_int n)
static std::string name(unsigned char op)
Easy access to all the functions for a particular type.
static bool is_binary(unsigned char op)
Is binary operation?
static std::string post(unsigned char op)
static std::string pre(unsigned char op)
static void der(unsigned char op, const T &x, const T &y, const T &f, T *d)
Evaluate a built in derivative function.
static void fun_linear(unsigned char op, const T *x, const T *y, T *f)
Evaluate function on a const/linear/nonlinear partition.
static casadi_int ndeps(unsigned char op)
Number of dependencies.
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.
static std::string name(unsigned char op)
static void fun(unsigned char op, const T &x, const T &y, T &f)
Evaluate a built in function (scalar-scalar)
static std::string sep(unsigned char op)
static void derF(unsigned char op, const T &x, const T &y, T &f, T *d)
Evaluate the function and the derivative function.
static bool is_unary(unsigned char op)
Is unary operation?