Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
symmetryfactor.hpp
Go to the documentation of this file.
1
6#pragma once
7
8#include <cstdint>
9#include <stdexcept>
10#include <string>
11#include <string_view>
12#include <unordered_map>
13
14namespace uni20::detail
15{
16
18class SymmetryFactorBase {
19 public:
20 virtual ~SymmetryFactorBase() = default;
21
24 virtual auto type_name() const -> std::string_view = 0;
25
29 virtual auto dual_code(std::uint64_t code) const -> std::uint64_t = 0;
30
34 virtual auto qdim_code(std::uint64_t code) const -> double = 0;
35
39 virtual auto degree_code(std::uint64_t code) const -> int = 0;
40
45 virtual auto add_codes(std::uint64_t lhs, std::uint64_t rhs) const -> std::uint64_t = 0;
46
50 virtual auto format_code(std::uint64_t code) const -> std::string = 0;
51};
52
55template <typename Q> struct SymmetryFactorTraits;
56
59template <typename Q> class SymmetryFactor final : public SymmetryFactorBase {
60 public:
64 auto encode(Q const& value) const -> std::uint64_t { return SymmetryFactorTraits<Q>::encode(value); }
65
69 auto decode(std::uint64_t code) const -> Q { return SymmetryFactorTraits<Q>::decode(code); }
70
73 auto type_name() const -> std::string_view override { return SymmetryFactorTraits<Q>::type_name(); }
74
78 auto dual_code(std::uint64_t code) const -> std::uint64_t override
79 {
80 return this->encode(dual(this->decode(code)));
81 }
82
86 auto qdim_code(std::uint64_t code) const -> double override { return qdim(this->decode(code)); }
87
91 auto degree_code(std::uint64_t code) const -> int override { return degree(this->decode(code)); }
92
97 auto add_codes(std::uint64_t lhs, std::uint64_t rhs) const -> std::uint64_t override
98 {
99 return this->encode(this->decode(lhs) + this->decode(rhs));
100 }
101
105 auto format_code(std::uint64_t code) const -> std::string override { return to_string(this->decode(code)); }
106};
107
110inline auto symmetry_factor_registry() -> std::unordered_map<std::string, SymmetryFactorBase const*>&
111{
112 static std::unordered_map<std::string, SymmetryFactorBase const*> registry;
113 return registry;
114}
115
119inline auto register_symmetry_factor(SymmetryFactorBase const* factor) -> SymmetryFactorBase const*
120{
121 symmetry_factor_registry().emplace(std::string{factor->type_name()}, factor);
122 return factor;
123}
124
128inline auto find_symmetry_factor(std::string_view type_name) -> SymmetryFactorBase const*
129{
130 auto const it = symmetry_factor_registry().find(std::string{type_name});
131 if (it == symmetry_factor_registry().end())
132 {
133 throw std::invalid_argument("unsupported symmetry factor type: " + std::string{type_name});
134 }
135 return it->second;
136}
137
138} // namespace uni20::detail
locale_t value
Definition data_table.cpp:49
Definition qnum.hpp:403
auto degree(QNum const &q) -> int
Return the integral degree of a quantum number.
Definition qnum.hpp:270
auto qdim(QNum const &q) -> double
Return the quantum dimension of a quantum number.
Definition qnum.hpp:255
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