limes 3.1.0
Composable Calculus Expressions for C++20
Loading...
Searching...
No Matches
named_var.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <span>
4#include <string>
5#include <string_view>
6#include <cstddef>
7#include <cassert>
8#include "const.hpp"
9
10namespace limes::expr {
11
12// NamedVar<T>: Like Var<N, T> but carries a runtime name for debugging/to_string()
13//
14// Example:
15// auto x = var(0, "x");
16// auto y = var(1, "y");
17// auto f = sin(x) * cos(y);
18// f.to_string(); // "(* (sin x) (cos y))"
19//
20template<typename T = double>
21struct NamedVar {
22 using value_type = T;
23 static constexpr std::size_t arity_v = 1;
24
25 std::size_t dim;
26 std::string_view name;
27
28 constexpr NamedVar(std::size_t dimension, std::string_view n) noexcept
29 : dim{dimension}, name{n} {}
30
31 [[nodiscard]] constexpr std::size_t arity() const noexcept {
32 return dim + 1;
33 }
34
35 [[nodiscard]] constexpr T eval(std::span<T const> args) const noexcept {
36 assert(args.size() > dim && "Not enough arguments for named variable");
37 return args[dim];
38 }
39
40 [[nodiscard]] [[deprecated("use eval() instead")]]
41 constexpr T evaluate(std::span<T const> args) const noexcept {
42 return eval(args);
43 }
44
45 // Compile-time derivative: limited because dim is a runtime value.
46 // Only correct when Dim matches the actual runtime dim.
47 template<std::size_t Dim>
48 [[nodiscard]] constexpr auto derivative() const noexcept {
49 if constexpr (Dim == 0) {
50 return (dim == Dim) ? One<T>{} : Zero<T>{};
51 } else {
52 return Zero<T>{};
53 }
54 }
55
56 [[nodiscard]] constexpr auto derivative_rt(std::size_t d) const noexcept {
57 return (d == dim) ? One<T>{} : Zero<T>{};
58 }
59
60 [[nodiscard]] std::string to_string() const {
61 return std::string(name);
62 }
63
64 [[nodiscard]] constexpr std::size_t dimension() const noexcept {
65 return dim;
66 }
67};
68
69template<typename T>
70struct is_named_var : std::false_type {};
71
72template<typename T>
73struct is_named_var<NamedVar<T>> : std::true_type {};
74
75template<typename T>
76inline constexpr bool is_named_var_v = is_named_var<T>::value;
77
78template<typename T = double>
79[[nodiscard]] constexpr NamedVar<T> var(std::size_t dim, std::string_view name) noexcept {
80 return NamedVar<T>{dim, name};
81}
82
83// StaticNamedVar<N, T>: Combines compile-time dimension (like Var<N>) with a runtime name.
84//
85// Example:
86// auto x = named<0>("x");
87// auto y = named<1>("y");
88//
89template<std::size_t N, typename T = double>
91 using value_type = T;
92 static constexpr std::size_t arity_v = N + 1;
93 static constexpr std::size_t index_v = N;
94
95 std::string_view name;
96
97 constexpr explicit StaticNamedVar(std::string_view n) noexcept : name{n} {}
98
99 [[nodiscard]] constexpr T eval(std::span<T const> args) const noexcept {
100 assert(args.size() > N && "Not enough arguments for named variable");
101 return args[N];
102 }
103
104 [[nodiscard]] [[deprecated("use eval() instead")]]
105 constexpr T evaluate(std::span<T const> args) const noexcept {
106 return eval(args);
107 }
108
109 template<std::size_t Dim>
110 [[nodiscard]] constexpr auto derivative() const noexcept {
111 if constexpr (Dim == N) {
112 return One<T>{};
113 } else {
114 return Zero<T>{};
115 }
116 }
117
118 [[nodiscard]] std::string to_string() const {
119 return std::string(name);
120 }
121
122 [[nodiscard]] static constexpr std::size_t dimension() noexcept {
123 return N;
124 }
125};
126
127template<typename T>
128struct is_static_named_var : std::false_type {};
129
130template<std::size_t N, typename T>
131struct is_static_named_var<StaticNamedVar<N, T>> : std::true_type {};
132
133template<typename T>
135
136template<std::size_t N, typename T = double>
137[[nodiscard]] constexpr StaticNamedVar<N, T> named(std::string_view name) noexcept {
138 return StaticNamedVar<N, T>{name};
139}
140
141// Multi-variable declaration helpers
142
143template<std::size_t N, typename T, std::size_t... Is>
144constexpr auto declare_vars_impl(std::array<std::string_view, N> const& names,
145 std::index_sequence<Is...>) {
146 return std::make_tuple(StaticNamedVar<Is, T>{names[Is]}...);
147}
148
150template<std::size_t N, typename T = double, typename... Names>
151 requires (sizeof...(Names) == N)
152[[nodiscard]] constexpr auto declare_vars(Names... names) {
153 std::array<std::string_view, N> name_array{names...};
154 return declare_vars_impl<N, T>(name_array, std::make_index_sequence<N>{});
155}
156
157template<typename T = double>
158[[nodiscard]] constexpr auto vars_xy(std::string_view x_name = "x",
159 std::string_view y_name = "y") {
160 return std::make_pair(StaticNamedVar<0, T>{x_name},
161 StaticNamedVar<1, T>{y_name});
162}
163
164template<typename T = double>
165[[nodiscard]] constexpr auto vars_xyz(std::string_view x_name = "x",
166 std::string_view y_name = "y",
167 std::string_view z_name = "z") {
168 return std::make_tuple(StaticNamedVar<0, T>{x_name},
169 StaticNamedVar<1, T>{y_name},
170 StaticNamedVar<2, T>{z_name});
171}
172
173} // namespace limes::expr
Expression layer for composable calculus.
Definition analysis.hpp:7
constexpr StaticNamedVar< N, T > named(std::string_view name) noexcept
constexpr auto declare_vars(Names... names)
Usage: auto [x, y, z] = declare_vars<3>("x", "y", "z");.
constexpr bool is_static_named_var_v
constexpr auto vars_xyz(std::string_view x_name="x", std::string_view y_name="y", std::string_view z_name="z")
constexpr auto declare_vars_impl(std::array< std::string_view, N > const &names, std::index_sequence< Is... >)
constexpr bool is_named_var_v
Definition named_var.hpp:76
constexpr NamedVar< T > var(std::size_t dim, std::string_view name) noexcept
Definition named_var.hpp:79
constexpr auto vars_xy(std::string_view x_name="x", std::string_view y_name="y")
std::string_view name
Definition named_var.hpp:26
constexpr NamedVar(std::size_t dimension, std::string_view n) noexcept
Definition named_var.hpp:28
std::string to_string() const
Definition named_var.hpp:60
constexpr std::size_t dimension() const noexcept
Definition named_var.hpp:64
constexpr auto derivative_rt(std::size_t d) const noexcept
Definition named_var.hpp:56
constexpr auto derivative() const noexcept
Definition named_var.hpp:48
constexpr T eval(std::span< T const > args) const noexcept
Definition named_var.hpp:35
constexpr std::size_t arity() const noexcept
Definition named_var.hpp:31
constexpr T evaluate(std::span< T const > args) const noexcept
Definition named_var.hpp:41
static constexpr std::size_t arity_v
Definition named_var.hpp:23
constexpr T evaluate(std::span< T const > args) const noexcept
static constexpr std::size_t arity_v
Definition named_var.hpp:92
static constexpr std::size_t index_v
Definition named_var.hpp:93
std::string to_string() const
constexpr auto derivative() const noexcept
static constexpr std::size_t dimension() noexcept
constexpr T eval(std::span< T const > args) const noexcept
Definition named_var.hpp:99
constexpr StaticNamedVar(std::string_view n) noexcept
Definition named_var.hpp:97