Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions SeQuant/core/index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,9 @@ std::string Index::to_string() const {
return sequant::to_string(this->label());
}

std::shared_ptr<const IndexSpaceRegistry>
Index::obtain_default_index_registry() {
return get_default_context().index_space_registry();
}

} // namespace sequant
18 changes: 10 additions & 8 deletions SeQuant/core/index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@
#define SEQUANT_INDEX_H

#include <SeQuant/core/container.hpp>
#include <SeQuant/core/context.hpp>
#include <SeQuant/core/hash.hpp>
#include <SeQuant/core/index_space_registry.hpp>
#include <SeQuant/core/space.hpp>
#include <SeQuant/core/tag.hpp>
#include <SeQuant/core/utility/macros.hpp>
#include <SeQuant/core/utility/string.hpp>
#include <SeQuant/core/utility/swap.hpp>

#include <algorithm>
#include <atomic>
#include <charconv>
#include <cstdint>
#include <cwchar>
#include <functional>
#include <initializer_list>
#include <iostream>
#include <iterator>
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <stdexcept>
Expand Down Expand Up @@ -328,12 +329,11 @@ class Index : public Taggable {
/// the cost of slightly increased danger
template <basic_string_convertible String>
Index(String &&label)
: Index(
get_default_context().index_space_registry()
? get_default_context().index_space_registry()->retrieve(label)
: IndexSpace{base_label(label), IndexSpace::Type::reserved,
IndexSpace::QuantumNumbers::reserved},
to_ordinal(label), {}) {
: Index(obtain_default_index_registry()
? obtain_default_index_registry()->retrieve(label)
: IndexSpace{base_label(label), IndexSpace::Type::reserved,
IndexSpace::QuantumNumbers::reserved},
to_ordinal(label), {}) {
check_nonreserved();
if constexpr (std::is_same_v<String, std::wstring>) {
label_ = std::move(label);
Expand Down Expand Up @@ -1043,6 +1043,8 @@ class Index : public Taggable {
return i1_Q < i2_Q ? SO::less : SO::greater;
}

static std::shared_ptr<const IndexSpaceRegistry> obtain_default_index_registry();

}; // class Index

inline const IndexSpace::Attr Index::default_space_attr{
Expand Down
4 changes: 2 additions & 2 deletions SeQuant/core/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ CanonicalizeOptions CanonicalizeOptions::copy_and_set(
}

CanonicalizeOptions CanonicalizeOptions::copy_and_set(
std::optional<std::initializer_list<Index>> arg) const {
std::optional<std::vector<Index>> arg) const {
auto result = *this;
result.named_indices = arg;
result.named_indices = std::move(arg);
return result;
}

Expand Down
11 changes: 6 additions & 5 deletions SeQuant/core/options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
#ifndef SEQUANT_CORE_OPTIONS_HPP
#define SEQUANT_CORE_OPTIONS_HPP

#include <SeQuant/core/index.hpp>

#include <optional>
#include <string>
#include <vector>

namespace sequant {

class Index;

/// canonicalization methods
enum class CanonicalizationMethod {
/// Enables use of expression topology in the canonicalization, may be
Expand Down Expand Up @@ -47,7 +49,7 @@ struct CanonicalizeOptions {
/// specifies named indices; by default all indices that appear only once are
/// deduced to be named, but this may be misleading if e.g. single
/// summed-over dummy index appears in an expression
std::optional<std::initializer_list<Index>> named_indices = std::nullopt;
std::optional<std::vector<Index>> named_indices = std::nullopt;
/// whether to ignore the labels of named indices. Setting
/// to false will cause named indices to be treated as equivalent slots, which
/// the result to be independent of their labels. This does not make sense in
Expand All @@ -57,8 +59,7 @@ struct CanonicalizeOptions {

static CanonicalizeOptions default_options();
CanonicalizeOptions copy_and_set(CanonicalizationMethod) const;
CanonicalizeOptions copy_and_set(
std::optional<std::initializer_list<Index>>) const;
CanonicalizeOptions copy_and_set(std::optional<std::vector<Index>>) const;
CanonicalizeOptions copy_and_set(IgnoreNamedIndexLabel) const;

friend constexpr bool operator==(const CanonicalizeOptions& a,
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/test_spin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,20 @@ SECTION("partial spintracing + S_maps = full spintracing") {
//(canonicalized: -2 t{a_1,a_2;i_2,i_1}:N-C-S + 4 t{a_1,a_2;i_1,i_2}:N-C-S)
}

SECTION("external indices have to remain consistent") {
// Internally, closed_shell_spintrace performs canonicalization which can end
// up renaming external indices (due to the presence of the symmetrizer). This
// will cause an inconsistency with the explicitly provided external index
// names.
ExprPtr input = parse_expr(
L"A{p_8,p_9;a_8,a_9}:A-C-S * y{p_3,p_4;p_8,p_9}:A-C-S * "
L"g{i_3,a_8;p_3,p_4}:A-C-S * t{a_9;i_3}:A-C-S");
ExprPtr result =
closed_shell_spintrace(input, {{L"a_8", L"p_8"}, {L"a_9", L"p_9"}});

// REQUIRE_THAT(result, EquivalentTo(L"TODO"));
}

SECTION("Symmetrize expression") {
{
// g * t1 + g * t1
Expand Down
Loading