-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add JSON serialisations #7396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add JSON serialisations #7396
Changes from all commits
9a0f8f1
6c0d9bb
51d9035
bcc575c
8da202f
0643e61
e5fa84b
4e98a55
52f72cd
7d29cad
edb0c6d
2e9bbd9
9b8b7fe
b867010
0f06ac3
555495e
a3b9ea4
e46ebfe
45942cd
6957dea
0f3aab9
c8d88a7
ec315f0
e03d267
c6d3059
9c02b87
2d2af5c
4bcbb8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"cirq_type": "DampedReadoutNoiseModel", | ||
"decay_prob": 0.3, | ||
"prepend": true | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cirq.contrib.noise_models.DampedReadoutNoiseModel(0.3, prepend=True) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"cirq_type": "DepolarizingNoiseModel", | ||
"depol_prob": 0.1, | ||
"prepend": false | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cirq.contrib.noise_models.DepolarizingNoiseModel(0.1, prepend=False) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"cirq_type": "DepolarizingWithDampedReadoutNoiseModel", | ||
"depol_prob": 0.1, | ||
"bitflip_prob": 0.2, | ||
"decay_prob": 0.3 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cirq.contrib.noise_models.DepolarizingWithDampedReadoutNoiseModel(0.1, 0.2, 0.3) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"cirq_type": "DepolarizingWithReadoutNoiseModel", | ||
"depol_prob": 0.1, | ||
"bitflip_prob": 0.2 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cirq.contrib.noise_models.DepolarizingWithReadoutNoiseModel(0.1, 0.2) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"cirq_type": "ReadoutNoiseModel", | ||
"bitflip_prob": 0.2, | ||
"prepend": true | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cirq.contrib.noise_models.ReadoutNoiseModel(0.2, prepend=True) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Copyright 2025 The Cirq Developers | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Test data for JSON serialization of :mod:`cirq.contrib` objects.""" | ||
|
||
from cirq.contrib.json_test_data.spec import TestSpec as TestSpec |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# pylint: disable=wrong-or-nonexistent-copyright-notice | ||
from __future__ import annotations | ||
|
||
import pathlib | ||
|
||
import cirq | ||
from cirq.contrib.json import _class_resolver_dictionary | ||
from cirq.testing.json import ModuleJsonTestSpec | ||
|
||
TestSpec = ModuleJsonTestSpec( | ||
name="cirq.contrib", | ||
packages=[cirq.contrib], | ||
test_data_path=pathlib.Path(__file__).parent, | ||
not_yet_serializable=[], | ||
should_not_be_serialized=[ | ||
"QuantumVolumeResult", | ||
"SwapPermutationGate", | ||
"BayesianNetworkGate", | ||
Comment on lines
+16
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The first 3 classes are serializable and should NOT be listed here. Please add the corresponding After that you can replace the dictionary filtering below with
|
||
"Unique", | ||
"CircuitDag", | ||
], | ||
resolver_cache={ | ||
k: v | ||
for k, v in _class_resolver_dictionary().items() | ||
if k | ||
not in { | ||
"QuantumVolumeResult", | ||
"SwapPermutationGate", | ||
"BayesianNetworkGate", | ||
"Unique", | ||
"CircuitDag", | ||
} | ||
}, | ||
deprecated={}, | ||
) |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -23,6 +23,7 @@ | |||||||
import cirq | ||||||||
|
||||||||
|
||||||||
@value.value_equality() | ||||||||
class DepolarizingNoiseModel(devices.NoiseModel): | ||||||||
"""Applies depolarizing noise to each qubit individually at the end of | ||||||||
every moment. | ||||||||
|
@@ -39,9 +40,20 @@ def __init__(self, depol_prob: float, prepend: bool = False): | |||||||
prepend: If True, put noise before affected gates. Default: False. | ||||||||
""" | ||||||||
value.validate_probability(depol_prob, 'depol prob') | ||||||||
self.depol_prob = depol_prob | ||||||||
self.qubit_noise_gate = ops.DepolarizingChannel(depol_prob) | ||||||||
self._prepend = prepend | ||||||||
|
||||||||
def _value_equality_values_(self): | ||||||||
return self.depol_prob, self._prepend | ||||||||
|
||||||||
def __repr__(self) -> str: | ||||||||
p = self.depol_prob | ||||||||
return ( | ||||||||
f'cirq.contrib.noise_models.DepolarizingNoiseModel(' | ||||||||
f'{p!r}, prepend={self._prepend!r})' | ||||||||
) | ||||||||
|
||||||||
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]): | ||||||||
if validate_all_measurements(moment) or self.is_virtual_moment(moment): # pragma: no cover | ||||||||
return moment | ||||||||
|
@@ -54,7 +66,15 @@ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]): | |||||||
] | ||||||||
return output[::-1] if self._prepend else output | ||||||||
|
||||||||
def _json_dict_(self) -> dict[str, object]: | ||||||||
return {'depol_prob': self.depol_prob, 'prepend': self._prepend} | ||||||||
|
||||||||
@classmethod | ||||||||
def _from_json_dict_(cls, depol_prob, prepend, **kwargs): | ||||||||
return cls(depol_prob, prepend=prepend) | ||||||||
Comment on lines
+72
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When
Suggested change
|
||||||||
|
||||||||
|
||||||||
@value.value_equality() | ||||||||
class ReadoutNoiseModel(devices.NoiseModel): | ||||||||
"""NoiseModel with probabilistic bit flips preceding measurement. | ||||||||
|
||||||||
|
@@ -75,9 +95,17 @@ def __init__(self, bitflip_prob: float, prepend: bool = True): | |||||||
prepend: If True, put noise before affected gates. Default: True. | ||||||||
""" | ||||||||
value.validate_probability(bitflip_prob, 'bitflip prob') | ||||||||
self.bitflip_prob = bitflip_prob | ||||||||
self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob) | ||||||||
self._prepend = prepend | ||||||||
|
||||||||
def _value_equality_values_(self): | ||||||||
return self.bitflip_prob, self._prepend | ||||||||
|
||||||||
def __repr__(self) -> str: | ||||||||
p = self.bitflip_prob | ||||||||
return f'cirq.contrib.noise_models.ReadoutNoiseModel(' f'{p!r}, prepend={self._prepend!r})' | ||||||||
|
||||||||
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]): | ||||||||
if self.is_virtual_moment(moment): | ||||||||
return moment | ||||||||
|
@@ -91,7 +119,15 @@ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]): | |||||||
return output if self._prepend else output[::-1] | ||||||||
return moment | ||||||||
|
||||||||
def _json_dict_(self) -> dict[str, object]: | ||||||||
return {'bitflip_prob': self.bitflip_prob, 'prepend': self._prepend} | ||||||||
|
||||||||
@classmethod | ||||||||
def _from_json_dict_(cls, bitflip_prob, prepend, **kwargs): | ||||||||
return cls(bitflip_prob, prepend=prepend) | ||||||||
|
||||||||
|
||||||||
@value.value_equality() | ||||||||
class DampedReadoutNoiseModel(devices.NoiseModel): | ||||||||
"""NoiseModel with T1 decay preceding measurement. | ||||||||
|
||||||||
|
@@ -112,9 +148,20 @@ def __init__(self, decay_prob: float, prepend: bool = True): | |||||||
prepend: If True, put noise before affected gates. Default: True. | ||||||||
""" | ||||||||
value.validate_probability(decay_prob, 'decay_prob') | ||||||||
self.decay_prob = decay_prob | ||||||||
self.readout_decay_gate = ops.AmplitudeDampingChannel(decay_prob) | ||||||||
self._prepend = prepend | ||||||||
|
||||||||
def _value_equality_values_(self): | ||||||||
return self.decay_prob, self._prepend | ||||||||
|
||||||||
def __repr__(self) -> str: | ||||||||
p = self.decay_prob | ||||||||
return ( | ||||||||
f'cirq.contrib.noise_models.DampedReadoutNoiseModel(' | ||||||||
f'{p!r}, prepend={self._prepend!r})' | ||||||||
) | ||||||||
|
||||||||
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]): | ||||||||
if self.is_virtual_moment(moment): | ||||||||
return moment | ||||||||
|
@@ -128,7 +175,15 @@ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]): | |||||||
return output if self._prepend else output[::-1] | ||||||||
return moment | ||||||||
|
||||||||
def _json_dict_(self) -> dict[str, object]: | ||||||||
return {'decay_prob': self.decay_prob, 'prepend': self._prepend} | ||||||||
|
||||||||
@classmethod | ||||||||
def _from_json_dict_(cls, decay_prob, prepend, **kwargs): | ||||||||
return cls(decay_prob, prepend=prepend) | ||||||||
|
||||||||
|
||||||||
@value.value_equality() | ||||||||
class DepolarizingWithReadoutNoiseModel(devices.NoiseModel): | ||||||||
"""DepolarizingNoiseModel with probabilistic bit flips preceding | ||||||||
measurement. | ||||||||
|
@@ -145,15 +200,33 @@ def __init__(self, depol_prob: float, bitflip_prob: float): | |||||||
""" | ||||||||
value.validate_probability(depol_prob, 'depol prob') | ||||||||
value.validate_probability(bitflip_prob, 'bitflip prob') | ||||||||
self.depol_prob = depol_prob | ||||||||
self.bitflip_prob = bitflip_prob | ||||||||
self.qubit_noise_gate = ops.DepolarizingChannel(depol_prob) | ||||||||
self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob) | ||||||||
|
||||||||
def _value_equality_values_(self): | ||||||||
return self.depol_prob, self.bitflip_prob | ||||||||
|
||||||||
def __repr__(self) -> str: | ||||||||
p = self.depol_prob | ||||||||
b = self.bitflip_prob | ||||||||
return 'cirq.contrib.noise_models.DepolarizingWithReadoutNoiseModel(' f'{p!r}, {b!r})' | ||||||||
|
||||||||
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]): | ||||||||
if validate_all_measurements(moment): | ||||||||
return [circuits.Moment(self.readout_noise_gate(q) for q in system_qubits), moment] | ||||||||
return [moment, circuits.Moment(self.qubit_noise_gate(q) for q in system_qubits)] | ||||||||
|
||||||||
def _json_dict_(self) -> dict[str, object]: | ||||||||
return {'depol_prob': self.depol_prob, 'bitflip_prob': self.bitflip_prob} | ||||||||
|
||||||||
@classmethod | ||||||||
def _from_json_dict_(cls, depol_prob, bitflip_prob, **kwargs): | ||||||||
return cls(depol_prob, bitflip_prob) | ||||||||
|
||||||||
|
||||||||
@value.value_equality() | ||||||||
class DepolarizingWithDampedReadoutNoiseModel(devices.NoiseModel): | ||||||||
"""DepolarizingWithReadoutNoiseModel with T1 decay preceding | ||||||||
measurement. | ||||||||
|
@@ -174,10 +247,25 @@ def __init__(self, depol_prob: float, bitflip_prob: float, decay_prob: float): | |||||||
value.validate_probability(depol_prob, 'depol prob') | ||||||||
value.validate_probability(bitflip_prob, 'bitflip prob') | ||||||||
value.validate_probability(decay_prob, 'decay_prob') | ||||||||
self.depol_prob = depol_prob | ||||||||
self.bitflip_prob = bitflip_prob | ||||||||
self.decay_prob = decay_prob | ||||||||
self.qubit_noise_gate = ops.DepolarizingChannel(depol_prob) | ||||||||
self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob) | ||||||||
self.readout_decay_gate = ops.AmplitudeDampingChannel(decay_prob) | ||||||||
|
||||||||
def _value_equality_values_(self): | ||||||||
return self.depol_prob, self.bitflip_prob, self.decay_prob | ||||||||
|
||||||||
def __repr__(self) -> str: | ||||||||
p = self.depol_prob | ||||||||
b = self.bitflip_prob | ||||||||
d = self.decay_prob | ||||||||
return ( | ||||||||
'cirq.contrib.noise_models.DepolarizingWithDampedReadoutNoiseModel(' | ||||||||
f'{p!r}, {b!r}, {d!r})' | ||||||||
) | ||||||||
|
||||||||
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]): | ||||||||
if validate_all_measurements(moment): | ||||||||
return [ | ||||||||
|
@@ -187,3 +275,14 @@ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]): | |||||||
] | ||||||||
else: | ||||||||
return [moment, circuits.Moment(self.qubit_noise_gate(q) for q in system_qubits)] | ||||||||
|
||||||||
def _json_dict_(self) -> dict[str, object]: | ||||||||
return { | ||||||||
'depol_prob': self.depol_prob, | ||||||||
'bitflip_prob': self.bitflip_prob, | ||||||||
'decay_prob': self.decay_prob, | ||||||||
} | ||||||||
|
||||||||
@classmethod | ||||||||
def _from_json_dict_(cls, depol_prob, bitflip_prob, decay_prob, **kwargs): | ||||||||
return cls(depol_prob, bitflip_prob, decay_prob) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please replace with the actual copyright statement as in
__init__.py
.