limes 3.1.0
Composable Calculus Expressions for C++20
Loading...
Searching...
No Matches
unary.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <span>
4#include <string>
5#include <cstddef>
6#include "binary.hpp"
7
8namespace limes::expr {
9
10struct Neg {};
11
12template<typename Op, typename E> struct Unary;
13
14template<typename E> inline constexpr bool is_negation_v = false;
15template<typename E> inline constexpr bool is_negation_v<Unary<Neg, E>> = true;
16
17template<typename E> struct negation_inner { using type = void; };
18template<typename E> struct negation_inner<Unary<Neg, E>> { using type = E; };
19template<typename E> using negation_inner_t = typename negation_inner<E>::type;
20
21// Unary<Op, E>: A unary operation node wrapping a child expression.
22// Currently only supports Neg (negation).
23template<typename Op, typename E>
24struct Unary {
25 using value_type = typename E::value_type;
26 using op_type = Op;
27 using child_type = E;
28
29 static constexpr std::size_t arity_v = E::arity_v;
30
32
33 constexpr explicit Unary(E c) noexcept : child{c} {}
34
35 [[nodiscard]] constexpr value_type eval(std::span<value_type const> args) const {
36 if constexpr (std::is_same_v<Op, Neg>) {
37 return -child.eval(args);
38 }
39 }
40
41 [[nodiscard]] [[deprecated("use eval() instead")]]
42 constexpr value_type evaluate(std::span<value_type const> args) const {
43 return eval(args);
44 }
45
46 // d/dx[-e] = -(de/dx)
47 template<std::size_t Dim>
48 [[nodiscard]] constexpr auto derivative() const {
49 if constexpr (std::is_same_v<Op, Neg>) {
50 return -child.template derivative<Dim>();
51 }
52 }
53
54 [[nodiscard]] std::string to_string() const {
55 if constexpr (std::is_same_v<Op, Neg>) {
56 return "(- " + child.to_string() + ")";
57 }
58 }
59};
60
61// Unary negation with simplification
62template<typename E>
63 requires is_expr_node_v<E>
64[[nodiscard]] constexpr auto operator-(E e) {
65 if constexpr (is_zero_v<E>) {
66 return e; // -0 = 0
67 } else if constexpr (is_negation_v<E>) {
68 return e.child; // --x = x
69 } else {
70 return Unary<Neg, E>{e};
71 }
72}
73
74// Unary plus (identity)
75template<typename E>
76 requires is_expr_node_v<E>
77[[nodiscard]] constexpr auto operator+(E e) {
78 return e;
79}
80
81} // namespace limes::expr
Expression layer for composable calculus.
Definition analysis.hpp:7
typename negation_inner< E >::type negation_inner_t
Definition unary.hpp:19
constexpr auto operator-(L l, R r)
Definition binary.hpp:153
constexpr bool is_negation_v
Definition unary.hpp:14
constexpr auto operator+(L l, R r)
Definition binary.hpp:119
constexpr value_type eval(std::span< value_type const > args) const
Definition unary.hpp:35
std::string to_string() const
Definition unary.hpp:54
constexpr value_type evaluate(std::span< value_type const > args) const
Definition unary.hpp:42
constexpr auto derivative() const
Definition unary.hpp:48
constexpr Unary(E c) noexcept
Definition unary.hpp:33
typename E::value_type value_type
Definition unary.hpp:25
static constexpr std::size_t arity_v
Definition unary.hpp:29