Skip to content
Open
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
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ set(SeQuant_src
SeQuant/core/runtime.hpp
SeQuant/core/space.cpp
SeQuant/core/space.hpp
SeQuant/core/slotted_index.hpp
SeQuant/core/tag.hpp
SeQuant/core/tensor_canonicalizer.cpp
SeQuant/core/tensor_canonicalizer.hpp
Expand Down Expand Up @@ -359,6 +360,7 @@ set(SeQuant_src
SeQuant/core/utility/macros.hpp
SeQuant/core/utility/memoize.hpp
SeQuant/core/utility/nodiscard.hpp
SeQuant/core/utility/overloads.hpp
SeQuant/core/utility/permutation.hpp
SeQuant/core/utility/scope.hpp
SeQuant/core/utility/singleton.hpp
Expand All @@ -381,6 +383,7 @@ set(SeQuant_src
SeQuant/domain/mbpt/context.hpp
SeQuant/domain/mbpt/convention.cpp
SeQuant/domain/mbpt/convention.hpp
SeQuant/domain/mbpt/detail/concepts.hpp
SeQuant/domain/mbpt/models/cc.cpp
SeQuant/domain/mbpt/models/cc.hpp
SeQuant/domain/mbpt/op_registry.hpp
Expand Down
31 changes: 31 additions & 0 deletions SeQuant/core/attr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <cassert>
#include <cstdlib>
#include <ostream>
#include <string>

namespace sequant {
Expand Down Expand Up @@ -79,6 +80,36 @@ inline std::wstring to_wolfram(BraKetPos a) {
}
}

/// index slot types
///
/// @note This does not include slot bundles, like braket, etc.
enum class SlotType {
Bra,
Ket,
Aux,
Proto,
};

template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& stream, SlotType origin) {
switch (origin) {
case SlotType::Bra:
stream << "Bra";
break;
case SlotType::Ket:
stream << "Ket";
break;
case SlotType::Aux:
stream << "Aux";
break;
case SlotType::Proto:
stream << "Proto";
break;
}
return stream;
}

enum class Statistics {
FermiDirac,
BoseEinstein,
Expand Down
26 changes: 0 additions & 26 deletions SeQuant/core/expressions/abstract_tensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

#include <cstdlib>
#include <memory>
#include <ostream>
#include <stdexcept>
#include <string>
#include <string_view>
Expand All @@ -27,31 +26,6 @@

namespace sequant {

/// index slot types
///
/// @note This does not include slot bundles, like braket, etc.
enum class SlotType { Bra = 0, Ket = 1, Aux = 2, Proto = 3 };

template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& stream, SlotType origin) {
switch (origin) {
case SlotType::Bra:
stream << "Bra";
break;
case SlotType::Ket:
stream << "Ket";
break;
case SlotType::Aux:
stream << "Aux";
break;
case SlotType::Proto:
stream << "Proto";
break;
}
return stream;
}

class TensorCanonicalizer;

/// AbstractTensor is a [tensor](https://en.wikipedia.org/wiki/Tensor) over
Expand Down
18 changes: 14 additions & 4 deletions SeQuant/core/expressions/result_expr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <SeQuant/core/expressions/tensor.hpp>
#include <SeQuant/core/expressions/variable.hpp>
#include <SeQuant/core/index.hpp>
#include <SeQuant/core/slotted_index.hpp>
#include <SeQuant/core/utility/macros.hpp>

#include <initializer_list>
Expand Down Expand Up @@ -102,15 +103,24 @@ class ResultExpr {
// based on the particle they belong to and that bra and
// ket indices are assigned to the same set of particles.
for (std::size_t i = 0; i < m_braIndices.size(); ++i) {
if constexpr (std::is_constructible_v<Group,
std::initializer_list<Index>>) {
if constexpr (std::is_constructible_v<
Group, std::initializer_list<SlottedIndex>>) {
groups.emplace_back(std::initializer_list<SlottedIndex>{
{m_braIndices.at(i), SlotType::Bra},
{m_ketIndices.at(i), SlotType::Ket}});
} else if constexpr (std::is_constructible_v<
Group, std::initializer_list<Index>>) {
groups.emplace_back(std::initializer_list<Index>{m_braIndices.at(i),
m_ketIndices.at(i)});
} else if constexpr (std::is_constructible_v<Group, SlottedIndex,
SlottedIndex>) {
groups.emplace_back(SlottedIndex{m_braIndices.at(i), SlotType::Bra},
SlottedIndex{m_ketIndices.at(i), SlotType::Ket});
} else {
static_assert(
std::is_constructible_v<Group, Index, Index>,
"Group is expected to be constructible from two indices or from an "
"initializer_list of indices");
"Group is expected to be constructible from two (slotted) indices "
"or from an initializer_list of (slotted) indices");
groups.emplace_back(m_braIndices.at(i), m_ketIndices.at(i));
}
}
Expand Down
78 changes: 77 additions & 1 deletion SeQuant/core/meta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

#include <complex>
#include <memory>
#include <type_traits>

#include <range/v3/range/access.hpp>
#include <range/v3/range/traits.hpp>
#include <type_traits>

namespace sequant {

Expand Down Expand Up @@ -506,6 +507,81 @@ struct std_array_size<std::array<T, N>>
template <typename T>
constexpr inline std::size_t std_array_size_v = std_array_size<T>::value;

/// make_immutable_t
/// Contrary to std::add_const_t, this works as one would expect on reference
/// types
template <typename T>
using make_immutable_t = std::conditional_t<
std::is_lvalue_reference_v<T>,
std::add_lvalue_reference_t<std::add_const_t<std::remove_reference_t<T>>>,
std::conditional_t<std::is_rvalue_reference_v<T>,
std::add_rvalue_reference_t<
std::add_const_t<std::remove_reference_t<T>>>,
std::add_const_t<T>>>;
static_assert(std::is_const_v<make_immutable_t<float>>);
static_assert(std::is_const_v<make_immutable_t<const float>>);
static_assert(std::is_lvalue_reference_v<make_immutable_t<float &>>);
static_assert(std::is_lvalue_reference_v<make_immutable_t<const float &>>);
static_assert(
std::is_const_v<std::remove_reference_t<make_immutable_t<float &>>>);
static_assert(
std::is_const_v<std::remove_reference_t<make_immutable_t<const float &>>>);
static_assert(std::is_rvalue_reference_v<make_immutable_t<float &&>>);
static_assert(std::is_rvalue_reference_v<make_immutable_t<const float &&>>);
static_assert(
std::is_const_v<std::remove_reference_t<make_immutable_t<float &&>>>);
static_assert(
std::is_const_v<std::remove_reference_t<make_immutable_t<const float &&>>>);

/// make_mutable_t
/// Contrary to std::remove_const_t, this works as one would expect on reference
/// types
template <typename T>
using make_mutable_t = std::conditional_t<
std::is_lvalue_reference_v<T>,
std::add_lvalue_reference_t<
std::remove_const_t<std::remove_reference_t<T>>>,
std::conditional_t<std::is_rvalue_reference_v<T>,
std::add_rvalue_reference_t<
std::remove_const_t<std::remove_reference_t<T>>>,
std::remove_const_t<T>>>;
static_assert(!std::is_const_v<make_mutable_t<float>>);
static_assert(!std::is_const_v<make_mutable_t<const float>>);
static_assert(std::is_lvalue_reference_v<make_mutable_t<float &>>);
static_assert(std::is_lvalue_reference_v<make_mutable_t<const float &>>);
static_assert(
!std::is_const_v<std::remove_reference_t<make_mutable_t<float &>>>);
static_assert(
!std::is_const_v<std::remove_reference_t<make_mutable_t<const float &>>>);
static_assert(std::is_rvalue_reference_v<make_mutable_t<float &&>>);
static_assert(std::is_rvalue_reference_v<make_mutable_t<const float &&>>);
static_assert(
!std::is_const_v<std::remove_reference_t<make_mutable_t<float &&>>>);
static_assert(
!std::is_const_v<std::remove_reference_t<make_mutable_t<const float &&>>>);

/// is_immutable_v
/// Contrary to std::is_const_v, this works as one would expect on reference
/// types
template <typename T>
constexpr bool is_immutable_v = std::is_const_v<std::remove_reference_t<T>>;
static_assert(is_immutable_v<const float>);
static_assert(!is_immutable_v<float>);
static_assert(is_immutable_v<const float &>);
static_assert(!is_immutable_v<float &>);
static_assert(is_immutable_v<const float &&>);
static_assert(!is_immutable_v<float &&>);

/// mimic_constness_t
/// Makes To const, if From is const, else makes To non-const
template <typename From, typename To>
using mimic_constness_t =
std::conditional_t<is_immutable_v<From>, make_immutable_t<To>,
make_mutable_t<To>>;
static_assert(
std::same_as<mimic_constness_t<const int &, float &>, const float &>);
static_assert(std::same_as<mimic_constness_t<int &, const float &>, float &>);

} // namespace meta
} // namespace sequant

Expand Down
42 changes: 42 additions & 0 deletions SeQuant/core/slotted_index.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef SEQUANT_SLOTTED_INDEX_H
#define SEQUANT_SLOTTED_INDEX_H

#include <SeQuant/core/attr.hpp>
#include <SeQuant/core/index.hpp>

namespace sequant {

/// Combination of an Index along with information about the Slot it occupies
///
/// @note Usage of this class only makes sense, if the index in question does
/// not appear in multiple slots
///
/// @sa Index
/// @sa Slot
class SlottedIndex {
public:
SlottedIndex(Index idx, SlotType slot)
: idx_(std::move(idx)), slot_(std::move(slot)) {}

Index &index() { return idx_; }

const Index &index() const { return idx_; }

SlotType slot_type() const { return slot_; }

friend bool operator==(const SlottedIndex &lhs, const SlottedIndex &rhs) {
return lhs.index() == rhs.index() && lhs.slot_type() == rhs.slot_type();
}

friend bool operator!=(const SlottedIndex &lhs, const SlottedIndex &rhs) {
return !(lhs == rhs);
}

private:
Index idx_;
SlotType slot_;
};

} // namespace sequant

#endif
Loading