File indexing completed on 2026-08-17 08:48:09
0001
0002
0003
0004
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
0023
0024
0025 using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0026
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 & ,
0039 const inner_t & ,
0040 const inner_t & )
0041 {
0042 return inner_t(static_cast<RealType>(1.0));
0043 }
0044 static const inner_t right_derivative(const inner_t & ,
0045 const inner_t & ,
0046 const inner_t & )
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
0059
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 & ,
0070 const inner_t & ,
0071 const RealType & )
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
0085
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 & ,
0100 const inner_t &r,
0101 const inner_t & ) noexcept
0102 {
0103 return r;
0104 };
0105 static const inner_t right_derivative(const inner_t &l,
0106 const inner_t & ,
0107 const inner_t & ) 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
0120
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 & ,
0133 const inner_t & ,
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
0148
0149
0150 using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0151
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 & ,
0164 const inner_t & ,
0165 const inner_t & )
0166 {
0167 return inner_t(static_cast<RealType>(1.0));
0168 }
0169 static const inner_t right_derivative(const inner_t & ,
0170 const inner_t & ,
0171 const inner_t & )
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
0186
0187
0188 using inner_t = rvar_t<RealType, DerivativeOrder - 1>;
0189
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 & ,
0202 const inner_t &r,
0203 const inner_t & )
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 & )
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
0220
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 & ,
0234 const inner_t & ,
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
0249
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 & ,
0264 const RealType &constant)
0265 {
0266 return -inner_t{constant} / (argv * argv);
0267 }
0268 };
0269
0270
0271 }
0272 }
0273 }
0274 }
0275
0276 #endif