Skip to content

Commit

Permalink
Black Strawberry Fields prior to pre-release, and add continuous inte…
Browse files Browse the repository at this point in the history
…gration for PEP8 formatting (#351)

* Black Strawberry Fields prior to release

* Add a CI to check formatting

* blacking
  • Loading branch information
josh146 authored Apr 2, 2020
1 parent ab3196b commit 5535bfe
Show file tree
Hide file tree
Showing 40 changed files with 1,727 additions and 973 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Formatting check
on:
- pull_request

jobs:
black:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Black Code Formatter
uses: lgeiger/black-action@v1.0.1
with:
args: "-l 100 strawberryfields/ --check"
2 changes: 1 addition & 1 deletion strawberryfields/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
Version number (major.minor.patch[-label])
"""

__version__ = '0.13.0.rc0'
__version__ = "0.13.0.rc0"
6 changes: 3 additions & 3 deletions strawberryfields/api/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def create_job(self, target: str, program: Program, run_options: dict = None) ->
circuit = bb.serialize()

path = "/jobs"
response = requests.post(self._url(path), headers=self._headers, json={"circuit": circuit},)
response = requests.post(self._url(path), headers=self._headers, json={"circuit": circuit})
if response.status_code == 201:
if self._verbose:
log.info("The job was successfully submitted.")
Expand Down Expand Up @@ -220,7 +220,7 @@ def get_job_result(self, job_id: str) -> Result:
"""
path = "/jobs/{}/result".format(job_id)
response = requests.get(
self._url(path), headers={"Accept": "application/x-numpy", **self._headers},
self._url(path), headers={"Accept": "application/x-numpy", **self._headers}
)
if response.status_code == 200:
# Read the numpy binary data in the payload into memory
Expand All @@ -241,7 +241,7 @@ def cancel_job(self, job_id: str):
"""
path = "/jobs/{}".format(job_id)
response = requests.patch(
self._url(path), headers=self._headers, json={"status": JobStatus.CANCELLED.value},
self._url(path), headers=self._headers, json={"status": JobStatus.CANCELLED.value}
)
if response.status_code == 204:
if self._verbose:
Expand Down
6 changes: 3 additions & 3 deletions strawberryfields/apps/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,9 @@ def __init__(self):
self.w = scipy.sparse.load_npz(DATA_PATH + self._data_filename + "_w.npz").toarray()[0]
self.wp = scipy.sparse.load_npz(DATA_PATH + self._data_filename + "_wp.npz").toarray()[0]
self.Ud = scipy.sparse.load_npz(DATA_PATH + self._data_filename + "_Ud.npz").toarray()
self.delta = scipy.sparse.load_npz(DATA_PATH + self._data_filename + "_delta.npz").toarray(

)[0]
self.delta = scipy.sparse.load_npz(
DATA_PATH + self._data_filename + "_delta.npz"
).toarray()[0]

# pylint: disable=missing-docstring
@property
Expand Down
2 changes: 1 addition & 1 deletion strawberryfields/apps/points.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def rbf_kernel(R: np.ndarray, sigma: float) -> np.ndarray:
Returns:
K (array): the RBF kernel matrix
"""
return np.exp(-(scipy.spatial.distance.cdist(R, R)) ** 2 / 2 / sigma ** 2)
return np.exp(-((scipy.spatial.distance.cdist(R, R)) ** 2) / 2 / sigma ** 2)


def sample(K: np.ndarray, n_mean: float, n_samples: int) -> list:
Expand Down
4 changes: 2 additions & 2 deletions strawberryfields/apps/vibronic.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,6 @@ def energies(samples: list, w: np.ndarray, wp: np.ndarray) -> Union[list, float]
a single sample energy if only one sample is input
"""
if not isinstance(samples[0], list):
return np.dot(samples[:len(samples)//2], wp) - np.dot(samples[len(samples)//2:], w)
return np.dot(samples[: len(samples) // 2], wp) - np.dot(samples[len(samples) // 2 :], w)

return [np.dot(s[:len(s)//2], wp) - np.dot(s[len(s)//2:], w) for s in samples]
return [np.dot(s[: len(s) // 2], wp) - np.dot(s[len(s) // 2 :], w) for s in samples]
6 changes: 2 additions & 4 deletions strawberryfields/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,13 @@
"TFBackend",
"BaseState",
"BaseFockState",
"BaseGaussianState"
"BaseGaussianState",
]


virtual_backends = ["X8_01"]

local_backends = {
b.short_name: b for b in (BaseBackend, GaussianBackend, FockBackend)
}
local_backends = {b.short_name: b for b in (BaseBackend, GaussianBackend, FockBackend)}


def load_backend(name):
Expand Down
15 changes: 9 additions & 6 deletions strawberryfields/backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ModeMap:
"""
Simple internal class for maintaining a map of existing modes.
"""

def __init__(self, num_subsystems):
self._init = num_subsystems
#: list[int]: _map[k] is the internal index used by the backend for
Expand Down Expand Up @@ -117,7 +118,7 @@ class BaseBackend:
"""Abstract base class for backends."""

#: str: short name of the backend
short_name = 'base'
short_name = "base"
#: str, None: Short name of the CircuitSpecs class used to validate Programs for this backend. None if no validation is required.
circuit_spec = None

Expand Down Expand Up @@ -449,9 +450,10 @@ def state(self, modes=None, **kwargs):
raise NotImplementedError


#=============================
# =============================
# Fock-basis backends
#=============================
# =============================


class BaseFock(BaseBackend):
"""Abstract base class for backends capable of Fock state manipulation."""
Expand Down Expand Up @@ -519,7 +521,6 @@ def prepare_dm_state(self, state, modes):
"""
raise NotImplementedError


def cubic_phase(self, gamma, mode):
r"""Apply the cubic phase operation to the specified mode.
Expand Down Expand Up @@ -584,9 +585,11 @@ def state(self, modes=None, **kwargs):
"""
raise NotImplementedError

#==============================

# ==============================
# Gaussian-formulation backends
#==============================
# ==============================


class BaseGaussian(BaseBackend):
"""Abstract base class for backends that are only capable of Gaussian state manipulation."""
Expand Down
51 changes: 31 additions & 20 deletions strawberryfields/backends/fockbackend/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,18 @@ class FockBackend(BaseFock):
~ops
"""

short_name = 'fock'
circuit_spec = 'fock'
short_name = "fock"
circuit_spec = "fock"

def __init__(self):
"""Instantiate a FockBackend object."""
super().__init__()
self._supported["mixed_states"] = True
self._init_modes = None #: int: initial number of modes in the circuit
self._modemap = None #: Modemap: maps external mode indices to internal ones
self.circuit = None #: ~.fockbackend.circuit.Circuit: representation of the simulated quantum state
self._modemap = None #: Modemap: maps external mode indices to internal ones
self.circuit = (
None #: ~.fockbackend.circuit.Circuit: representation of the simulated quantum state
)

def _remap_modes(self, modes):
if isinstance(modes, int):
Expand All @@ -84,7 +86,7 @@ def _remap_modes(self, modes):
map_ = self._modemap.show()
submap = [map_[m] for m in modes]
if not self._modemap.valid(modes) or None in submap:
raise ValueError('The specified modes are not valid.')
raise ValueError("The specified modes are not valid.")

remapped_modes = self._modemap.remap(modes)
if was_int:
Expand All @@ -110,8 +112,8 @@ def begin_circuit(self, num_subsystems, **kwargs):
For each mode, the simulator can represent the Fock states :math:`\ket{0}, \ket{1}, \ldots, \ket{\text{cutoff_dim}-1}`.
pure (bool): If True (default), use a pure state representation (otherwise will use a mixed state representation).
"""
cutoff_dim = kwargs.get('cutoff_dim', None)
pure = kwargs.get('pure', True)
cutoff_dim = kwargs.get("cutoff_dim", None)
pure = kwargs.get("pure", True)
if cutoff_dim is None:
raise ValueError("Argument 'cutoff_dim' must be passed to the Fock backend")
if not isinstance(cutoff_dim, int):
Expand Down Expand Up @@ -140,7 +142,7 @@ def get_modes(self):
return [i for i, j in enumerate(self._modemap._map) if j is not None]

def reset(self, pure=True, **kwargs):
cutoff = kwargs.get('cutoff_dim', self.circuit._trunc)
cutoff = kwargs.get("cutoff_dim", self.circuit._trunc)
self._modemap.reset()
self.circuit.reset(pure, num_subsystems=self._init_modes, cutoff_dim=cutoff)

Expand Down Expand Up @@ -169,12 +171,16 @@ def squeeze(self, z, mode):
self.circuit.squeeze(abs(z), phase(z), self._remap_modes(mode))

def two_mode_squeeze(self, z, mode1, mode2):
self.circuit.two_mode_squeeze(abs(z), phase(z), self._remap_modes(mode1), self._remap_modes(mode2))
self.circuit.two_mode_squeeze(
abs(z), phase(z), self._remap_modes(mode1), self._remap_modes(mode2)
)

def beamsplitter(self, t, r, mode1, mode2):
if isinstance(t, complex):
raise ValueError("Beamsplitter transmittivity t must be a float.")
self.circuit.beamsplitter(t, abs(r), phase(r), self._remap_modes(mode1), self._remap_modes(mode2))
self.circuit.beamsplitter(
t, abs(r), phase(r), self._remap_modes(mode1), self._remap_modes(mode2)
)

def measure_homodyne(self, phi, mode, shots=1, select=None, **kwargs):
"""Perform a homodyne measurement on the specified mode.
Expand All @@ -187,8 +193,9 @@ def measure_homodyne(self, phi, mode, shots=1, select=None, **kwargs):
max (float): The pdf is discretized onto the 1D grid [-max,max] (default: 10).
"""
if shots != 1:
raise NotImplementedError("fock backend currently does not support "
"shots != 1 for homodyne measurement")
raise NotImplementedError(
"fock backend currently does not support " "shots != 1 for homodyne measurement"
)
return self.circuit.measure_homodyne(phi, self._remap_modes(mode), select=select, **kwargs)

def loss(self, T, mode):
Expand All @@ -200,7 +207,6 @@ def is_vacuum(self, tol=0.0, **kwargs):
def get_cutoff_dim(self):
return self.circuit._trunc


def state(self, modes=None, **kwargs):
s, pure = self.circuit.get_state()

Expand All @@ -216,7 +222,7 @@ def state(self, modes=None, **kwargs):
left_str = [indices[i] for i in range(0, 2 * num_modes, 2)]
right_str = [indices[i] for i in range(1, 2 * num_modes, 2)]
out_str = [indices[: 2 * num_modes]]
einstr = ''.join(left_str + [','] + right_str + ['->'] + out_str)
einstr = "".join(left_str + [","] + right_str + ["->"] + out_str)
rho = np.einsum(einstr, s, s.conj())
else:
rho = s
Expand All @@ -230,7 +236,9 @@ def state(self, modes=None, **kwargs):

num_modes = len(rho.shape) // 2
if len(modes) > num_modes:
raise ValueError("The number of specified modes cannot be larger than the number of subsystems.")
raise ValueError(
"The number of specified modes cannot be larger than the number of subsystems."
)

keep_indices = indices[: 2 * len(modes)]
trace_indices = indices[2 * len(modes) : len(modes) + num_modes]
Expand All @@ -242,13 +250,13 @@ def state(self, modes=None, **kwargs):
ind.insert(m, keep_indices[2 * ctr : 2 * (ctr + 1)])
ctr += 1

indStr = ''.join(ind) + '->' + keep_indices
indStr = "".join(ind) + "->" + keep_indices
red_state = np.einsum(indStr, rho)

# permute indices of returned state to reflect the ordering of modes (we know and hence can assume that red_state is a mixed state)
if modes != sorted(modes):
mode_permutation = np.argsort(modes)
index_permutation = [2*x+i for x in mode_permutation for i in (0, 1)]
index_permutation = [2 * x + i for x in mode_permutation for i in (0, 1)]
red_state = np.transpose(red_state, np.argsort(index_permutation))

cutoff = self.circuit._trunc
Expand Down Expand Up @@ -276,10 +284,13 @@ def kerr_interaction(self, kappa, mode):
self.circuit.kerr_interaction(kappa, self._remap_modes(mode))

def cross_kerr_interaction(self, kappa, mode1, mode2):
self.circuit.cross_kerr_interaction(kappa, self._remap_modes(mode1), self._remap_modes(mode2))
self.circuit.cross_kerr_interaction(
kappa, self._remap_modes(mode1), self._remap_modes(mode2)
)

def measure_fock(self, modes, shots=1, select=None, **kwargs):
if shots != 1:
raise NotImplementedError("fock backend currently does not support "
"shots != 1 for Fock measurement")
raise NotImplementedError(
"fock backend currently does not support " "shots != 1 for Fock measurement"
)
return self.circuit.measure_fock(self._remap_modes(modes), select=select)
Loading

0 comments on commit 5535bfe

Please sign in to comment.