Class Expr¶
Defined in File expr.hpp
Nested Relationships¶
Nested Types¶
Inheritance Relationships¶
Base Type¶
public std::enable_shared_from_this< Expr >
Derived Types¶
public sequant::NormalOperatorSequence< S >(Template Class NormalOperatorSequence)public sequant::Operator< S >(Template Class Operator)public sequant::Operator< void, S >(Template Class Operator)public sequant::Constant(Class Constant)public sequant::NormalOperatorSequence< S >(Template Class NormalOperatorSequence)public sequant::Operator< S >(Template Class Operator)public sequant::Power(Class Power)public sequant::Product(Class Product)public sequant::Sum(Class Sum)public sequant::Tensor(Class Tensor)public sequant::Variable(Class Variable)public sequant::mbpt::Operator< void, S >(Template Class Operator< void, S >)
Class Documentation¶
-
class Expr : public std::enable_shared_from_this<Expr>¶
Base expression class.
Expr represents the interface needed to form expression trees. Classes that represent expressions should publicly derive from this class. Each Expr on a tree has links to its children Expr objects. The lifetime of Expr objects is expected to be managed by std::shared_ptr . Expr is an Iterable over subexpressions (each of which is an Expr itself). More precisely, Expr meets the SizedIterable concept (see https://raw.githubusercontent.com/ericniebler/range-v3/master/doc/std/D4128.md). Specifically, iterators to subexpressions dereference to ExprPtr. Since Expr is a range, it provides begin/end/etc. that can participate in overloads with other functions in the derived class. Consider a Container class derived from a BaseContainer class:
There are two possible scenarios:template <typename T> class Container : public BaseContainer, public Expr { // WARNING: BaseContainer::begin clashes with Expr::begin // WARNING: BaseContainer::end clashes with Expr::end // etc. };
if
Containeris a container of Expr objects, BaseContainer will iterate over ExprPtr objects already and both ranges will be equivalent; it is sufficient to addusing BaseContainer::begin, etc. to Container’s public API.if
Containeris a container of non-Expr objects, iteration over BaseContainer is likely to be more commonly used in practice, hence again addingusing BaseContainer::begin, etc. will suffice. To be able to iterate over subexpression range (in this case it is empty) Expr provides Expr::expr member to cast to Expr:Container c(...); for(const auto& e: c) { // iterates over elements of BaseContainer } for(const auto& e: c.expr()) { // iterates over subexpressions }
Subclassed by sequant::NormalOperatorSequence< S >, sequant::Operator< S >, sequant::Operator< void, S >, sequant::Constant, sequant::NormalOperatorSequence< S >, sequant::Operator< S >, sequant::Power, sequant::Product, sequant::Sum, sequant::Tensor, sequant::Variable, sequant::mbpt::Operator< void, S >
Public Types
-
using hash_type = std::size_t¶
-
using type_id_type = std::uint64_t¶
-
using type_rank_type = std::uint8_t¶
Public Functions
-
Expr() = default¶
-
virtual ~Expr() = default¶
-
inline bool is_atom() const¶
- Returns:
true if this is a leaf
-
inline virtual bool is_zero() const¶
- Returns:
true if this is zero
-
virtual std::wstring to_latex() const¶
- Returns:
the string representation of
thisin the LaTeX format
-
virtual ExprPtr clone() const = 0¶
- Returns:
a clone of this object, i.e. an object that is equal to
this
-
inline virtual ExprPtr canonicalize(CanonicalizeOptions = CanonicalizeOptions::default_options())¶
Canonicalizes
thisand returns the byproduct of canonicalization (e.g. phase)- Returns:
the byproduct of canonicalization, or
nullptrif no byproduct generated
-
inline virtual ExprPtr rapid_canonicalize(CanonicalizeOptions opts = CanonicalizeOptions::default_options().copy_and_set(CanonicalizationMethod::Rapid))¶
Performs approximate, but fast, canonicalization of
thisand returns the byproduct of canonicalization (e.g. phase) The default is to use canonicalize(), unless overridden in the derived class.- Returns:
the byproduct of canonicalization, or
nullptrif no byproduct generated
-
bool is_canonical(const CanonicalizeOptions &opts = CanonicalizeOptions::default_options()) const¶
Note
always false if
optsdoes not request Complete canonicalization, the only method whose result is the same for every spelling of an expression- Parameters:
opts – the canonicalization options
- Returns:
true if this is the full canonical form that canonicalization with
optsproduced, and since then neither this nor any of its subexpressions has been mutated or replaced, nor have the contexts in effect changed (see current_contexts_version())
-
void mark_canonical(const CanonicalizeOptions &opts, std::uint64_t contexts_version = current_contexts_version()) const¶
records that this, with its subexpressions as they are now, is the full canonical form for
opts, so that is_canonical(opts) holds until this or any of its subexpressions is mutated or replaced, or the contexts in effect changeNote
no-op if
optsdoes not request Complete canonicalizationWarning
only to be called with the result of canonicalization with
opts:canonicalization leaves an expression marked as canonical alone- Parameters:
opts – the canonicalization options
contexts_version – the value of current_contexts_version() when the canonicalization started; if it has changed since, the mark is not valid
-
template<typename Visitor>
inline bool visit(Visitor &&visitor, const bool atoms_only = false)¶ recursively visit this expression, i.e. call visitor on each subexpression in depth-first fashion.
See also
Warning
this will only work for tree expressions; no checking is performed that each subexpression has only been visited once TODO make work for graphs
- Template Parameters:
Visitor – a callable of type void(ExprPtr&) or void(const ExprPtr&)
- Parameters:
visitor – the visitor object
atoms_only – if true, will visit only the leaves; the default is to visit all nodes
- Returns:
true if this object was visited
-
template<typename Visitor>
inline bool visit(Visitor &&visitor, const bool atoms_only = false) const¶ const version of visit
-
inline virtual bool is_scalar() const¶
Reports if this is a pure scalar (number-like) expression.
Note
This is distinct from is_cnumber()
Warning
this returns false for all leaves by default, hence must be overridden for scalar leaf types.
- Returns:
true if this is a scalar
-
inline virtual bool is_cnumber() const¶
Reports if this is a c-number (https://en.wikipedia.org/wiki/C-number), i.e. it commutes multiplicatively with c-numbers and q-numbers.
Note
for leaves this has O(1) cost, for non-leaves this involves checking subexpressions
Warning
this returns true for all leaves, hence must be overridden for leaf q-numbers
- Returns:
true if this is a c-number
-
inline bool commutes_with(const Expr &that) const¶
Checks if this commutes (wrt multiplication) with
that.Note
the default implementation checks if either is c-number; if both are q-numbers this checks commutativity of each subexpression with (each subexpression of)
thatNote
expressions are assumed to always commute with respect to additions since it does not appear that +nonabelian near-rings (https://en.wikipedia.org/wiki/Near-ring) are commonly needed.
Note
commutativity of leaves is checked by commutes_with_atom()
- Returns:
true if this commutes with
that
-
virtual void adjoint() = 0¶
changes this to its adjoint
Computes and returns the hash value. If default
hasheris used then the value will be memoized, otherwisehasherwill be used to compute the hash every time.See also
Note
always returns 0 unless this derived class overrides Expr::memoizing_hash
- Parameters:
hasher – the hasher object, if omitted, the default is used (
- Returns:
the hash value for this Expr
-
virtual type_id_type type_id() const = 0¶
Computes and returns the derived type identifier
See also
- Returns:
the hash value for this Expr
-
template<typename T>
inline bool operator<(const T &that) const¶ Note
the derived class must implement Expr::static_less_than
-
template<typename T>
inline bool is() const¶ - Template Parameters:
T – an Expr type
- Returns:
true if this object is of type
T
-
template<typename T>
inline const T &as() const¶ - Template Parameters:
T – an Expr type
- Returns:
this object cast to type
T
-
template<typename T>
inline T &as()¶ - Template Parameters:
T – an Expr type
- Returns:
this object cast to type
T
-
inline std::string type_name() const¶
Note
uses RTTI
- Returns:
the (demangled) name of this type
-
ExprIterator begin()¶
-
ExprIterator end()¶
-
ConstExprIterator begin() const¶
-
ConstExprIterator end() const¶
-
ConstExprIterator cbegin() const¶
-
ConstExprIterator cend() const¶
-
virtual ExprIterator begin_subexpr()¶
-
virtual ExprIterator end_subexpr()¶
-
virtual ConstExprIterator begin_subexpr() const¶
-
virtual ConstExprIterator end_subexpr() const¶
-
std::size_t size() const¶
-
bool empty() const¶
-
ExprPtr &operator[](std::size_t idx)¶
unchecked element access
Note
the bounds check is only performed if
SEQUANT_ASSERT_ENABLEDis #defined; use at() for a bounds check that is always performed
-
const ExprPtr &operator[](std::size_t idx) const¶
unchecked element access
Note
the bounds check is only performed if
SEQUANT_ASSERT_ENABLEDis #defined; use at() for a bounds check that is always performed
Public Static Functions
-
static inline constexpr type_id_type make_type_id(type_rank_type rank, std::string_view name)¶
- Returns:
the type id of a type of rank
ranknamedname:rankin the top 8 bits, the top 56 bits offnv1a_64(name)below them
-
static inline constexpr type_rank_type type_rank_of(type_id_type id)¶
See also
- Returns:
the rank encoded in type id
id
-
template<typename T>
static inline type_id_type get_type_id()¶ The id is
make_type_id(rank, name), whererankisT::type_rank(astatic constexpr Expr::type_rank_type) ifTdeclares it, else Expr::default_type_rank , andnameissequant::type_name_of<T>(). Hence Expr::operator< orders unlike types by rank first. A type whose relative order must not depend on the compiler declaresstatic constexpr std::string static_type_name(std::type_identity<Self> = {});constexprmakes it usable in constant expressions, but is not required. A derived class inherits its base’stype_rankbut not its name, so unless it declares its own name it gets the compiler-derived one. A type in an unnamed namespace declares a name if another translation unit may define one of the same name, since types are told apart by mangled name and such a pair would silently share an id.- Throws:
sequant::Exception – if a type of another mangled name already has this id
- Returns:
the (unique) type id of class T
Public Static Attributes
-
static constexpr type_rank_type default_type_rank = 128¶
rank of an Expr type that does not declare
type_rankSee also
Protected Functions
-
inline virtual void reset_hash_value() const¶
invalidates the memoized hash and the canonical mark
Note
to be called by every mutation of this object’s own data
-
inline void reset_canonical_mark() const¶
invalidates the canonical mark, see is_canonical()
Note
to be called by every mutation of this object’s own data that does not call reset_hash_value() (mutations of subexpressions, and their replacement, are detected without it)
-
inline void copy_canonical_mark(const Expr &other) const¶
copies the canonical mark of
other- Pre:
the own data of
*thisis identical to that ofother, and its subexpressions are copies (or clones) of those ofother
-
virtual bool static_equal(const Expr &that) const = 0¶
Note
thatis guaranteed to be of same type as*this, hence can be statically cast- Parameters:
that – an Expr object
- Returns:
true if
thatis equivalent to *this
-
inline virtual bool static_less_than(const Expr &that) const¶
Note
thatis guaranteed to be of same type as*this, hence can be statically castNote
base comparison compares Expr::hash_value() , specialize to each type as needed
- Parameters:
that – an Expr object
- Returns:
true if
*thisis less thanthat
-
inline virtual bool commutes_with_atom(const Expr &that) const¶
Note
*thisandthatare guaranteed to be leaves, and neither is a c-number , hence honest checking is neededNote
this returns true unless overridden in derived class
- Parameters:
that – an Expr object
- Returns:
true if
*thismultiplicatively commutes withthat
Friends