Legacy

While, with its latest versions, Perceval tends to stabilise its public API, some changes may break existing user code.

This section lists the major breaking changes.

Breaking changes in Perceval 1.0

FockState was split in three different classes

To achieve better optimisation in noisy simulation and to clarify the intent of different states usage, it has been decided to get rid of the former generic FockState that could hold richly annotated photons as well as just a plain perfect state.

Definition of the new classes

  • FockState: A light-weight object only containing photon positions in mode (e.g. |1,0,1>). Can be used to represent detections.

  • NoisyFockState: A collection of indistinguishable photon groups, that are totally distinguishable. The distinguishability index is an integer and is referred to as the noise tag (e.g. |{0},{1},{0}{2}> contains three groups of indistinguishable photons tagged 0, 1 and 2).

  • AnnotatedBasicState: Replace the previous FockState by allowing rich annotations, having one or more string types, each having a complex number for value. This enables to accurately encode physical parameters and play with partial distinguishability (e.g. |{P:H,lambda:0.625},{P:V,lambda:0.618}>). Please note that apart from polarisation, Perceval does not provide a generic algorithm to separate rich annotated states, and the user would have to write one.

Some calls will use or return only the type that makes sense (e.g. AnnotatedFockState::threshold_detection() always returns a FockState as a detected state naturally loses all kinds of photon annotation.

Note

Note that arithmetic still works between states of different types. The result is the most complex type of both operands (e.g. NoisyFockStateFockState gives a NoisyFockState).

Usage in Perceval

The BasicState class still exists and has the same responsibility as before: representing any non superposed pure state. It can construct any of the forementioned state type from a string representation, of vectors of position, and optionally noise tags or annotations.

Even though, Perceval code makes it so isinstance(any_fockstate, BasicState) returns True, the type hinting of user code in an IDE could alert that the types do not match after the update.

Note

StateVector (and therefore SVDistribution) accept any of the three Fock state types as components.

Processor add with Component or Circuit

When adding a Circuit or a Component to a Processor on non-consecutive modes, a permutation was added so that we could add the component to the Processor. The inverse permutation is now also added after the component so that the in-between modes are not impacted by the addition, similarly to what was already done when adding a Processor to a Processor.

BSDistribution and SVDistribution

These classes have been moved to Exqalibur with a C++ implementation. As such, they are no longer Python dictionaries and may not support some advanced dict features. This has several consequences:

  • You can no longer instantiate BSDistribution or SVDistribution using a dictionary with mixed type keys, nor with non-BasicState or non-StateVector keys.

  • BSDistribution and SVDistribution can no longer be compared to a regular dict (for example by using ==).

  • The order of insertion is no longer preserved.

  • keys() and values() methods now return an iterator, so methods like len no longer work on their result.

Also, note that:

  • Inserting a StateVector in SVDistribution no longer normalises it.

  • Using the tensor product with an empty distribution now always returns an empty distribution. To keep the same behaviour as before (the result was the non-empty distribution), one would have to replace the empty distribution by a distribution containing a void state (BSDistribution(BasicState())) for tensor product or a 0-photon state (BSDistribution(BasicState(m))) for a merge.

StateVector

The method StateVector.keys() now returns an iterator on the keys instead of a BSSamples. This avoids doing unnecessary copy.

Please note that due to this change:

  • Keys must now be copied before being modified when iterating on StateVector.keys().

  • StateVector.keys() no longer has list methods such as len, __getitem__

Removal of deprecated methods and classes

The following methods and classes have been removed or definitely modified as they were deprecated:

  • TokenProvider (deprecated since 0.13, replaced by RemoteConfig)

  • AProbAmpliBackend (deprecated since 0.12, replaced by AStrongSimulationBackend)

  • postselect_independent (deprecated since 0.12, replaced by PostSelect method is_independent_with)

  • The n parameter of SLOS backend (deprecated since 0.12, now automatically chosen when using set_input_state)

  • thresholded_output method of Processor and RemoteProcessor (deprecated since 0.12, replaced by adding several Detector.threshold())

  • with_polarized_input method of Processor (because Processor.with_input is now able to handle a polarized AnnotatedFockState transparently)

  • tensorproduct(states: list) from perceval.utils (due to tensor products being handled well by multiplication operators and specific methods - see BSDistribution.list_tensor_product, for instance)

  • JobGroup.list_existing() has been renamed into JobGroup.list_locally_saved()

NoiseModel

The way of NoiseModel to handle its attributes has changed to be more pythonic. Now, your IDE should be able to tell that the attributes exist in the class, and the attributes can be changed using a syntax like noise_model.g2 = 0.1.

This change is accompanied by the removal of some methods: - The __getitem__ has been removed since it was giving a class that is not accessible anymore - The set_value method has been removed, and can be replaced either by spelling directly the attribute (noise_model.g2 = 0.1)

or by using the python method setattr(noise_model, "g2", 0.1).

Older changes

The documentation to update from an older legacy version to a more recent one can still be found here.