Factory functions for creation/annihilation/spin operators

Factory functions create the most basic expressions: Single creation/annihilation/number operators of fermions and bosons, as well as components of spin operators. These can be further combined to build all sorts of many-body Hamiltonians and observables. The expression index types are automatically deduced from the types of arguments passed to the factories.

There are two sets of factory functions - each defined in a separate namespace - differing in the index types of the created expression being static/dynamic.

Namespace

Expression type

libcommute::static_indices

expression<ScalarType, IndexTypes...>

libcommute::dynamic_indices

expression<ScalarType, dynamic_indices::dyn_indices>

By default, the scalar type of expressions returned by most factory functions is double. The only exceptions are factory functions for spin component operators \(S_x\) and \(S_y\), which use the fixed scalar type std::complex<double>. The following two functions can be used to manually convert real expressions into their complex analogs.

template<typename ...IndexTypes>
static_indices::expr_complex<IndexTypes...> make_complex(static_indices::expr_real<IndexTypes...> const &e)

Complexify a real expression with statically typed indices.

dynamic_indices::expr_complex make_complex(dynamic_indices::expr_real const &e)

Complexify a real expression with dynamic indices.

Statically typed indices

Defined in <libcommute/expression/factories.hpp>

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::c_dag(IndexTypes&&... indices)

Make a fermionic creation operator \(c^\dagger\) with given indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::c(IndexTypes&&... indices)

Make a fermionic annihilation operator \(c\) with given indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::n(IndexTypes&&... indices)

Make a fermionic number operator \(n = c^\dagger c\) with given indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::a_dag(IndexTypes&&... indices)

Make a bosonic creation operator \(a^\dagger\) with given indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::a(IndexTypes&&... indices)

Make a bosonic annihilation operator \(a\) with given indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::S_p(IndexTypes&&... indices)

Make a spin \(S=1/2\) raising operator \(S_+\) with given indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::S_m(IndexTypes&&... indices)

Make a spin \(S=1/2\) lowering operator \(S_-\) with given indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::S_z(IndexTypes&&... indices)

Make a spin \(S=1/2\) z-projection operator \(S_z\) with given indices and an arbitrary scalar type.

template<int Multiplicity, typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::S_p(IndexTypes&&... indices)

Make a general spin raising operator \(S_+\) with given indices and an arbitrary scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.

template<int Multiplicity, typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::S_m(IndexTypes&&... indices)

Make a general spin lowering operator \(S_-\) with given indices and an arbitrary scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.

template<int Multiplicity, typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, IndexTypes...> static_indices::S_z(IndexTypes&&... indices)

Make a general spin z-projection operator \(S_z\) with given indices and an arbitrary scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.

template<typename ...IndexTypes>
expression<std::complex<double>, IndexTypes...> static_indices::S_x(IndexTypes&&... indices)

Make a spin \(S=1/2\) x-projection operator \(S_x\) with given indices and the complex scalar type.

template<typename ...IndexTypes>
expression<std::complex<double>, IndexTypes...> static_indices::S_y(IndexTypes&&... indices)

Make a spin \(S=1/2\) y-projection operator \(S_y\) with given indices and the complex scalar type.

template<int Multiplicity, typename ...IndexTypes>
expression<std::complex<double>, IndexTypes...> static_indices::S_x(IndexTypes&&... indices)

Make a general spin x-projection operator \(S_x\) with given indices and the complex scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.

template<int Multiplicity, typename ...IndexTypes>
expression<std::complex<double>, IndexTypes...> static_indices::S_y(IndexTypes&&... indices)

Make a general spin y-projection operator \(S_y\) with given indices and the complex scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.

Note

Passing a C string literal as an index argument to a factory function will result in an expression with the corresponding index being a std::string.

[C++17] Dynamically typed index sequences

Defined in <libcommute/expression/factories_dyn.hpp>

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::c_dag(IndexTypes&&... indices)

Make a fermionic creation operator \(c^\dagger\) with given dynamically typed indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::c(IndexTypes&&... indices)

Make a fermionic annihilation operator \(c\) with given dynamically typed indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::n(IndexTypes&&... indices)

Make a fermionic number operator \(n = c^\dagger c\) with given dynamically indices typed and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::a_dag(IndexTypes&&... indices)

Make a bosonic creation operator \(a^\dagger\) with given dynamically typed indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::a(IndexTypes&&... indices)

Make a bosonic annihilation operator \(a\) with given dynamically typed indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::S_p(IndexTypes&&... indices)

Make a spin \(S=1/2\) raising operator \(S_+\) with given dynamically typed indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::S_m(IndexTypes&&... indices)

Make a spin \(S=1/2\) lowering operator \(S_-\) with given dynamically typed indices and an arbitrary scalar type.

template<typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::S_z(IndexTypes&&... indices)

Make a spin \(S=1/2\) z-projection operator \(S_z\) with given dynamically typed indices and an arbitrary scalar type.

template<int Multiplicity, typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::S_p(IndexTypes&&... indices)

Make a general spin raising operator \(S_+\) with given dynamically typed indices and an arbitrary scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.

template<int Multiplicity, typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::S_m(IndexTypes&&... indices)

Make a general spin lowering operator \(S_-\) with given dynamically typed indices and an arbitrary scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.

template<int Multiplicity, typename ScalarType = double, typename ...IndexTypes>
expression<ScalarType, dyn_indices> dynamic_indices::S_z(IndexTypes&&... indices)

Make a general spin z-projection operator \(S_z\) with given dynamically typed indices and an arbitrary scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.

template<typename ...IndexTypes>
expression<std::complex<double>, dyn_indices> dynamic_indices::S_x(IndexTypes&&... indices)

Make a spin \(S=1/2\) x-projection operator \(S_x\) with given dynamically typed indices and the complex scalar type.

template<typename ...IndexTypes>
expression<std::complex<double>, dyn_indices> dynamic_indices::S_y(IndexTypes&&... indices)

Make a spin \(S=1/2\) y-projection operator \(S_y\) with given dynamically typed indices and the complex scalar type.

template<int Multiplicity, typename ...IndexTypes>
expression<std::complex<double>, dyn_indices> dynamic_indices::S_x(IndexTypes&&... indices)

Make a general spin x-projection operator \(S_x\) with given dynamically typed indices and the complex scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.

template<int Multiplicity, typename ...IndexTypes>
expression<std::complex<double>, dyn_indices> dynamic_indices::S_y(IndexTypes&&... indices)

Make a general spin y-projection operator \(S_y\) with given dynamically typed indices and the complex scalar type. The Multiplicity template parameter must equal \(2S+1\), where \(S\) is the wanted spin.