Find the optimal parameters for quantum Bell violations.

The Nonlocality.jl module provides tools to optimize quantum non-locality in Bell scenarios.

Module Exports:

  • optimize_measurement: Finds the quantum measurement which violates a specified Bell inequality maximally.

BipartiteNonSignaling scenario:

    game :: BellGame,
    scenario :: BipartiteNonSignaling,
    ρ_AB :: AbstractMatrix;
    A_POVMs :: Vector{<:AbstractVector{<:AbstractMatrix}},
) :: Dict

Find Bob's measurement which optimizes a BellGame's score for the shared quantum state ρ_AB and POVM measurement applied by Alice. The following semi-definite program optimizes the Bob's POVM:

\[\begin{aligned} &\max_{\{\Pi_b^y\}} \sum_{a,b,x,y} G_{a,b,x,y}\text{Tr}[(\Pi_a^x \otimes \Pi_b^y)\rho_{AB}] \\ &s.t. \quad \sum_b \Pi_b^y = \mathbb{I},\quad \Pi_b^y \geq 0 \quad \forall\; y \end{aligned}\]

    game :: BellGame,
    scenario :: BipartiteNonSignaling,
    ρ_AB :: AbstractMatrix;
    B_POVMs :: Vector{<:AbstractVector{<:AbstractMatrix}},
) :: Dict

Find Alice's measurement which optimizes a BellGame's score for the shared quantum state ρ_{AB} and POVM measurement applied by Bob. The following semi-definite program optimizes the Alice's POVM:

\[\begin{aligned} &\max_{\{\Pi_a^x\}} \sum_{a,b,x,y} G_{a,b,x,y}\text{Tr}[(\Pi_a^x \otimes \Pi_b^y)\rho_{AB}] \\ &s.t. \quad \sum_a \Pi_a^x = \mathbb{I},\quad \Pi_a^x \geq 0 \quad \forall \;x \end{aligned}\]


LocalSignaling scenario:

    scenario :: LocalSignaling,
    game :: BellGame,
    ρ_states :: Vector{<:AbstractMatrix}

Finds the measurement that optimizes the score of the BellGame against the set of quantum states ρ_states. The optimization is performed with the following semi-definite program:

\[\begin{aligned} &\max_{\{\Pi_y\}} \sum_{x,y} G_{x,y} \text{Tr}[\Pi_y \rho_x] \\ &s.t. \quad \sum_y \Pi_y = \mathbb{I}, \quad \Pi_y \geq 0 \end{aligned}\]


Compute the bounds of classical Bell scenarios.

The LocalPolytope.jl module provides tools for characterizing the convex polyhedral structure of the correlations attainable using classical resources in a Bell scenario.

Each distinct strategy for a given Bell scenario corresponds to a point in vector space. The complete set of attainable strategies for a particular Bell scenario is denoted $\mathbf{P}$. Given the constraints of normalization and non-negativity, the extreme points of $\mathbf{P}$ correspond to deterministic strategies (matrices with 0,1 elements). Furthermore, when shared randomness is used in a Bell scenario, any two strategies can be mixed together in a convex combination. Hence, $\mathbf{P}$ is a convex polyhedron referred to as the local polytope.

A convex polytope has two equivalent descriptions:

  1. V-Description: The polytope is the convex hull of a set of extreme points known as vertices $\mathbf{V}$, $\quad\mathbf{P} = \text{conv}(\mathbf{V})$.
  2. H-Description: The polytope is the intersection of a set of linear half-spaces known as facets $\mathbf{F}$, $\quad\mathbf{P} = \cap\mathbf{F}$.

These two descriptions are equivalent,

\[\mathbf{P} = \text{conv}(\mathbf{V}) = \cap\mathbf{F},\]

and there exists a transformation between the set of vertices and facets $\mathbf{V} \leftrightarrow \mathbf{F}$.

For a given Bell scenario, the V-Description is typically easier to compute, however, the H-Description describes the bounds of the local polytope as as linear inequalities known as Bell inequalities. Bell inequalities are important because they provide a simple test to verify that a strategy is not contained by the local polyotpe. That is, if a Bell inequality is violated, the classical resources considered for the local polytope are not sufficient to reproduce the strategy. Hence, a Bell violation witnesses the use of resources with greater operational value. Bell violations are often used to characterize the advantages of quantum resources, however, it is important to note that a Bell violation can simply mean that more classical resources were used than anticipated.

Module Exports:

  • vertices - Compute the set of extreme-points for the local polytope.
  • num_vertices - The number of vertices for the local polytope.
  • vrep - Construct a Polyhedron in the vertex representation.
  • facets - Compute the linear inequalities which bound the local polytope.
  • generator_vertex - Provide a canonical form for a vertex.
  • generator_facet - Provide a canonical form for a facet.
  • adjacency_decomposition - Efficiently compute the generator facets for the local polytope using the adjacency decomposition technique.
    vertices :: Vector{Vector{Int64}},
    BG_seed :: BellGame,
    scenario :: LocalSignaling;
) :: Dict

Given a polytpe represented by vertices, returns the complete set of canonical facets for prepare and measure scenario scenario. The adjacencydecomposition algorithm requires a seeded vertex which is supplied with the `BGseed` argument. Facets are returned in the lexicographic normal form.

Returned Dictionary Format

Returns a dictionary where the keys are canonical BellGames and the value is a dictionary with keys

  • "considered" => true, if the facet was considered in the algorithm.
  • "skipped" => true, if the facet was skipped (not considered).
  • "num_vertices" => number of vertices.
  • "norm_facet" => facet vector representative (normalized rep) of canonical game

Keyword Arguments: kwargs...

  • skip_games = [] :: Vector{BellGame} - List of games to skip.
  • max_vertices = 100 :: Int64 - The maximum number of vertices to allow in target facets.
  • dir = "./" :: String- Directory in which to createporta_tmp/and.json` files.
  • log = false :: Bool - If true, the facet dictionary is written to .json each iteration.
  • log_filename = "adjacency_decomposition_now.json" :: String
    vertices :: Vector{Vector{Int64}},
    F :: Vector{int64};
    dir = "./" :: String,
    cleanup = true ::Bool
) :: Vector{Vector{Int64}}

For the polytope represented by vertices, returns the set of facets adjacent to F.

Facet vector F and the return facet vectors are assumed to ba in the normalized subspace.

The dir argument specifies where to where to write files and directories from XPORTA.jl. If cleanup is true, then a porta_tmp directory is created as a subdirectory of dir.

If cleanup is false, the created porta_tmp directory is not removed.

dimension( vertices :: Vector{Vector{Int64}} ) :: Int64

For the provided vertices (points), finds the dimension of the affine space spanned by the vertices. This method computes the dimension of a polytope, facet, or collection of points.

This also accepts matrices and DeterministicStrategy types as arguments:

dimension( vertices :: Vector{Matrix{Int64}} ) :: Int64

dimension( vertices :: Vector{DeterministicStrategy} ) :: Int64
facets(poly::Polyhedron) :: Vector{Vector{Int64}}

Returns the facets of the local polytope poly. If the facets have not already been computed, then they are transformed into the half-space representation from the vertex representation.

    vertices :: Vector{Vector{Int64}};
    dir = "./" :: String,
    cleanup=true :: Bool
) :: Dict{String, Vector{Vector{Int64}}}

Computes the facet inequalities and equalities which bound the convex polyhedron defined by the set of vertices. If the optimal representation is used for the vertices, then no equalitities will be present. For example, if the "generalized" vertex representation is used the normalization constraints will be included in the resulting equalities. The output of this method is structured:

    "facets" => inequalities, # :: Vector{Vector{Int64}}
    "equalitites" => equalities, # :: Vector{Vector{Int64}}

Facet inequalities and equalities are represented as single vector f where f[1:(end-1)] contains the coefficients of the linear inquality and f[end] is the bound. Facet inequalities and equalities act upon a vertex v where inequalities are arranged such that there is an implicit f[1:(end-1)]' * v ≤ f[end] and equalities are arranged such that f[1:(end-1)]' * v == f[end]

Supporting Software

The vertex -> facet transformation is performed using the traf method of XPORTA.jl. Please refer to the source code for more details.

Performance Limitations

Vertex -> facet transformations are notoriously difficult computational problems. The performance limits of this method will be met far before the limits the vertex enumeration methods.

generator_facet( BG :: BellGame, scenario :: LocalSignaling ) :: BellGame

Finds the generating facet for the provided BellGame. The generator is provided in lexicographic normal form. The generating facet is found recursively by an algorithm which sorts by lexicographic scores.

    vertices :: Vector{Vector{T}} where T <: Real,
    test_behavior :: Vector{<:Real};
    verbose=false :: Bool
) :: Vector{Float64}

Obtains a linear inequality $(\mathbf{G}^\star, \beta^\star)$ bounding the convex hull of the set of vertices ($\mathcal{V}$) and is violated by the test_behavior $(\mathbf{P}\notin \text{Conv}(\mathcal{V}))$. This task is achieved using the linear program described by Brunner et al. in Eq. 19 of The linear program is

\[\begin{align} \min_{(\mathbf{G}, \beta)} \quad & \langle \mathbf{G},\mathbf{P}\rangle - \beta & \notag\\ \text{s.t.} \quad & \langle \mathbf{G}, \mathbf{V} \rangle - \beta \leq 0 & \quad \forall \;\; \mathbf{V} \in \mathcal{V} \notag\\ & \langle \mathbf{G}, \mathbf{P} \rangle \leq 1 & \notag\\ \end{align}\]

The solution to the linear program is a linear nonclassicality witness $(\mathbf{G}^\star, \beta^\star)$ becuase the constraint $\lange\mathbf{G}^\star, \mathbf{V} \rangle - \beta^\star \leq 0$ ensures that no behavior in the polytope $\text{Conv}(\mathcal{V})$ can violate the inequality. Provided that $\mathbf{P} \notin \text{Conv}(\mathcal{V})$ technique the output linear inequality witnesses the nonclassicality of the test_behavior.

The optimized facet inequality $(\mathbf{G}^\star, \beta^\star)$ is returned as a vector $(G^\star_{0,0}, \dots, G^\star_{Y,X}, -\beta^\star)$ where $G^\star_{y,x}$ are the elements of $\mathbf{G}^\star$.

Supporting Software

The linear programming is performed using HiGHS solver via the JuMP interface. Please refer to the source code for more details.

Converting Output into Bell Game

The linear programming software outputs numerical values that have numerical error. Moreover, the linear inequality is scaled such that the classical bound is zero and the test_behavior score is one. In order to convert the output inequality into a BellGame, care must be taken to obtain the correct scaling factor to ensure that elements are integers.

Classical Test Behavior

If the test_behavior $\mathbf{P}$ is classical, meaning it satisfies $\mathbf{P}\in\text{Conv}(\mathcal{V})$, then the zero vector is returned as the optimal solution. Note that if all elements of $\mathbf{G}^\star$ satisfy $G^\star_{y,x}=0$, then all behaviors $\mathbf{P} \in \text{Conv}(\mathcal{V})$ are trivially optimal as $\langle\mathbf{G}^{\star}, \mathbf{P} \rangle - \beta^\star \leq 0$.

num_vertices( scenario :: BipartiteNonSignaling ) :: Int64

For two non-signaling black-boxes with $X$ and $Y$ inputs and $A$ and $B$ outputs respectively, the number of vertices $|\mathcal{V}|$ are counted:

\[|\mathbf{V}| = A^X B^Y\]

num_vertices( scenario :: BlackBox ) :: Int64

For $n$ outputs and $m$ inputs the number of vertices $|\mathcal{V}|$ are counted:

\[|\mathbf{V}| = n^m\]

num_vertices( scenario :: LocalSignaling;
    rank_d_only = false :: Bool
) :: Int64

If rank_d_only = true, then only strategies using d-dits are counted. For $X$ inputs and $Y$ outputs the number of vertices $|\mathcal{V}|$ are counted:

\[|\mathbf{V}| = \sum_{c=1}^d \left\{X \atop c \right\}\binom{Y}{c}c!\]

    F :: Vector{Int64},
    G :: Vector{Int64},
    xbar :: Vector{Int64}
) :: Vector{Int64}

Performs a rotation of facet F relative to non-included vertex xbar and returns the rotated facet vector. F is a polytope facet, G is a subfacet of F and xbar is a vertex not contained by F. By construction, the rotated facet contains xbar.


For the given Scenario, returns the length of the vertex in the representation specified by rep. A DomainError is thrown if the rep is invalid.

vertex_dims(scenario :: Union{BlackBox,LocalSignaling}, rep :: String) :: Int64

Valid values of rep are "normalized" and "generalized".

vertices( scenario :: BipartiteNonSignaling,
    rep="non-signaling" :: String
) :: Vector{Vector{Int64}}

Enumerates the LocalPolytope vertices for the BipartiteNonSignaling scenario. Valid representations for the vertices include:

  • "non-signaling", "normalized", "generalized"

A DomainError is thrown if a valid representation is not specified.

vertices( scenario :: BlackBox;
    rep = "normalized" :: String
) :: Vector{Vector{Int64}}

Generates the Local Polytope vertices for a BlackBox scenario. Valid represenations are:

*rep == "normalized" or rep == "generalized".

vertices( scenario :: LocalSignaling;
    rep = "normalized" :: String
    rank_d_only = false :: Bool
) ::  Vector{Vector{Int64}}

Generates the deterministic strategies for the local polytope of LocalSignaling scenarios. The rank_d_only keyword arg specifies whether to exclude vertices which use fewer dits of communication and thus have a matrix rank less than d.


The vertices computed in this method are vectorized directly from a strategy matrix by column-majorization. These vertices are distinct from those produced by older LocalPolytope.vertices() methods which are row-majorized.

vrep(scenario::Scenario; vertices_kwargs...) :: XPORTA.Polyhedron

Constructs a Polyhedron using the vertex representation. See Polyhedra.jl for more details. The vertices_kwargs keyword arguments are passed through to the vertices function for each Scenario.

Return Type

This function differs from the Polyhedra.jl implementation in that it returns a Polyhedron type rather than a V-Representation. This is done to reduce the number of steps required to construct a polyhedron.


Types and constructors that represent Bell scenarios, their statistics, and their bounds.

The BellScenario.jl module is the base library for Bell scenario analysis.


A game theoretic framework is used to evaluate the performance of black-box systems. A cost function testing the black-box system is regarded as a game while the statistics generated by the black-box system are regarded as a strategy. A strategy is played against a game to achieve a score, hence, this framework provides a quantitative metric of the performance of a black-box system in regards to a particular task.


An AbstractGame is the abstract type that is parent to type representing a cost function for strategies. A Game is a linear inequality dual to Strategy matrices, it is represented by a matrix $G$ containing scalar coefficients and a bound $\beta$. The bound of the linear inequality is typically a maximum score attainable by Bell scenario using a certain set of resources. A Game $G$ is played by a Strategy $S$ to achieve a score computed as,

\[\beta \geq \langle G, S\rangle = \sum_{x,y} G_{y,x}S(y|x).\]

The game is "won" if the strategy scores greater than $\beta$, that is, the above inequality is violated. Since $\beta$ is the maximum score for a set of resources, the game is won only if the tested strategy used a set of resources of greater operational value than than considered when computing the bound $\beta$.

Conveniently, Strategy matrices have normalized columns and non-negative elements. This means that any game inequality can be converted into a form where game matrix $G$ has positive elements and $\beta$ designates a positive upper bound.


An AbstractStrategy is an abstract type parent to all strategy matrices. A black-box device is characterized by its conditional probabilities which can be organized into a strategy matrix or column-stochastic map $S : \mathcal{X} \to \mathcal{Y}$. The strategy matrix $S$ is constructed as follows,

\[S = \sum_{x,y} P(y|x) |y\rangle\langle x|\]

where the elements of a strategy matrix must be non-negative and normalized:

  • $P(y|x) \geq 0$
  • $\sum_y P(y|x) = 1$

Since strategies are just stochastic matrices, the product of two strategies yields a new strategy, e.g. $S_A*S_B = S_C$.

*(S1::AbstractStrategy, S2::AbstractStrategy) :: Strategy

When multiplied together, two strategies may represent a new Scenario, hence, a the multiplication operator can also be passed a Scenario.

*(S1::AbstractStrategy, S2::AbstractStrategy, scenario::Scenario) :: Strategy
BellGame(game::Matrix{Int64}, β::Int64, scenario::Scenario)

A BellGame represents a Bell inequality or tight facet of the local polytope. Since the vertices of the local polytope are deterministic strategies with 0,1 elements, the linear inequalities describing facets of the local polytope have rational coefficients. Therefore, if a inequality tightly bounds the local polytope, it can be represented by a game with integer coefficients.

    A :: Int64,
    B :: Int64,
    X :: Int64,
    Y :: Int64
) <: Scenario

A bipartite non-signaling scenario where each device receives an input and produces an output. Let Alice be the device with A outputs and X inputs while Bob is the device with B outputs and Y inputs.

Bipartite Non-Signaling Scenario

Shared randomness is held between Alice and Bob. When Alice and Bob share quantum entanglement, Bell violations are known to occur.


A DomainError is thrown if A, B, X, or Y is less than 1.

    A :: Tuple{Int64, Int64},
    B :: Tuple{Int64, Int64};
    dits :: Int64 = 1,
    bidirectional :: Bool = false
) <: Scenario

A bipartite signaling scenario where each device can send a message to the other.

Bipartite Signaling Scenario

BlackBox(num_out :: Int64, num_in :: Int64) <: Scenario

A Bell scenario consisting of a single black-box device with num_in inputs and num_out outputs.

Black-Box Device

The black-box device computes the output $y$ from the input $x$ by performing a stochastic map $S(y|x)$.


A DomainError is thrown if parameters num_out or num_in is less than 1.

DeterministicStrategy(conditionals :: Matrix{Int64}) <: AbstractStrategy{Int64}

A strategy matrix describing the behavior of a deterministic black-box. A strategy deterministic if its elements satisfy $P(y|x)\in\{0,1\}$ in addition to the non-negativity and normalization constraints. By default, the constructor creates a strategy for a 'BlackBox' scenario, however, a Scenario can be passed to the DeterministicStrategy constructor.

DeterministicStrategy(conditionals :: Matrix{Int}, scenario :: Scenario)

The product of two deterministic strategies is a DeterministicStrategy.

*(S1::DeterministicStrategy, S2::DeterministicStrategy) :: DeterministicStrategy

When multiplied a new Scenario can be specified.

) :: Deterministic Strategy


A DomainError is thrown if:

  • The provided Scenario does not match the dimension of the conditionals matrix.
  • The elements of conditionals are not 0 or 1.
  • The strategy elements are not non-negative and normalized.
Game(game::Matrix{T}, β::Real) <: AbstractGame{T}

A Game is represented by a Matrix of coefficients and a scalar bound β.

Type parameter T can be either Int64 or Float64.

    X :: Int64,
    Y :: Int64,
    d :: Int64,
) <: Scenario

A bipartite signaling scenario where information is passed from a transmitter black-box to a receiver black-box using no more than d dits of communication.

Local Signaling Scenario

The transmitter device has X inputs and the receiver device has Y outputs and shared randomness is held between the two devices. When quantum communication is used instead of classical communication no Bell violations occur.


A DomainError is thrown if X, Y, or d is less than 1.


A Scenario is an abstract type parent to all Bell scenarios. Each child of this abstract type describes a distinct black-box system configuration.

Strategy(conditionals :: Matrix{<:Real}; atol::Float64 = 1e-7) <: AbstractMatrix{Float64}

Strategy(conditionals :: Conditionals; atol::Float64 = 1e-7) <: AbstractMatrix{Float64}

The conditionals parameter is a column stochastic matrix. The conditionals can either be accepted in a raw Matrix{<:Real} format or as a Conditionals type from QBase.jl. The atol parameter expresses the absolute tolerance for numerical error in the constraints of conditional probablities. By default, the constructor creates a strategy for a 'BlackBox' scenario. However, a Scenario can be passed to the Strategy constructor.

Strategy(conditionals :: Matrix{<:Real}, scenario :: Scenario, atol::Float64=1e-7)


A DomainError is thrown if:

  • The provided Scenario does not match the expected dimension of the conditionals matrix.
  • The conditionals matrix is not a valid stochastic matrix, e.g. non-negative and normalized.
    S :: Type{<:AbstractStrategy}, vertex::Vector{<:Real}, scenario::BipartiteNonSignaling;
    rep="non-signaling" :: String

Transforms a behavior vector or vertex in to either a Strategy or DeterministicStrategy. If converting into a DeterministicStrategy, the vertex must contain Int64 values. Valid representations are "non-signaling", "normalized", and "generalized".


Facet (Vector{Int64}) -> BellGame

    rep = "non-signaling"::String

Transforms LocalPolytope facets into BellGame types.


Facet (Vector{Int64}) -> BellGame

    scenario::Union{BlackBox, LocalSignaling};
    rep = "normalized"::String

Vertex (Vector{Int64}) -> DeterministicStrategy

    vertex  :: Vector{Int64},
    scenario :: Scenario;
    rep = "normalized" :: String

XPORTA.IEQ to BellGame's

    scenario::Union{BlackBox, LocalSignaling};
    rep = "normalized" :: String

BellGame -> Vector{Int64}

    rep = "non-signaling" :: String

Transforms a BellGame for a BipartiteNonSignaling scenario into a facet vector.


BellGame -> Facet (Vector{Int64})

convert(::Type{Vector{Int64}}, BG::BellGame; rep = "normalized" :: String)

DeterministicStrategy -> Vertex (Vector{Int64})

    strategy :: DeterministicStrategy;
    rep = "normalized" :: String

BellGame's to XPORTA.IEQ

convert(::Type{IEQ}, bell_games::Vector{BellGame}; rep = "normalized" :: String)
    num_array :: Vector{Int64},
    base :: Int64;
    big_endian=true :: Bool
) :: Int64

Given an array representing a number in base-n returns the value of that number in base-10.


  • num_array - Vector containing semi-positive integers less than base.
  • base - The base-n number represented by num_array.
  • big_endian - true if most significant place is at index 1, else false.
deterministic_strategies(scenario :: BlackBox) :: Vector{Matrix{Int64}}

deterministic_strategies(num_out :: Int64, num_in :: Int64) :: Vector{Matrix{Int64}}

Enumerates the set of deterministic strategies for the specified BlackBox. For performance, enumerated deterministic strategies are left as matrices and not constructed into DeterministicStrategy types.

is_deterministic( strategy :: AbstractMatrix  ) :: Bool

Returns true if all elements of strategy are either 0 or 1 and the matrix is a valid conditional probability distribution.

n_choose_k_matrices( n :: Int64, k :: Int64 ) :: Vector{Matrix{Bool}}

Generates a set of n by k matrices which represent all combinations of selecting k columns from n rows. Each column, contains a single non-zero element and k rows contain a non-zero element.


julia> n_choose_k_matrices( 4, 2 )
6-element Vector{Matrix{Bool}}:
 [1 0; 0 1; 0 0; 0 0]
 [1 0; 0 0; 0 1; 0 0]
 [1 0; 0 0; 0 0; 0 1]
 [0 0; 1 0; 0 1; 0 0]
 [0 0; 1 0; 0 0; 0 1]
 [0 0; 0 0; 1 0; 0 1]

A DomainError is thrown if n ≥ k ≥ 1 is not satisfied.

permutation_matrices( dim :: Int64 ) :: Vector{Matrix{Bool}}

Generates the set of square permutation matrices of dimension dim.


julia> permutation_matrices(3)
6-element Vector{Matrix{Bool}}:
 [1 0 0; 0 1 0; 0 0 1]
 [1 0 0; 0 0 1; 0 1 0]
 [0 1 0; 1 0 0; 0 0 1]
 [0 0 1; 1 0 0; 0 1 0]
 [0 1 0; 0 0 1; 1 0 0]
 [0 0 1; 0 1 0; 1 0 0]
pretty_print_txt( bell_games :: Vector{BellGame}, filename :: String )

Prints a set of BellGame's to filename.txt in a human-readable form.


BipartiteNonSignaling scenarios:

        ρ_AB :: AbstractMatrix,
        Π_Ax :: Vector{<:AbstractVector{<:AbstractMatrix}},
        Π_By :: Vector{<:AbstractVector{<:AbstractMatrix}},
        scenario :: BipartiteNonSignaling;
        atol::Float64 = 1e-7

Constructs a strategy matrix in the generalized representation for the quantum system with conditional probabilities.

\[ P(ab|xy) = \text{Tr}[(\Pi_a^x\otimes\Pi_b^y)\rho_{AB}]\]

A DomainError is thrown if

  • The length of each POVM does not match the scenarios number of outputs
  • The number of each party's POVMS doesn't match the the number of inputs.

LocalSignaling scenarios:

    Π :: AbstractVector{<:AbstractMatrix},
    ρ_states :: Vector{<:AbstractMatrix},
    scenario :: LocalSignaling;
) :: Strategy

For quantum systems the conditional probabilities are construct as

\[ P(y|x) = \text{Tr}[\Pi_y\rho_x].\]

A DomainError is thrown if the provided states and measurements are not compatible with the specified scenario.


Constructs a strategy matrix given quantum states and measurements. The supported scenarios include:

BlackBox scenarios:

    Π :: AbstractVector{<:AbstractMatrix},
    ρ_states :: Vector{<:State};
) :: Strategy

For a quantum system the conditional proabilities are constructed as

\[ P(y|x) = \text{Tr}[\Pi_y\rho_x].\]

    num_inputs :: Int64,
    num_outputs :: Int64;
) :: Strategy

Constructs a randomized Strategy matrix. Zeros are inserted into the strategy to ensure that it does not closely resemble a uniform distribution.

stirling2( n :: Int64, k :: Int64  ) :: Int64

Counts the number of ways to partition n items into k unlabelled groups. This quantity is known as Stirling's number of the 2nd kind:

\[\left\{n \atop k \right\} = \frac{1}{k!}\sum_{i=0}^k (-1)^i\binom{k}{i}(k-i)^n\]

Throws a DomainError if inputs do not satisfy n ≥ k ≥ 1.

stirling2_matrices( n :: Int64, k :: Int64 ) :: Vector{Matrix{Bool}}

Generates the set of matrices with k rows and n columns where rows correspond to the groups and columns are the grouped elements. A non-zero element designates that the column id is grouped into the corresponding row.


julia> stirling2_matrices(4, 2)
7-element Vector{Matrix{Bool}}:
 [1 1 1 0; 0 0 0 1]
 [0 0 1 0; 1 1 0 1]
 [1 1 0 0; 0 0 1 1]
 [1 0 1 0; 0 1 0 1]
 [0 1 0 0; 1 0 1 1]
 [0 1 1 0; 1 0 0 1]
 [1 0 0 0; 0 1 1 1]

A DomainError is thrown if n ≥ k ≥ 1 is not satisfied.

stirling2_partitions( n :: Int64, k :: Int64 ) :: Vector{Vector{Vector{Int64}}}

Enumerates the unique partitions of n items into k unlabelled sets. Each partition is a vector containing a set of k vectors designating each group.


julia> stirling2_partitions(4, 2)
7-element Vector{Vector{Vector{Int64}}}:
 [[1, 2, 3], [4]]
 [[3], [1, 2, 4]]
 [[1, 2], [3, 4]]
 [[1, 3], [2, 4]]
 [[2], [1, 3, 4]]
 [[2, 3], [1, 4]]
 [[1], [2, 3, 4]]

This recursive algorithm was inspired by this blog.

strategy_dims( scenario :: Scenario ) :: Tuple{Int64, Int64}

Returns the dimensions of the Conditionals matrix describing a Strategy for the Scenario at hand. Each Scenario, can place unique constraints on the matrix dimensions, therfore, separate methods are called for each concrete Scenario.