C++ API
The C++ API reference is generated from the public headers and pybind11 binding source.
Decision Diagram Header
Functions
-
inline double canonicalize_component(double x) noexcept
-
inline double canonicalize_special_component(double x) noexcept
-
inline std_complex canonicalize_complex(std_complex z) noexcept
-
inline std_complex canonicalize_special_complex(std_complex z) noexcept
-
mEdge makeGate(QubitCount q, GateMatrix g, Qubit target, const Controls &c)
-
mEdge makeGate(QubitCount q, GateMatrix g, Qubit target)
-
mEdge makeTwoQubitGate(QubitCount q, TwoQubitGateMatrix g, Qubit target0, Qubit target1, const Controls &c)
-
mEdge makeTwoQubitGate(QubitCount q, TwoQubitGateMatrix g, Qubit target0, Qubit target1)
-
mEdge makeLargeGate(QubitCount q, ComplexMatrix &g)
-
mEdge makeLargeGate(QubitCount q, ComplexMatrix &g, const std::vector<Qubit> &targets)
-
mEdge makeLargeGate(ComplexMatrix &g, const Qubit level, const std::size_t rowStart, const std::size_t rowEnd, const std::size_t colStart, const std::size_t colEnd, const std::vector<bool> skip, const Qubit target_min)
-
vEdge makeZeroState(QubitCount q)
-
vEdge makeOneState(QubitCount q)
-
std::string measureAll(vEdge &rootEdge, const bool collapse, std::mt19937_64 &mt, double epsilon = 0.001)
-
char measureOneCollapsing(vEdge &rootEdge, const Qubit index, std::mt19937_64 &mt, double epsilon = 0.001)
-
mEdge RX(QubitCount qnum, int target, double angle)
-
mEdge RY(QubitCount qnum, int target, double angle)
-
mEdge RZ(QubitCount qnum, int target, double angle)
-
mEdge CX(QubitCount qnum, int target, int control)
-
GateMatrix rx(double angle)
-
GateMatrix ry(double angle)
-
GateMatrix rz(double angle)
-
GateMatrix u3(double theta, double phi, double lambda)
-
GateMatrix u1(double lambda)
-
GateMatrix u2(double phi, double lambda)
-
GateMatrix u(double theta, double phi, double lambda, double gamma)
-
GateMatrix p(double angle)
-
GateMatrix r(double theta, double phi)
-
mEdge makeSwap(QubitCount qnum, int target0, int target1)
-
mEdge RXX(QubitCount qnum, int target0, int target1, double angle)
-
mEdge RYY(QubitCount qnum, int target0, int target1, double angle)
-
mEdge RZZ(QubitCount qnum, int target0, int target1, double angle)
-
mEdge RZX(QubitCount qnum, int target0, int target1, double angle)
-
mEdge SWAP(QubitCount qnum, int target0, int target1)
-
mEdge ISWAP(QubitCount qnum, int target0, int target1)
-
mEdge CSWAP(QubitCount qnum, int target0, int target1, int control)
-
TwoQubitGateMatrix rxx_matrix(double angle)
-
TwoQubitGateMatrix ryy_matrix(double angle)
-
TwoQubitGateMatrix rzz_matrix(double angle)
-
TwoQubitGateMatrix rzx_matrix(double angle)
-
TwoQubitGateMatrix swap_matrix()
-
TwoQubitGateMatrix iswap_matrix()
-
void clear_cache(bool force = false)
-
void set_gc_thr(int gc_v, int gc_m)
-
struct Complex
- #include <dd.h>
Lightweight complex number used as a decision diagram edge weight.
QDD uses this type instead of std::complex so that equality, approximate comparisons, hashing, and optional MPI serialization remain consistent across vector and matrix decision diagram operations.
Public Functions
-
Complex() = default
-
inline Complex(const std::complex<double> &c)
-
inline Complex(double rr, double ii)
-
inline double mag2() const
-
inline bool isZero() const noexcept
-
inline bool isApproximatelyZero() const noexcept
-
inline bool isApproximatelyOne() const noexcept
-
inline bool isOne() const noexcept
-
inline bool operator==(const std::complex<double> rhs) const noexcept
-
inline double real() const noexcept
-
inline double imag() const noexcept
Public Static Attributes
-
static const double TOLERANCE = std::numeric_limits<double>::epsilon() * 1024
-
Complex() = default
-
struct vEdge
- #include <dd.h>
Weighted edge in a vector decision diagram.
A vector edge combines a complex weight with a pointer to a vector node. The terminal and zero edges are represented by the static members of this type.
-
struct vNode
- #include <dd.h>
Node in a vector decision diagram.
Each vector node is associated with a qubit variable and has two child edges, corresponding to the low and high branches of that variable.
Public Functions
-
vNode() = default
Public Static Attributes
-
static constexpr vNode *terminal = {&terminalNode}
-
vNode() = default
-
struct mEdge
- #include <dd.h>
Weighted edge in a matrix decision diagram.
A matrix edge combines a complex weight with a pointer to a matrix node. The edge is the public handle used by matrix operations and Python bindings.
Public Functions
-
inline bool isTerminal() const noexcept
-
std_complex **getMatrix(std::size_t *dim, Qubit nQubits = -1) const
-
inline bool isTerminal() const noexcept
-
template<>
struct hash<std_complex> - #include <dd.h>
Public Functions
-
inline std::size_t operator()(const std_complex &v) const noexcept
-
inline std::size_t operator()(const std_complex &v) const noexcept
-
struct mNode
- #include <dd.h>
Node in a matrix decision diagram.
Each matrix node is associated with a qubit variable and has four child edges, corresponding to the 2x2 block decomposition of an operator.
Public Functions
-
mNode() = default
Public Static Attributes
-
static constexpr mNode *terminal = {&terminalNode}
-
mNode() = default
-
struct MEdgeExactEqual
- #include <dd.h>
-
struct VEdgeExactEqual
- #include <dd.h>
-
struct MNodeExactEqual
- #include <dd.h>
-
struct VNodeExactEqual
- #include <dd.h>
-
struct ControlComparator
- #include <dd.h>
-
struct vContent
- #include <dd.h>
Public Functions
-
inline vContent(Qubit qpos, std_complex w1, std_complex w2, int i1, int i2)
-
inline vContent()
-
inline vContent(Qubit qpos, std_complex w1, std_complex w2, int i1, int i2)
-
struct mContent
- #include <dd.h>
Public Functions
-
inline mContent(Qubit qpos, std_complex w1, std_complex w2, std_complex w3, std_complex w4, int i1, int i2, int i3, int i4)
-
inline mContent()
-
inline mContent(Qubit qpos, std_complex w1, std_complex w2, std_complex w3, std_complex w4, int i1, int i2, int i3, int i4)
Cache Header
Variables
-
constexpr std::size_t hardware_constructive_interference_size = 64
-
constexpr std::size_t hardware_destructive_interference_size = 64
-
class AddCache
- #include <cache.hpp>
Memoization cache for decision diagram addition.
The cache stores results of vector-vector and matrix-matrix addition keyed by operand edges. It reduces repeated recursive work during decision diagram arithmetic.
Public Functions
-
inline AddCache(QubitCount q)
-
inline void clearAll()
-
inline double hitRatio() const noexcept
-
inline std::size_t getSize()
Private Functions
Private Members
-
std::mt19937_64 rng
-
std::uniform_int_distribution<int> dist
-
std::size_t lookups = {0}
-
std::size_t hits = {0}
-
struct Bucket
-
struct Cache
Public Functions
-
inline Cache()
Public Members
-
std::size_t chunkID = {0}
-
std::size_t allocationSize = {INITIAL_ALLOCATION_SIZE_CACHE * GROWTH_FACTOR}
-
std::size_t allocations = INITIAL_ALLOCATION_SIZE_CACHE
-
inline Cache()
-
struct Table
-
inline AddCache(QubitCount q)
-
class MulCache
- #include <cache.hpp>
Memoization cache for decision diagram multiplication.
The cache stores multiplication results for edge operands and is shared by matrix-vector and matrix-matrix recursive operations.
Public Functions
-
inline MulCache(QubitCount q)
-
template<typename LT, typename RT, typename RetT = std::conditional_t<std::is_same_v<RT, vNode>, vEdge, mEdge>>
inline RetT find(const LT *lhs, const RT *rhs)
-
template<typename LT, typename RT, typename ResT = std::conditional_t<std::is_same_v<RT, vNode>, vEdge, mEdge>>
inline void set(const LT *lhs, const RT *rhs, const ResT &result)
-
inline void clearAll()
-
inline double hitRatio() const noexcept
-
inline std::size_t getSize()
Private Functions
Private Members
-
std::mt19937_64 rng
-
std::uniform_int_distribution<int> dist
-
std::size_t lookups = {0}
-
std::size_t hits = {0}
Private Static Functions
-
static inline std::size_t bucket_key(uintptr_t l, uintptr_t r) noexcept
-
struct Bucket
-
struct Cache
Public Functions
-
inline Cache()
Public Members
-
std::size_t chunkID = {0}
-
std::size_t allocationSize = {INITIAL_ALLOCATION_SIZE_CACHE * GROWTH_FACTOR}
-
std::size_t allocations = INITIAL_ALLOCATION_SIZE_CACHE
-
inline Cache()
-
struct Table
-
inline MulCache(QubitCount q)
Table Header
Typedefs
-
using mNodeTable = CHashTable<mNode, std::hash<mNode>, MNodeExactEqual>
-
using vNodeTable = CHashTable<vNode, std::hash<vNode>, VNodeExactEqual>
Variables
-
static const uint64_t CL_MASK = ~(((LINE_SIZE) / 8) - 1)
-
static const uint64_t CL_MASK_R = ((LINE_SIZE) / 8) - 1
-
mNodeTable mUnique
-
vNodeTable vUnique
-
template<typename T, typename Hash = std::hash<T>, typename ValueEqual = std::equal_to<T>>
class CHashTable - #include <table.hpp>
Unique table and node allocator for decision diagram nodes.
The table interns equivalent nodes per qubit variable and reuses returned nodes through an internal free list. This keeps canonical decision diagram nodes shared across operations.
Public Functions
-
inline CHashTable(QubitCount n)
-
inline QubitCount getQubitCount() const
-
inline void dump()
-
inline std::size_t get_allocations()
Private Static Functions
-
static inline constexpr bool is_power_of_two(std::size_t x) noexcept
-
static inline constexpr std::size_t bucket_index(std::size_t h) noexcept
-
struct Cache
Public Types
Public Members
-
std::size_t chunkID = {0}
-
std::size_t allocationSize = {INITIAL_ALLOCATION_SIZE * GROWTH_FACTOR}
-
std::size_t allocations = {0}
-
struct Chunk
- #include <table.hpp>
-
std::size_t chunkID = {0}
-
struct NodeSlot
-
struct Table
-
inline CHashTable(QubitCount n)
Common Types
Typedefs
-
using duration_micro = std::chrono::duration<double, std::micro>
-
using Qubit = int32_t
-
using QubitCount = uint32_t
-
using Index = std::size_t
-
using double_pair = std::pair<double, double>
-
using GateMatrix = std::array<std::complex<double>, 4>
-
using TwoQubitGateMatrix = std::array<std::array<std::complex<double>, 4>, 4>
-
using ComplexMatrix = std::vector<std::vector<std::complex<double>>>
Functions
-
constexpr std::size_t hash_combine(std::size_t lhs, std::size_t rhs)
-
constexpr std::size_t murmur_hash(std::size_t k)
Variables
-
const std::size_t NQUBITS = 100
-
const std::size_t NBUCKETS = 524288
-
const std::size_t INITIAL_ALLOCATION_SIZE = 1024 * 2
-
const std::size_t INITIAL_ALLOCATION_SIZE_CACHE = 1024 * 8
-
const std::size_t GROWTH_FACTOR = 2
-
const uint64_t INDEX_MASK = 0x00000000FFFFFFFFLL
-
const uint64_t HASH_MASK = 0xFFFFFFFF00000000LL
-
const uint64_t HASH_SHIFT = 32
-
const std::size_t REGION_SIZE = 512
-
const uint64_t UT_INIT_SZ = 8 * REGION_SIZE
-
const uint64_t UT_MAX_SZ = 16 * REGION_SIZE
-
constexpr double SQRT2 = 0.707106781186547524400844362104849039284835937688474036588L
-
constexpr double PI = 3.141592653589793238462643383279502884L
-
constexpr std::complex<double> cf_one = {1., 0.}
-
constexpr std::complex<double> cf_mone = {-1., 0.}
-
constexpr std::complex<double> cf_zero = {0., 0.}
-
constexpr std::complex<double> cf_i = {0., 1.}
-
constexpr std::complex<double> cf_mi = {0., -1.}
-
constexpr std::complex<double> cf_1plusi_2 = {0.5, 0.5}
-
constexpr std::complex<double> cf_1minusi_2 = {0.5, -0.5}
-
constexpr GateMatrix Hmat = {cf_SQRT2_2, cf_SQRT2_2, cf_SQRT2_2, cf_mSQRT2_2}
-
constexpr GateMatrix Tdagmat = {cf_one, cf_zero, cf_zero, cf_1minusi}
-
constexpr GateMatrix SXmat = {cf_1plusi_2, cf_1minusi_2, cf_1minusi_2, cf_1plusi_2}
-
constexpr GateMatrix SXdagmat = {cf_1minusi_2, cf_1plusi_2, cf_1plusi_2, cf_1minusi_2}
-
constexpr GateMatrix Vmat = {cf_SQRT2_2, cf_miSQRT2_2, cf_miSQRT2_2, cf_SQRT2_2}
-
constexpr GateMatrix Vdagmat = {cf_SQRT2_2, cf_iSQRT2_2, cf_iSQRT2_2, cf_SQRT2_2}
-
template<size_t I, typename ...Ts>
struct get_index_impl - #include <common.h>
-
template<size_t I, typename T, typename ...Ts>
struct get_index_impl<I, T, T, Ts...> : public std::integral_constant<size_t, I> - #include <common.h>