18template<
typename Tag,
typename L,
typename R>
struct BinaryFunc;
22template<
typename Tag,
typename L,
typename R>
23inline constexpr bool is_binary_func_v<BinaryFunc<Tag, L, R>> =
true;
26template<
typename L,
typename R>
27inline constexpr bool is_runtime_pow_v<BinaryFunc<PowTag, L, R>> =
true;
29template<
typename E>
inline constexpr bool is_max_v =
false;
30template<
typename L,
typename R>
31inline constexpr bool is_max_v<BinaryFunc<MaxTag, L, R>> =
true;
33template<
typename E>
inline constexpr bool is_min_v =
false;
34template<
typename L,
typename R>
35inline constexpr bool is_min_v<BinaryFunc<MinTag, L, R>> =
true;
38template<
typename Tag,
typename L,
typename R>
45 static constexpr std::size_t
arity_v = std::max(L::arity_v, R::arity_v);
52 [[nodiscard]]
constexpr value_type eval(std::span<value_type const> args)
const {
56 if constexpr (std::is_same_v<Tag, PowTag>) {
57 return std::pow(l_val, r_val);
58 }
else if constexpr (std::is_same_v<Tag, MaxTag>) {
59 return std::max(l_val, r_val);
60 }
else if constexpr (std::is_same_v<Tag, MinTag>) {
61 return std::min(l_val, r_val);
65 [[nodiscard]] [[deprecated(
"use eval() instead")]]
73 template<std::
size_t Dim>
75 auto df =
left.template derivative<Dim>();
76 auto dg =
right.template derivative<Dim>();
78 if constexpr (std::is_same_v<Tag, PowTag>) {
82 return f_to_g_minus_1 * (
right * df +
left * dg * log_f);
83 }
else if constexpr (std::is_same_v<Tag, MaxTag>) {
87 return half * (df + dg) + half * sign_diff * (df - dg);
88 }
else if constexpr (std::is_same_v<Tag, MinTag>) {
92 return half * (df + dg) - half * sign_diff * (df - dg);
97 std::string func_name;
98 if constexpr (std::is_same_v<Tag, PowTag>) {
100 }
else if constexpr (std::is_same_v<Tag, MaxTag>) {
102 }
else if constexpr (std::is_same_v<Tag, MinTag>) {
105 return "(" + func_name +
" " +
left.to_string() +
" " +
right.to_string() +
")";
112template<
typename L,
typename R>
113 requires (is_expr_node_v<L> && is_expr_node_v<R>)
114[[nodiscard]]
constexpr auto pow(L base, R exponent) {
115 if constexpr (is_zero_v<R>) {
117 }
else if constexpr (is_one_v<R>) {
119 }
else if constexpr (is_one_v<L>) {
121 }
else if constexpr (is_const_expr_v<L> && is_const_expr_v<R>) {
129template<
typename L,
typename T>
130 requires (is_expr_node_v<L> && std::is_arithmetic_v<T>)
131[[nodiscard]]
constexpr auto pow(L base, T exponent) {
132 using VT =
typename L::value_type;
137template<
typename T,
typename R>
138 requires (std::is_arithmetic_v<T> && is_expr_node_v<R>)
139[[nodiscard]]
constexpr auto pow(T base, R exponent) {
140 using VT =
typename R::value_type;
145template<
typename L,
typename R>
146 requires (is_expr_node_v<L> && is_expr_node_v<R>)
147[[nodiscard]]
constexpr auto max(L a, R b) {
148 if constexpr (is_const_expr_v<L> && is_const_expr_v<R>) {
150 }
else if constexpr (std::is_same_v<L, R>) {
158template<
typename L,
typename T>
159 requires (is_expr_node_v<L> && std::is_arithmetic_v<T>)
160[[nodiscard]]
constexpr auto max(L a, T b) {
161 using VT =
typename L::value_type;
166template<
typename T,
typename R>
167 requires (std::is_arithmetic_v<T> && is_expr_node_v<R>)
168[[nodiscard]]
constexpr auto max(T a, R b) {
169 using VT =
typename R::value_type;
174template<
typename L,
typename R>
175 requires (is_expr_node_v<L> && is_expr_node_v<R>)
176[[nodiscard]]
constexpr auto min(L a, R b) {
177 if constexpr (is_const_expr_v<L> && is_const_expr_v<R>) {
179 }
else if constexpr (std::is_same_v<L, R>) {
187template<
typename L,
typename T>
188 requires (is_expr_node_v<L> && std::is_arithmetic_v<T>)
189[[nodiscard]]
constexpr auto min(L a, T b) {
190 using VT =
typename L::value_type;
195template<
typename T,
typename R>
196 requires (std::is_arithmetic_v<T> && is_expr_node_v<R>)
197[[nodiscard]]
constexpr auto min(T a, R b) {
198 using VT =
typename R::value_type;
203template<
typename L,
typename R>
206template<
typename L,
typename R>
209template<
typename L,
typename R>
Expression layer for composable calculus.
constexpr auto max(L a, R b)
constexpr bool is_runtime_pow_v
constexpr bool is_binary_func_v
constexpr auto min(L a, R b)
constexpr auto pow(L base, R exponent)
constexpr value_type evaluate(std::span< value_type const > args) const
constexpr auto derivative() const
constexpr BinaryFunc(L l, R r) noexcept
typename L::value_type value_type
constexpr value_type eval(std::span< value_type const > args) const
std::string to_string() const
static constexpr std::size_t arity_v