calculus.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_CALCULUS_HPP
27 #define CASADI_CALCULUS_HPP
28 
29 #include <iostream>
30 #include <string>
31 #include <cmath>
32 #include <limits>
33 #include <algorithm>
34 #include "casadi_common.hpp"
35 
36 // Define pi if the compiler fails to do so
37 
39 
40 namespace casadi {
41 #ifndef SWIG
43 #ifdef M_PI
44  const double pi = M_PI;
45 #else
46  const double pi = 3.14159265358979323846;
47 #endif
48 
50  const double inf = std::numeric_limits<double>::infinity();
51 
53  const double nan = std::numeric_limits<double>::quiet_NaN();
54 
56  const double eps = std::numeric_limits<double>::epsilon();
57 #endif // SWIG
58 
60  enum Operation {
61  // Simple assignment
63 
64  // Standard unary and binary functions
77 
78  // Double constant
80 
81  // Function input and output
83 
84  // Free parameter
86 
87  // Embedded function call
89 
90  // Find first nonzero in a vector
92 
93  // Find first nonzero in a vector
95 
96  // Embedded function call in parallel
98 
99  // Matrix multiplication
101 
102  // Solve linear system of equations
104 
105  // Matrix transpose
107 
108  // Matrix determinant
110 
111  // Matrix inverse
113 
114  // Inner product
116 
117  // Bilinear form
119 
120  // Rank-1 update
122 
123  // Horizontal concatenation
125 
126  // Vertical concatenation of vectors
128 
129  // Diagonal concatenation
131 
132  // Horizontal split
134 
135  // Vertical split of vectors
137 
138  // Diagonal split
140 
141  // Reshape an expression
143 
144  // Submatrix reference
146 
147  // Submatrix assignment
149 
150  // Nonzero reference
152 
153  // Parametric nonzero reference
155 
156  // Nonzero addition
158 
159  // parametric nonzero addition
161 
162  // Nonzero assignment
164 
165  // Parametric nonzero assignment
167 
168  // Set sparse
170 
171  // Assertion
173 
174  // Monitor
176 
177  // Norms
179 
180  // min/max
182 
183  // Horizontal repeat
185 
186  // Horizontal repeat sum
188 
192 
194 
196 
198 
199  // Sparsity cast
201 
203 
205 
207 
209 
211 
212  };
213  #define NUM_BUILT_IN_OPS (OP_REMAINDER+1)
214 
215  #define OP_
216 
217 #ifndef SWIG
218 
220 
223  using std::isfinite;
224  using std::sqrt;
225  using std::sin;
226  using std::cos;
227  using std::tan;
228  using std::atan;
229  using std::asin;
230  using std::acos;
231  using std::sinh;
232  using std::cosh;
233  using std::tanh;
234  using std::exp;
235  using std::log;
236  using std::log10;
237  using std::abs;
238  using std::fabs;
239  using std::floor;
240  using std::ceil;
241  using std::pow;
242  using std::fmod;
243  using std::remainder;
244  using std::atan2;
245  using std::erf;
246  using std::fmin;
247  using std::fmax;
248  using std::fabs;
249  using std::atanh;
250  using std::asinh;
251  using std::acosh;
252  using std::isnan;
253  using std::isinf;
254  using std::log1p;
255  using std::expm1;
256  using std::hypot;
257  using std::copysign;
259 
261  // Implement "missing" operations
262 
264  inline double sign(double x) { return x<0 ? -1 : x>0 ? 1 : x;}
266 
268 
270 
271  inline double simplify(double x) { return x;}
272  inline double constpow(double x, double y) { return pow(x, y);}
273  inline double printme(double x, double y) {
274  std::ios::fmtflags f(uout().flags());
275  uout() << "|> " << y << " : ";
276  uout() << std::setprecision(std::numeric_limits<double>::digits10 + 1) << std::scientific;
277  uout() << x << std::endl;
278  uout().flags(f);
279  return x;
280  }
281  inline bool is_equal(double x, double y, casadi_int depth=0) { return x==y;}
282 
283 
284  // Integer maximum and minimum
285  inline casadi_int casadi_max(casadi_int x, casadi_int y) { return std::max(x, y);}
286  inline casadi_int casadi_min(casadi_int x, casadi_int y) { return std::min(x, y);}
287 
289  inline double if_else_zero(double x, double y) { return x==0 ? 0 : y;}
290  inline double if_else(double x, double y, double z) { return x==0 ? z : y;}
291 #ifdef HAS_ERFINV
292  using ::erfinv;
293 #else // HAS ERFINV
294  inline double erfinv(double x) throw() {
295  // Approximation found in Sourceforge and modified: Not very efficient
296  if (x>=1) {
297  return x==1 ? inf : nan;
298  } else if (x<=-1) {
299  return x==-1 ? -inf : nan;
300  } else if (x<-0.7) {
301  double z = sqrt(-log((1.0+x)/2.0));
302  return -(((1.641345311*z+3.429567803)*z-1.624906493)*z-1.970840454)/
303  ((1.637067800*z+3.543889200)*z+1.0);
304  } else {
305  double y;
306  if (x<0.7) {
307  double z = x*x;
308  y = x*(((-0.140543331*z+0.914624893)*z-1.645349621)*z+0.886226899)/
309  ((((-0.329097515*z+0.012229801)*z+1.442710462)*z-2.118377725)*z+1.0);
310  } else {
311  double z = sqrt(-log((1.0-x)/2.0));
312  y = (((1.641345311*z+3.429567803)*z-1.624906493)*z-1.970840454)/
313  ((1.637067800*z+3.543889200)*z+1.0);
314  }
315 
316  //polish x to full accuracy
317  y = y - (erf(y) - x) / (2.0/sqrt(pi) * exp(-y*y));
318  y = y - (erf(y) - x) / (2.0/sqrt(pi) * exp(-y*y));
319  return y;
320  }
321  }
322 #endif // HAS_ERFINV
324 
325  template<typename T>
326  T twice(const T& x) {
327  return x+x;
328  }
329 
330  template<typename T>
331  T sq(const T& x) {
332  return x*x;
333  }
334 
335  template<casadi_int I>
336  struct UnaryOperation {
338  template<typename T> static inline void fcn(const T& x, T& f);
339 
341  template<typename T> static inline void der(const T& x, const T& f, T* d);
342  };
343 
344  template<casadi_int I>
347  template<typename T> static inline void fcn(const T& x, const T& y, T& f) {
348  UnaryOperation<I>::fcn(x, f);}
349 
351  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
352  UnaryOperation<I>::der(x, f, d); d[1]=0; }
353  };
354 
355  template<casadi_int I>
358  template<typename T> static inline T fcn(const T& x, const T& y) {
359  T ret;
360  BinaryOperation<I>::fcn(x, y, ret);
361  return ret;
362  }
363  };
364 
366  template<casadi_int I>
369  template<typename T> static inline void derf(const T& x, const T& y, T& f, T* d) {
370 
374  T tmp;
375 
377  BinaryOperation<I>::fcn(x, y, tmp);
378 
380  BinaryOperation<I>::der(x, y, tmp, d);
381 
383  f = tmp;
384  }
385  };
386 
388  template<casadi_int I>
391  template<typename T> static inline void fcn(const T& x, const T& y, T& f, casadi_int n) {
392  BinaryOperation<I>::fcn(x, y, f);
393  }
394 
396  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d,
397  casadi_int n) {
398  BinaryOperation<I>::der(x, y, f, d);
399  }
400  };
401 
402 
404  template<casadi_int I>
407  template<typename T> static inline void fcn(const T* x, const T* y, T* f, casadi_int n) {
408  for (casadi_int i=0; i<n; ++i) {
409  BinaryOperation<I>::fcn(*x++, *y++, *f++);
410  }
411  }
412 
414  template<typename T> static inline void der(const T* x, const T* y,
415  const T* f, T* d, casadi_int n) {
416  for (casadi_int i=0; i<n; ++i, d+=2) {
417  BinaryOperation<I>::der(*x++, *y++, *f++, d);
418  }
419  }
420  };
421 
423  template<casadi_int I>
426  template<typename T> static inline void fcn(const T* x, const T& y, T* f, casadi_int n) {
427  for (casadi_int i=0; i<n; ++i) {
428  BinaryOperation<I>::fcn(*x++, y, *f++);
429  }
430  }
431 
433  template<typename T> static inline void der(const T* x, const T& y,
434  const T* f, T* d, casadi_int n) {
435  for (casadi_int i=0; i<n; ++i, d+=2) {
436  BinaryOperation<I>::der(*x++, y, *f++, d);
437  }
438  }
439  };
440 
442  template<casadi_int I>
445  template<typename T> static inline void fcn(const T& x, const T* y, T* f, casadi_int n) {
446  for (casadi_int i=0; i<n; ++i) {
447  BinaryOperation<I>::fcn(x, *y++, *f++);
448  }
449  }
450 
452  template<typename T> static inline void der(const T& x, const T* y,
453  const T* f, T* d, casadi_int n) {
454  for (casadi_int i=0; i<n; ++i, d+=2) {
455  BinaryOperation<I>::der(x, *y++, *f++, d);
456  }
457  }
458  };
459 
462  template<casadi_int I> struct SmoothChecker { static const bool check=true;};
463  template<> struct SmoothChecker<OP_LT>{ static const bool check=false;};
464  template<> struct SmoothChecker<OP_LE>{ static const bool check=false;};
465  template<> struct SmoothChecker<OP_FLOOR>{ static const bool check=false;};
466  template<> struct SmoothChecker<OP_CEIL>{ static const bool check=false;};
467  template<> struct SmoothChecker<OP_FMOD>{ static const bool check=false;};
468  template<> struct SmoothChecker<OP_REMAINDER>{ static const bool check=false;};
469  template<> struct SmoothChecker<OP_EQ>{ static const bool check=false;};
470  template<> struct SmoothChecker<OP_NE>{ static const bool check=false;};
471  template<> struct SmoothChecker<OP_SIGN>{ static const bool check=false;};
472  template<> struct SmoothChecker<OP_COPYSIGN>{ static const bool check=false;};
473  template<> struct SmoothChecker<OP_NOT>{ static const bool check=false;};
474  template<> struct SmoothChecker<OP_AND>{ static const bool check=false;};
475  template<> struct SmoothChecker<OP_OR>{ static const bool check=false;};
476  template<> struct SmoothChecker<OP_IF_ELSE_ZERO>{ static const bool check=false;};
478 
481  template<casadi_int I> struct F0XChecker { static const bool check=false;};
482  template<> struct F0XChecker<OP_ASSIGN>{ static const bool check=true;};
483  template<> struct F0XChecker<OP_MUL>{ static const bool check=true;};
484  template<> struct F0XChecker<OP_DIV>{ static const bool check=true;};
485  template<> struct F0XChecker<OP_NEG>{ static const bool check=true;};
486  template<> struct F0XChecker<OP_SQRT>{ static const bool check=true;};
487  template<> struct F0XChecker<OP_SQ>{ static const bool check=true;};
488  template<> struct F0XChecker<OP_TWICE>{ static const bool check=true;};
489  template<> struct F0XChecker<OP_SIN>{ static const bool check=true;};
490  template<> struct F0XChecker<OP_TAN>{ static const bool check=true;};
491  template<> struct F0XChecker<OP_ATAN>{ static const bool check=true;};
492  template<> struct F0XChecker<OP_ASIN>{ static const bool check=true;};
493  template<> struct F0XChecker<OP_FLOOR>{ static const bool check=true;};
494  template<> struct F0XChecker<OP_CEIL>{ static const bool check=true;};
495  template<> struct F0XChecker<OP_FMOD>{ static const bool check=true;};
496  template<> struct F0XChecker<OP_REMAINDER>{ static const bool check=true;};
497  template<> struct F0XChecker<OP_FABS>{ static const bool check=true;};
498  template<> struct F0XChecker<OP_SIGN>{ static const bool check=true;};
499  template<> struct F0XChecker<OP_COPYSIGN>{ static const bool check=true;};
500  template<> struct F0XChecker<OP_ERF>{ static const bool check=true;};
501  template<> struct F0XChecker<OP_SINH>{ static const bool check=true;};
502  template<> struct F0XChecker<OP_TANH>{ static const bool check=true;};
503  template<> struct F0XChecker<OP_ASINH>{ static const bool check=true;};
504  template<> struct F0XChecker<OP_ATANH>{ static const bool check=true;};
505  template<> struct F0XChecker<OP_ERFINV>{ static const bool check=true;};
506  template<> struct F0XChecker<OP_AND>{ static const bool check=true;};
507  template<> struct F0XChecker<OP_IF_ELSE_ZERO>{ static const bool check=true;};
508  template<> struct F0XChecker<OP_LOG1P>{ static const bool check=true;};
509  template<> struct F0XChecker<OP_EXPM1>{ static const bool check=true;};
511 
514  template<casadi_int I> struct FX0Checker { static const bool check=false;};
515  template<> struct FX0Checker<OP_MUL>{ static const bool check=true;};
516  template<> struct FX0Checker<OP_AND>{ static const bool check=true;};
517  template<> struct FX0Checker<OP_IF_ELSE_ZERO>{ static const bool check=true;};
519 
522  template<casadi_int I> struct F00Checker {
524  };
525  template<> struct F00Checker<OP_ADD>{ static const bool check=true;};
526  template<> struct F00Checker<OP_SUB>{ static const bool check=true;};
527  template<> struct F00Checker<OP_FMIN>{ static const bool check=true;};
528  template<> struct F00Checker<OP_FMAX>{ static const bool check=true;};
529  template<> struct F00Checker<OP_AND>{ static const bool check=true;};
530  template<> struct F00Checker<OP_OR>{ static const bool check=true;};
531  template<> struct F00Checker<OP_COPYSIGN>{ static const bool check=true;};
532  template<> struct F00Checker<OP_LT>{ static const bool check=true;};
533  template<> struct F00Checker<OP_HYPOT>{ static const bool check=true;};
535 
538  template<casadi_int I> struct CommChecker { static const bool check=false;};
539  template<> struct CommChecker<OP_ADD>{ static const bool check=true;};
540  template<> struct CommChecker<OP_MUL>{ static const bool check=true;};
541  template<> struct CommChecker<OP_EQ>{ static const bool check=true;};
542  template<> struct CommChecker<OP_NE>{ static const bool check=true;};
543  template<> struct CommChecker<OP_AND>{ static const bool check=true;};
544  template<> struct CommChecker<OP_OR>{ static const bool check=true;};
545  template<> struct CommChecker<OP_HYPOT>{ static const bool check=true;};
547 
550  template<casadi_int I> struct NonnegativeChecker { static const bool check=false;};
551  template<> struct NonnegativeChecker<OP_SQRT>{ static const bool check=true;};
552  template<> struct NonnegativeChecker<OP_SQ>{ static const bool check=true;};
553  template<> struct NonnegativeChecker<OP_EXP>{ static const bool check=true;};
554  template<> struct NonnegativeChecker<OP_LT>{ static const bool check=true;};
555  template<> struct NonnegativeChecker<OP_LE>{ static const bool check=true;};
556  template<> struct NonnegativeChecker<OP_EQ>{ static const bool check=true;};
557  template<> struct NonnegativeChecker<OP_NE>{ static const bool check=true;};
558  template<> struct NonnegativeChecker<OP_NOT>{ static const bool check=true;};
559  template<> struct NonnegativeChecker<OP_AND>{ static const bool check=true;};
560  template<> struct NonnegativeChecker<OP_OR>{ static const bool check=true;};
561  template<> struct NonnegativeChecker<OP_HYPOT>{ static const bool check=true;};
563 
566  template<casadi_int I> struct NargChecker { static const casadi_int check=1;};
567  template<> struct NargChecker<OP_ADD>{ static const casadi_int check=2;};
568  template<> struct NargChecker<OP_SUB>{ static const casadi_int check=2;};
569  template<> struct NargChecker<OP_MUL>{ static const casadi_int check=2;};
570  template<> struct NargChecker<OP_DIV>{ static const casadi_int check=2;};
571  template<> struct NargChecker<OP_POW>{ static const casadi_int check=2;};
572  template<> struct NargChecker<OP_CONSTPOW>{ static const casadi_int check=2;};
573  template<> struct NargChecker<OP_EQ>{ static const casadi_int check=2;};
574  template<> struct NargChecker<OP_NE>{ static const casadi_int check=2;};
575  template<> struct NargChecker<OP_AND>{ static const casadi_int check=2;};
576  template<> struct NargChecker<OP_OR>{ static const casadi_int check=2;};
577  template<> struct NargChecker<OP_FMIN>{ static const casadi_int check=2;};
578  template<> struct NargChecker<OP_FMAX>{ static const casadi_int check=2;};
579  template<> struct NargChecker<OP_PRINTME>{ static const casadi_int check=2;};
580  template<> struct NargChecker<OP_ATAN2>{ static const casadi_int check=2;};
581  template<> struct NargChecker<OP_IF_ELSE_ZERO>{ static const casadi_int check=2;};
582  template<> struct NargChecker<OP_FMOD>{ static const casadi_int check=2;};
583  template<> struct NargChecker<OP_REMAINDER>{ static const casadi_int check=2;};
584  template<> struct NargChecker<OP_COPYSIGN>{ static const casadi_int check=2;};
585  template<> struct NargChecker<OP_CONST>{ static const casadi_int check=0;};
586  template<> struct NargChecker<OP_PARAMETER>{ static const casadi_int check=0;};
587  template<> struct NargChecker<OP_INPUT>{ static const casadi_int check=0;};
588  template<> struct NargChecker<OP_HYPOT>{ static const casadi_int check=2;};
590 
592  template<>
594  public:
595  template<typename T> static inline void fcn(const T& x, T& f) { f = x;}
596  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = 1; }
597  };
598 
600  template<>
602  public:
603  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x+y;}
604  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
605  d[0]=d[1]=1;}
606  };
607 
609  template<>
611  public:
612  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x-y;}
613  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
614  d[0]=1; d[1]=-1;}
615  };
616 
618  template<>
620  public:
621  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x*y;}
622  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
623  d[0]=y; d[1]=x;}
624  };
625 
627  template<>
629  public:
630  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x/y;}
631  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
632  d[0]=1/y; d[1]=-f/y;}
633  };
634 
636  template<>
638  public:
639  template<typename T> static inline void fcn(const T& x, T& f) { f = -x;}
640  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0]=-1;}
641  };
642 
644  template<>
646  public:
647  template<typename T> static inline void fcn(const T& x, T& f) { f = exp(x);}
648  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0]=f;}
649  };
650 
652  template<>
654  public:
655  template<typename T> static inline void fcn(const T& x, T& f) { f = log(x);}
656  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0]=1/x;}
657  };
658 
660  template<>
662  public:
663  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = pow(x, y);}
664  // See issue #104 why d[0] is no longer y*f/x
665  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
666  d[0]=y*pow(x, y-1); d[1]=log(x)*f;}
667  };
668 
670  template<>
672  public:
673  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = pow(x, y);}
674  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
675  d[0]=y*pow(x, y-1); d[1]=0;}
676  };
677 
679  template<>
681  public:
682  template<typename T> static inline void fcn(const T& x, T& f) { f = sqrt(x);}
683  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0]=1/(twice(f));}
684  };
685 
687  template<>
689  public:
690  template<typename T> static inline void fcn(const T& x, T& f) { f = sq(x);}
691  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0]=twice(x);}
692  };
693 
695  template<>
697  template<typename T> static inline void fcn(const T& x, T& f) { f = 2.*x;}
698  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = 2; }
699  };
700 
702  template<>
704  public:
705  template<typename T> static inline void fcn(const T& x, T& f) { f = sin(x);}
706  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0]=cos(x);}
707  };
708 
710  template<>
712  public:
713  template<typename T> static inline void fcn(const T& x, T& f) { f = cos(x);}
714  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0]=-sin(x);}
715  };
716 
718  template<>
720  public:
721  template<typename T> static inline void fcn(const T& x, T& f) { f = tan(x);}
722  template<typename T> static inline void der(const T& x, const T& f, T* d)
723  { d[0] = 1/sq(cos(x));}
724  };
725 
727  template<>
729  public:
730  template<typename T> static inline void fcn(const T& x, T& f) { f = asin(x);}
731  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0]=1/sqrt(1-x*x);}
732  };
733 
735  template<>
737  public:
738  template<typename T> static inline void fcn(const T& x, T& f) { f = acos(x);}
739  template<typename T> static inline void der(const T& x, const T& f, T* d)
740  { d[0]=-1/sqrt(1-x*x);}
741  };
742 
744  template<>
746  public:
747  template<typename T> static inline void fcn(const T& x, T& f) { f = atan(x);}
748  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = 1/(1+x*x);}
749  };
750 
752  template<>
754  public:
755  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x < y;}
756  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
757  d[0]=d[1]=0;}
758  };
759 
761  template<>
763  public:
764  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x <= y;}
765  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
766  d[0]=d[1]=0;}
767  };
768 
770  template<>
772  public:
773  template<typename T> static inline void fcn(const T& x, T& f) { f = floor(x);}
774  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = 0;}
775  };
776 
778  template<>
780  public:
781  template<typename T> static inline void fcn(const T& x, T& f) { f = ceil(x);}
782  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = 0;}
783  };
784 
786  template<>
788  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = fmod(x, y);}
789  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
790  d[0]=1; d[1]=(f-x)/y;}
791  };
792 
794  template<>
796  template<typename T> static inline void fcn(const T& x, const T& y, T& f) {
797  f = remainder(x, y);}
798  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
799  d[0]=1; d[1]=(f-x)/y;}
800  };
801 
803  template<>
805  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x==y;}
806  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
807  d[0]=d[1]=0;}
808  };
809 
811  template<>
813  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x!=y;}
814  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
815  d[0]=d[1]=0;}
816  };
817 
819  template<>
821  public:
822  template<typename T> static inline void fcn(const T& x, T& f) { f = !x;}
823  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = 0;}
824  };
825 
827  template<>
829  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x && y;}
830  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
831  d[0]=d[1]=0;}
832  };
833 
835  template<>
837  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x || y;}
838  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
839  d[0]=d[1]=0;}
840  };
841 
843  template<>
845  template<typename T> static inline void fcn(const T& x, T& f) { f = erf(x);}
846  template<typename T> static inline void der(const T& x, const T& f, T* d) {
847  d[0] = (2/sqrt(pi))*exp(-x*x);}
848  };
849 
851  template<>
853  template<typename T> static inline void fcn(const T& x, T& f) { f = fabs(x);}
854  template<typename T> static inline void der(const T& x, const T& f, T* d) {
855  d[0]=sign(x);}
856  };
857 
859  template<>
861  template<typename T> static inline void fcn(const T& x, T& f) { f = sign(x);}
862  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0]=0;}
863  };
864 
866  template<>
868  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = copysign(x, y);}
869  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
870  T e = 1; d[0]=copysign(e, y); d[1]=0;}
871  };
872 
874  template<>
876  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = fmin(x, y);}
877  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
878  T a = x<=y;
879  T b = y<=x;
880  T c = a+b;
881  d[0]=a/c; d[1]=b/c;}
882  };
883 
885  template<>
887  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = fmax(x, y);}
888  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
889  T a = y<=x;
890  T b = x<=y;
891  T c = a+b;
892  d[0]=a/c; d[1]=b/c;}
893  };
894 
896  template<>
898  template<typename T> static inline void fcn(const T& x, T& f) { f = 1./x;}
899  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = -f*f; }
900  };
901 
903  template<>
905  template<typename T> static inline void fcn(const T& x, T& f) { f = sinh(x);}
906  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = cosh(x); }
907  };
908 
910  template<>
912  template<typename T> static inline void fcn(const T& x, T& f) { f = cosh(x);}
913  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = sinh(x); }
914  };
915 
917  template<>
919  template<typename T> static inline void fcn(const T& x, T& f) { f = tanh(x);}
920  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = 1-f*f; }
921  };
922 
924  template<>
926  template<typename T> static inline void fcn(const T& x, T& f) { f = asinh(x);}
927  template<typename T> static inline void der(const T& x, const T& f, T* d) {
928  d[0] = 1/sqrt(1+x*x); }
929  };
930 
932  template<>
934  template<typename T> static inline void fcn(const T& x, T& f) { f = acosh(x);}
935  template<typename T> static inline void der(const T& x, const T& f, T* d) {
936  d[0] = 1/sqrt(x-1)/sqrt(x+1); }
937  };
938 
940  template<>
942  template<typename T> static inline void fcn(const T& x, T& f) { f = atanh(x);}
943  template<typename T> static inline void der(const T& x, const T& f, T* d) { d[0] = 1/(1-x*x); }
944  };
945 
947  template<>
949  template<typename T> static inline void fcn(const T& x, T& f) { f = erfinv(x);}
950  template<typename T> static inline void der(const T& x, const T& f, T* d) {
951  d[0] = (sqrt(pi)/2)*exp(f*f); }
952  };
953 
955  template<>
957  template<typename T> static inline void fcn(const T& x, T& f) { f = log1p(x);}
958  template<typename T> static inline void der(const T& x, const T& f, T* d) {
959  d[0] = 1/(1+x);}
960  };
961 
963  template<>
965  template<typename T> static inline void fcn(const T& x, T& f) { f = expm1(x);}
966  template<typename T> static inline void der(const T& x, const T& f, T* d) {
967  d[0] = exp(x); }
968  };
969 
971  template<>
973  template<typename T> static inline void fcn(const T& x, const T& y, T& f) {f = printme(x, y); }
974  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
975  d[0]=1; d[1]=0;}
976  };
977 
979  template<>
981  public:
982  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = atan2(x, y);}
983  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
984  T t = x*x+y*y; d[0]=y/t; d[1]=-x/t;}
985  };
986 
988  template<>
990  public:
991  template<typename T> static inline void fcn(const T& x, const T& y, T& f) {
992  f = if_else_zero(x, y);}
993  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
994  d[0]=0; d[1]=x;}
995  };
996 
998  template<>
1000  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = x;}
1001  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
1002  d[0] = 1; d[1] = 0; }
1003  };
1004 
1006  template<>
1008  template<typename T> static inline void fcn(const T& x, const T& y, T& f) { f = hypot(x, y);}
1009  template<typename T> static inline void der(const T& x, const T& y, const T& f, T* d) {
1010  d[0] = x/f; d[1] = y/f; }
1011  };
1012 
1013  template<template<casadi_int> class F, typename T>
1014  T operation_getter(casadi_int op) {
1015  switch (static_cast<Operation>(op)) {
1016  case OP_ASSIGN: return F<OP_ASSIGN>::check;
1017  case OP_ADD: return F<OP_ADD>::check;
1018  case OP_SUB: return F<OP_SUB>::check;
1019  case OP_MUL: return F<OP_MUL>::check;
1020  case OP_DIV: return F<OP_DIV>::check;
1021  case OP_NEG: return F<OP_NEG>::check;
1022  case OP_EXP: return F<OP_EXP>::check;
1023  case OP_LOG: return F<OP_LOG>::check;
1024  case OP_POW: return F<OP_POW>::check;
1025  case OP_CONSTPOW: return F<OP_CONSTPOW>::check;
1026  case OP_SQRT: return F<OP_SQRT>::check;
1027  case OP_SQ: return F<OP_SQ>::check;
1028  case OP_TWICE: return F<OP_TWICE>::check;
1029  case OP_SIN: return F<OP_SIN>::check;
1030  case OP_COS: return F<OP_COS>::check;
1031  case OP_TAN: return F<OP_TAN>::check;
1032  case OP_ASIN: return F<OP_ASIN>::check;
1033  case OP_ACOS: return F<OP_ACOS>::check;
1034  case OP_ATAN: return F<OP_ATAN>::check;
1035  case OP_LT: return F<OP_LT>::check;
1036  case OP_LE: return F<OP_LE>::check;
1037  case OP_EQ: return F<OP_EQ>::check;
1038  case OP_NE: return F<OP_NE>::check;
1039  case OP_NOT: return F<OP_NOT>::check;
1040  case OP_AND: return F<OP_AND>::check;
1041  case OP_OR: return F<OP_OR>::check;
1042  case OP_FLOOR: return F<OP_FLOOR>::check;
1043  case OP_CEIL: return F<OP_CEIL>::check;
1044  case OP_FMOD: return F<OP_FMOD>::check;
1045  case OP_REMAINDER: return F<OP_REMAINDER>::check;
1046  case OP_FABS: return F<OP_FABS>::check;
1047  case OP_SIGN: return F<OP_SIGN>::check;
1048  case OP_COPYSIGN: return F<OP_COPYSIGN>::check;
1049  case OP_IF_ELSE_ZERO: return F<OP_IF_ELSE_ZERO>::check;
1050  case OP_ERF: return F<OP_ERF>::check;
1051  case OP_FMIN: return F<OP_FMIN>::check;
1052  case OP_FMAX: return F<OP_FMAX>::check;
1053  case OP_INV: return F<OP_INV>::check;
1054  case OP_SINH: return F<OP_SINH>::check;
1055  case OP_COSH: return F<OP_COSH>::check;
1056  case OP_TANH: return F<OP_TANH>::check;
1057  case OP_ASINH: return F<OP_ASINH>::check;
1058  case OP_ACOSH: return F<OP_ACOSH>::check;
1059  case OP_ATANH: return F<OP_ATANH>::check;
1060  case OP_ATAN2: return F<OP_ATAN2>::check;
1061  case OP_CONST: return F<OP_CONST>::check;
1062  case OP_INPUT: return F<OP_INPUT>::check;
1063  case OP_OUTPUT: return F<OP_OUTPUT>::check;
1064  case OP_PARAMETER: return F<OP_PARAMETER>::check;
1065  case OP_CALL: return F<OP_CALL>::check;
1066  case OP_FIND: return F<OP_FIND>::check;
1067  case OP_LOW: return F<OP_LOW>::check;
1068  case OP_MAP: return F<OP_MAP>::check;
1069  case OP_MTIMES: return F<OP_MTIMES>::check;
1070  case OP_SOLVE: return F<OP_SOLVE>::check;
1071  case OP_TRANSPOSE: return F<OP_TRANSPOSE>::check;
1072  case OP_DETERMINANT: return F<OP_DETERMINANT>::check;
1073  case OP_INVERSE: return F<OP_INVERSE>::check;
1074  case OP_DOT: return F<OP_DOT>::check;
1075  case OP_BILIN: return F<OP_BILIN>::check;
1076  case OP_RANK1: return F<OP_RANK1>::check;
1077  case OP_HORZCAT: return F<OP_HORZCAT>::check;
1078  case OP_VERTCAT: return F<OP_VERTCAT>::check;
1079  case OP_DIAGCAT: return F<OP_DIAGCAT>::check;
1080  case OP_HORZSPLIT: return F<OP_HORZSPLIT>::check;
1081  case OP_VERTSPLIT: return F<OP_VERTSPLIT>::check;
1082  case OP_DIAGSPLIT: return F<OP_DIAGSPLIT>::check;
1083  case OP_RESHAPE: return F<OP_RESHAPE>::check;
1084  case OP_SPARSITY_CAST: return F<OP_SPARSITY_CAST>::check;
1085  case OP_SUBREF: return F<OP_SUBREF>::check;
1086  case OP_SUBASSIGN: return F<OP_SUBASSIGN>::check;
1087  case OP_GETNONZEROS: return F<OP_GETNONZEROS>::check;
1088  case OP_GETNONZEROS_PARAM: return F<OP_GETNONZEROS_PARAM>::check;
1089  case OP_ADDNONZEROS: return F<OP_ADDNONZEROS>::check;
1090  case OP_ADDNONZEROS_PARAM: return F<OP_ADDNONZEROS>::check;
1091  case OP_SETNONZEROS: return F<OP_SETNONZEROS>::check;
1092  case OP_SETNONZEROS_PARAM: return F<OP_SETNONZEROS>::check;
1093  case OP_PROJECT: return F<OP_PROJECT>::check;
1094  case OP_ASSERTION: return F<OP_ASSERTION>::check;
1095  case OP_MONITOR: return F<OP_MONITOR>::check;
1096  case OP_NORM2: return F<OP_NORM2>::check;
1097  case OP_NORM1: return F<OP_NORM1>::check;
1098  case OP_NORMINF: return F<OP_NORMINF>::check;
1099  case OP_NORMF: return F<OP_NORMF>::check;
1100  case OP_MMIN: return F<OP_MMIN>::check;
1101  case OP_MMAX: return F<OP_MMAX>::check;
1102  case OP_HORZREPMAT: return F<OP_HORZREPMAT>::check;
1103  case OP_HORZREPSUM: return F<OP_HORZREPSUM>::check;
1104  case OP_ERFINV: return F<OP_ERFINV>::check;
1105  case OP_PRINTME: return F<OP_PRINTME>::check;
1106  case OP_LIFT: return F<OP_LIFT>::check;
1107  case OP_EINSTEIN: return F<OP_EINSTEIN>::check;
1108  case OP_BSPLINE: return F<OP_BSPLINE>::check;
1109  case OP_CONVEXIFY: return F<OP_CONVEXIFY>::check;
1110  case OP_LOG1P: return F<OP_LOG1P>::check;
1111  case OP_EXPM1: return F<OP_EXPM1>::check;
1112  case OP_HYPOT: return F<OP_HYPOT>::check;
1113  case OP_LOGSUMEXP: return F<OP_LOGSUMEXP>::check;
1114  }
1115  return T();
1116  }
1117 
1118  template<template<casadi_int> class F>
1119  bool operation_checker(casadi_int op) {
1120  return operation_getter<F, bool>(op);
1121  }
1122 
1124  template<typename T>
1125  struct casadi_math {
1126 
1130  static inline void fun(unsigned char op, const T& x, const T& y, T& f);
1131 
1135  static inline void fun(unsigned char op, const T* x, const T* y, T* f, casadi_int n);
1136 
1140  static inline void fun(unsigned char op, const T* x, const T& y, T* f, casadi_int n);
1141 
1145  static inline void fun(unsigned char op, const T& x, const T* y, T* f, casadi_int n);
1146 
1150  static inline void der(unsigned char op, const T& x, const T& y, const T& f, T* d);
1151 
1155  static inline void derF(unsigned char op, const T& x, const T& y, T& f, T* d);
1156 
1160  static inline void fun_linear(unsigned char op, const T*x, const T* y, T* f);
1161 
1165  static inline bool is_binary(unsigned char op);
1166 
1170  static inline bool is_unary(unsigned char op);
1171 
1175  static inline casadi_int ndeps(unsigned char op);
1176 
1180  static inline std::string print(unsigned char op, const std::string& x,
1181  const std::string& y);
1182  static inline std::string print(unsigned char op, const std::string& x);
1183  static inline std::string name(unsigned char op);
1184  static inline std::string pre(unsigned char op);
1185  static inline std::string sep(unsigned char op);
1186  static inline std::string post(unsigned char op);
1187  };
1188 
1190  template<>
1191  struct casadi_math<casadi_int>{
1192 
1196  static inline void fun(unsigned char op, const casadi_int& x,
1197  const casadi_int& y, casadi_int& f) {
1198  double ff(0);
1199  casadi_math<double>::fun(op, static_cast<double>(x), static_cast<double>(y), ff);
1200  f = static_cast<casadi_int>(ff);
1201  }
1202 
1203  static inline void fun(unsigned char op, const casadi_int* x, const casadi_int* y,
1204  casadi_int* f, casadi_int n) {
1205  for (casadi_int i=0; i<n; ++i) {
1206  double ff(0);
1207  casadi_math<double>::fun(op, static_cast<double>(*x++), static_cast<double>(*y++), ff);
1208  *f++ = static_cast<casadi_int>(ff);
1209  }
1210  }
1211 
1212  static inline void fun(unsigned char op, const casadi_int* x, const casadi_int& y,
1213  casadi_int* f, casadi_int n) {
1214  for (casadi_int i=0; i<n; ++i) {
1215  double ff;
1216  casadi_math<double>::fun(op, static_cast<double>(*x++), static_cast<double>(y), ff);
1217  *f++ = static_cast<casadi_int>(ff);
1218  }
1219  }
1220 
1221  static inline void fun(unsigned char op, const casadi_int& x, const casadi_int* y,
1222  casadi_int* f, casadi_int n) {
1223  for (casadi_int i=0; i<n; ++i) {
1224  double ff;
1225  casadi_math<double>::fun(op, static_cast<double>(x), static_cast<double>(*y++), ff);
1226  *f++ = static_cast<casadi_int>(ff);
1227  }
1228  }
1229 
1233  static inline void der(unsigned char op, const casadi_int& x, const casadi_int& y,
1234  const casadi_int& f, casadi_int* d) {
1235  double d_real[2] = {static_cast<double>(d[0]), static_cast<double>(d[1])};
1236  casadi_math<double>::der(op, static_cast<double>(x), static_cast<double>(y),
1237  static_cast<double>(f), d_real);
1238  d[0] = static_cast<casadi_int>(d_real[0]);
1239  d[1] = static_cast<casadi_int>(d_real[1]);
1240  }
1241 
1245  static inline void derF(unsigned char op, const casadi_int& x, const casadi_int& y,
1246  casadi_int& f, casadi_int* d) {
1247  double d_real[2] = {static_cast<double>(d[0]), static_cast<double>(d[1])};
1248  double f_real = static_cast<double>(f);
1249  casadi_math<double>::derF(op, static_cast<double>(x), static_cast<double>(y), f_real, d_real);
1250  f = static_cast<casadi_int>(f_real);
1251  d[0] = static_cast<casadi_int>(d_real[0]);
1252  d[1] = static_cast<casadi_int>(d_real[1]);
1253  }
1254 
1258  static inline casadi_int ndeps(unsigned char op) {
1259  return casadi_math<double>::ndeps(op);
1260  }
1261 
1265  static inline std::string print(unsigned char op, const std::string& x,
1266  const std::string& y) {
1267  return casadi_math<double>::print(op, x, y);
1268  }
1269  static inline std::string print(unsigned char op, const std::string& x) {
1270  return casadi_math<double>::print(op, x);
1271  }
1272  static inline std::string pre(unsigned char op) {
1273  return casadi_math<double>::pre(op);
1274  }
1275  static inline std::string name(unsigned char op) {
1276  return casadi_math<double>::name(op);
1277  }
1278  static inline std::string sep(unsigned char op) {
1279  return casadi_math<double>::sep(op);
1280  }
1281  static inline std::string post(unsigned char op) {
1282  return casadi_math<double>::post(op);
1283  }
1284  };
1285 
1286  // Template implementations
1287 
1288  template<typename T>
1289  inline void casadi_math<T>::fun(unsigned char op, const T& x, const T& y, T& f) {
1290  // NOTE: We define the implementation in a preprocessor macro to be able to force inlining,
1291  // and to allow extensions in the VM
1292 #define CASADI_MATH_FUN_BUILTIN_GEN(CNAME, X, Y, F, N) \
1293  case OP_ASSIGN: CNAME<OP_ASSIGN>::fcn(X, Y, F, N); break; \
1294  case OP_ADD: CNAME<OP_ADD>::fcn(X, Y, F, N); break; \
1295  case OP_SUB: CNAME<OP_SUB>::fcn(X, Y, F, N); break; \
1296  case OP_MUL: CNAME<OP_MUL>::fcn(X, Y, F, N); break; \
1297  case OP_DIV: CNAME<OP_DIV>::fcn(X, Y, F, N); break; \
1298  case OP_NEG: CNAME<OP_NEG>::fcn(X, Y, F, N); break; \
1299  case OP_EXP: CNAME<OP_EXP>::fcn(X, Y, F, N); break; \
1300  case OP_LOG: CNAME<OP_LOG>::fcn(X, Y, F, N); break; \
1301  case OP_POW: CNAME<OP_POW>::fcn(X, Y, F, N); break; \
1302  case OP_CONSTPOW: CNAME<OP_CONSTPOW>::fcn(X, Y, F, N); break; \
1303  case OP_SQRT: CNAME<OP_SQRT>::fcn(X, Y, F, N); break; \
1304  case OP_SQ: CNAME<OP_SQ>::fcn(X, Y, F, N); break; \
1305  case OP_TWICE: CNAME<OP_TWICE>::fcn(X, Y, F, N); break; \
1306  case OP_SIN: CNAME<OP_SIN>::fcn(X, Y, F, N); break; \
1307  case OP_COS: CNAME<OP_COS>::fcn(X, Y, F, N); break; \
1308  case OP_TAN: CNAME<OP_TAN>::fcn(X, Y, F, N); break; \
1309  case OP_ASIN: CNAME<OP_ASIN>::fcn(X, Y, F, N); break; \
1310  case OP_ACOS: CNAME<OP_ACOS>::fcn(X, Y, F, N); break; \
1311  case OP_ATAN: CNAME<OP_ATAN>::fcn(X, Y, F, N); break; \
1312  case OP_LT: CNAME<OP_LT>::fcn(X, Y, F, N); break; \
1313  case OP_LE: CNAME<OP_LE>::fcn(X, Y, F, N); break; \
1314  case OP_EQ: CNAME<OP_EQ>::fcn(X, Y, F, N); break; \
1315  case OP_NE: CNAME<OP_NE>::fcn(X, Y, F, N); break; \
1316  case OP_NOT: CNAME<OP_NOT>::fcn(X, Y, F, N); break; \
1317  case OP_AND: CNAME<OP_AND>::fcn(X, Y, F, N); break; \
1318  case OP_OR: CNAME<OP_OR>::fcn(X, Y, F, N); break; \
1319  case OP_IF_ELSE_ZERO: CNAME<OP_IF_ELSE_ZERO>::fcn(X, Y, F, N); break; \
1320  case OP_FLOOR: CNAME<OP_FLOOR>::fcn(X, Y, F, N); break; \
1321  case OP_CEIL: CNAME<OP_CEIL>::fcn(X, Y, F, N); break; \
1322  case OP_FMOD: CNAME<OP_FMOD>::fcn(X, Y, F, N); break; \
1323  case OP_REMAINDER: CNAME<OP_REMAINDER>::fcn(X, Y, F, N); break; \
1324  case OP_FABS: CNAME<OP_FABS>::fcn(X, Y, F, N); break; \
1325  case OP_SIGN: CNAME<OP_SIGN>::fcn(X, Y, F, N); break; \
1326  case OP_COPYSIGN: CNAME<OP_COPYSIGN>::fcn(X, Y, F, N); break; \
1327  case OP_ERF: CNAME<OP_ERF>::fcn(X, Y, F, N); break; \
1328  case OP_FMIN: CNAME<OP_FMIN>::fcn(X, Y, F, N); break; \
1329  case OP_FMAX: CNAME<OP_FMAX>::fcn(X, Y, F, N); break; \
1330  case OP_INV: CNAME<OP_INV>::fcn(X, Y, F, N); break; \
1331  case OP_SINH: CNAME<OP_SINH>::fcn(X, Y, F, N); break; \
1332  case OP_COSH: CNAME<OP_COSH>::fcn(X, Y, F, N); break; \
1333  case OP_TANH: CNAME<OP_TANH>::fcn(X, Y, F, N); break; \
1334  case OP_ASINH: CNAME<OP_ASINH>::fcn(X, Y, F, N); break; \
1335  case OP_ACOSH: CNAME<OP_ACOSH>::fcn(X, Y, F, N); break; \
1336  case OP_ATANH: CNAME<OP_ATANH>::fcn(X, Y, F, N); break; \
1337  case OP_ATAN2: CNAME<OP_ATAN2>::fcn(X, Y, F, N); break; \
1338  case OP_ERFINV: CNAME<OP_ERFINV>::fcn(X, Y, F, N); break; \
1339  case OP_LIFT: CNAME<OP_LIFT>::fcn(X, Y, F, N); break; \
1340  case OP_PRINTME: CNAME<OP_PRINTME>::fcn(X, Y, F, N); break; \
1341  case OP_LOG1P: CNAME<OP_LOG1P>::fcn(X, Y, F, N); break; \
1342  case OP_EXPM1: CNAME<OP_EXPM1>::fcn(X, Y, F, N); break; \
1343  case OP_HYPOT: CNAME<OP_HYPOT>::fcn(X, Y, F, N); break;
1344 
1345 #define CASADI_MATH_FUN_BUILTIN(X, Y, F) CASADI_MATH_FUN_BUILTIN_GEN(BinaryOperationSS, X, Y, F, 1)
1346 
1347  switch (op) {
1348  CASADI_MATH_FUN_BUILTIN(x, y, f)
1349  }
1350  }
1351 
1352  template<typename T>
1353  inline void casadi_math<T>::fun(unsigned char op, const T* x, const T* y, T* f, casadi_int n) {
1354  switch (op) {
1355  CASADI_MATH_FUN_BUILTIN_GEN(BinaryOperationVV, x, y, f, n)
1356  }
1357  }
1358 
1359  template<typename T>
1360  inline void casadi_math<T>::fun(unsigned char op, const T* x, const T& y, T* f, casadi_int n) {
1361  switch (op) {
1362  CASADI_MATH_FUN_BUILTIN_GEN(BinaryOperationVS, x, y, f, n)
1363  }
1364  }
1365 
1366  template<typename T>
1367  inline void casadi_math<T>::fun(unsigned char op, const T& x, const T* y, T* f, casadi_int n) {
1368  switch (op) {
1369  CASADI_MATH_FUN_BUILTIN_GEN(BinaryOperationSV, x, y, f, n)
1370  }
1371  }
1372 
1373 
1374  template<typename T>
1375  inline void casadi_math<T>::der(unsigned char op, const T& x, const T& y, const T& f, T* d) {
1376  // NOTE: We define the implementation in a preprocessor macro to be able to force inlining,
1377  // and to allow extensions in the VM
1378 #define CASADI_MATH_DER_BUILTIN(X, Y, F, D) \
1379  case OP_ASSIGN: BinaryOperation<OP_ASSIGN>::der(X, Y, F, D); break; \
1380  case OP_ADD: BinaryOperation<OP_ADD>::der(X, Y, F, D); break; \
1381  case OP_SUB: BinaryOperation<OP_SUB>::der(X, Y, F, D); break; \
1382  case OP_MUL: BinaryOperation<OP_MUL>::der(X, Y, F, D); break; \
1383  case OP_DIV: BinaryOperation<OP_DIV>::der(X, Y, F, D); break; \
1384  case OP_NEG: BinaryOperation<OP_NEG>::der(X, Y, F, D); break; \
1385  case OP_EXP: BinaryOperation<OP_EXP>::der(X, Y, F, D); break; \
1386  case OP_LOG: BinaryOperation<OP_LOG>::der(X, Y, F, D); break; \
1387  case OP_POW: BinaryOperation<OP_POW>::der(X, Y, F, D); break; \
1388  case OP_CONSTPOW: BinaryOperation<OP_CONSTPOW>::der(X, Y, F, D); break; \
1389  case OP_SQRT: BinaryOperation<OP_SQRT>::der(X, Y, F, D); break; \
1390  case OP_SQ: BinaryOperation<OP_SQ>::der(X, Y, F, D); break; \
1391  case OP_TWICE: BinaryOperation<OP_TWICE>::der(X, Y, F, D); break; \
1392  case OP_SIN: BinaryOperation<OP_SIN>::der(X, Y, F, D); break; \
1393  case OP_COS: BinaryOperation<OP_COS>::der(X, Y, F, D); break; \
1394  case OP_TAN: BinaryOperation<OP_TAN>::der(X, Y, F, D); break; \
1395  case OP_ASIN: BinaryOperation<OP_ASIN>::der(X, Y, F, D); break; \
1396  case OP_ACOS: BinaryOperation<OP_ACOS>::der(X, Y, F, D); break; \
1397  case OP_ATAN: BinaryOperation<OP_ATAN>::der(X, Y, F, D); break; \
1398  case OP_LT: BinaryOperation<OP_LT>::der(X, Y, F, D); break; \
1399  case OP_LE: BinaryOperation<OP_LE>::der(X, Y, F, D); break; \
1400  case OP_EQ: BinaryOperation<OP_EQ>::der(X, Y, F, D); break; \
1401  case OP_NE: BinaryOperation<OP_NE>::der(X, Y, F, D); break; \
1402  case OP_NOT: BinaryOperation<OP_NOT>::der(X, Y, F, D); break; \
1403  case OP_AND: BinaryOperation<OP_AND>::der(X, Y, F, D); break; \
1404  case OP_OR: BinaryOperation<OP_OR>::der(X, Y, F, D); break; \
1405  case OP_IF_ELSE_ZERO: BinaryOperation<OP_IF_ELSE_ZERO>::der(X, Y, F, D); break; \
1406  case OP_FLOOR: BinaryOperation<OP_FLOOR>::der(X, Y, F, D); break; \
1407  case OP_CEIL: BinaryOperation<OP_CEIL>::der(X, Y, F, D); break; \
1408  case OP_FMOD: BinaryOperation<OP_FMOD>::der(X, Y, F, D); break; \
1409  case OP_REMAINDER: BinaryOperation<OP_REMAINDER>::der(X, Y, F, D); break; \
1410  case OP_FABS: BinaryOperation<OP_FABS>::der(X, Y, F, D); break; \
1411  case OP_SIGN: BinaryOperation<OP_SIGN>::der(X, Y, F, D); break; \
1412  case OP_COPYSIGN: BinaryOperation<OP_COPYSIGN>::der(X, Y, F, D); break; \
1413  case OP_ERF: BinaryOperation<OP_ERF>::der(X, Y, F, D); break; \
1414  case OP_FMIN: BinaryOperation<OP_FMIN>::der(X, Y, F, D); break; \
1415  case OP_FMAX: BinaryOperation<OP_FMAX>::der(X, Y, F, D); break; \
1416  case OP_INV: BinaryOperation<OP_INV>::der(X, Y, F, D); break; \
1417  case OP_SINH: BinaryOperation<OP_SINH>::der(X, Y, F, D); break; \
1418  case OP_COSH: BinaryOperation<OP_COSH>::der(X, Y, F, D); break; \
1419  case OP_TANH: BinaryOperation<OP_TANH>::der(X, Y, F, D); break; \
1420  case OP_ASINH: BinaryOperation<OP_ASINH>::der(X, Y, F, D); break; \
1421  case OP_ACOSH: BinaryOperation<OP_ACOSH>::der(X, Y, F, D); break; \
1422  case OP_ATANH: BinaryOperation<OP_ATANH>::der(X, Y, F, D); break; \
1423  case OP_ATAN2: BinaryOperation<OP_ATAN2>::der(X, Y, F, D); break; \
1424  case OP_ERFINV: BinaryOperation<OP_ERFINV>::der(X, Y, F, D); break; \
1425  case OP_LIFT: BinaryOperation<OP_LIFT>::der(X, Y, F, D); break; \
1426  case OP_PRINTME: BinaryOperation<OP_PRINTME>::der(X, Y, F, D); break; \
1427  case OP_LOG1P: BinaryOperation<OP_LOG1P>::der(X, Y, F, D); break; \
1428  case OP_EXPM1: BinaryOperation<OP_EXPM1>::der(X, Y, F, D); break; \
1429  case OP_HYPOT: BinaryOperation<OP_HYPOT>::der(X, Y, F, D); break;
1430  switch (op) {
1431  CASADI_MATH_DER_BUILTIN(x, y, f, d)
1432  }
1433  }
1434 
1435 
1436  template<typename T>
1437  inline void casadi_math<T>::derF(unsigned char op, const T& x, const T& y, T& f, T* d) {
1438  // NOTE: We define the implementation in a preprocessor macro to be able to force inlining,
1439  // and to allow extensions in the VM
1440 #define CASADI_MATH_DERF_BUILTIN(X, Y, F, D) \
1441 case OP_ASSIGN: DerBinaryOperation<OP_ASSIGN>::derf(X, Y, F, D); break; \
1442 case OP_ADD: DerBinaryOperation<OP_ADD>::derf(X, Y, F, D); break; \
1443 case OP_SUB: DerBinaryOperation<OP_SUB>::derf(X, Y, F, D); break; \
1444 case OP_MUL: DerBinaryOperation<OP_MUL>::derf(X, Y, F, D); break; \
1445 case OP_DIV: DerBinaryOperation<OP_DIV>::derf(X, Y, F, D); break; \
1446 case OP_NEG: DerBinaryOperation<OP_NEG>::derf(X, Y, F, D); break; \
1447 case OP_EXP: DerBinaryOperation<OP_EXP>::derf(X, Y, F, D); break; \
1448 case OP_LOG: DerBinaryOperation<OP_LOG>::derf(X, Y, F, D); break; \
1449 case OP_POW: DerBinaryOperation<OP_POW>::derf(X, Y, F, D); break; \
1450 case OP_CONSTPOW: DerBinaryOperation<OP_CONSTPOW>::derf(X, Y, F, D); break; \
1451 case OP_SQRT: DerBinaryOperation<OP_SQRT>::derf(X, Y, F, D); break; \
1452 case OP_SQ: DerBinaryOperation<OP_SQ>::derf(X, Y, F, D); break; \
1453 case OP_TWICE: DerBinaryOperation<OP_TWICE>::derf(X, Y, F, D); break; \
1454 case OP_SIN: DerBinaryOperation<OP_SIN>::derf(X, Y, F, D); break; \
1455 case OP_COS: DerBinaryOperation<OP_COS>::derf(X, Y, F, D); break; \
1456 case OP_TAN: DerBinaryOperation<OP_TAN>::derf(X, Y, F, D); break; \
1457 case OP_ASIN: DerBinaryOperation<OP_ASIN>::derf(X, Y, F, D); break; \
1458 case OP_ACOS: DerBinaryOperation<OP_ACOS>::derf(X, Y, F, D); break; \
1459 case OP_ATAN: DerBinaryOperation<OP_ATAN>::derf(X, Y, F, D); break; \
1460 case OP_LT: DerBinaryOperation<OP_LT>::derf(X, Y, F, D); break; \
1461 case OP_LE: DerBinaryOperation<OP_LE>::derf(X, Y, F, D); break; \
1462 case OP_EQ: DerBinaryOperation<OP_EQ>::derf(X, Y, F, D); break; \
1463 case OP_NE: DerBinaryOperation<OP_NE>::derf(X, Y, F, D); break; \
1464 case OP_NOT: DerBinaryOperation<OP_NOT>::derf(X, Y, F, D); break; \
1465 case OP_AND: DerBinaryOperation<OP_AND>::derf(X, Y, F, D); break; \
1466 case OP_OR: DerBinaryOperation<OP_OR>::derf(X, Y, F, D); break; \
1467 case OP_IF_ELSE_ZERO: DerBinaryOperation<OP_IF_ELSE_ZERO>::derf(X, Y, F, D); break; \
1468 case OP_FLOOR: DerBinaryOperation<OP_FLOOR>::derf(X, Y, F, D); break; \
1469 case OP_CEIL: DerBinaryOperation<OP_CEIL>::derf(X, Y, F, D); break; \
1470 case OP_FMOD: DerBinaryOperation<OP_FMOD>::derf(X, Y, F, D); break; \
1471 case OP_REMAINDER: DerBinaryOperation<OP_REMAINDER>::derf(X, Y, F, D); break; \
1472 case OP_FABS: DerBinaryOperation<OP_FABS>::derf(X, Y, F, D); break; \
1473 case OP_SIGN: DerBinaryOperation<OP_SIGN>::derf(X, Y, F, D); break; \
1474 case OP_COPYSIGN: DerBinaryOperation<OP_COPYSIGN>::derf(X, Y, F, D); break; \
1475 case OP_ERF: DerBinaryOperation<OP_ERF>::derf(X, Y, F, D); break; \
1476 case OP_FMIN: DerBinaryOperation<OP_FMIN>::derf(X, Y, F, D); break; \
1477 case OP_FMAX: DerBinaryOperation<OP_FMAX>::derf(X, Y, F, D); break; \
1478 case OP_INV: DerBinaryOperation<OP_INV>::derf(X, Y, F, D); break; \
1479 case OP_SINH: DerBinaryOperation<OP_SINH>::derf(X, Y, F, D); break; \
1480 case OP_COSH: DerBinaryOperation<OP_COSH>::derf(X, Y, F, D); break; \
1481 case OP_TANH: DerBinaryOperation<OP_TANH>::derf(X, Y, F, D); break; \
1482 case OP_ASINH: DerBinaryOperation<OP_ASINH>::derf(X, Y, F, D); break; \
1483 case OP_ACOSH: DerBinaryOperation<OP_ACOSH>::derf(X, Y, F, D); break; \
1484 case OP_ATANH: DerBinaryOperation<OP_ATANH>::derf(X, Y, F, D); break; \
1485 case OP_ATAN2: DerBinaryOperation<OP_ATAN2>::derf(X, Y, F, D); break; \
1486 case OP_ERFINV: DerBinaryOperation<OP_ERFINV>::derf(X, Y, F, D); break; \
1487 case OP_LIFT: DerBinaryOperation<OP_LIFT>::derf(X, Y, F, D); break; \
1488 case OP_PRINTME: DerBinaryOperation<OP_PRINTME>::derf(X, Y, F, D); break; \
1489 case OP_LOG1P: DerBinaryOperation<OP_LOG1P>::derf(X, Y, F, D); break; \
1490 case OP_EXPM1: DerBinaryOperation<OP_EXPM1>::derf(X, Y, F, D); break; \
1491 case OP_HYPOT: DerBinaryOperation<OP_HYPOT>::derf(X, Y, F, D); break;
1492  switch (op) {
1493  CASADI_MATH_DERF_BUILTIN(x, y, f, d)
1494  }
1495  }
1496 
1497  #define CASADI_MATH_BINARY_BUILTIN \
1498  case OP_ADD: \
1499  case OP_SUB: \
1500  case OP_MUL: \
1501  case OP_DIV: \
1502  case OP_POW: \
1503  case OP_CONSTPOW: \
1504  case OP_LT: \
1505  case OP_LE: \
1506  case OP_EQ: \
1507  case OP_NE: \
1508  case OP_AND: \
1509  case OP_OR: \
1510  case OP_COPYSIGN: \
1511  case OP_FMOD: \
1512  case OP_REMAINDER: \
1513  case OP_FMIN: \
1514  case OP_FMAX: \
1515  case OP_ATAN2: \
1516  case OP_PRINTME: \
1517  case OP_LIFT: \
1518  case OP_HYPOT:
1519 
1520  #define CASADI_MATH_UNARY_BUILTIN \
1521  case OP_ASSIGN: \
1522  case OP_NEG: \
1523  case OP_EXP: \
1524  case OP_LOG: \
1525  case OP_SQRT: \
1526  case OP_SQ: \
1527  case OP_TWICE: \
1528  case OP_SIN: \
1529  case OP_COS: \
1530  case OP_TAN: \
1531  case OP_ASIN: \
1532  case OP_ACOS: \
1533  case OP_ATAN: \
1534  case OP_FLOOR: \
1535  case OP_CEIL: \
1536  case OP_NOT: \
1537  case OP_ERF: \
1538  case OP_FABS: \
1539  case OP_SIGN: \
1540  case OP_INV: \
1541  case OP_SINH: \
1542  case OP_COSH: \
1543  case OP_TANH: \
1544  case OP_ASINH: \
1545  case OP_ACOSH: \
1546  case OP_ATANH: \
1547  case OP_ERFINV: \
1548  case OP_LOG1P: \
1549  case OP_EXPM1:
1550 
1551  template<typename T>
1552  inline void casadi_math<T>::fun_linear(unsigned char op, const T* x, const T* y, T* f) {
1553  if (op==OP_ADD || op==OP_SUB) {
1554  for (int i=0;i<3;++i) {
1555  f[i] = T::binary(op, x[i], y[i]);
1556  }
1557  } else if (op==OP_TWICE || op==OP_NEG) {
1558  for (int i=0;i<3;++i) {
1559  f[i] = T::unary(op, x[i]);
1560  }
1561  } else if (op==OP_MUL) {
1562  f[0] += x[0]*y[0];
1563  f[1] += x[0]*y[1];
1564  f[2] += x[0]*y[2];
1565  f[1] += x[1]*y[0];
1566  f[2] += x[1]*y[1];
1567  f[2] += x[1]*y[2];
1568  f[2] += x[2]*y[0];
1569  f[2] += x[2]*y[1];
1570  f[2] += x[2]*y[2];
1571  } else if (op==OP_DIV) {
1572  bool const_argy = y[1].is_zero() && y[2].is_zero();
1573  if (const_argy) {
1574  f[0] = x[0]/y[0];
1575  f[1] = x[1]/y[0];
1576  f[2] = x[2]/y[0];
1577  } else {
1578  f[2] = (x[0]+x[1]+x[2])/(y[0]+y[1]+y[2]);
1579  }
1580  } else if (casadi_math<T>::is_unary(op)) {
1581  bool const_arg = x[1].is_zero() && x[2].is_zero();
1582  if (const_arg) {
1583  f[0] = T::unary(op, x[0]);
1584  } else {
1585  f[2] = T::unary(op, x[0]+x[1]+x[2]);
1586  }
1587 
1588  } else if (casadi_math<T>::is_binary(op)) {
1589  bool const_argx = x[1].is_zero() && x[2].is_zero();
1590  bool const_argy = y[1].is_zero() && y[2].is_zero();
1591  if (const_argx && const_argy) {
1592  f[0] = T::binary(op, x[0], y[0]);
1593  } else {
1594  f[2] = T::binary(op, x[0]+x[1]+x[2], y[0]+y[1]+y[2]);
1595  }
1596  } else {
1597  casadi_error("Not implemented");
1598  }
1599  }
1600 
1601  template<typename T>
1602  bool casadi_math<T>::is_binary(unsigned char op) {
1603  switch (op) {
1604  CASADI_MATH_BINARY_BUILTIN
1605  case OP_IF_ELSE_ZERO:
1606  return true;
1607  default:
1608  return false;
1609  }
1610  }
1611 
1612  template<typename T>
1613  bool casadi_math<T>::is_unary(unsigned char op) {
1614  switch (op) {
1615  CASADI_MATH_UNARY_BUILTIN
1616  return true;
1617  default:
1618  return false;
1619  }
1620  }
1621 
1622  template<typename T>
1623  inline casadi_int casadi_math<T>::ndeps(unsigned char op) {
1624  switch (op) {
1625  case OP_CONST:
1626  case OP_PARAMETER:
1627  case OP_INPUT:
1628  return 0;
1629  CASADI_MATH_BINARY_BUILTIN
1630  case OP_IF_ELSE_ZERO:
1631  return 2;
1632  case OP_CALL:
1633  return -1;
1634  default:
1635  return 1;
1636  }
1637  }
1638 
1639  template<typename T>
1640  inline std::string
1641  casadi_math<T>::print(unsigned char op,
1642  const std::string& x, const std::string& y) {
1643  casadi_assert_dev(ndeps(op)==2);
1644  return pre(op) + x + sep(op) + y + post(op);
1645  }
1646 
1647  template<typename T>
1648  inline std::string
1649  casadi_math<T>::print(unsigned char op, const std::string& x) {
1650  casadi_assert_dev(ndeps(op)==1);
1651  return pre(op) + x + post(op);
1652  }
1653 
1654  template<typename T>
1655  inline std::string casadi_math<T>::name(unsigned char op) {
1656  switch (op) {
1657  case OP_ASSIGN: return "assign";
1658  case OP_ADD: return "add";
1659  case OP_SUB: return "sub";
1660  case OP_MUL: return "mul";
1661  case OP_DIV: return "div";
1662  case OP_NEG: return "neg";
1663  case OP_EXP: return "exp";
1664  case OP_LOG: return "log";
1665  case OP_CONSTPOW:
1666  case OP_POW: return "pow";
1667  case OP_SQRT: return "sqrt";
1668  case OP_SQ: return "sq";
1669  case OP_TWICE: return "twice";
1670  case OP_SIN: return "sin";
1671  case OP_COS: return "cos";
1672  case OP_TAN: return "tan";
1673  case OP_ASIN: return "asin";
1674  case OP_ACOS: return "acos";
1675  case OP_ATAN: return "atan";
1676  case OP_LT: return "lt";
1677  case OP_LE: return "le";
1678  case OP_EQ: return "eq";
1679  case OP_NE: return "ne";
1680  case OP_NOT: return "not";
1681  case OP_AND: return "and";
1682  case OP_OR: return "or";
1683  case OP_FLOOR: return "floor";
1684  case OP_CEIL: return "ceil";
1685  case OP_FMOD: return "fmod";
1686  case OP_REMAINDER: return "remainder";
1687  case OP_FABS: return "fabs";
1688  case OP_SIGN: return "sign";
1689  case OP_COPYSIGN: return "copysign";
1690  case OP_IF_ELSE_ZERO: return "if_else_zero";
1691  case OP_ERF: return "erf";
1692  case OP_FMIN: return "fmin";
1693  case OP_FMAX: return "fmax";
1694  case OP_INV: return "inv";
1695  case OP_SINH: return "sinh";
1696  case OP_COSH: return "cosh";
1697  case OP_TANH: return "tanh";
1698  case OP_ASINH: return "asinh";
1699  case OP_ACOSH: return "acosh";
1700  case OP_ATANH: return "atanh";
1701  case OP_ATAN2: return "atan2";
1702  case OP_CONST: return "const";
1703  case OP_INPUT: return "input";
1704  case OP_OUTPUT: return "output";
1705  case OP_PARAMETER: return "parameter";
1706  case OP_CALL: return "call";
1707  case OP_MTIMES: return "mtimes";
1708  case OP_SOLVE: return "solve";
1709  case OP_TRANSPOSE: return "transpose";
1710  case OP_DETERMINANT: return "determinant";
1711  case OP_INVERSE: return "inverse";
1712  case OP_DOT: return "dot";
1713  case OP_HORZCAT: return "horzcat";
1714  case OP_VERTCAT: return "vertcat";
1715  case OP_DIAGCAT: return "diagcat";
1716  case OP_HORZSPLIT: return "horzsplit";
1717  case OP_VERTSPLIT: return "vertsplit";
1718  case OP_DIAGSPLIT: return "diagsplit";
1719  case OP_RESHAPE: return "reshape";
1720  case OP_SPARSITY_CAST: return "sparsity_cast";
1721  case OP_SUBREF: return "subref";
1722  case OP_SUBASSIGN: return "subassign";
1723  case OP_GETNONZEROS: return "getnonzeros";
1724  case OP_GETNONZEROS_PARAM: return "getnonzeros_param";
1725  case OP_ADDNONZEROS: return "addnonzeros";
1726  case OP_ADDNONZEROS_PARAM: return "addnonzeros_param";
1727  case OP_SETNONZEROS: return "setnonzeros";
1728  case OP_SETNONZEROS_PARAM: return "setnonzeros_param";
1729  case OP_PROJECT: return "project";
1730  case OP_ASSERTION: return "assertion";
1731  case OP_NORM2: return "norm2";
1732  case OP_NORM1: return "norm1";
1733  case OP_NORMINF: return "norminf";
1734  case OP_NORMF: return "normf";
1735  case OP_ERFINV: return "erfinv";
1736  case OP_PRINTME: return "printme";
1737  case OP_LIFT: return "lift";
1738  case OP_EINSTEIN: return "einstein";
1739  case OP_BSPLINE: return "bspline";
1740  case OP_CONVEXIFY: return "convexify";
1741  case OP_LOG1P: return "log1p";
1742  case OP_EXPM1: return "expm1";
1743  case OP_HYPOT: return "hypot";
1744  case OP_LOGSUMEXP: return "logsumexp";
1745  }
1746  return "<invalid-op>";
1747  }
1748 
1749  template<typename T>
1750  inline std::string casadi_math<T>::pre(unsigned char op) {
1751  switch (op) {
1752  case OP_ASSIGN: return "";
1753  case OP_ADD: return "(";
1754  case OP_SUB: return "(";
1755  case OP_MUL: return "(";
1756  case OP_DIV: return "(";
1757  case OP_NEG: return "(-";
1758  case OP_TWICE: return "(2.*";
1759  case OP_LT: return "(";
1760  case OP_LE: return "(";
1761  case OP_EQ: return "(";
1762  case OP_NE: return "(";
1763  case OP_NOT: return "(!";
1764  case OP_AND: return "(";
1765  case OP_OR: return "(";
1766  case OP_IF_ELSE_ZERO: return "(";
1767  case OP_INV: return "(1./";
1768  default: return name(op) + "(";
1769  }
1770  }
1771 
1772  template<typename T>
1773  inline std::string casadi_math<T>::sep(unsigned char op) {
1774  switch (op) {
1775  case OP_ADD: return "+";
1776  case OP_SUB: return "-";
1777  case OP_MUL: return "*";
1778  case OP_DIV: return "/";
1779  case OP_LT: return "<";
1780  case OP_LE: return "<=";
1781  case OP_EQ: return "==";
1782  case OP_NE: return "!=";
1783  case OP_AND: return "&&";
1784  case OP_OR: return "||";
1785  case OP_IF_ELSE_ZERO: return "?";
1786  default: return ",";
1787  }
1788  }
1789 
1790  template<typename T>
1791  inline std::string casadi_math<T>::post(unsigned char op) {
1792  switch (op) {
1793  case OP_ASSIGN: return "";
1794  case OP_IF_ELSE_ZERO: return ":0)";
1795  default: return ")";
1796  }
1797  }
1798 
1799 #endif // SWIG
1800 
1801 } // namespace casadi
1802 
1804 
1805 #endif // CASADI_CALCULUS_HPP
The casadi namespace.
Definition: archiver.cpp:28
bool is_equal(double x, double y, casadi_int depth=0)
Definition: calculus.hpp:281
double if_else_zero(double x, double y)
Conditional assignment.
Definition: calculus.hpp:289
const double eps
Machine epsilon.
Definition: calculus.hpp:56
T sq(const T &x)
Definition: calculus.hpp:331
double if_else(double x, double y, double z)
Definition: calculus.hpp:290
double sign(double x)
Sign function, note that sign(nan) == nan.
Definition: calculus.hpp:264
T twice(const T &x)
Definition: calculus.hpp:326
double erfinv(double x)
Definition: calculus.hpp:294
casadi_int casadi_min(casadi_int x, casadi_int y)
Definition: calculus.hpp:286
const double inf
infinity
Definition: calculus.hpp:50
double printme(double x, double y)
Definition: calculus.hpp:273
bool operation_checker(casadi_int op)
Definition: calculus.hpp:1119
const double nan
Not a number.
Definition: calculus.hpp:53
double constpow(double x, double y)
Definition: calculus.hpp:272
T operation_getter(casadi_int op)
Definition: calculus.hpp:1014
casadi_int casadi_max(casadi_int x, casadi_int y)
Definition: calculus.hpp:285
std::ostream & uout()
Operation
Enum for quick access to any node.
Definition: calculus.hpp:60
@ OP_DIAGCAT
Definition: calculus.hpp:130
@ OP_SIGN
Definition: calculus.hpp:71
@ OP_COS
Definition: calculus.hpp:68
@ OP_ERF
Definition: calculus.hpp:72
@ OP_NE
Definition: calculus.hpp:70
@ OP_HORZCAT
Definition: calculus.hpp:124
@ OP_FMAX
Definition: calculus.hpp:72
@ OP_SINH
Definition: calculus.hpp:74
@ OP_COSH
Definition: calculus.hpp:74
@ OP_VERTCAT
Definition: calculus.hpp:127
@ OP_SPARSITY_CAST
Definition: calculus.hpp:200
@ OP_ASINH
Definition: calculus.hpp:75
@ OP_ACOS
Definition: calculus.hpp:69
@ OP_LOW
Definition: calculus.hpp:94
@ OP_ATAN2
Definition: calculus.hpp:76
@ OP_HORZREPSUM
Definition: calculus.hpp:187
@ OP_ADDNONZEROS_PARAM
Definition: calculus.hpp:160
@ OP_COPYSIGN
Definition: calculus.hpp:71
@ OP_IF_ELSE_ZERO
Definition: calculus.hpp:71
@ OP_MMAX
Definition: calculus.hpp:181
@ OP_AND
Definition: calculus.hpp:70
@ OP_BSPLINE
Definition: calculus.hpp:195
@ OP_ATAN
Definition: calculus.hpp:69
@ OP_SQRT
Definition: calculus.hpp:67
@ OP_REMAINDER
Definition: calculus.hpp:210
@ OP_DIAGSPLIT
Definition: calculus.hpp:139
@ OP_INV
Definition: calculus.hpp:73
@ OP_INVERSE
Definition: calculus.hpp:112
@ OP_EXP
Definition: calculus.hpp:66
@ OP_OUTPUT
Definition: calculus.hpp:82
@ OP_MMIN
Definition: calculus.hpp:181
@ OP_SETNONZEROS
Definition: calculus.hpp:163
@ OP_LOG1P
Definition: calculus.hpp:202
@ OP_SIN
Definition: calculus.hpp:68
@ OP_ASIN
Definition: calculus.hpp:69
@ OP_FIND
Definition: calculus.hpp:91
@ OP_VERTSPLIT
Definition: calculus.hpp:136
@ OP_LT
Definition: calculus.hpp:70
@ OP_PRINTME
Definition: calculus.hpp:190
@ OP_ACOSH
Definition: calculus.hpp:75
@ OP_CEIL
Definition: calculus.hpp:71
@ OP_EQ
Definition: calculus.hpp:70
@ OP_CONST
Definition: calculus.hpp:79
@ OP_OR
Definition: calculus.hpp:70
@ OP_TWICE
Definition: calculus.hpp:67
@ OP_HYPOT
Definition: calculus.hpp:206
@ OP_EINSTEIN
Definition: calculus.hpp:193
@ OP_INPUT
Definition: calculus.hpp:82
@ OP_LIFT
Definition: calculus.hpp:191
@ OP_SUB
Definition: calculus.hpp:65
@ OP_ATANH
Definition: calculus.hpp:75
@ OP_SUBREF
Definition: calculus.hpp:145
@ OP_DETERMINANT
Definition: calculus.hpp:109
@ OP_DOT
Definition: calculus.hpp:115
@ OP_FMIN
Definition: calculus.hpp:72
@ OP_POW
Definition: calculus.hpp:66
@ OP_PROJECT
Definition: calculus.hpp:169
@ OP_EXPM1
Definition: calculus.hpp:204
@ OP_ADDNONZEROS
Definition: calculus.hpp:157
@ OP_PARAMETER
Definition: calculus.hpp:85
@ OP_SETNONZEROS_PARAM
Definition: calculus.hpp:166
@ OP_FABS
Definition: calculus.hpp:71
@ OP_BILIN
Definition: calculus.hpp:118
@ OP_MTIMES
Definition: calculus.hpp:100
@ OP_CONVEXIFY
Definition: calculus.hpp:197
@ OP_LOG
Definition: calculus.hpp:66
@ OP_LOGSUMEXP
Definition: calculus.hpp:208
@ OP_TANH
Definition: calculus.hpp:74
@ OP_NORM1
Definition: calculus.hpp:178
@ OP_CALL
Definition: calculus.hpp:88
@ OP_ADD
Definition: calculus.hpp:65
@ OP_ERFINV
Definition: calculus.hpp:189
@ OP_MAP
Definition: calculus.hpp:97
@ OP_NORM2
Definition: calculus.hpp:178
@ OP_LE
Definition: calculus.hpp:70
@ OP_RESHAPE
Definition: calculus.hpp:142
@ OP_DIV
Definition: calculus.hpp:65
@ OP_TRANSPOSE
Definition: calculus.hpp:106
@ OP_SOLVE
Definition: calculus.hpp:103
@ OP_FLOOR
Definition: calculus.hpp:71
@ OP_ASSERTION
Definition: calculus.hpp:172
@ OP_NEG
Definition: calculus.hpp:66
@ OP_RANK1
Definition: calculus.hpp:121
@ OP_CONSTPOW
Definition: calculus.hpp:66
@ OP_NOT
Definition: calculus.hpp:70
@ OP_SUBASSIGN
Definition: calculus.hpp:148
@ OP_MUL
Definition: calculus.hpp:65
@ OP_ASSIGN
Definition: calculus.hpp:62
@ OP_HORZREPMAT
Definition: calculus.hpp:184
@ OP_HORZSPLIT
Definition: calculus.hpp:133
@ OP_GETNONZEROS_PARAM
Definition: calculus.hpp:154
@ OP_SQ
Definition: calculus.hpp:67
@ OP_NORMF
Definition: calculus.hpp:178
@ OP_MONITOR
Definition: calculus.hpp:175
@ OP_GETNONZEROS
Definition: calculus.hpp:151
@ OP_FMOD
Definition: calculus.hpp:71
@ OP_TAN
Definition: calculus.hpp:68
@ OP_NORMINF
Definition: calculus.hpp:178
double simplify(double x)
Definition: calculus.hpp:271
const double pi
Define pi.
Definition: calculus.hpp:46
static T fcn(const T &x, const T &y)
Function evaluation.
Definition: calculus.hpp:358
Perform a binary operation on two scalars.
Definition: calculus.hpp:389
static void der(const T &x, const T &y, const T &f, T *d, casadi_int n)
Partial derivatives - binary function.
Definition: calculus.hpp:396
static void fcn(const T &x, const T &y, T &f, casadi_int n)
Function evaluation.
Definition: calculus.hpp:391
Perform a binary operation on a scalar and a vector.
Definition: calculus.hpp:443
static void der(const T &x, const T *y, const T *f, T *d, casadi_int n)
Partial derivatives - binary function.
Definition: calculus.hpp:452
static void fcn(const T &x, const T *y, T *f, casadi_int n)
Function evaluation.
Definition: calculus.hpp:445
Perform a binary operation on a vector and a scalar.
Definition: calculus.hpp:424
static void fcn(const T *x, const T &y, T *f, casadi_int n)
Function evaluation.
Definition: calculus.hpp:426
static void der(const T *x, const T &y, const T *f, T *d, casadi_int n)
Partial derivatives - binary function.
Definition: calculus.hpp:433
Perform a binary operation on two vectors.
Definition: calculus.hpp:405
static void fcn(const T *x, const T *y, T *f, casadi_int n)
Function evaluation.
Definition: calculus.hpp:407
static void der(const T *x, const T *y, const T *f, T *d, casadi_int n)
Partial derivatives - binary function.
Definition: calculus.hpp:414
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:603
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:604
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:830
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:829
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:983
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:982
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:673
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:674
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:868
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:869
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:631
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:630
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:806
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:805
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:888
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:887
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:876
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:877
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:788
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:789
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:1008
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:1009
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:993
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:991
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:764
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:765
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:1000
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:1001
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:756
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:755
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:621
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:622
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:814
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:813
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:837
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:838
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:665
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:663
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:973
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:974
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:796
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:798
static void der(const T &x, const T &y, const T &f, T *d)
Definition: calculus.hpp:613
static void fcn(const T &x, const T &y, T &f)
Definition: calculus.hpp:612
static void der(const T &x, const T &y, const T &f, T *d)
Partial derivatives - binary function.
Definition: calculus.hpp:351
static void fcn(const T &x, const T &y, T &f)
Function evaluation.
Definition: calculus.hpp:347
static const bool check
Definition: calculus.hpp:538
Calculate function and derivative.
Definition: calculus.hpp:367
static void derf(const T &x, const T &y, T &f, T *d)
Perform the operation.
Definition: calculus.hpp:369
static const bool check
Definition: calculus.hpp:523
static const bool check
Definition: calculus.hpp:481
static const bool check
Definition: calculus.hpp:514
static const casadi_int check
Definition: calculus.hpp:566
static const bool check
Definition: calculus.hpp:550
static const bool check
Definition: calculus.hpp:462
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:935
static void fcn(const T &x, T &f)
Definition: calculus.hpp:934
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:739
static void fcn(const T &x, T &f)
Definition: calculus.hpp:738
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:927
static void fcn(const T &x, T &f)
Definition: calculus.hpp:926
static void fcn(const T &x, T &f)
Definition: calculus.hpp:730
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:731
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:596
static void fcn(const T &x, T &f)
Definition: calculus.hpp:595
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:943
static void fcn(const T &x, T &f)
Definition: calculus.hpp:942
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:748
static void fcn(const T &x, T &f)
Definition: calculus.hpp:747
static void fcn(const T &x, T &f)
Definition: calculus.hpp:781
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:782
static void fcn(const T &x, T &f)
Definition: calculus.hpp:912
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:913
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:714
static void fcn(const T &x, T &f)
Definition: calculus.hpp:713
static void fcn(const T &x, T &f)
Definition: calculus.hpp:949
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:950
static void fcn(const T &x, T &f)
Definition: calculus.hpp:845
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:846
static void fcn(const T &x, T &f)
Definition: calculus.hpp:965
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:966
static void fcn(const T &x, T &f)
Definition: calculus.hpp:647
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:648
static void fcn(const T &x, T &f)
Definition: calculus.hpp:853
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:854
static void fcn(const T &x, T &f)
Definition: calculus.hpp:773
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:774
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:899
static void fcn(const T &x, T &f)
Definition: calculus.hpp:898
static void fcn(const T &x, T &f)
Definition: calculus.hpp:957
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:958
static void fcn(const T &x, T &f)
Definition: calculus.hpp:655
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:656
static void fcn(const T &x, T &f)
Definition: calculus.hpp:639
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:640
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:823
static void fcn(const T &x, T &f)
Definition: calculus.hpp:822
static void fcn(const T &x, T &f)
Definition: calculus.hpp:861
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:862
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:906
static void fcn(const T &x, T &f)
Definition: calculus.hpp:905
static void fcn(const T &x, T &f)
Definition: calculus.hpp:705
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:706
static void fcn(const T &x, T &f)
Definition: calculus.hpp:682
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:683
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:691
static void fcn(const T &x, T &f)
Definition: calculus.hpp:690
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:920
static void fcn(const T &x, T &f)
Definition: calculus.hpp:919
static void fcn(const T &x, T &f)
Definition: calculus.hpp:721
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:722
static void fcn(const T &x, T &f)
Definition: calculus.hpp:697
static void der(const T &x, const T &f, T *d)
Definition: calculus.hpp:698
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.
Definition: calculus.hpp:1258
static std::string pre(unsigned char op)
Definition: calculus.hpp:1272
static std::string post(unsigned char op)
Definition: calculus.hpp:1281
static void fun(unsigned char op, const casadi_int &x, const casadi_int &y, casadi_int &f)
Evaluate a built in function.
Definition: calculus.hpp:1196
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.
Definition: calculus.hpp:1245
static void fun(unsigned char op, const casadi_int *x, const casadi_int *y, casadi_int *f, casadi_int n)
Definition: calculus.hpp:1203
static std::string sep(unsigned char op)
Definition: calculus.hpp:1278
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.
Definition: calculus.hpp:1233
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.
Definition: calculus.hpp:1265
static void fun(unsigned char op, const casadi_int *x, const casadi_int &y, casadi_int *f, casadi_int n)
Definition: calculus.hpp:1212
static std::string print(unsigned char op, const std::string &x)
Definition: calculus.hpp:1269
static void fun(unsigned char op, const casadi_int &x, const casadi_int *y, casadi_int *f, casadi_int n)
Definition: calculus.hpp:1221
static std::string name(unsigned char op)
Definition: calculus.hpp:1275
Easy access to all the functions for a particular type.
Definition: calculus.hpp:1125
static bool is_binary(unsigned char op)
Is binary operation?
Definition: calculus.hpp:1602
static std::string post(unsigned char op)
Definition: calculus.hpp:1791
static std::string pre(unsigned char op)
Definition: calculus.hpp:1750
static void der(unsigned char op, const T &x, const T &y, const T &f, T *d)
Evaluate a built in derivative function.
Definition: calculus.hpp:1375
static void fun_linear(unsigned char op, const T *x, const T *y, T *f)
Evaluate function on a const/linear/nonlinear partition.
Definition: calculus.hpp:1552
static casadi_int ndeps(unsigned char op)
Number of dependencies.
Definition: calculus.hpp:1623
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.
Definition: calculus.hpp:1641
static std::string name(unsigned char op)
Definition: calculus.hpp:1655
static void fun(unsigned char op, const T &x, const T &y, T &f)
Evaluate a built in function (scalar-scalar)
Definition: calculus.hpp:1289
static std::string sep(unsigned char op)
Definition: calculus.hpp:1773
static void derF(unsigned char op, const T &x, const T &y, T &f, T *d)
Evaluate the function and the derivative function.
Definition: calculus.hpp:1437
static bool is_unary(unsigned char op)
Is unary operation?
Definition: calculus.hpp:1613