Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
u1.hpp
Go to the documentation of this file.
1
8#pragma once
9
12
13#include <concepts>
14#include <cstdint>
15#include <format>
16#include <functional>
17#include <iosfwd>
18#include <limits>
19#include <ostream>
20#include <stdexcept>
21#include <string>
22#include <string_view>
23
24namespace uni20
25{
26
29class U1 {
30 public:
32 constexpr U1() = default;
33
36 constexpr explicit U1(half_int value) : value_(value) {}
37
40 template <std::integral T> constexpr U1(T value) : value_(value) {}
41
44 template <std::floating_point T> explicit U1(T value) : value_(value) {}
45
48 constexpr auto value() const -> half_int { return value_; }
49
53 constexpr auto operator<=>(U1 const& other) const = default;
54
55 private:
56 half_int value_{};
57};
58
62inline constexpr auto dual(U1 value) -> U1 { return U1{-value.value()}; }
63
67inline constexpr auto qdim(U1 value) -> double
68{
69 static_cast<void>(value);
70 return 1.0;
71}
72
76inline constexpr auto degree(U1 value) -> int
77{
78 static_cast<void>(value);
79 return 1;
80}
81
86inline constexpr auto operator+(U1 lhs, U1 rhs) -> U1 { return U1{lhs.value() + rhs.value()}; }
87
92inline constexpr auto operator-(U1 lhs, U1 rhs) -> U1 { return U1{lhs.value() - rhs.value()}; }
93
97inline auto to_string(U1 value) -> std::string { return uni20::to_string(value.value()); }
98
102inline auto to_string_fraction(U1 value) -> std::string { return uni20::to_string_fraction(value.value()); }
103
108inline auto operator<<(std::ostream& out, U1 value) -> std::ostream&
109{
110 out << to_string(value);
111 return out;
112}
113
114} // namespace uni20
115
116namespace uni20::detail
117{
118
120template <> struct SymmetryFactorTraits<uni20::U1>
121{
124 static constexpr auto type_name() -> std::string_view { return "U(1)"; }
125
129 static constexpr auto encode(uni20::U1 value) -> std::uint64_t
130 {
131 auto const twice_value = value.value().twice();
132 if (twice_value == 0)
133 {
134 return 0;
135 }
136 if (twice_value > 0)
137 {
138 auto const magnitude = static_cast<std::uint64_t>(twice_value);
139 return magnitude * 2 - 1;
140 }
141
142 if (twice_value == std::numeric_limits<half_int::value_type>::min())
143 {
144 throw std::overflow_error("U1 encoding cannot represent the most negative half_int value");
145 }
146
147 auto const magnitude = static_cast<std::uint64_t>(-twice_value);
148 return magnitude * 2;
149 }
150
154 static constexpr auto decode(std::uint64_t code) -> uni20::U1
155 {
156 if (code == 0)
157 {
158 return uni20::U1{};
159 }
160 if ((code & 1U) != 0U)
161 {
162 return uni20::U1{from_twice(static_cast<half_int::value_type>((code + 1) / 2))};
163 }
164 return uni20::U1{from_twice(-static_cast<half_int::value_type>(code / 2))};
165 }
166};
167
170inline auto u1_factor() -> SymmetryFactor<uni20::U1> const&
171{
172 static SymmetryFactor<uni20::U1> factor;
173 static auto const* registered = register_symmetry_factor(&factor);
174 static_cast<void>(registered);
175 return factor;
176}
177
179inline void register_builtin_symmetry_factors() { static_cast<void>(u1_factor()); }
180
181} // namespace uni20::detail
182
183template <typename CharT> struct std::formatter<uni20::U1, CharT>
184{
185 constexpr auto parse(std::basic_format_parse_context<CharT>& ctx) { return ctx.begin(); }
186
187 template <typename FormatContext> auto format(uni20::U1 const& value, FormatContext& ctx) const
188 {
189 return std::format_to(ctx.out(), "{}", uni20::to_string(value));
190 }
191};
192
193template <> struct std::hash<uni20::U1>
194{
198 auto operator()(uni20::U1 const& value) const noexcept -> std::size_t
199 {
200 return std::hash<uni20::half_int>{}(value.value());
201 }
202};
Value-level quantum number type representing one U(1) irrep.
Definition u1.hpp:29
constexpr auto value() const -> half_int
Return the stored U(1) charge.
Definition u1.hpp:48
constexpr U1(T value)
Construct from an integral U(1) charge.
Definition u1.hpp:40
constexpr U1()=default
Construct the scalar U(1) irrep.
constexpr auto operator<=>(U1 const &other) const =default
Compare two U(1) irreps by charge.
U1(T value)
Construct from a floating-point U(1) charge by rounding to the nearest half-integer.
Definition u1.hpp:44
constexpr U1(half_int value)
Construct from a half-integer U(1) charge.
Definition u1.hpp:36
T value_type
Underlying signed storage type.
Definition half_int.hpp:37
locale_t value
Definition data_table.cpp:49
Defines basic_half_int<T>, a signed integer type with half-integer resolution.
DiagnosticMagnitude< R > magnitude(R const &value)
Definition gmres_diagnostics.hpp:98
Definition async/async.hpp:26
auto operator<<(std::ostream &out, basic_half_int< T > value) -> std::ostream &
Stream a half-integer in integer or .5 decimal form.
Definition half_int.hpp:515
auto degree(QNum const &q) -> int
Return the integral degree of a quantum number.
Definition qnum.hpp:270
constexpr auto operator-(basic_half_int< T > lhs, basic_half_int< T > rhs) -> basic_half_int< T >
Subtract two half-integer values.
Definition half_int.hpp:345
auto qdim(QNum const &q) -> double
Return the quantum dimension of a quantum number.
Definition qnum.hpp:255
constexpr auto from_twice(T twice_value) -> basic_half_int< T >
Construct a half-integer from its doubled representation.
Definition half_int.hpp:322
auto to_string_fraction(basic_half_int< T > value) -> std::string
Format a half-integer as an integer or n/2.
Definition half_int.hpp:464
auto dual(SpaceType const &space) -> Dual< std::remove_cvref_t< SpaceType > >
Construct an explicitly dual basis without changing occurrence order.
Definition dual_space.hpp:244
auto to_string(basic_half_int< T > value) -> std::string
Format a half-integer as an integer or decimal .5.
Definition half_int.hpp:477
auto format(uni20::U1 const &value, FormatContext &ctx) const
Definition u1.hpp:187
constexpr auto parse(std::basic_format_parse_context< CharT > &ctx)
Definition u1.hpp:185
auto operator()(uni20::U1 const &value) const noexcept -> std::size_t
Hash a U(1) irrep by its stored half-integer charge.
Definition u1.hpp:198
Defines the internal runtime interface for concrete symmetry-factor adapters.