Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-17 08:48:09

0001 //           Copyright Maksym Zhelyenzyakov 2025-2026.
0002 // Distributed under the Boost Software License, Version 1.0.
0003 //      (See accompanying file LICENSE_1_0.txt or copy at
0004 //           https://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef REVERSE_MODE_AUTODOFF_BASIC_OPERATOR_OVERLOADS_HPP
0006 #define REVERSE_MODE_AUTODOFF_BASIC_OPERATOR_OVERLOADS_HPP
0007 
0008 #include <boost/math/differentiation/detail/reverse_mode_autodiff_expression_template_base.hpp>
0009 
0010 namespace boost {
0011 namespace math {
0012 namespace differentiation {
0013 namespace reverse_mode {
0014 /****************************************************************************************************************/
0015 template<typename RealType, size_t DerivativeOrder, typename LHS, typename RHS>
0016 struct add_expr : public abstract_binary_expression<RealType,
0017                                                     DerivativeOrder,
0018                                                     LHS,
0019                                                     RHS,
0020                                                     add_expr<RealType, DerivativeOrder, LHS, RHS>>
0021 {
0022     /* @brief addition
0023    * rvar+rvar
0024    * */
0025     using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0026     // Explicitly define constructor to forward to base class
0027     explicit add_expr(const expression<RealType, DerivativeOrder, LHS> &left_hand_expr,
0028                       const expression<RealType, DerivativeOrder, RHS> &right_hand_expr)
0029         : abstract_binary_expression<RealType,
0030                                      DerivativeOrder,
0031                                      LHS,
0032                                      RHS,
0033                                      add_expr<RealType, DerivativeOrder, LHS, RHS>>(left_hand_expr,
0034                                                                                     right_hand_expr)
0035     {}
0036 
0037     inner_t              evaluate() const { return this->lhs.evaluate() + this->rhs.evaluate(); }
0038     static const inner_t left_derivative(const inner_t & /*l*/,
0039                                          const inner_t & /*r*/,
0040                                          const inner_t & /*v*/)
0041     {
0042         return inner_t(static_cast<RealType>(1.0));
0043     }
0044     static const inner_t right_derivative(const inner_t & /*l*/,
0045                                           const inner_t & /*r*/,
0046                                           const inner_t & /*v*/)
0047     {
0048         return inner_t(static_cast<RealType>(1.0));
0049     }
0050 };
0051 template<typename RealType, size_t DerivativeOrder, typename ARG>
0052 struct add_const_expr
0053     : public abstract_unary_expression<RealType,
0054                                        DerivativeOrder,
0055                                        ARG,
0056                                        add_const_expr<RealType, DerivativeOrder, ARG>>
0057 {
0058     /* @brief
0059    * rvar+float or float+rvar
0060    * */
0061     using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0062     explicit add_const_expr(const expression<RealType, DerivativeOrder, ARG> &arg_expr,
0063                             const RealType                                    v)
0064         : abstract_unary_expression<RealType,
0065                                     DerivativeOrder,
0066                                     ARG,
0067                                     add_const_expr<RealType, DerivativeOrder, ARG>>(arg_expr, v){};
0068     inner_t              evaluate() const { return this->arg.evaluate() + inner_t(this->constant); }
0069     static const inner_t derivative(const inner_t & /*argv*/,
0070                                     const inner_t & /*v*/,
0071                                     const RealType & /*constant*/)
0072     {
0073         return inner_t(static_cast<RealType>(1.0));
0074     }
0075 };
0076 /****************************************************************************************************************/
0077 template<typename RealType, size_t DerivativeOrder, typename LHS, typename RHS>
0078 struct mult_expr : public abstract_binary_expression<RealType,
0079                                                      DerivativeOrder,
0080                                                      LHS,
0081                                                      RHS,
0082                                                      mult_expr<RealType, DerivativeOrder, LHS, RHS>>
0083 {
0084     /* @brief multiplication
0085    * rvar * rvar
0086    * */
0087     using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0088     explicit mult_expr(const expression<RealType, DerivativeOrder, LHS> &left_hand_expr,
0089                        const expression<RealType, DerivativeOrder, RHS> &right_hand_expr)
0090         : abstract_binary_expression<RealType,
0091                                      DerivativeOrder,
0092                                      LHS,
0093                                      RHS,
0094                                      mult_expr<RealType, DerivativeOrder, LHS, RHS>>(left_hand_expr,
0095                                                                                      right_hand_expr)
0096     {}
0097 
0098     inner_t              evaluate() const { return this->lhs.evaluate() * this->rhs.evaluate(); };
0099     static const inner_t left_derivative(const inner_t & /*l*/,
0100                                          const inner_t &r,
0101                                          const inner_t & /*v*/) noexcept
0102     {
0103         return r;
0104     };
0105     static const inner_t right_derivative(const inner_t &l,
0106                                           const inner_t & /*r*/,
0107                                           const inner_t & /*v*/) noexcept
0108     {
0109         return l;
0110     };
0111 };
0112 template<typename RealType, size_t DerivativeOrder, typename ARG>
0113 struct mult_const_expr
0114     : public abstract_unary_expression<RealType,
0115                                        DerivativeOrder,
0116                                        ARG,
0117                                        mult_const_expr<RealType, DerivativeOrder, ARG>>
0118 {
0119     /* @brief
0120    * rvar+float or float+rvar
0121    * */
0122     using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0123 
0124     explicit mult_const_expr(const expression<RealType, DerivativeOrder, ARG> &arg_expr,
0125                              const RealType                                    v)
0126         : abstract_unary_expression<RealType,
0127                                     DerivativeOrder,
0128                                     ARG,
0129                                     mult_const_expr<RealType, DerivativeOrder, ARG>>(arg_expr, v){};
0130 
0131     inner_t              evaluate() const { return this->arg.evaluate() * inner_t(this->constant); }
0132     static const inner_t derivative(const inner_t & /*argv*/,
0133                                     const inner_t & /*v*/,
0134                                     const RealType &constant)
0135     {
0136         return inner_t(constant);
0137     }
0138 };
0139 /****************************************************************************************************************/
0140 template<typename RealType, size_t DerivativeOrder, typename LHS, typename RHS>
0141 struct sub_expr : public abstract_binary_expression<RealType,
0142                                                     DerivativeOrder,
0143                                                     LHS,
0144                                                     RHS,
0145                                                     sub_expr<RealType, DerivativeOrder, LHS, RHS>>
0146 {
0147     /* @brief addition
0148    * rvar-rvar
0149    * */
0150     using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0151     // Explicitly define constructor to forward to base class
0152     explicit sub_expr(const expression<RealType, DerivativeOrder, LHS> &left_hand_expr,
0153                       const expression<RealType, DerivativeOrder, RHS> &right_hand_expr)
0154         : abstract_binary_expression<RealType,
0155                                      DerivativeOrder,
0156                                      LHS,
0157                                      RHS,
0158                                      sub_expr<RealType, DerivativeOrder, LHS, RHS>>(left_hand_expr,
0159                                                                                     right_hand_expr)
0160     {}
0161 
0162     inner_t              evaluate() const { return this->lhs.evaluate() - this->rhs.evaluate(); }
0163     static const inner_t left_derivative(const inner_t & /*l*/,
0164                                          const inner_t & /*r*/,
0165                                          const inner_t & /*v*/)
0166     {
0167         return inner_t(static_cast<RealType>(1.0));
0168     }
0169     static const inner_t right_derivative(const inner_t & /*l*/,
0170                                           const inner_t & /*r*/,
0171                                           const inner_t & /*v*/)
0172     {
0173         return inner_t(static_cast<RealType>(-1.0));
0174     }
0175 };
0176 
0177 /****************************************************************************************************************/
0178 template<typename RealType, size_t DerivativeOrder, typename LHS, typename RHS>
0179 struct div_expr : public abstract_binary_expression<RealType,
0180                                                     DerivativeOrder,
0181                                                     LHS,
0182                                                     RHS,
0183                                                     div_expr<RealType, DerivativeOrder, LHS, RHS>>
0184 {
0185     /* @brief multiplication
0186    * rvar / rvar
0187    * */
0188     using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0189     // Explicitly define constructor to forward to base class
0190     explicit div_expr(const expression<RealType, DerivativeOrder, LHS> &left_hand_expr,
0191                       const expression<RealType, DerivativeOrder, RHS> &right_hand_expr)
0192         : abstract_binary_expression<RealType,
0193                                      DerivativeOrder,
0194                                      LHS,
0195                                      RHS,
0196                                      div_expr<RealType, DerivativeOrder, LHS, RHS>>(left_hand_expr,
0197                                                                                     right_hand_expr)
0198     {}
0199 
0200     inner_t              evaluate() const { return this->lhs.evaluate() / this->rhs.evaluate(); };
0201     static const inner_t left_derivative(const inner_t & /*l*/,
0202                                          const inner_t &r,
0203                                          const inner_t & /*v*/)
0204     {
0205         return static_cast<RealType>(1.0) / r;
0206     };
0207     static const inner_t right_derivative(const inner_t &l, const inner_t &r, const inner_t & /*v*/)
0208     {
0209         return -l / (r * r);
0210     };
0211 };
0212 template<typename RealType, size_t DerivativeOrder, typename ARG>
0213 struct div_by_const_expr
0214     : public abstract_unary_expression<RealType,
0215                                        DerivativeOrder,
0216                                        ARG,
0217                                        div_by_const_expr<RealType, DerivativeOrder, ARG>>
0218 {
0219     /* @brief
0220    * rvar/float
0221    * */
0222     using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0223 
0224     explicit div_by_const_expr(const expression<RealType, DerivativeOrder, ARG> &arg_expr,
0225                                const RealType                                    v)
0226         : abstract_unary_expression<RealType,
0227                                     DerivativeOrder,
0228                                     ARG,
0229                                     div_by_const_expr<RealType, DerivativeOrder, ARG>>(arg_expr,
0230                                                                                        v){};
0231 
0232     inner_t              evaluate() const { return this->arg.evaluate() / inner_t(this->constant); }
0233     static const inner_t derivative(const inner_t & /*argv*/,
0234                                     const inner_t & /*v*/,
0235                                     const RealType &constant)
0236     {
0237         return inner_t(1.0 / constant);
0238     }
0239 };
0240 
0241 template<typename RealType, size_t DerivativeOrder, typename ARG>
0242 struct const_div_by_expr
0243     : public abstract_unary_expression<RealType,
0244                                        DerivativeOrder,
0245                                        ARG,
0246                                        const_div_by_expr<RealType, DerivativeOrder, ARG>>
0247 {
0248     /** @brief
0249     * float/rvar
0250     * */
0251     using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0252 
0253     explicit const_div_by_expr(const expression<RealType, DerivativeOrder, ARG> &arg_expr,
0254                                const RealType                                    v)
0255         : abstract_unary_expression<RealType,
0256                                     DerivativeOrder,
0257                                     ARG,
0258                                     const_div_by_expr<RealType, DerivativeOrder, ARG>>(arg_expr,
0259                                                                                        v){};
0260 
0261     inner_t              evaluate() const { return inner_t(this->constant) / this->arg.evaluate(); }
0262     static const inner_t derivative(const inner_t &argv,
0263                                     const inner_t & /*v*/,
0264                                     const RealType &constant)
0265     {
0266         return -inner_t{constant} / (argv * argv);
0267     }
0268 };
0269 /****************************************************************************************************************/
0270 
0271 } // namespace reverse_mode
0272 } // namespace differentiation
0273 } // namespace math
0274 } // namespace boost
0275 
0276 #endif