Skip to content

Release v0.4.0

Compare
Choose a tag to compare
@ziofil ziofil released this 08 Mar 18:07
· 14 commits to main since this release
1120e64

Release 0.4.0

New features

  • Ray-based distributed trainer is now added to training.trainer. It acts as a replacement
    for for loops and enables the parallelization of running many circuits as well as their
    optimizations. To install the extra dependencies: pip install .[ray].
    (#194)

    from mrmustard.lab import Vacuum, Dgate, Ggate
    from mrmustard.physics import fidelity
    from mrmustard.training.trainer import map_trainer
    def make_circ(x=0.):
        return Ggate(num_modes=1, symplectic_trainable=True) >> Dgate(x=x, x_trainable=True, y_trainable=True)
    def cost_fn(circ=make_circ(0.1), y_targ=0.):
        target = Gaussian(1) >> Dgate(-1.5, y_targ)
        s = Vacuum(1) >> circ
        return -fidelity(s, target)
    # Use case 0: Calculate the cost of a randomly initialized circuit 5 times without optimizing it.
    results_0 = map_trainer(
        cost_fn=cost_fn,
        tasks=5,
    )
    # Use case 1: Run circuit optimization 5 times on randomly initialized circuits.
    results_1 = map_trainer(
        cost_fn=cost_fn,
        device_factory=make_circ,
        tasks=5,
        max_steps=50,
        symplectic_lr=0.05,
    )
    # Use case 2: Run circuit optimization 2 times on randomly initialized circuits with custom parameters.
    results_2 = map_trainer(
        cost_fn=cost_fn,
        device_factory=make_circ,
        tasks=[
            {'x': 0.1, 'euclidean_lr': 0.005, 'max_steps': 50, 'HBAR': 1.},
            {'x': -0.7, 'euclidean_lr': 0.1, 'max_steps': 2, 'HBAR': 2.},
        ],
        y_targ=0.35,
        symplectic_lr=0.05,
        AUTOCUTOFF_MAX_CUTOFF=7,
    )
  • Sampling for homodyne measurements is now integrated in Mr Mustard: when no measurement outcome
    value is specified by the user, a value is sampled from the reduced state probability distribution
    and the conditional state on the remaining modes is generated.
    (#143)

    import numpy as np
    from mrmustard.lab import Homodyne, TMSV, SqueezedVacuum
    # conditional state from measurement
    conditional_state = TMSV(r=0.5, phi=np.pi)[0, 1] >> Homodyne(quadrature_angle=np.pi/2)[1]
    # measurement outcome
    measurement_outcome = SqueezedVacuum(r=0.5) >> Homodyne()
  • The optimizer minimize method now accepts an optional callback function, which will be called
    at each step of the optimization and it will be passed the step number, the cost value,
    and the value of the trainable parameters. The result is added to the callback_history
    attribute of the optimizer.
    (#175)

  • the Math interface now supports linear system solving via math.solve.
    (#185)

  • We introduce the tensor wrapper MMTensor (available in math.mmtensor) that allows for
    a very easy handling of tensor contractions. Internally MrMustard performs lots of tensor
    contractions and this wrapper allows one to label each index of a tensor and perform
    contractions using the @ symbol as if it were a simple matrix multiplication (the indices
    with the same name get contracted).
    (#185)

    (#195)

    from mrmustard.math.mmtensor import MMTensor
    # define two tensors
    A = MMTensor(np.random.rand(2, 3, 4), axis_labels=["foo", "bar", "contract"])
    B = MMTensor(np.random.rand(4, 5, 6), axis_labels=["contract", "baz", "qux"])
    # perform a tensor contraction
    C = A @ B
    C.axis_labels  # ["foo", "bar", "baz", "qux"]
    C.shape # (2, 3, 5, 6)
    C.tensor # extract actual result
  • MrMustard's settings object (accessible via from mrmustard import settings) now supports
    SEED (an int). This will give reproducible results whenever randomness is involved.
    The seed is assigned randomly by default, and it can be reassigned again by setting it to None:
    settings.SEED = None. If one desires, the seeded random number generator is accessible directly
    via settings.rng (e.g. settings.rng.normal()).
    (#183)

  • The Circuit class now has an ascii representation, which can be accessed via the repr method.
    It looks great in Jupyter notebooks! There is a new option at settings.CIRCUIT_DECIMALS
    which controls the number of decimals shown in the ascii representation of the gate parameters.
    If None, only the name of the gate is shown.
    (#196)

  • PNR sampling from Gaussian circuits using density matrices can now be performed faster.
    When all modes are detected, this is done by replacing math.hermite_renormalized by math.hermite_renormalized_diagonal. If all but the first mode are detected,
    math.hermite_renormalized_1leftoverMode can be used.
    The complexity of these new methods is equal to performing a pure state simulation.
    The methods are differentiable, so that they can be used for defining a cost function.
    (#154)

  • MrMustard repo now provides a fully furnished vscode development container and a Dockerfile. To
    find out how to use dev containers for development check the documentation
    here.
    (#214)

Breaking changes

Improvements

  • The Dgate is now implemented directly in MrMustard (instead of on The Walrus) to calculate the
    unitary and gradients of the displacement gate in Fock representation, providing better numerical
    stability for larger cutoff and displacement values.
    (#147)
    (#211)

  • Now the Wigner function is implemented in its own module and uses numba for speed.
    (#171)

      from mrmustard.utils.wigner import wigner_discretized
      W, Q, P = wigner_discretized(dm, q, p) # dm is a density matrix
  • Calculate marginals independently from the Wigner function thus ensuring that the marginals are
    physical even though the Wigner function might not contain all the features of the state
    within the defined window. Also, expose some plot parameters and return the figure and axes.
    (#179)

  • Allows for full cutoff specification (index-wise rather than mode-wise) for subclasses
    of Transformation. This allows for a more compact Fock representation where needed.
    (#181)

  • The mrmustard.physics.fock module now provides convenience functions for applying kraus
    operators and choi operators to kets and density matrices.
    (#180)

    from mrmustard.physics.fock import apply_kraus_to_ket, apply_kraus_to_dm, apply_choi_to_ket, apply_choi_to_dm
    ket_out = apply_kraus_to_ket(kraus, ket_in, indices)
    dm_out = apply_choi_to_dm(choi, dm_in, indices)
    dm_out = apply_kraus_to_dm(kraus, dm_in, indices)
    dm_out = apply_choi_to_ket(choi, ket_in, indices)
  • Replaced norm with probability in the repr of State. This improves consistency over the
    old behaviour (norm was the sqrt of prob if the state was pure and prob if the state was mixed).
    (#182)

  • Added two new modules (physics.bargmann and physics.husimi) to host the functions related
    to those representations, which have been refactored and moved out of physics.fock.
    (#185)

  • The internal type system in MrMustard has been beefed up with much clearer types, like ComplexVector,
    RealMatrix, etc... as well as a generic type Batch, which can be parametrized using the other types,
    like Batch[ComplexTensor]. This will allow for better type checking and better error messages.
    (#199)

  • Added multiple tests and improved the use of Hypothesis.
    (#191)

  • The fock.autocutoff function now uses the new diagonal methods for calculating a
    probability-based cutoff. Use settings.AUTOCUTOFF_PROBABILITY to set the probability threshold.
    (#203)

  • The unitary group optimization (for the interferometer) and the orthogonal group optimization
    (for the real interferometer) have been added. The symplectic matrix that describes an
    interferometer belongs to the intersection of the orthogonal group and the symplectic group,
    which is a unitary group, so we needed both.
    (#208)

Bug fixes

  • The Dgate and the Rgate now correctly parse the case when a single scalar is intended
    as the same parameter of a number of gates in parallel.
    (#180)

  • The trace function in the fock module was giving incorrect results when called with certain
    choices of modes. This is now fixed.
    (#180)

  • The purity function for fock states no longer normalizes the density matrix before computing
    the purity.
    (#180)

  • The function dm_to_ket no longer normalizes the density matrix before diagonalizing it.
    (#180)

  • The internal fock representation of states returns the correct cutoffs in all cases
    (solves an issue when a pure dm was converted to ket).
    (#184)

  • The ray related tests were hanging in github action causing tests to halt and fail.
    Now ray is forced to init with 1 cpu when running tests preventing the issue.
    (#201)

  • Various minor bug fixes.
    (#202)

  • Fixed the issue that the optimization of the interferometer was using orthogonal group
    optimization rather than unitary.
    (#208)

  • Fixes a slicing issue that arises when we compute the fidelity between gaussian and fock states.
    (#210)

  • The sign of parameters in the circuit drawer are now displayed correctly.
    (#209)

  • Fixed a bug in the Gaussian state which caused its covariance matrix to be multiplied
    by hbar/2 twice. Adds the argument modes to Ggate.
    (#212)

  • Fixes a bug in the cutoffs of the choi operator.
    (#216)

Documentation

Contributors

This release contains contributions from (in alphabetical order):
Robbe De Prins (@rdprins), Sebastian Duque Mesa (@sduquemesa),
Filippo Miatto (@ziofil), Zeyue Niu (@zeyueN),
Yuan Yao (@sylviemonet)