Strawberryfields

Latest version: v0.23.0

Safety actively analyzes 621498 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 5

0.23.0

New features

* Program Xanadu’s new Borealis hardware device via Strawberry Fields and Xanadu Cloud. [(714)]([https://github.com/XanaduAI/strawberryfields/pull/714](https://github.com/XanaduAI/strawberryfields/pull/714))

Borealis is a cloud-accessible photonic quantum computer, offering full programmability over all of its gates and capable of quantum advantage. Its hardware is based on [time-domain multiplexing (TDM)](https://strawberryfields.ai/photonics/demos/run_time_domain.html); a single squeezed-light source emits batches of 216 time-ordered squeezed-light pulses that interfere with one another with the help of optical delay loops, programmable beamsplitters, and phase shifters.

Learn more about Borealis via our [website](https://xanadu.ai/products/borealis) and [tutorials](https://strawberryfields.ai/photonics/demos/tutorial_borealis_beginner.html).


* GBS data visualization functions are added. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

* A set of TDM compilers are added, including a Borealis compiler which compiles and validates programs against the hardware specification and calibration certificate. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

* A `remove_loss` utility function is added to the `program_utils` module, allowing for the removal of `LossChannels` from Strawberry Fields programs. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

* Cropping vacuum modes from TDM program results is now possible by passing `crop=True` as a run option. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

python
n, N = get_mode_indices(delays)
prog = sf.TDMProgram(N)

with prog.context(*gate_args) as (p, q):
ops.Sgate(p[0]) | q[n[0]]
for i in range(len(delays)):
ops.Rgate(p[2 * i + 1]) | q[n[i]]
ops.BSgate(p[2 * i + 2], np.pi / 2) | (q[n[i + 1]], q[n[i]])
ops.MeasureX | q[0]

eng = sf.Engine("gaussian")
results = eng.run(prog, crop=True)


* Resulting samples from TDM jobs return only the non-empty mode measurements when setting the `crop` option to `True` in the program `run_options` or as a keyword argument in the engine `run` method. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

* Realistic loss can be added to a Borealis circuit for local simulation execution. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

python
compile_options = {
"device": device, hardware device object needed
"realistic_loss": True,
}

eng = sf.Engine("gaussian")
results = eng.run(prog, compile_options=compile_options)


* Utility functions are added to allow for easier Borealis program and parameter creation. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

* Functions are added for analyzing GBS results for comparisons with classical simulations. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

Improvements

* A locked program can now be (un)rolled, and automatically restores the lock if previously in place. [(703)](https://github.com/XanaduAI/strawberryfields/pull/703)

* Rolling and unrolling now only happens in place, and no longer returns the (un)rolled circuit. [(702)](https://github.com/XanaduAI/strawberryfields/pull/702)

* `Program.assert_number_of_modes` and `Program.assert_max_number_of_measurements` are combined into a single `assert_modes` method. [(709)](https://github.com/XanaduAI/strawberryfields/pull/709)

* Job results can now be retrieved without converting integers to `np.int64` objects by setting `integer_overflow_protection=False` (default `True`) when running a program via `RemoteEngine.run()`. [(712)](https://github.com/XanaduAI/strawberryfields/pull/712)

* The TDM module is refactored to contain `program.py`, with the `TDMProgram` class, and `utils.py`, with various utility functions. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

* The `Compiler` base class is updated to allow for setting a rigid circuit layout to validate a program during compilation. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

* The `Compiler` base class now contains methods that can be overwritten to provide subclass compilers with loss-additions (e.g., to add realistic loss to a circuit) and program parameter updates. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

Bug fixes

* Trying to unroll an already unrolled program with a different number of shots works as expected. [(702)](https://github.com/XanaduAI/strawberryfields/pull/702)

* Fixed bug with vacuum modes missing. [(702)](https://github.com/XanaduAI/strawberryfields/pull/702)

* Validating parameters now works with nested parameter arrays. [(711)](https://github.com/XanaduAI/strawberryfields/pull/711)

* Store correct rolled circuit before unrolling (fixes issue when rolled circuit has changed due to e.g., compilation). [(710)](https://github.com/XanaduAI/strawberryfields/pull/710)

Documentation

* The centralized [Xanadu Sphinx Theme](https://github.com/XanaduAI/xanadu-sphinx-theme) is now used to style the Sphinx documentation. [(#701)](https://github.com/XanaduAI/strawberryfields/pull/701)

* The documentation on Gaussian circuit operations is fixed so that it's properly rendered. [(714)](https://github.com/XanaduAI/strawberryfields/pull/714)

Contributors

This release contains contributions from (in alphabetical order):

Mikhail Andrenkov, Sebastian Duque, Luke Helt, Theodor Isacsson, Josh Izaac, Fabian Laudenbach

0.22.0

<h3>New features since last release</h3>

* `Device.layout` and `Device.gate_parameters` may now return `None`. This can happen when a remote simulator device is used. [(661)](https://github.com/XanaduAI/strawberryfields/pull/661)

* A new interferometer decomposition method is implemented following the proposal of the paper [_Simple factorization of unitary transformations_](https://doi.org/10.1103/PhysRevA.97.022328). [(#665)](https://github.com/XanaduAI/strawberryfields/pull/665)

python
import numpy as np

import strawberryfields as sf
from strawberryfields import ops

U = np.array([[-0.39302099+0.28732291j, 0.83734522+0.24866248j],
[ 0.00769051+0.87345344j, -0.3847068 +0.29836325j]])

prog = sf.Program(2)

with prog.context as q:
ops.Interferometer(U, mesh="sun_compact") | q


* A `Device.certificate` method is added which returns the hardware device certificate. [(679)](https://github.com/XanaduAI/strawberryfields/pull/679)

pycon
>>> import strawberryfields as sf
>>> eng = sf.RemoteEngine("X8")
>>> print(eng.device.certificate)
{'target': 'X8_01' ... }


* Setting `shots=None` in the engine or program run options will not execute any measurements applied on the circuit. [(682)](https://github.com/XanaduAI/strawberryfields/pull/682)

python
import strawberryfields as sf
from strawberryfields import ops

prog = sf.Program(1)
eng = sf.Engine("gaussian")

with prog.context as q:
ops.Sgate(0.5) | q[0]
ops.MeasureFock() | q

results = eng.run(prog, shots=None)

samples will output an empty list []
print(results.samples)

the resulting Gaussian state is still accessible
via its vector of means and covariance matrix
print(results.state.means())
print(results.state.cov())


* There's a `program_equivalence` function in `strawberryfields/program_utils.py` which checks Strawberry Fields programs for equivalence. [(686)](https://github.com/XanaduAI/strawberryfields/pull/686)

* An equality operator is implemented for `strawberryfields.Program`, checking that the exact same gates and respective parameters, are applied in order. [(686)](https://github.com/XanaduAI/strawberryfields/pull/686)

python
import strawberryfields as sf
from strawberryfields import ops

prog_1 = sf.Program(1)
prog_2 = sf.Program(1)

with prog.context as q:
ops.Sgate(0.42) | q[0]
ops.MeasureFock() | q

with prog.context as q:
ops.Sgate(0.42) | q[0]
ops.MeasureFock() | q

assert prog_1 == prog_2


* A `Program.equivalence` convenience method is added which calls the `program_equivalence` utility function. [(686)](https://github.com/XanaduAI/strawberryfields/pull/686)

python
prog_1 = sf.Program(1)
prog_2 = sf.Program(1)

with prog.context as q:
ops.Sgate(1.1) | q[0]
ops.MeasureFock() | q

with prog.context as q:
ops.Sgate(0.42) | q[0]
ops.MeasureFock() | q

assert prog_1.equivalence(prog_2, compare_params=False)


* A `Device.validate_target` static method is added which checks that the target in the layout is the same as the target field in the specification. This check is also performed at `Device` initialization. [(687)](https://github.com/XanaduAI/strawberryfields/pull/687)

* Tests are run in random order and the seed for NumPy's and Python's random number generators are set by `pytest-randomly`. [(692)](https://github.com/XanaduAI/strawberryfields/pull/692)

* Adds support for Python 3.10. [695](https://github.com/XanaduAI/strawberryfields/pull/695)

<h3>Breaking Changes</h3>

* `DeviceSpec` is renamed to `Device`, which now also contains more than only the device specification. [(679)](https://github.com/XanaduAI/strawberryfields/pull/679)

pycon
>>> import strawberryfields as sf
>>> eng = sf.RemoteEngine("X8")
>>> isinstance(eng.device, sf.Device)
True
>>> print(eng.device.target)
X8_01


<h3>Bug fixes</h3>

* It's now possible to show graphs using the plot apps layer when not run in notebooks. [(669)](https://github.com/XanaduAI/strawberryfields/pull/669)

* `program.compile` now raises an error if the device specification contains gate parameters but no circuit layout. Without a layout, the gate parameters cannot be validated against the device specification. [(661)](https://github.com/XanaduAI/strawberryfields/pull/661)

* The teleportation tutorial `examples/teleportation.py` now uses the correct value (now `phi = 0` instead of `phi = np.pi / 2`) for the phase shift of the beamsplitters. [(674)](https://github.com/XanaduAI/strawberryfields/pull/674)

* `Program.compile()` returns a deep copy of the program attributes, except for the circuit and the register references. [(688)](https://github.com/XanaduAI/strawberryfields/pull/688)

<h3>Contributors</h3>

This release contains contributions from (in alphabetical order):

Sebastian Duque, Theodor Isacsson, Jon Schlipf, Hossein Seifoory

0.21.0

<h3>New features since last release</h3>

* A `Result.metadata` property is added to retrieve the metadata of a job result. [(663)](https://github.com/XanaduAI/strawberryfields/pull/663)

* A setter method for `Result.state` is added for setting a state for a local simulation if a state has not previously been set. [(663)](https://github.com/XanaduAI/strawberryfields/pull/663)

* Functions are now available to convert between XIR and Strawberry Fields programs. [(643)](https://github.com/XanaduAI/strawberryfields/pull/643)

For example,

python
prog = sf.Program(3)
eng = sf.Engine("gaussian")

with prog.context as q:
ops.Sgate(0, 0) | q[0]
ops.Sgate(1, 0) | q[1]
ops.BSgate(0.45, 0.0) | (q[0], q[2])
ops.MeasureFock() | q[0]

xir_prog = sf.io.to_xir(prog)


resulting in the following XIR script

pycon
>>> print(xir_prog.serialize())
Sgate(0, 0) | [0];
Sgate(1, 0) | [1];
BSgate(0.45, 0.0) | [0, 2];
MeasureFock | [0];


<h3>Bug fixes</h3>

* The `TDMProgram.compile_info` and `TDMProgram.target` fields are now set when a `TDMProgram` is compiled using the "TDM" compiler. [(659)](https://github.com/XanaduAI/strawberryfields/pull/659)

* Updates `Program.assert_max_number_of_measurements` to expect the maximum number of measurements from the device specification as a flat dictionary entry instead of a nested one. [(662)](https://github.com/XanaduAI/strawberryfields/pull/662)

python
"modes": {
"pnr_max": 20,
"homodyne_max": 1000,
"heterodyne_max": 1000,
}


instead of

python
"modes": {
"max": {
"pnr": 20,
"homodyne": 1000,
"heterodyne": 1000,
}
}


<h3>Documentation</h3>

* README has been ported to Markdown. [(664)](https://github.com/XanaduAI/strawberryfields/pull/664)

<h3>Contributors</h3>

This release contains contributions from (in alphabetical order):

Theodor Isacsson

0.20.0

<h3>New features since last release</h3>

* The generic multimode Gaussian gate ``Ggate`` is now available in the ``sf.ops`` module with the backend choice of ``tf``. The N mode ``Ggate`` can be parametrized by a real symplectic matrix `S` (size `2N * 2N`) and a diplacement vector `d` (size `N`). You can also obtain the gradients of the Ggate gate via TensorFlow's ``tape.gradient`` [(599)](https://github.com/XanaduAI/strawberryfields/pull/599) [(#606)](https://github.com/XanaduAI/strawberryfields/pull/606)

python
from thewalrus.random import random_symplectic

num_mode = 2
cutoff = 10
S = tf.Variable(random_symplectic(num_mode))
d = tf.Variable(np.random.random(2 * num_mode))

eng = sf.Engine("tf", backend_options={"cutoff_dim": cutoff})
prog = sf.Program(2)

with prog.context as q:
sf.ops.Ggate(S, d) | (q[0], q[1])

state_out = eng.run(prog).state.ket()


Note that in order to update the parameter `S` by using its gradient, you cannot use gradient descent directly (as the unitary would not be symplectic after the update). Please use the function `sf.backends.tfbackend.update_symplectic` which is designed specifically for this purpose.

python
def overlap_loss(state, objective):
return -tf.abs(tf.reduce_sum(tf.math.conj(state) * objective)) ** 2

def norm_loss(state):
return -tf.abs(tf.linalg.norm(state)) ** 2

def loss(state, objective):
return overlap_loss(state, objective) + norm_loss(state)

num_mode = 1
cutoff = 10

S = tf.Variable(random_symplectic(num_mode))
d = tf.Variable(np.random.random(2 * num_mode))
kappa = tf.Variable(0.3)
objective = tf.Variable(np.eye(cutoff)[1], dtype=tf.complex64)

adam = tf.keras.optimizers.Adam(learning_rate=0.01)
eng = sf.Engine("tf", backend_options={"cutoff_dim": cutoff})
prog = sf.Program(1)

with prog.context as q:
sf.ops.Ggate(S, d) | q
sf.ops.Kgate(kappa) | q

loss_vals = []
for _ in range(200):
with tf.GradientTape() as tape:
state_out = eng.run(prog).state.ket()
loss_val = loss(state_out, objective)

eng.reset()
grad_S, gradients_d, gradients_kappa = tape.gradient(loss_val, [S, d, kappa])
adam.apply_gradients(zip([gradients_d, gradients_kappa], [d, kappa]))
update_symplectic(S, grad_S, lr=0.1) update S here
loss_vals.append(loss_val)


<h3>Breaking Changes</h3>

* Complex parameters of the `Catstate` operation are expected in polar form as two separate real parameters. [(441)](https://github.com/XanaduAI/strawberryfields/pull/441)

* The `sf` CLI has been removed in favour of the [Xanadu Cloud Client](https://github.com/XanaduAI/xanadu-cloud-client). [(#642)](https://github.com/XanaduAI/strawberryfields/pull/642)

1. Configuring account credentials using:

* Strawberry Fields v0.19.0

console
$ sf configure --token "foo"


* Strawberry Fields v0.20.0

console
$ xcc config set REFRESH_TOKEN "foo"
Successfully updated REFRESH_TOKEN setting to 'foo'.


2. Verifying your connection to the Xanadu Cloud using:

* Strawberry Fields v0.19.0

console
$ sf --ping
You have successfully authenticated to the platform!


* Strawberry Fields v0.20.0

console
$ xcc ping
Successfully connected to the Xanadu Cloud.


3. Submitting a Blackbird circuit to the Xanadu Cloud using:

* Strawberry Fields v0.19.0

console
$ Version 0.19.0
$ sf run "foo.xbb"
Executing program on remote hardware...
2021-11-02 03:04:05,06 - INFO - The device spec X8_01 has been successfully retrieved.
2021-11-02 03:04:05,07 - INFO - Compiling program for device X8_01 using compiler Xunitary.
2021-11-02 03:04:05,08 - INFO - Job b185a63c-f302-4adb-acf8-b6e4e413c11d was successfully submitted.
2021-11-02 03:04:05,09 - INFO - The remote job b185a63c-f302-4adb-acf8-b6e4e413c11d has been completed.
[[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]]


* Strawberry Fields v0.20.0

console
$ xcc job submit --name "bar" --target "X8_01" --circuit "$(cat foo.xbb)"
{
"id": "0b0f5a46-46d8-4157-8005-45a4764361ba", Use this ID below.
"name": "bar",
"status": "open",
"target": "X8_01",
"language": "blackbird:1.0",
"created_at": "2021-11-02 03:04:05,10",
"finished_at": null,
"running_time": null,
"metadata": {}
}
$ xcc job get 0b0f5a46-46d8-4157-8005-45a4764361ba --result
{
"output": [
"[[0 0 0 0]\n[0 0 0 0]\n[0 0 0 0]\n[0 0 0 0]]"
]
}


* The `sf.api.Connection` class has been replaced with the [xcc.Connection](https://xanadu-cloud-client.readthedocs.io/en/stable/api/xcc.Connection.html) class. [(#645)](https://github.com/XanaduAI/strawberryfields/pull/645)

Previously, in Strawberry Fields v0.19.0, an `sf.RemoteEngine` can be instantiated with a custom Xanadu Cloud connection as follows:

python
import strawberryfields as sf
import strawberryfields.api

connection = strawberryfields.api.Connection(
token="Xanadu Cloud API key goes here",
host="platform.strawberryfields.ai",
port=443,
use_ssl=True,
)
engine = sf.RemoteEngine("X8", connection=connection)


In Strawberry Fields v0.20.0, the same result can be achieved using
python
import strawberryfields as sf
import xcc

connection = xcc.Connection(
refresh_token="Xanadu Cloud API key goes here", See "token" argument above.
host="platform.strawberryfields.ai",
port=443,
tls=True, See "use_ssl" argument above.
)
engine = sf.RemoteEngine("X8", connection=connection)


* The `sf.configuration` module has been replaced with the [xcc.Settings](https://xanadu-cloud-client.readthedocs.io/en/stable/api/xcc.Settings.html) class. [(#649)](https://github.com/XanaduAI/strawberryfields/pull/649)

This means that Xanadu Cloud credentials are now stored in exactly one location, the path to which depends on your operating system:

1. Windows: `C:\Users\%USERNAME%\AppData\Local\Xanadu\xanadu-cloud\.env`

2. MacOS: `/home/$USER/Library/Application\ Support/xanadu-cloud/.env`

3. Linux: `/home/$USER/.config/xanadu-cloud/.env`

The format of the configuration file has also changed to [.env](https://saurabh-kumar.com/python-dotenv/) and the names of some fields have been updated. For example,

toml
Strawberry Fields v0.19.0 (config.toml)
[api]
authentication_token = "Xanadu Cloud API key goes here"
hostname = "platform.strawberryfields.ai"
port = 443
use_ssl = true


is equivalent to

python
Strawberry Fields v0.20.0 (.env)
XANADU_CLOUD_REFRESH_TOKEN='Xanadu Cloud API key goes here'
XANADU_CLOUD_HOST='platform.strawberryfields.ai'
XANADU_CLOUD_PORT=443
XANADU_CLOUD_TLS=True


Similarly, the names of the configuration environment variables have changed from

bash
Strawberry Fields v0.19.0
export SF_API_AUTHENTICATION_TOKEN="Xanadu Cloud API key goes here"
export SF_API_HOSTNAME="platform.strawberryfields.ai"
export SF_API_PORT=443
export SF_API_USE_SSL=true


to

bash
Strawberry Fields v0.20.0
export XANADU_CLOUD_REFRESH_TOKEN="Xanadu Cloud API key goes here"
export XANADU_CLOUD_HOST="platform.strawberryfields.ai"
export XANADU_CLOUD_PORT=443
export XANADU_CLOUD_TLS=true


Finally, `strawberryfields.store_account()` has been replaced such that

python
Strawberry Fields v0.19.0
import strawberryfields as sf
sf.store_account("Xanadu Cloud API key goes here")


becomes

python
Strawberry Fields v0.20.0
import xcc
xcc.Settings(REFRESH_TOKEN="Xanadu Cloud API key goes here").save()


* The `sf.api.Job` class has been replaced with the [xcc.Job](https://xanadu-cloud-client.readthedocs.io/en/stable/api/xcc.Job.html) class. [(#650)](https://github.com/XanaduAI/strawberryfields/pull/650)

A `Job` object is returned when running jobs asynchronously. In previous versions of Strawberry Fields (v0.19.0 and lower), the `Job` object can be used as follows:

pycon
>>> job = engine.run_async(program, shots=1)
>>> job.status
'queued'
>>> job.result
InvalidJobOperationError
>>> job.refresh()
>>> job.status
'complete'
>>> job.result
[[0 1 0 2 1 0 0 0]]


In Strawberry Fields v0.20.0, the `Job` object works slightly differently:

pycon
>>> job = engine.run_async(program, shots=1)
>>> job.status
'queued'
>>> job.wait()
>>> job.status
'complete'
>>> job.result
{'output': [array([[0 1 0 2 1 0 0 0]])]}


The `job.wait()` method is a blocking method that will wait for the job to finish. Alternatively, `job.clear()` can be called to clear the cache, allowing `job.status` to re-fetch the job status.

* The `sf.api.Result` class has been updated to support the Xanadu Cloud Client integration. [(651)](https://github.com/XanaduAI/strawberryfields/pull/651)

While `Result.samples` should return the same type and shape as before, the `Result.all_samples` property has been renamed to `Result.samples_dict` and returns the samples as a dictionary with corresponding measured modes as keys.

pycon
>>> res = eng.run(prog, shots=3)
>>> res.samples
array([[1, 0], [0, 1], [1, 1]])
>>> res.samples_dict
{0: [np.array([1, 0, 1])], 1: [np.array([0, 1, 1])]}


The samples dictionary is only accessible for simulators.

* The `sf.api.DeviceSpec` class has been updated to support the Xanadu Cloud Client integration. [(644)](https://github.com/XanaduAI/strawberryfields/pull/644)

It now works as a container for a device specification dictionary. There are no more API connection usages, and `DeviceSpec.target` is retrieved from the device specification rather than passed at initialization.

* The `api` subpackage has been removed and the contained `DeviceSpec` and `Result` classes have been moved to the root `strawberryfields` folder. [(652)](https://github.com/XanaduAI/strawberryfields/pull/652)

They can now be imported as follows:

python
import strawberryfields as sf
sf.DeviceSpec
sf.Result


<h3>Documentation</h3>

* Strawberry Fields interactive has been removed from the documentation. [(635)](https://github.com/XanaduAI/strawberryfields/pull/635)

<h3>Contributors</h3>

This release contains contributions from (in alphabetical order):

Mikhail Andrenkov, Sebastián Duque Mesa, Theodor Isacsson, Josh Izaac, Filippo Miatto, Nicolás Quesada, Antal Száva, Yuan Yao.

0.19.0

<h3>New features since last release</h3>

* Compact decompositions as described in <https://arxiv.org/abs/2104.07561>, (``rectangular_compact`` and ``triangular_compact``) are now available in the ``sf.decompositions`` module, and as options in the ``Interferometer`` operation. [(#584)](https://github.com/XanaduAI/strawberryfields/pull/584)

This decomposition allows for lower depth photonic circuits in physical devices by applying two independent phase shifts in parallel inside each Mach-Zehnder interferometer. ``rectangular_compact`` reduces the layers of phase shifters from 2N+1 to N+2 for an N mode interferometer when compared to e.g. ``rectangular_MZ``.

Example:

python
import numpy as np
from strawberryfields import Program
from strawberryfields.ops import Interferometer
from scipy.stats import unitary_group

M = 10

generate a 10x10 Haar random unitary
U = unitary_group.rvs(M)

prog = Program(M)

with prog.context as q:
Interferometer(U, mesh='rectangular_compact') | q

check that applied unitary is correct
compiled_circuit = prog.compile(compiler="gaussian_unitary")
commands = compiled_circuit.circuit
S = commands[0].op.p[0] symplectic transformation
Uout = S[:M,:M] + 1j * S[M:,:M] unitary transformation

print(np.allclose(U, Uout))


* A new compiler, ``GaussianMerge``, has been added. It is aimed at reducing calculation overhead for non-Gaussian circuits by minimizing the amount of Gaussian operations in a circuit, while retaining the same functionality. [(591)](https://github.com/XanaduAI/strawberryfields/pull/591)

``GaussianMerge`` merges Gaussian operations, where allowed, into ``GaussianTransform`` and ``Dgate`` operations. It utilizes the existing ``GaussianUnitary`` compiler to merge operations and Directed Acyclic Graphs to determine which operations can be merged.

python
modes = 4
cutoff_dim = 6

prepare an intial state with 4 photons in as many modes
initial_state = np.zeros([cutoff_dim] * modes, dtype=complex)
initial_state[1, 1, 1, 1] = 1

prog = sf.Program(4)

with prog.context as q:
ops.Ket(initial_state) | q Initial state preparation
Gaussian Layer
ops.S2gate(0.01, 0.01) | (q[0], q[1])
ops.BSgate(1.9, 1.7) | (q[1], q[2])
ops.BSgate(0.9, 0.2) | (q[0], q[1])
Non-Gaussian Layer
ops.Kgate(0.5) | q[3]
ops.CKgate(0.7) | (q[2], q[3])
Gaussian Layer
ops.BSgate(1.0, 0.4) | (q[0], q[1])
ops.BSgate(2.0, 1.5) | (q[1], q[2])
ops.Dgate(0.01) | q[0]
ops.Dgate(0.01) | q[0]
ops.Sgate(0.01, 0.01) | q[1]
Non-Gaussian Layer
ops.Vgate(0.5) | q[2]

prog_merged = prog.compile(compiler="gaussian_merge")


* A new operation, ``PassiveChannel`` has been added. It allows for arbitrary linear/passive transformations (i.e., any operation which is linear in creation operators). Currently only supported by the ``gaussian`` backend. [(600)](https://github.com/XanaduAI/strawberryfields/pull/600)

python
from strawberryfields.ops import PassiveChannel, Sgate
import strawberryfields as sf
from scipy.stats import unitary_group
import numpy as np

M = 4

circuit = sf.Program(M)
U1 = unitary_group.rvs(M)
U2 = unitary_group.rvs(M)
losses = np.random.random(M)

T = U2 np.diag(losses) U1

eng = sf.Engine(backend='gaussian')
circuit = sf.Program(M)
with circuit.context as q:
for i in range(M):
ops.Sgate(1) | q[i]
ops.PassiveChannel(T) | q

cov = eng.run(circuit).state.cov()


* A new compiler, ``passive``, allows for a circuit which only consists of passive elements to be compiled into a single ``PassiveChannel``. [(600)](https://github.com/XanaduAI/strawberryfields/pull/600)

python
from strawberryfields.ops import BSgate, LossChannel, Rgate
import strawberryfields as sf

circuit = sf.Program(2)
with circuit.context as q:
Rgate(np.pi) | q[0]
BSgate(0.25 * np.pi, 0) | (q[0], q[1])
LossChannel(0.9) | q[1]

compiled_circuit = circuit.compile(compiler="passive")

pycon
>>> print(compiled_circuit)
PassiveChannel([[-0.7071+8.6596e-17j -0.7071+0.0000e+00j]
[-0.6708+8.2152e-17j 0.6708+0.0000e+00j]]) | (q[0], q[1])


<h3>Improvements</h3>

* `backends/tfbackend/ops.py` is cleaned up to reduce line count, clarify function similarity across backend ops, and replace `tensorflow.tensordot` with broadcasting. [(567)](https://github.com/XanaduAI/strawberryfields/pull/567)

* Support is added for using a ``TDMProgram`` to construct time-domain circuits with Fock measurements and multiple loops. [(601)](https://github.com/XanaduAI/strawberryfields/pull/601)

* `measure_threshold` in the `gaussian` backend now supports displaced Gaussian states. [(615)](https://github.com/XanaduAI/strawberryfields/pull/615)

* Speed improvements are addded to ``gaussian_unitary`` compiler. [(603)](https://github.com/XanaduAI/strawberryfields/pull/603)

* Adds native support in the Fock backend for the MZgate. [(610)](https://github.com/XanaduAI/strawberryfields/issues/610)

* `measure_threshold` is now supported in the `bosonic` backend. [(618)](https://github.com/XanaduAI/strawberryfields/pull/618)


<h3>Bug fixes</h3>

* Fixes an unexpected behaviour that can result in increasing memory usage due to ``sympy.lambdify`` caching too much data using ``linecache``. [(579)](https://github.com/XanaduAI/strawberryfields/pull/579)

* Keeps symbolic expressions when converting a Strawberry Fields circuit to a Blackbird program by storing them as `blackbird.RegRefTransforms` in the resulting Blackbird program. [(596)](https://github.com/XanaduAI/strawberryfields/pull/596)

* Fixes a bug in the validation step of `strawberryfields.tdm.TdmProgram.compile` which almost always used the wrong set of allowed gate parameter ranges to validate the parameters in a program. [(605)](https://github.com/XanaduAI/strawberryfields/pull/605)

* The correct samples are now returned when running a `TDMProgram` with several shots, where `timebins % concurrent_modes != 0`. [(611)](https://github.com/XanaduAI/strawberryfields/pull/611)

* Fixes the formula used for sampling generaldyne outcomes in the gaussian backend. [(614)](https://github.com/XanaduAI/strawberryfields/pull/614)

* Measurement arguments are now stored as non-keyword arguments, instead of keyword arguments, in the resulting Blackbird program when using the `io.to_blackbird()` converter function. [(622)](https://github.com/XanaduAI/strawberryfields/pull/622)

* Factorials of numbers larger than 170 are now calculated using long integer arithmetic, using the flag `exact=True` in `scipy.special.factorial`, when calling `sf.apps.similarity.orbit_cardinality`. [(628)](https://github.com/XanaduAI/strawberryfields/pull/628)

<h3>Documentation</h3>

* References to the ``simulon`` simulator target have been rewritten to ``simulon_gaussian`` to reflect changes made on the Xanadu Quantum Cloud. The language has been modified to imply that multiple simulators could be available on XQC. [(576)](https://github.com/XanaduAI/strawberryfields/pull/576)

<h3>Contributors</h3>

This release contains contributions from (in alphabetical order):

J. Eli Bourassa, Jake Bulmer, Sebastian Duque, Theodor Isacsson, Aaron Robertson, Jeremy Swinarton, Antal Száva, Federico Rueda, Yuan Yao.

0.18.0post1

<h3>Documentation</h3>

* References to the ``simulon`` simulator target have been rewritten to ``simulon_gaussian`` to reflect changes made on the Xanadu Quantum Cloud. The language has been modified to imply that multiple simulators could be available on XQC. [(576)](https://github.com/XanaduAI/strawberryfields/pull/576)

<h3>Contributors</h3>

This release contains contributions from (in alphabetical order):

Jeremy Swinarton.

Page 1 of 5

© 2024 Safety CLI Cybersecurity Inc. All Rights Reserved.