NaiveBackend

The NaiveBackend is a strong simulation backend that can compute a single output probability amplitude at a time, by computing the permanent of a \(n \times n\) matrix, with a time complexity of \(\mathrm{O}(n2^n)\) (see Ryser [69] and Glynn [28]).

As such, it is very efficient to compute very precise output states, but not to compute the whole distribution.

Thus, using it is not recommended in Simulator (except when using probability()) or Processor, but it is well suited for applications where only a few output probabilities matter. If the whole or most of the computational space is needed, other backends like SLOSBackend are more suited.

This backend is available in Processor by using the name "Naive".

>>> import perceval as pcvl
>>> c = pcvl.Circuit(4) // pcvl.BS() // (2, pcvl.BS())
>>> backend = pcvl.NaiveBackend()
>>> backend.set_circuit(c)
>>> backend.set_input_state(pcvl.BasicState([1, 0, 1, 0]))
>>> print(backend.prob_amplitude(pcvl.BasicState([1, 0, 0, 1])))
0.5j
class perceval.backends._naive.NaiveBackend

Naive algorithm, no clever calculation path, does not cache anything, recompute all states on the fly

all_prob(input_state=None)

Computes the list of probabilities of all states (respecting the mask if any was set). The order of the states can be retrieved using allstate_iterator()

Return type:

list[float]

clear_mask()

Removes any pre-existing mask

evolve()

Evolves the input BasicState into a StateVector.

Return type:

StateVector

property name: str

Returns the back-end name as a string

prob_amplitude(output_state)

Computes the probability amplitude for a given output state. The input state and the circuit must already be set

Return type:

complex

prob_distribution()

Computes the probability distribution of all states (respecting the mask if any was set) under the form of a BSDistribution.

Return type:

BSDistribution

probability(output_state)

Computes the probability for a given output state. The input state and the circuit must already be set

Return type:

float

set_circuit(circuit)

Sets the circuit to simulate. This circuit must not contain polarized components (use PolarizationSimulator instead, if required).

set_input_state(input_state)

Sets an input state for the simulation. This state has to be a Fock state without annotations.

set_mask(masks, n=None)

Sets new masks, replacing the former ones if they exist. Clear possible cached data that depend on the mask. Masks are useful to limit strong simulation to only a part of the Fock space, ultimately saving memory and computation time.

Parameters:
  • masks (str | list[str]) – Can be a mask or a list of masks. Each mask is expressed as a string where each character is a condition on one mode. Digits are fixing the number of photons whereas spaces or “*” are accepting any number of detections. e.g. using “****00” as a mask limits the simulation to output states ending in two empty modes.

  • n – The number of photons to instantiate the mask with. This corresponds to the total number of photons in your non-separated state.