diff --git a/cirq-core/cirq/json_resolver_cache.py b/cirq-core/cirq/json_resolver_cache.py index c4a6765c764..c979646d7bc 100644 --- a/cirq-core/cirq/json_resolver_cache.py +++ b/cirq-core/cirq/json_resolver_cache.py @@ -146,6 +146,7 @@ def _symmetricalqidpair(qids): 'PauliString': cirq.PauliString, 'PauliStringPhasor': cirq.PauliStringPhasor, 'PauliStringPhasorGate': cirq.PauliStringPhasorGate, + 'PauliSum': cirq.PauliSum, '_PauliX': cirq.ops.pauli_gates._PauliX, '_PauliY': cirq.ops.pauli_gates._PauliY, '_PauliZ': cirq.ops.pauli_gates._PauliZ, diff --git a/cirq-core/cirq/ops/linear_combinations.py b/cirq-core/cirq/ops/linear_combinations.py index 9e7db8ba287..cc961074476 100644 --- a/cirq-core/cirq/ops/linear_combinations.py +++ b/cirq-core/cirq/ops/linear_combinations.py @@ -498,6 +498,20 @@ def _unitary_(self) -> np.ndarray: return m raise ValueError(f'{self} is not unitary') + def _json_dict_(self): + def key_json(k: UnitPauliStringT): + return [list(e) for e in sorted(k)] + + return {'items': list((key_json(k), v) for k, v in self._linear_dict.items())} + + @classmethod + def _from_json_dict_(cls, items, **kwargs): + mapping = { + frozenset(tuple(qid_pauli) for qid_pauli in unit_pauli_string): val + for unit_pauli_string, val in items + } + return cls(linear_dict=value.LinearDict(mapping)) + def expectation_from_state_vector( self, state_vector: np.ndarray, diff --git a/cirq-core/cirq/protocols/json_test_data/PauliSum.json b/cirq-core/cirq/protocols/json_test_data/PauliSum.json new file mode 100644 index 00000000000..6f3ffce7b55 --- /dev/null +++ b/cirq-core/cirq/protocols/json_test_data/PauliSum.json @@ -0,0 +1,67 @@ +{ + "cirq_type": "PauliSum", + "items": [ + [ + [ + [ + { + "cirq_type": "LineQubit", + "x": 0 + }, + { + "cirq_type": "_PauliX", + "exponent": 1.0, + "global_shift": 0.0 + } + ], + [ + { + "cirq_type": "LineQubit", + "x": 1 + }, + { + "cirq_type": "_PauliX", + "exponent": 1.0, + "global_shift": 0.0 + } + ] + ], + { + "cirq_type": "complex", + "real": 1.0, + "imag": 0.0 + } + ], + [ + [ + [ + { + "cirq_type": "LineQubit", + "x": 0 + }, + { + "cirq_type": "_PauliY", + "exponent": 1.0, + "global_shift": 0.0 + } + ], + [ + { + "cirq_type": "LineQubit", + "x": 1 + }, + { + "cirq_type": "_PauliY", + "exponent": 1.0, + "global_shift": 0.0 + } + ] + ], + { + "cirq_type": "complex", + "real": 0.0, + "imag": 1.0 + } + ] + ] +} \ No newline at end of file diff --git a/cirq-core/cirq/protocols/json_test_data/PauliSum.repr b/cirq-core/cirq/protocols/json_test_data/PauliSum.repr new file mode 100644 index 00000000000..e993bafb90e --- /dev/null +++ b/cirq-core/cirq/protocols/json_test_data/PauliSum.repr @@ -0,0 +1 @@ +cirq.PauliSum(cirq.LinearDict({frozenset({(cirq.LineQubit(1), cirq.X), (cirq.LineQubit(0), cirq.X)}): (1+0j), frozenset({(cirq.LineQubit(1), cirq.Y), (cirq.LineQubit(0), cirq.Y)}): (1j)})) \ No newline at end of file diff --git a/cirq-core/cirq/protocols/json_test_data/spec.py b/cirq-core/cirq/protocols/json_test_data/spec.py index ba93126fb14..dd183f37e68 100644 --- a/cirq-core/cirq/protocols/json_test_data/spec.py +++ b/cirq-core/cirq/protocols/json_test_data/spec.py @@ -47,7 +47,6 @@ 'DiagonalGate', 'NeutralAtomDevice', 'PauliInteractionGate', - 'PauliSum', 'PauliSumCollector', 'PauliSumExponential', 'PauliTransform',