C++ decompositions

namespace decompositions

Typedefs

using num_target_t = uint32_t
using num_control_t = int32_t
using num_param_t = uint32_t
using GateDecompositionRule = GateDecompositionRuleCXX17<derived_t, kinds_t, num_targets, num_controls, num_params, atoms_t...>
using ParametricSimpleAtom = ParametricAtom<op_t, traits::num_targets<op_t>, num_controls_>
using TrivialSimpleAtom = TrivialAtom<op_t, traits::num_targets<op_t>, num_controls_>
using circuit_t = tweedledum::Circuit
using instruction_t = tweedledum::Instruction

Functions

struct mindquantum::decompositions::DecompositionRuleParam MQ_ALIGN (16)
void decompose_cnot2cz(circuit_t &result, const instruction_t &inst)
void decompose_cnot2rxx_M(circuit_t &result, const instruction_t &inst)

Decompose CNOT gate, M for ‘Minus’ because ends with Ry(-pi/2)

void decompose_cnot2rxx_P(circuit_t &result, const instruction_t &inst)

Decompose CNOT gate, M for ‘Minus’ because ends with Ry(+pi/2)

void decompose_cnu2toffoliandcu(circuit_t &result, const instruction_t &inst)

Decompose multi-controlled gates.

void decompose_entangle(circuit_t &result, const instruction_t &inst)

Decompose entangle into h and cnot/cx gates.

void decompose_ph2r(circuit_t &result, const instruction_t &inst)

Decompose controlled global phase gates into (controlled) R/r1.

Shaves off one control qubit when applied

void decompose_PhNoCtrl(circuit_t &result, const instruction_t &inst)

Delete all phase/ph gates without controls.

void decompose_h2rx_M(circuit_t &result, const instruction_t &inst)

Decompose H gate, M for ‘Minus’ because ends with Ry(-pi/2)

void decompose_h2rx_N(circuit_t &result, const instruction_t &inst)

Decompose H gate, N for ‘Neutral’.

void decompose_qft2crandhadamard(circuit_t &result, const instruction_t &inst)

Decompose QFT (Quantum Fourier Transform) into h and controlled R (cr1)

void decompose_qubitop2onequbit(circuit_t &result, const instruction_t &inst)

Decompose (controlled) Qubit Operator into (controlled) Paulis.

void decompose_rx2rz(circuit_t &result, const instruction_t &inst)
void decompose_ry2rz(circuit_t &result, const instruction_t &inst)
void decompose_rz2rx_P(circuit_t &result, const instruction_t &inst)
void decompose_rz2rx_M(circuit_t &result, const instruction_t &inst)
void decompose_r2rzandph(circuit_t &result, const instruction_t &inst)

Decompose (controlled) phase-shift gate using z-rotation and global phase.

void decompose_sqrtswap2cnot(circuit_t &result, const instruction_t &inst)

Decompose sqrtswap into controlled x and sqrtx.

void decompose_swap2cnot(circuit_t &result, const instruction_t &inst)

Decompose swap into controlled x gates.

bool recognize_time_evolution_commuting(const instruction_t &inst)
void decompose_time_evolution_commuting(circuit_t &result, const instruction_t &inst)
bool recognize_time_evolution_individual_terms(const instruction_t &inst)
void decompose_time_evolution_individual_terms(circuit_t &result, const instruction_t &inst)
void decompose_toffoli2cnotandtgate(circuit_t &result, const instruction_t &inst)

Decompose toffoli gate (ccx) into cx, t, tdg and h gates.

Variables

static constexpr auto any_target = num_target_t(0)

Constant representing no constraints on the number of target qubits.

static constexpr auto any_control = num_control_t(-1)

Constant representing no constraints on the number of control qubits.

class mindquantum::decompositions::DecompositionRule MQ_ALIGN
class AtomStorage
#include <atom_storage.hpp>

Public Types

using atom_t = DecompositionAtom
using map_t = std::map<std::pair<std::string, num_control_t>, atom_t, details::atom_less>

Public Functions

inline MQ_NODISCARD auto size() const noexcept

Return the number of decomposition atoms in the storage.

Returns

Pointer to inserted element, pointer to compatible element or nullptr.

template<typename o_atom_t> MQ_NODISCARD bool has_atom () const noexcept

Check whether a matching (gate) atom can be found in the storage.

The comparison is performed based on the value of o_atom_t::num_controls(), o_atom_t::name(), as well as taking o_atom_t::kinds_t into account. The matching for the kind is performed by calling atom->is_kind(type::kind()) for each operator contained in o_atom_t::kinds_t.

Template Parameters

o_atom_t – Type of atom to look for

Returns

True/false depending on whether the atom can be found or not

template<typename o_atom_t, typename... op_t> MQ_NODISCARD bool has_atom (num_control_t num_controls, std::string_view name) const noexcept

Check whether a matching (gate) atom can be found in the storage.

Note

This method does not take general decompositions into account.

Parameters
  • kind – Kind of atom to look for

  • num_controls – Number of control the atom must be constrained by

  • name – Name of atom to look for

Returns

True/false depending on whether the atom can be found or not

MQ_NODISCARD atom_t * get_atom_for (const instruction_t &inst) noexcept

Look for a suitable decomposition atom within the storage.

Parameters

inst – An instruction

Returns

Pointer to atom if any, nullptr otherwise

template<typename o_atom_t, std::size_t kind_idx = 0, typename... args_t> MQ_NODISCARD atom_t * add_or_compatible_atom (args_t &&... args)

Inserts a new element, constructed in-place with the given args or returns an existing compatible atom.

This is different from add_or_return_atom in the sense that it does not enforce an exact match for the atom.

Template Parameters
  • o_atom_t – Type of atom to insert/return

  • kind_idx – If the atom has multiple element in its kinds_t tuple, this is the index of the type in that tuple to use to register the atom inside the storage.

Returns

Pointer to inserted element, pointer to compatible element.

template<typename o_atom_t, std::size_t kind_idx = 0, typename... args_t> MQ_NODISCARD atom_t * add_or_return_atom (args_t &&... args)

Inserts a new element, constructed in-place with the given args or returns an existing one.

This is different from add_or_compatible_atom in that it looks for an exact match.

Template Parameters
  • o_atom_t – Type of atom to insert/return

  • kind_idx – If the atom has multiple element in its kinds_t tuple, this is the index of the type in that tuple to use to register the atom inside the storage.

Returns

Pointer to inserted element, pointer to compatible element.

template<typename o_atom_t, std::size_t kind_idx = 0, typename... args_t> MQ_NODISCARD atom_t * add_or_replace_atom (args_t &&... args)

Inserts or replaces a new element, constructed in-place with the given args.

Template Parameters
  • o_atom_t – Type of atom to insert/replace

  • kind_idx – If the atom has multiple element in its kinds_t tuple, this is the index of the type in that tuple to use to register the atom inside the storage.

Returns

Pointer to inserted element, pointer to compatible element or nullptr.

class DecompositionAtom
#include <decomposition_atom.hpp>

Public Types

using gate_param_t = mindquantum::ops::parametric::gate_param_t

Public Functions

template<typename atom_t, typename = std::enable_if_t<!std::is_same_v<std::remove_cvref_t<atom_t>, DecompositionAtom>>>
inline DecompositionAtom(atom_t &&atom) noexcept
inline DecompositionAtom(const DecompositionAtom &other) noexcept
inline DecompositionAtom &operator=(const DecompositionAtom &other) noexcept
inline DecompositionAtom(DecompositionAtom &&other) noexcept
inline DecompositionAtom &operator=(DecompositionAtom &&other) noexcept
inline ~DecompositionAtom() noexcept
inline MQ_NODISCARD auto name() const noexcept

Return the name of this decomposition atom.

inline MQ_NODISCARD auto is_kind(std::string_view kind) const noexcept

Test whether an atom has (supports) a particular kind of operator.

inline MQ_NODISCARD bool is_applicable (const instruction_t &inst) const noexcept

Test whether this atom is applicable to a particular instruction.

Child classes may implement a method named is_applicable_impl in order to customize the default behaviour for this method.

Parameters

inst – An instruction

Returns

True if the atom can be applied, false otherwise

inline void apply(circuit_t &circuit, const instruction_t &inst) noexcept

Apply a decomposition atom to decompose an instruction.

Parameters
  • circuit – A quantum circuit to apply the decomposition atom to

  • inst – A quantum instruction to decompose

Pre

is_applicable() returns true

inline void apply(circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t &cbits = {}) noexcept

Apply the atom (ie. the decomposition it represents) to a quantum circuit.

This overload assumes the decomposition atom is not parametric

Note

Currently the cbits parameter is not used at all! It is here to make the API futureproof.

Parameters
  • circuit – A quantum circuit to apply the decomposition atom to

  • op – A quantum operation

  • qubits – A list of qubits to apply the decomposition atom

  • cbits – A list of classical bit the decomposition applies to

template<class atom_t>
struct Model<atom_t, false>
#include <decomposition_atom.hpp>

Public Functions

inline explicit Model(atom_t &&op) noexcept
inline explicit Model(atom_t const &op) noexcept

Public Members

std::unique_ptr<atom_t> operator_

Public Static Functions

static inline auto *self_cast(void *self) noexcept
static inline auto *self_cast(const void *self) noexcept
static inline void dtor(void *self) noexcept
static inline void clone(void const *self, void *other) noexcept
static inline constexpr std::string_view name() noexcept
static inline constexpr bool is_kind(std::string_view kind) noexcept
static inline bool is_applicable(void const *self, const instruction_t &inst) noexcept
static inline void apply(void *self, circuit_t &circuit, const instruction_t &inst) noexcept
static inline void apply_operator(void *self, circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t &cbits) noexcept

Public Static Attributes

static constexpr Concept vtable_ = {dtor, clone, name, is_kind, is_applicable, apply, apply_operator}
template<class atom_t>
struct Model<atom_t, true>
#include <decomposition_atom.hpp>

Public Types

using type = atom_t

Public Functions

inline explicit Model(atom_t &&op) noexcept
inline explicit Model(atom_t const &op) noexcept

Public Members

atom_t operator_

Public Static Functions

static inline auto *self_cast(void *self) noexcept
static inline auto *self_cast(const void *self) noexcept
static inline void dtor(void *self) noexcept
static inline void clone(void const *self, void *other) noexcept
static inline constexpr std::string_view name() noexcept
static inline constexpr bool is_kind(std::string_view kind) noexcept
static inline bool is_applicable(void const *self, const instruction_t &inst) noexcept
static inline void apply(void *self, circuit_t &circuit, const instruction_t &inst) noexcept
static inline void apply_operator(void *self, circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t &cbits) noexcept

Public Static Attributes

static constexpr Concept vtable_ = {dtor, clone, name, is_kind, is_applicable, apply, apply_operator}
template<typename derived_t, typename ...atoms_t>
class DecompositionRule
#include <decomposition_rule.hpp>

Public Types

using base_t = DecompositionRule
using self_t = DecompositionRule<derived_t, atoms_t...>
using gate_param_t = ops::parametric::gate_param_t

Public Functions

explicit DecompositionRule(AtomStorage &storage)

Constructor.

Note

The atoms of this decomposition rule will be insertd into the storage if they are not already present. However, existing (exactly matching) atoms will not be replaced.

Parameters

storage – Atom storage within which this decomposition will live in

template<std::size_t idx> constexpr auto * atom () noexcept MQ_REQUIRES((idx< sizeof...(atoms_t)))

Getter function for the individual atoms.

Overload using a non-type template parameter corresponding to the index of the atom in the atom list.

Template Parameters

idx – Index of atom in atom list

template<typename atom_t> constexpr auto *atom() noexcept MQ_REQUIRES((concepts atom (circuit_t &circuit, const operator_t&op, const qubits_t &qubits, const cbits_t &cbits) noexceptvoid

Getter function for the individual atoms.

Overload using a type template type parameter. This works since the list of atoms contains only unique values.

Note

Currently the cbits parameter is not used at all! It is here to make the API futureproof.

Template Parameters

atom_t – Type of atom to look for.Apply a decomposition

Parameters
  • circuit – A quantum circuit to apply the decomposition atom to

  • op – A quantum operation to decompose

  • qubits – A list of qubits to apply the decomposition atom

  • cbits – A list of classical bit the decomposition applies to

Public Static Functions

static inline constexpr auto name() noexcept

Return the name of this DecompositionRule.

template<typename ...args_t>
static inline MQ_NODISCARD auto create(AtomStorage &storage, args_t&&... args) noexcept

Helper function to create a DecompositionRule instance.

Parameters

storage – Atom storage within which this decomposition will live in

struct DecompositionRuleParam
#include <decomposition_param.hpp>

Aggregate type to store DecompositionRule template parameters.

Public Members

num_target_t num_targets

Number of target qubits the decomposition is constrained on.

num_control_t num_controls

Number of control qubits the decomposition is constrained on.

num_param_t num_params

Number of parameters the decomposition rule possesses.

class GateDecomposer
#include <gate_decomposer.hpp>

Public Types

using atom_storage_t = AtomStorage
using atom_t = atom_storage_t::atom_t
using general_rule_storage_t = std::set<DecompositionAtom, details::rules_less>

Public Functions

inline MQ_NODISCARD auto num_atoms() const noexcept

Return the number of atoms in the internal storage.

inline MQ_NODISCARD auto num_rules() const noexcept

Return the number of general decomposition rules in the internal storage.

inline MQ_NODISCARD const auto & storage () const noexcept

Simple getter to the internal storage.

template<typename o_atom_t> MQ_NODISCARD bool has_atom () const noexcept

Check whether a matching (gate) atom can be found in the storage.

The comparison is performed based on the value of o_atom_t::num_controls(), o_atom_t::name(), as well as taking o_atom_t::kinds_t into account. The matching for the kind is performed by calling atom->is_kind(type::kind()) for each operator contained in o_atom_t::kinds_t.

Note

This method does not take general decompositions into account.

Template Parameters

o_atom_t – Type of atom to look for

Returns

True/false depending on whether the atom can be found or not

MQ_NODISCARD atom_t * get_atom_for (const instruction_t &inst) noexcept

Look for a suitable decomposition within the storages.

This method will favour gate decompositions over general decompositions when looking for a match.

Parameters

inst – An instruction

Returns

Pointer to atom if any, nullptr otherwise

template<typename o_atom_t, std::size_t kind_idx = 0, typename... args_t> MQ_NODISCARD atom_t * add_or_replace_atom (args_t &&... args)

Inserts a new element, constructed in-place with the given args.

The type o_atom_t will be used to determine where the atom will be stored; ie. whether it is a gate decomposition or a general decomposition.

Template Parameters
  • o_atom_t – Type of atom to insert/replace

  • kind_idx – If the atom has multiple element in its kinds_t tuple, this is the index of the type in that tuple to use to register the atom inside the storage.

Returns

Pointer to inserted element, pointer to compatible element or nullptr.

template<typename derived_t, typename kinds_t_, DecompositionRuleParam param_ = tparam::default_t, typename ...atoms_t>
class GateDecompositionRule : public mindquantum::decompositions::DecompositionRule<derived_t, atoms_t...>, public mindquantum::traits::controls<param_.num_controls>
#include <gate_decomposition_rule_cxx20.hpp>

Public Types

using base_t = GateDecompositionRule
using kinds_t = kinds_t_
using self_t = GateDecompositionRule<derived_t, kinds_t, param_, atoms_t...>
using gate_param_t = ops::parametric::gate_param_t
using double_list_t = ops::parametric::double_list_t
using param_list_t = ops::parametric::param_list_t

Public Functions

template<typename rule_t> MQ_NODISCARD constexpr bool is_compatible () const noexcept

Check whether a decomposition is compatible with another one.

Another GateDecompositionRule instance is deemed compatible iff:

  • the number of target qubit are identical

  • the number of controls are compatible:

    • the number of control qubits in the decomposition rule is left undefined

    • or they have the same number of controls

Parameters
  • num_targets – Number of target qubits of the operation to decompose

  • num_controls – Number of control qubits of the operation to decompose

MQ_NODISCARD bool is_applicable (const instruction_t &inst) const noexcept

Check whether a decomposition is applicable with a given instruction.

Parameters

inst – A quantum instruction

Public Static Functions

static inline constexpr auto num_targets() noexcept

Return the number of target qubits this DecompositionRule is constrained on.

static inline constexpr auto num_controls() noexcept

Return the number of control qubits this DecompositionRule is constrained on.

static inline constexpr auto num_params() noexcept

Return the number of parameters of this GateDecompositionRule.

Public Static Attributes

static constexpr auto is_parametric = param_.num_params != 0U

Constant boolean indicating whether the GateDecompositionRule is parametric or not.

template<typename derived_t, typename kinds_t_, uint32_t num_targets_, num_control_t num_controls_, uint32_t num_params_, typename ...atoms_t>
class GateDecompositionRuleCXX17 : public mindquantum::decompositions::DecompositionRule<derived_t, atoms_t...>, public mindquantum::traits::controls<num_controls_>
#include <gate_decomposition_rule_cxx17.hpp>

Public Types

using base_t = GateDecompositionRuleCXX17
using kinds_t = kinds_t_
using parent_t = DecompositionRule<derived_t, atoms_t...>
using self_t = GateDecompositionRuleCXX17<derived_t, kinds_t, num_targets_, num_controls_, num_params_, atoms_t...>
using gate_param_t = ops::parametric::gate_param_t
using double_list_t = ops::parametric::double_list_t
using param_list_t = ops::parametric::param_list_t

Public Functions

template<typename rule_t> MQ_NODISCARD constexpr bool is_compatible () const noexcept

Check whether a decomposition is compatible with another one.

Another GateDecompositionRuleCXX17 instance is deemed compatible iff:

  • the number of target qubit are identical

  • the number of controls are compatible:

    • the number of control qubits in the decomposition rule is left undefined

    • or they have the same number of controls

Parameters
  • num_targets – Number of target qubits of the operation to decompose

  • num_controls – Number of control qubits of the operation to decompose

MQ_NODISCARD bool is_applicable (const instruction_t &inst) const noexcept

Check whether a decomposition is applicable with a given instruction.

Parameters

inst – A quantum instruction

Public Static Functions

static inline constexpr auto num_targets() noexcept

Return the number of target qubits this DecompositionRule is constrained on.

static inline constexpr auto num_controls() noexcept

Return the number of control qubits this DecompositionRule is constrained on.

static inline constexpr auto num_params() noexcept

Return the number of parameters of this GateDecompositionRuleCXX17.

Public Static Attributes

static constexpr auto is_parametric = num_params_ != 0U

Constant boolean indicating whether the GateDecompositionRuleCXX17 is parametric or not.

template<typename derived_t, typename ...atoms_t>
class NonGateDecompositionRule : public mindquantum::decompositions::DecompositionRule<derived_t, atoms_t...>
#include <non_gate_decomposition_rule.hpp>

Public Types

using base_t = NonGateDecompositionRule
using self_t = NonGateDecompositionRule<derived_t, atoms_t...>
using parent_t = DecompositionRule<derived_t, atoms_t...>
using non_gate_decomposition = void

Public Functions

inline explicit NonGateDecompositionRule(AtomStorage &storage)
template<typename atom_t, typename ...args_t>
constexpr auto *atom(args_t&&... args) noexcept

Getter function for the individual atoms.

Overload using a type template type parameter. This works since the list of atoms contains only unique values.

Template Parameters

atom_t – Type of atom to look for.

inline auto &storage() noexcept
void apply(circuit_t &circuit, const instruction_t &inst) noexcept

Apply a decomposition rule.

Parameters
  • circuit – Quantum circuit

  • inst – Quantum instructio to decompose

template<typename op_t, num_target_t num_targets_ = any_target, num_control_t num_controls_ = any_control>
class ParametricAtom : public mindquantum::traits::controls<num_controls_>
#include <parametric_atom.hpp>

A decomposition atom representing a gate with some free-parameter(s)

Note

This must be a parametric gate with at least one free parameter

Template Parameters
  • operator_t – Type of the gate the atom is representing

  • num_targets_ – Number of target qubits the gate this atom is representing has

  • num_controls_ – Number of control qubits the gate this atom is representing has. Possible values: -1 for any number of control qubits, >= 0 for a specified number of control qubits.

Public Types

using subs_map_t = mindquantum::ops::parametric::subs_map_t
using double_list_t = mindquantum::ops::parametric::double_list_t
using param_list_t = mindquantum::ops::parametric::param_list_t
using self_t = ParametricAtom<op_t, num_targets_, num_controls_>
using kinds_t = std::tuple<op_t>

Public Functions

inline explicit ParametricAtom(AtomStorage&)
MQ_NODISCARD bool is_applicable (const instruction_t &inst) const noexcept

Test whether this atom is applicable to a particular instruction.

Parameters

inst – An instruction

Returns

True if the atom can be applied, false otherwise

void apply(circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t &cbits) noexcept

Apply the atom (ie. the decomposition it represents) to a quantum circuit.

Note

Currently the cbits parameter is not used at all! It is here to make the API futureproof.

Parameters
  • circuit – A quantum circuit to apply the decomposition atom to

  • op – A quantum operation to decompose

  • qubits – A list of qubits to apply the decomposition atom

  • param – Some parameters to apply the decomposition atom with

  • cbits – A list of classical bit the decomposition applies to

Public Static Functions

static inline MQ_NODISCARD constexpr std::string_view name () noexcept

Return the name of this decomposition atom.

static inline MQ_NODISCARD constexpr auto num_targets () noexcept

Return the number of target qubits this decomposition atom is constrained on.

static inline MQ_NODISCARD constexpr auto num_controls () noexcept

Return the number of control qubits this decomposition atom is constrained on.

static inline MQ_NODISCARD constexpr auto num_params () noexcept

Return the number of parameters of this decomposition atom.

static inline MQ_NODISCARD auto create(AtomStorage &storage) noexcept

Helper function to create an instance of this atom.

Parameters

storage – Atom storage within which this decomposition will live in

template<typename op_t, num_target_t num_targets_ = any_target, num_control_t num_controls_ = any_control>
class TrivialAtom : public mindquantum::traits::controls<num_controls_>
#include <trivial_atom.hpp>

A decomposition atom representing a gate with no free-parameter.

Note

This can be a parametric gate with all of its parameters fully specified

Template Parameters
  • operator_t – Type of the gate the atom is representing

  • num_controls_ – Number of control qubits the gate this atom is representing has. Possible values: -1 for any number of control qubits, >= 0 for a specified number of control qubits.

Public Types

using self_t = TrivialAtom<op_t, num_targets_, num_controls_>
using kinds_t = std::tuple<op_t>

Public Functions

inline explicit TrivialAtom(AtomStorage&)
MQ_NODISCARD bool is_applicable (const instruction_t &inst) const noexcept

Test whether this atom is applicable to a particular instruction.

Parameters

inst – An instruction

Returns

True if the atom can be applied, false otherwise

void apply(circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t &cbits) noexcept

Apply the atom (ie. the decomposition it represents) to a quantum circuit.

Note

Currently the cbits parameter is not used at all! It is here to make the API futureproof.

Parameters
  • circuit – A quantum circuit to apply the decomposition atom to

  • op – A quantum operation to decompose

  • qubits – A list of qubits to apply the decomposition atom

  • cbits – A list of classical bit the decomposition applies to

Public Static Functions

static inline MQ_NODISCARD constexpr std::string_view name () noexcept

Return the name of this decomposition atom.

static inline MQ_NODISCARD constexpr auto num_targets () noexcept

Return the number of target qubits this decomposition atom is constrained on.

static inline MQ_NODISCARD constexpr auto num_controls () noexcept

Return the number of control qubits this decomposition atom is constrained on.

static inline MQ_NODISCARD constexpr auto num_params () noexcept

Return the number of parameters of this decomposition atom.

static inline MQ_NODISCARD auto create(AtomStorage &storage) noexcept

Helper function to create an instance of this atom.

Parameters

storage – Atom storage within which this decomposition will live in

namespace atoms

Typedefs

using Control = typename traits::atom_control_type<op_t, num_controls>::control_type
using C = Control<op_t, num_controls>
namespace details

Functions

template<typename T, typename U, typename V>
constexpr auto kind_lookup(const T &lhs, const std::pair<U, V> &rhs)
template<typename atom_t>
void apply_gate(atom_t &atom, circuit_t &circuit, const instruction_t &inst)
template<std::size_t idx, typename elem_t, typename tuple_t>
constexpr auto index_in_tuple_fn()

Variables

template<typename elem_t, typename tuple_t>
constexpr auto index_in_tuple = index_in_tuple_fn<0, elem_t, tuple_t>()
struct atom_less
#include <atom_storage.hpp>

Public Types

using is_transparent = void

Public Functions

template<typename T, typename U, typename = std::enable_if_t<!is_pair<std::remove_cvref_t<T>>::value && !is_pair<std::remove_cvref_t<U>>::value>>
inline constexpr auto operator()(T &&lhs, U &&rhs) const
template<typename T, typename U, typename V>
inline constexpr auto operator()(const std::pair<T, V> &lhs, const std::pair<U, V> &rhs) const
template<typename T>
struct is_pair : public false_type
#include <atom_storage.hpp>
template<typename T, typename U> pair< T, U > > : public true_type
#include <atom_storage.hpp>
struct rules_less
#include <gate_decomposer.hpp>

Public Types

using is_transparent = void

Public Functions

template<typename T, typename U>
inline constexpr auto operator()(T &&lhs, U &&rhs) const
namespace impl

Functions

template<typename CircuitType>
void decompose_time_evolution_individual_terms(CircuitType &result, const instruction_t &inst)
namespace rules

Variables

static constexpr auto PI_VAL = 3.141592653589793
static constexpr auto PI_VAL_2 = PI_VAL / 2.
static constexpr auto PI_VAL_4 = PI_VAL / 4.
class CNOT2CZ : public mindquantum::decompositions::GateDecompositionRule<CNOT2CZ, std::tuple<ops::X>, SINGLE_TGT_SINGLE_CTRL, ops::H, atoms::C<ops::Z>>
#include <cnot2cz.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t&, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class CNOT2Rxx : public mindquantum::decompositions::GateDecompositionRule<CNOT2Rxx, std::tuple<ops::X>, SINGLE_TGT_SINGLE_CTRL, ops::parametric::Rx, ops::parametric::Ry, ops::parametric::Ph, atoms::C<ops::parametric::Rxx>>
#include <cnot2rxx.hpp>

Public Functions

inline explicit CNOT2Rxx(AtomStorage &storage)
inline void apply_positive_decomp(circuit_t &circuit, const qubits_t &qubits)
inline void apply_negative_decomp(circuit_t &circuit, const qubits_t &qubits)
inline void apply_impl(circuit_t &circuit, const operator_t&, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class CNu2ToffoliAndCu : public mindquantum::decompositions::NonGateDecompositionRule<CNu2ToffoliAndCu, atoms::C<ops::X, 2>>
#include <cnu2toffoliandcu.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const instruction_t &inst, const qubits_t &qubits)

Public Static Functions

static inline constexpr auto name() noexcept
static inline MQ_NODISCARD bool is_applicable (const decompositions::instruction_t &inst)
class CRZ2CXAndRz : public mindquantum::decompositions::NonGateDecompositionRule<CRZ2CXAndRz, ops::parametric::Rz, ops::X>
#include <crz2cxandrz.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const instruction_t &inst)

Public Static Functions

static inline constexpr auto name() noexcept
static inline MQ_NODISCARD bool is_applicable (const instruction_t &inst)
class Entangle2HAndCNOT : public mindquantum::decompositions::GateDecompositionRule<Entangle2HAndCNOT, std::tuple<ops::Entangle>, ANY_TGT_NO_CTRL, ops::H, atoms::C<ops::X>>
#include <entangle.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const decompositions::operator_t&, const decompositions::qubits_t &qubits, const decompositions::cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class H2Rx : public mindquantum::decompositions::GateDecompositionRule<H2Rx, std::tuple<ops::H>, SINGLE_TGT_NO_CTRL, ops::parametric::Rx, ops::parametric::Ph, ops::parametric::Ry>
#include <h2rx.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t&, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class Ph2R : public mindquantum::decompositions::GateDecompositionRule<Ph2R, std::tuple<ops::Ph, ops::parametric::Ph>, SINGLE_TGT_PARAM_SINGLE_CTRL, ops::parametric::P>
#include <ph2r.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class QFT2CrAndHadamard : public mindquantum::decompositions::GateDecompositionRule<QFT2CrAndHadamard, std::tuple<ops::X>, ANY_TGT_NO_CTRL, ops::H, atoms::C<ops::P>>
#include <qft2crandhadamard.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t&, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class R2RzAndPh : public mindquantum::decompositions::GateDecompositionRule<R2RzAndPh, std::tuple<ops::P, ops::parametric::P>, SINGLE_TGT_PARAM_ANY_CTRL, ops::parametric::Rz, ops::parametric::Ph>
#include <r2rzandph.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class RemovePhNoCtrl : public mindquantum::decompositions::NonGateDecompositionRule<RemovePhNoCtrl>
#include <no_control_ph.hpp>

Public Functions

inline void apply_impl(circuit_t&, const instruction_t&)

Public Static Functions

static inline constexpr auto name() noexcept
static inline MQ_NODISCARD bool is_applicable (const instruction_t &inst)
class Rx2Rz : public mindquantum::decompositions::GateDecompositionRule<Rx2Rz, std::tuple<ops::Rx, ops::parametric::Rx>, SINGLE_TGT_PARAM_ANY_CTRL, ops::H, ops::parametric::Rz>
#include <rx2rz.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class Ry2Rz : public mindquantum::decompositions::GateDecompositionRule<Ry2Rz, std::tuple<ops::Ry, ops::parametric::Ry>, SINGLE_TGT_PARAM_ANY_CTRL, ops::parametric::Rx, ops::parametric::Rz>
#include <ry2rz.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class Rz2RxAndRy : public mindquantum::decompositions::GateDecompositionRule<Rz2RxAndRy, std::tuple<ops::Rz, ops::parametric::Rz>, SINGLE_TGT_PARAM_ANY_CTRL, ops::parametric::Rx, ops::parametric::Ry>
#include <rz2rxandry.hpp>

Public Functions

inline explicit Rz2RxAndRy(AtomStorage &storage)
inline void apply_positive_decomp(circuit_t &circuit, const qubits_t &qubits, const gate_param_t &param)
inline void apply_negative_decomp(circuit_t &circuit, const qubits_t &qubits, const gate_param_t &param)
inline void apply_impl(circuit_t &circuit, const operator_t &op, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class SqrtSwap2CNOTAndSqrtX : public mindquantum::decompositions::GateDecompositionRule<SqrtSwap2CNOTAndSqrtX, std::tuple<ops::SqrtSwap>, DUAL_TGT_ANY_CTRL, ops::Sx, atoms::C<ops::X>>
#include <sqrtswap2cnotandsqrtx.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t&, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class Swap2CNOT : public mindquantum::decompositions::GateDecompositionRule<Swap2CNOT, std::tuple<ops::Swap>, DUAL_TGT_ANY_CTRL, atoms::C<ops::X>>
#include <swap2cnot.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t&, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
class Toffoli2CNOTAndT : public mindquantum::decompositions::GateDecompositionRule<Toffoli2CNOTAndT, std::tuple<ops::X>, SINGLE_TGT_DOUBLE_CTRL, atoms::C<ops::X>, ops::H, ops::T, ops::Tdg>
#include <toffoli2cnotandtgate.hpp>

Public Functions

inline void apply_impl(circuit_t &circuit, const operator_t&, const qubits_t &qubits, const cbits_t&)

Public Static Functions

static inline constexpr auto name() noexcept
namespace tparam

Namespace containing some helper constants to use when defining DecompositionRule classes.

Variables

static constexpr auto default_t = any_tgt::any_ctrl
namespace any_tgt

Constants for decomposition rules without constraints on the number of target qubits.

Variables

static constexpr auto any_ctrl = DecompositionRuleParam{0, any_control, 0}
static constexpr auto no_ctrl = DecompositionRuleParam{0, 0, 0}
static constexpr auto single_ctrl = DecompositionRuleParam{0, 1, 0}
static constexpr auto double_ctrl = DecompositionRuleParam{0, 2, 0}
namespace dual_tgt

Constants for decomposition rules for single target qubit gates.

Variables

static constexpr auto any_ctrl = DecompositionRuleParam{2, any_control, 0}
static constexpr auto no_ctrl = DecompositionRuleParam{2, 0, 0}
static constexpr auto single_ctrl = DecompositionRuleParam{2, 1, 0}
static constexpr auto double_ctrl = DecompositionRuleParam{2, 2, 0}
namespace single_tgt

Constants for decomposition rules for single target qubit gates.

Variables

static constexpr auto any_ctrl = DecompositionRuleParam{1, any_control, 0}
static constexpr auto no_ctrl = DecompositionRuleParam{1, 0, 0}
static constexpr auto single_ctrl = DecompositionRuleParam{1, 1, 0}
static constexpr auto double_ctrl = DecompositionRuleParam{1, 2, 0}
namespace single_tgt_param

Constants for decomposition rules for single target qubit with parameteric gates with 1 parameter.

Variables

static constexpr auto any_ctrl = DecompositionRuleParam{1, any_control, 1}
static constexpr auto no_ctrl = DecompositionRuleParam{1, 0, 1}
static constexpr auto single_ctrl = DecompositionRuleParam{1, 1, 1}
static constexpr auto double_ctrl = DecompositionRuleParam{1, 2, 1}