LCOV - code coverage report
Current view: top level - lepton - Operation.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 165 232 71.1 %
Date: 2021-11-18 15:22:59 Functions: 42 56 75.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :  * -------------------------------------------------------------------------- *
       3             :  *                                   Lepton                                   *
       4             :  * -------------------------------------------------------------------------- *
       5             :  * This is part of the Lepton expression parser originating from              *
       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
       9             :  *                                                                            *
      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
      11             :  * Authors: Peter Eastman                                                     *
      12             :  * Contributors:                                                              *
      13             :  *                                                                            *
      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
      15             :  * copy of this software and associated documentation files (the "Software"), *
      16             :  * to deal in the Software without restriction, including without limitation  *
      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
      19             :  * Software is furnished to do so, subject to the following conditions:       *
      20             :  *                                                                            *
      21             :  * The above copyright notice and this permission notice shall be included in *
      22             :  * all copies or substantial portions of the Software.                        *
      23             :  *                                                                            *
      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
      31             :  * -------------------------------------------------------------------------- *
      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      33             : 
      34             : /* -------------------------------------------------------------------------- *
      35             :  *                                   lepton                                   *
      36             :  * -------------------------------------------------------------------------- *
      37             :  * This is part of the lepton expression parser originating from              *
      38             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
      39             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
      40             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
      41             :  *                                                                            *
      42             :  * Portions copyright (c) 2009-2015 Stanford University and the Authors.      *
      43             :  * Authors: Peter Eastman                                                     *
      44             :  * Contributors:                                                              *
      45             :  *                                                                            *
      46             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
      47             :  * copy of this software and associated documentation files (the "Software"), *
      48             :  * to deal in the Software without restriction, including without limitation  *
      49             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
      50             :  * and/or sell copies of the Software, and to permit persons to whom the      *
      51             :  * Software is furnished to do so, subject to the following conditions:       *
      52             :  *                                                                            *
      53             :  * The above copyright notice and this permission notice shall be included in *
      54             :  * all copies or substantial portions of the Software.                        *
      55             :  *                                                                            *
      56             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
      57             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
      58             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
      59             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
      60             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
      61             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
      62             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
      63             :  * -------------------------------------------------------------------------- */
      64             : 
      65             : #include "Operation.h"
      66             : #include "ExpressionTreeNode.h"
      67             : #include "MSVC_erfc.h"
      68             : 
      69             : #ifndef M_PI
      70             : #define M_PI           3.14159265358979323846
      71             : #endif
      72             : 
      73             : namespace PLMD {
      74             : using namespace lepton;
      75             : using namespace std;
      76             : 
      77         101 : double Operation::Erf::evaluate(double* args, const map<string, double>& variables) const {
      78         101 :     return erf(args[0]);
      79             : }
      80             : 
      81           0 : double Operation::Erfc::evaluate(double* args, const map<string, double>& variables) const {
      82           0 :     return erfc(args[0]);
      83             : }
      84             : 
      85        1319 : ExpressionTreeNode Operation::Constant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
      86        2638 :     return ExpressionTreeNode(new Operation::Constant(0.0));
      87             : }
      88             : 
      89        1709 : ExpressionTreeNode Operation::Variable::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
      90        1709 :     if (variable == name)
      91        1978 :         return ExpressionTreeNode(new Operation::Constant(1.0));
      92        1440 :     return ExpressionTreeNode(new Operation::Constant(0.0));
      93             : }
      94             : 
      95           0 : ExpressionTreeNode Operation::Custom::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
      96           0 :     if (function->getNumArguments() == 0)
      97           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
      98           0 :     ExpressionTreeNode result = ExpressionTreeNode(new Operation::Multiply(), ExpressionTreeNode(new Operation::Custom(*this, 0), children), childDerivs[0]);
      99           0 :     for (int i = 1; i < getNumArguments(); i++) {
     100           0 :         result = ExpressionTreeNode(new Operation::Add(),
     101             :                                     result,
     102           0 :                                     ExpressionTreeNode(new Operation::Multiply(), ExpressionTreeNode(new Operation::Custom(*this, i), children), childDerivs[i]));
     103             :     }
     104           0 :     return result;
     105             : }
     106             : 
     107         589 : ExpressionTreeNode Operation::Add::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     108        1178 :     return ExpressionTreeNode(new Operation::Add(), childDerivs[0], childDerivs[1]);
     109             : }
     110             : 
     111         435 : ExpressionTreeNode Operation::Subtract::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     112         870 :     return ExpressionTreeNode(new Operation::Subtract(), childDerivs[0], childDerivs[1]);
     113             : }
     114             : 
     115        1258 : ExpressionTreeNode Operation::Multiply::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     116        1258 :     return ExpressionTreeNode(new Operation::Add(),
     117        3774 :                               ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]),
     118        5032 :                               ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]));
     119             : }
     120             : 
     121         207 : ExpressionTreeNode Operation::Divide::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     122         207 :     return ExpressionTreeNode(new Operation::Divide(),
     123         621 :                               ExpressionTreeNode(new Operation::Subtract(),
     124         621 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]),
     125         621 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1])),
     126         828 :                               ExpressionTreeNode(new Operation::Square(), children[1]));
     127             : }
     128             : 
     129          94 : ExpressionTreeNode Operation::Power::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     130          94 :     return ExpressionTreeNode(new Operation::Add(),
     131         282 :                               ExpressionTreeNode(new Operation::Multiply(),
     132         282 :                                                  ExpressionTreeNode(new Operation::Multiply(),
     133             :                                                                     children[1],
     134         282 :                                                                     ExpressionTreeNode(new Operation::Power(),
     135         282 :                                                                                        children[0], ExpressionTreeNode(new Operation::AddConstant(-1.0), children[1]))),
     136             :                                                  childDerivs[0]),
     137         282 :                               ExpressionTreeNode(new Operation::Multiply(),
     138         282 :                                                  ExpressionTreeNode(new Operation::Multiply(),
     139         282 :                                                                     ExpressionTreeNode(new Operation::Log(), children[0]),
     140         282 :                                                                     ExpressionTreeNode(new Operation::Power(), children[0], children[1])),
     141         188 :                                                  childDerivs[1]));
     142             : }
     143             : 
     144           6 : ExpressionTreeNode Operation::Negate::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     145          12 :     return ExpressionTreeNode(new Operation::Negate(), childDerivs[0]);
     146             : }
     147             : 
     148          38 : ExpressionTreeNode Operation::Sqrt::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     149          38 :     return ExpressionTreeNode(new Operation::Multiply(),
     150         114 :                               ExpressionTreeNode(new Operation::MultiplyConstant(0.5),
     151         114 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
     152         114 :                                                                     ExpressionTreeNode(new Operation::Sqrt(), children[0]))),
     153          76 :                               childDerivs[0]);
     154             : }
     155             : 
     156           2 : ExpressionTreeNode Operation::Exp::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     157           2 :     return ExpressionTreeNode(new Operation::Multiply(),
     158           6 :                               ExpressionTreeNode(new Operation::Exp(), children[0]),
     159           4 :                               childDerivs[0]);
     160             : }
     161             : 
     162           1 : ExpressionTreeNode Operation::Log::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     163           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     164           3 :                               ExpressionTreeNode(new Operation::Reciprocal(), children[0]),
     165           2 :                               childDerivs[0]);
     166             : }
     167             : 
     168          53 : ExpressionTreeNode Operation::Sin::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     169          53 :     return ExpressionTreeNode(new Operation::Multiply(),
     170         159 :                               ExpressionTreeNode(new Operation::Cos(), children[0]),
     171         106 :                               childDerivs[0]);
     172             : }
     173             : 
     174         629 : ExpressionTreeNode Operation::Cos::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     175         629 :     return ExpressionTreeNode(new Operation::Multiply(),
     176        1887 :                               ExpressionTreeNode(new Operation::Negate(),
     177        1887 :                                                  ExpressionTreeNode(new Operation::Sin(), children[0])),
     178        1258 :                               childDerivs[0]);
     179             : }
     180             : 
     181           1 : ExpressionTreeNode Operation::Sec::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     182           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     183           3 :                               ExpressionTreeNode(new Operation::Multiply(),
     184           3 :                                                  ExpressionTreeNode(new Operation::Sec(), children[0]),
     185           3 :                                                  ExpressionTreeNode(new Operation::Tan(), children[0])),
     186           2 :                               childDerivs[0]);
     187             : }
     188             : 
     189           1 : ExpressionTreeNode Operation::Csc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     190           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     191           3 :                               ExpressionTreeNode(new Operation::Negate(),
     192           3 :                                                  ExpressionTreeNode(new Operation::Multiply(),
     193           3 :                                                                     ExpressionTreeNode(new Operation::Csc(), children[0]),
     194           3 :                                                                     ExpressionTreeNode(new Operation::Cot(), children[0]))),
     195           2 :                               childDerivs[0]);
     196             : }
     197             : 
     198           1 : ExpressionTreeNode Operation::Tan::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     199           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     200           3 :                               ExpressionTreeNode(new Operation::Square(),
     201           3 :                                                  ExpressionTreeNode(new Operation::Sec(), children[0])),
     202           2 :                               childDerivs[0]);
     203             : }
     204             : 
     205           1 : ExpressionTreeNode Operation::Cot::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     206           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     207           3 :                               ExpressionTreeNode(new Operation::Negate(),
     208           3 :                                                  ExpressionTreeNode(new Operation::Square(),
     209           3 :                                                                     ExpressionTreeNode(new Operation::Csc(), children[0]))),
     210           2 :                               childDerivs[0]);
     211             : }
     212             : 
     213           1 : ExpressionTreeNode Operation::Asin::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     214           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     215           3 :                               ExpressionTreeNode(new Operation::Reciprocal(),
     216           3 :                                                  ExpressionTreeNode(new Operation::Sqrt(),
     217           3 :                                                                     ExpressionTreeNode(new Operation::Subtract(),
     218           3 :                                                                                        ExpressionTreeNode(new Operation::Constant(1.0)),
     219           3 :                                                                                        ExpressionTreeNode(new Operation::Square(), children[0])))),
     220           2 :                               childDerivs[0]);
     221             : }
     222             : 
     223           1 : ExpressionTreeNode Operation::Acos::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     224           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     225           3 :                               ExpressionTreeNode(new Operation::Negate(),
     226           3 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
     227           3 :                                                                     ExpressionTreeNode(new Operation::Sqrt(),
     228           3 :                                                                                        ExpressionTreeNode(new Operation::Subtract(),
     229           3 :                                                                                                           ExpressionTreeNode(new Operation::Constant(1.0)),
     230           3 :                                                                                                           ExpressionTreeNode(new Operation::Square(), children[0]))))),
     231           2 :                               childDerivs[0]);
     232             : }
     233             : 
     234           1 : ExpressionTreeNode Operation::Atan::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     235           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     236           3 :                               ExpressionTreeNode(new Operation::Reciprocal(),
     237           3 :                                                  ExpressionTreeNode(new Operation::AddConstant(1.0),
     238           3 :                                                                     ExpressionTreeNode(new Operation::Square(), children[0]))),
     239           2 :                               childDerivs[0]);
     240             : }
     241             : 
     242           1 : ExpressionTreeNode Operation::Sinh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     243           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     244           3 :                               ExpressionTreeNode(new Operation::Cosh(),
     245             :                                                  children[0]),
     246           2 :                               childDerivs[0]);
     247             : }
     248             : 
     249           1 : ExpressionTreeNode Operation::Cosh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     250           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     251           3 :                               ExpressionTreeNode(new Operation::Sinh(),
     252             :                                                  children[0]),
     253           2 :                               childDerivs[0]);
     254             : }
     255             : 
     256           1 : ExpressionTreeNode Operation::Tanh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     257           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     258           3 :                               ExpressionTreeNode(new Operation::Subtract(),
     259           3 :                                                  ExpressionTreeNode(new Operation::Constant(1.0)),
     260           3 :                                                  ExpressionTreeNode(new Operation::Square(),
     261           3 :                                                                     ExpressionTreeNode(new Operation::Tanh(), children[0]))),
     262           2 :                               childDerivs[0]);
     263             : }
     264             : 
     265           1 : ExpressionTreeNode Operation::Erf::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     266           1 :     return ExpressionTreeNode(new Operation::Multiply(),
     267           3 :                               ExpressionTreeNode(new Operation::Multiply(),
     268           3 :                                                  ExpressionTreeNode(new Operation::Constant(2.0/sqrt(M_PI))),
     269           3 :                                                  ExpressionTreeNode(new Operation::Exp(),
     270           3 :                                                                     ExpressionTreeNode(new Operation::Negate(),
     271           3 :                                                                                        ExpressionTreeNode(new Operation::Square(), children[0])))),
     272           2 :                               childDerivs[0]);
     273             : }
     274             : 
     275           0 : ExpressionTreeNode Operation::Erfc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     276           0 :     return ExpressionTreeNode(new Operation::Multiply(),
     277           0 :                               ExpressionTreeNode(new Operation::Multiply(),
     278           0 :                                                  ExpressionTreeNode(new Operation::Constant(-2.0/sqrt(M_PI))),
     279           0 :                                                  ExpressionTreeNode(new Operation::Exp(),
     280           0 :                                                                     ExpressionTreeNode(new Operation::Negate(),
     281           0 :                                                                                        ExpressionTreeNode(new Operation::Square(), children[0])))),
     282           0 :                               childDerivs[0]);
     283             : }
     284             : 
     285           3 : ExpressionTreeNode Operation::Step::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     286           6 :     return ExpressionTreeNode(new Operation::Delta(),children[0]);
     287             : }
     288             : 
     289           1 : ExpressionTreeNode Operation::Delta::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     290           2 :     return ExpressionTreeNode(new Operation::Nandelta(), children[0]);
     291             : }
     292             : 
     293           1 : ExpressionTreeNode Operation::Nandelta::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     294           2 :     return ExpressionTreeNode(new Operation::Nandelta(), children[0]);
     295             : }
     296             : 
     297           0 : ExpressionTreeNode Operation::Square::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     298           0 :     return ExpressionTreeNode(new Operation::Multiply(),
     299           0 :                               ExpressionTreeNode(new Operation::MultiplyConstant(2.0),
     300             :                                                  children[0]),
     301           0 :                               childDerivs[0]);
     302             : }
     303             : 
     304           0 : ExpressionTreeNode Operation::Cube::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     305           0 :     return ExpressionTreeNode(new Operation::Multiply(),
     306           0 :                               ExpressionTreeNode(new Operation::MultiplyConstant(3.0),
     307           0 :                                                  ExpressionTreeNode(new Operation::Square(), children[0])),
     308           0 :                               childDerivs[0]);
     309             : }
     310             : 
     311           0 : ExpressionTreeNode Operation::Reciprocal::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     312           0 :     return ExpressionTreeNode(new Operation::Multiply(),
     313           0 :                               ExpressionTreeNode(new Operation::Negate(),
     314           0 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
     315           0 :                                                                     ExpressionTreeNode(new Operation::Square(), children[0]))),
     316           0 :                               childDerivs[0]);
     317             : }
     318             : 
     319           0 : ExpressionTreeNode Operation::AddConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     320           0 :     return childDerivs[0];
     321             : }
     322             : 
     323           0 : ExpressionTreeNode Operation::MultiplyConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     324           0 :     return ExpressionTreeNode(new Operation::MultiplyConstant(value),
     325           0 :                               childDerivs[0]);
     326             : }
     327             : 
     328           0 : ExpressionTreeNode Operation::PowerConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     329           0 :     return ExpressionTreeNode(new Operation::Multiply(),
     330           0 :                               ExpressionTreeNode(new Operation::MultiplyConstant(value),
     331           0 :                                                  ExpressionTreeNode(new Operation::PowerConstant(value-1),
     332             :                                                                     children[0])),
     333           0 :                               childDerivs[0]);
     334             : }
     335             : 
     336           0 : ExpressionTreeNode Operation::Min::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     337           0 :     ExpressionTreeNode step(new Operation::Step(),
     338           0 :                             ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
     339           0 :     return ExpressionTreeNode(new Operation::Subtract(),
     340           0 :                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[1], step),
     341           0 :                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[0],
     342           0 :                                                  ExpressionTreeNode(new Operation::AddConstant(-1), step)));
     343             : }
     344             : 
     345           0 : ExpressionTreeNode Operation::Max::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     346           0 :     ExpressionTreeNode step(new Operation::Step(),
     347           0 :                             ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
     348           0 :     return ExpressionTreeNode(new Operation::Subtract(),
     349           0 :                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[0], step),
     350           0 :                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[1],
     351           0 :                                                  ExpressionTreeNode(new Operation::AddConstant(-1), step)));
     352             : }
     353             : 
     354           2 : ExpressionTreeNode Operation::Abs::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     355           6 :     ExpressionTreeNode step(new Operation::Step(), children[0]);
     356           2 :     return ExpressionTreeNode(new Operation::Multiply(),
     357             :                               childDerivs[0],
     358           6 :                               ExpressionTreeNode(new Operation::AddConstant(-1),
     359          10 :                                                  ExpressionTreeNode(new Operation::MultiplyConstant(2), step)));
     360             : }
     361             : 
     362           0 : ExpressionTreeNode Operation::Floor::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     363           0 :     return ExpressionTreeNode(new Operation::Constant(0.0));
     364             : }
     365             : 
     366           0 : ExpressionTreeNode Operation::Ceil::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     367           0 :     return ExpressionTreeNode(new Operation::Constant(0.0));
     368             : }
     369             : 
     370           0 : ExpressionTreeNode Operation::Select::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     371           0 :     vector<ExpressionTreeNode> derivChildren;
     372           0 :     derivChildren.push_back(children[0]);
     373           0 :     derivChildren.push_back(childDerivs[1]);
     374           0 :     derivChildren.push_back(childDerivs[2]);
     375           0 :     return ExpressionTreeNode(new Operation::Select(), derivChildren);
     376             : }
     377             : 
     378             : #define LEPTON_CONST(x) ExpressionTreeNode(new Operation::Constant(x))
     379             : #define LEPTON_OP1(name,x) ExpressionTreeNode(new Operation::name(),x)
     380             : #define LEPTON_OP2(name,x,y) ExpressionTreeNode(new Operation::name(),x,y)
     381             : #define LEPTON_ADD_CONST(x,y) ExpressionTreeNode(new Operation::AddConstant(x),y)
     382             : 
     383           1 : ExpressionTreeNode Operation::Acot::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     384             :     return
     385           6 :       LEPTON_OP2(Multiply,
     386             :         LEPTON_OP1(Negate,
     387             :           LEPTON_OP1(Reciprocal,
     388             :             LEPTON_ADD_CONST(1.0,
     389             :               LEPTON_OP1(Square,children[0])
     390             :             )
     391             :           )
     392             :         ),
     393             :         childDerivs[0]
     394             :       );
     395             : }
     396             : 
     397           1 : ExpressionTreeNode Operation::Asec::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     398             :     return
     399          11 :       LEPTON_OP2(Multiply,
     400             :         LEPTON_OP1(Reciprocal,
     401             :           LEPTON_OP2(Multiply,
     402             :             LEPTON_OP1(Abs,children[0]),
     403             :             LEPTON_OP1(Sqrt,
     404             :               LEPTON_OP2(Subtract,
     405             :                 LEPTON_OP1(Square,children[0]),
     406             :                 LEPTON_CONST(1.0)
     407             :               )
     408             :             )
     409             :           )
     410             :         ),
     411             :         childDerivs[0]
     412             :       );
     413             : }
     414             : 
     415           1 : ExpressionTreeNode Operation::Acsc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     416             :     return
     417          12 :     LEPTON_OP2(Multiply,
     418             :       LEPTON_OP1(Negate,
     419             :         LEPTON_OP1(Reciprocal,
     420             :           LEPTON_OP2(Multiply,
     421             :             LEPTON_OP1(Abs,children[0]),
     422             :             LEPTON_OP1(Sqrt,
     423             :               LEPTON_OP2(Subtract,
     424             :                 LEPTON_OP1(Square,children[0]),
     425             :                 LEPTON_CONST(1.0)
     426             :               )
     427             :             )
     428             :           )
     429             :         )
     430             :       ),
     431             :       childDerivs[0]
     432             :     );
     433             : }
     434             : 
     435           1 : ExpressionTreeNode Operation::Coth::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     436             :     return
     437           6 :     LEPTON_OP2(Multiply,
     438             :       LEPTON_OP2(Subtract,
     439             :         LEPTON_CONST(1.0),
     440             :         LEPTON_OP1(Square,
     441             :           LEPTON_OP1(Coth,children[0])
     442             :         )
     443             :       ),
     444             :       childDerivs[0]
     445             :     );
     446             : }
     447             : 
     448           1 : ExpressionTreeNode Operation::Sech::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     449             :     return
     450           7 :     LEPTON_OP2(Multiply,
     451             :       LEPTON_OP1(Negate,
     452             :         LEPTON_OP2(Multiply,
     453             :           LEPTON_OP1(Tanh,children[0]),
     454             :           LEPTON_OP1(Sech,children[0])
     455             :         )
     456             :       ),
     457             :       childDerivs[0]
     458             :     );
     459             : }
     460             : 
     461           1 : ExpressionTreeNode Operation::Csch::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     462             :     return
     463           7 :     LEPTON_OP2(Multiply,
     464             :       LEPTON_OP1(Negate,
     465             :         LEPTON_OP2(Multiply,
     466             :           LEPTON_OP1(Coth,children[0]),
     467             :           LEPTON_OP1(Csch,children[0])
     468             :         )
     469             :       ),
     470             :       childDerivs[0]
     471             :     );
     472             : }
     473             : 
     474           1 : ExpressionTreeNode Operation::Acosh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     475             :     return
     476           8 :     LEPTON_OP2(Multiply,
     477             :       LEPTON_OP1(Reciprocal,
     478             :         LEPTON_OP1(Sqrt,
     479             :           LEPTON_OP2(Subtract,
     480             :             LEPTON_OP1(Square,children[0]),
     481             :             LEPTON_CONST(1.0)
     482             :           )
     483             :         )
     484             :       ),
     485             :       childDerivs[0]
     486             :     );
     487             : }
     488             : 
     489           1 : ExpressionTreeNode Operation::Atanh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     490             :     return
     491           6 :     LEPTON_OP2(Multiply,
     492             :       LEPTON_OP1(Reciprocal,
     493             :         LEPTON_OP2(Subtract,
     494             :           LEPTON_CONST(1.0),
     495             :           LEPTON_OP1(Square,children[0])
     496             :         )
     497             :       ),
     498             :       childDerivs[0]
     499             :     );
     500             : }
     501             : 
     502           1 : ExpressionTreeNode Operation::Asinh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     503             :     return
     504           6 :     LEPTON_OP2(Multiply,
     505             :       LEPTON_OP1(Reciprocal,
     506             :         LEPTON_OP1(Sqrt,
     507             :           LEPTON_ADD_CONST(1.0,
     508             :             LEPTON_OP1(Square,children[0])
     509             :           )
     510             :         )
     511             :       ),
     512             :       childDerivs[0]
     513             :     );
     514             : }
     515             : 
     516           1 : ExpressionTreeNode Operation::Acoth::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     517             :     return
     518           6 :     LEPTON_OP2(Multiply,
     519             :       LEPTON_OP1(Reciprocal,
     520             :         LEPTON_OP2(Subtract,
     521             :           LEPTON_CONST(1.0),
     522             :           LEPTON_OP1(Square,children[0])
     523             :         )
     524             :       ),
     525             :       childDerivs[0]
     526             :     );
     527             : }
     528             : 
     529           1 : ExpressionTreeNode Operation::Asech::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     530             :     return
     531          15 :     LEPTON_OP2(Multiply,
     532             :       LEPTON_OP1(Negate,
     533             :         LEPTON_OP1(Reciprocal,
     534             :           LEPTON_OP2(Multiply,
     535             :             children[0],
     536             :             LEPTON_OP2(Multiply,
     537             :               LEPTON_ADD_CONST(1.0,
     538             :                 children[0]
     539             :               ),
     540             :               LEPTON_OP1(Sqrt,
     541             :                 LEPTON_OP2(Divide,
     542             :                   LEPTON_OP2(Subtract,
     543             :                     LEPTON_CONST(1.0),
     544             :                     children[0]
     545             :                   ),
     546             :                   LEPTON_ADD_CONST(1.0,
     547             :                     children[0]
     548             :                   )
     549             :                 )
     550             :               )
     551             :             )
     552             :           )
     553             :         )
     554             :       ),
     555             :       childDerivs[0]
     556             :     );
     557             : }
     558             : 
     559           1 : ExpressionTreeNode Operation::Acsch::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     560             :     return
     561          11 :     LEPTON_OP2(Multiply,
     562             :       LEPTON_OP1(Negate,
     563             :         LEPTON_OP1(Reciprocal,
     564             :           LEPTON_OP2(Multiply,
     565             :             LEPTON_OP1(Square,children[0]),
     566             :             LEPTON_OP1(Sqrt,
     567             :               LEPTON_ADD_CONST(1.0,
     568             :                 LEPTON_OP1(Reciprocal,
     569             :                   LEPTON_OP1(Square,children[0])
     570             :                 )
     571             :               )
     572             :             )
     573             :           )
     574             :         )
     575             :       ),
     576             :       childDerivs[0]
     577             :     );
     578             : }
     579             : 
     580           4 : ExpressionTreeNode Operation::Atan2::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
     581             :     return
     582          44 :     LEPTON_OP2(Divide,
     583             :       LEPTON_OP2(Subtract,
     584             :         LEPTON_OP2(Multiply, children[1], childDerivs[0]),
     585             :         LEPTON_OP2(Multiply, children[0], childDerivs[1])
     586             :       ),
     587             :       LEPTON_OP2(Add,
     588             :         LEPTON_OP1(Square, children[0]),
     589             :         LEPTON_OP1(Square, children[1])
     590             :       )
     591             :     );
     592             : }
     593             : 
     594             : }

Generated by: LCOV version 1.14