25template <
class SpaceType>
class Dual;
30template <
class T>
struct IsDualSpace : std::false_type
33template <
class SpaceType>
struct IsDualSpace<
Dual<SpaceType>> : std::true_type
36template <
class T>
struct PrimalSpaceType
38 using type = std::remove_cvref_t<T>;
41template <
class SpaceType>
struct PrimalSpaceType<
Dual<SpaceType>>
43 using type = SpaceType;
46inline auto dual_space_entry(QNum
const& q) -> QNum {
return dual(q); }
48inline auto dual_space_entry(BlockSector
const& sector) -> BlockSector
50 return BlockSector{
dual(sector.q), sector.dim};
53template <std::input_iterator Iterator>
class DualSpaceIterator {
55 using iterator_concept = std::input_iterator_tag;
56 using iterator_category = std::input_iterator_tag;
57 using difference_type = std::iter_difference_t<Iterator>;
58 using value_type = std::remove_cvref_t<decltype(dual_space_entry(*std::declval<Iterator const&>()))>;
61 requires std::default_initializable<Iterator>
64 explicit DualSpaceIterator(Iterator iterator) : iterator_(
std::move(iterator)) {}
66 auto operator*() const -> value_type {
return dual_space_entry(*iterator_); }
68 auto operator++() -> DualSpaceIterator&
74 void operator++(
int) { ++iterator_; }
76 auto operator==(DualSpaceIterator
const&)
const ->
bool =
default;
89template <
class SpaceType>
class Dual {
91 static_assert(!detail::IsDualSpace<std::remove_cvref_t<SpaceType>>
::value,
92 "use dual(Dual<S>) to recover S instead of nesting Dual adaptors");
108 return space_.symmetry();
112 auto label() const ->
std::
string const& {
return space_.label(); }
121 { space.size() } -> std::same_as<std::size_t>;
124 return space_.size();
130 { space.empty() } -> std::convertible_to<bool>;
133 return space_.empty();
139 { space.total_dim() } -> std::same_as<std::size_t>;
142 return space_.total_dim();
148 { space.extent() } -> std::same_as<std::size_t>;
151 return space_.extent();
157 { space.qnum() } -> std::convertible_to<QNum>;
160 return dual(space_.qnum());
168 using entry_type = std::remove_cvref_t<
decltype(space_[index])>;
169 static_assert(std::same_as<entry_type, QNum> || std::same_as<entry_type, BlockSector>,
170 "indexed Dual-space access currently supports QNum and BlockSector entries");
171 return detail::dual_space_entry(space_[index]);
178 return detail::DualSpaceIterator(space_.begin());
185 return detail::DualSpaceIterator(space_.end());
192 return space_.qnums() | std::views::transform([](
QNum const& q) {
return dual(q); });
199 return space_.sectors() |
207 { space.contains(
value) } -> std::convertible_to<bool>;
210 if (!q.valid() || q.symmetry() != this->
symmetry())
212 throw std::invalid_argument(
"Dual-space query has the wrong symmetry");
214 return space_.contains(
dual(q));
236template <
class T>
using primal_space_t =
typename detail::PrimalSpaceType<std::remove_cvref_t<T>>::type;
242template <Space SpaceType>
253template <Space SpaceType>
254 requires(!DualSpace<SpaceType>)
270template <
class SpaceType>
auto dual(
Dual<SpaceType>&& space) -> SpaceType {
return std::move(space).release_base(); }
Defines one quantum-number sector and its degeneracy dimension.
Tensor space represented in an explicitly dual basis.
Definition dual_space.hpp:89
Dual(base_space_type space)
Construct a dual adaptor from its primal-basis value.
Definition dual_space.hpp:99
auto symmetry() const -> Symmetry
Return the symmetry shared with the underlying space.
Definition dual_space.hpp:105
auto contains(QNum q) const -> bool
Return whether the exposed dual basis contains an irrep.
Definition dual_space.hpp:205
auto qnum() const -> QNum
Return the dual of a fixed irrep label.
Definition dual_space.hpp:155
auto empty() const -> bool
Forward whether the underlying space is empty.
Definition dual_space.hpp:128
auto operator==(Dual const &other) const -> bool=default
Compare explicit dual-basis space values.
auto release_base() &&-> base_space_type
Transfer the underlying primal-basis value out of this adaptor.
Definition dual_space.hpp:221
auto qnums() const
Return a lazy range of dualized local-state quantum numbers.
Definition dual_space.hpp:189
auto operator[](std::size_t index) const
Return one dualized basis occurrence without changing its index.
Definition dual_space.hpp:165
auto label() const -> std::string const &
Return the semantic leg label.
Definition dual_space.hpp:112
void set_label(std::string label)
Replace the semantic leg label without changing the basis.
Definition dual_space.hpp:116
auto total_dim() const -> std::size_t
Forward the total degeneracy dimension.
Definition dual_space.hpp:137
auto size() const -> std::size_t
Forward the number of structural basis occurrences.
Definition dual_space.hpp:119
auto end() const
Return the end iterator for dualized basis occurrences.
Definition dual_space.hpp:182
auto begin() const
Return an iterator which dualizes each observed basis occurrence.
Definition dual_space.hpp:175
auto sectors() const
Return a lazy range of dualized block sectors.
Definition dual_space.hpp:196
auto extent() const -> std::size_t
Forward a symmetry-neutral dense extent.
Definition dual_space.hpp:146
SpaceType base_space_type
Definition dual_space.hpp:95
auto base() const &noexcept -> base_space_type const &
Return the underlying primal-basis space.
Definition dual_space.hpp:102
One irrep label together with the symmetry context needed to interpret it.
Definition qnum.hpp:29
Public handle to a canonicalized direct-product symmetry specification.
Definition symmetry.hpp:24
Space value whose object basis is explicitly dual.
Definition dual_space.hpp:232
Tensor-space value with a mutable semantic leg label.
Definition space.hpp:22
Space whose structure is interpreted in one explicit symmetry context.
Definition space.hpp:31
locale_t value
Definition data_table.cpp:49
Var< T > operator*(T x, Var< T > y)
Computes x * y with reverse-mode gradient propagation.
Definition var_toys.hpp:176
typename optional_traits< T >::value_type value_type
Definition data_table.hpp:42
Definition async/async.hpp:26
typename detail::PrimalSpaceType< std::remove_cvref_t< T > >::type primal_space_t
Remove one explicit dual-space adaptor from a space type.
Definition dual_space.hpp:236
bool operator==(exact_rational const &a, exact_rational const &b)
Definition exact_rational.hpp:284
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
Dual(SpaceType &&) -> Dual< std::remove_cvref_t< SpaceType > >
Defines packed quantum numbers and same-symmetry quantum-number containers.
Defines the common tensor-space concepts.
One symmetry sector inside a block-structured space.
Definition block_sector.hpp:18
QNum q
Quantum number carried by the block.
Definition block_sector.hpp:20
std::size_t dim
Degeneracy / number of states in the block.
Definition block_sector.hpp:23