|
37 | 37 |
|
38 | 38 | import cirq
|
39 | 39 | from cirq import circuits, study, ops, protocols, value
|
40 |
| -from cirq.ops import pauli_gates |
41 | 40 | from cirq.ops.clifford_gate import SingleQubitCliffordGate
|
42 | 41 | from cirq.ops.dense_pauli_string import DensePauliString
|
43 |
| -from cirq.protocols import unitary |
44 |
| -from cirq.sim import simulator |
45 |
| -from cirq.sim.clifford import clifford_tableau, stabilizer_state_ch_form |
| 42 | +from cirq.protocols import act_on, unitary |
| 43 | +from cirq.sim import clifford, simulator |
46 | 44 | from cirq._compat import deprecated, deprecated_parameter
|
47 | 45 |
|
48 | 46 |
|
@@ -277,9 +275,8 @@ def __init__(self, qubit_map, initial_state=0):
|
277 | 275 | self.qubit_map = qubit_map
|
278 | 276 | self.n = len(qubit_map)
|
279 | 277 |
|
280 |
| - self.tableau = clifford_tableau.CliffordTableau(self.n, initial_state) |
281 |
| - self.ch_form = stabilizer_state_ch_form.StabilizerStateChForm( |
282 |
| - self.n, initial_state) |
| 278 | + self.tableau = clifford.CliffordTableau(self.n, initial_state) |
| 279 | + self.ch_form = clifford.StabilizerStateChForm(self.n, initial_state) |
283 | 280 |
|
284 | 281 | def _json_dict_(self):
|
285 | 282 | return {
|
@@ -336,94 +333,18 @@ def wave_function(self):
|
336 | 333 | return self.state_vector()
|
337 | 334 |
|
338 | 335 | def apply_unitary(self, op: 'cirq.Operation'):
|
339 |
| - if len(op.qubits) == 1: |
340 |
| - self.apply_single_qubit_unitary(op) |
341 |
| - elif isinstance(op, GlobalPhaseOperation): |
342 |
| - self.ch_form.omega *= op.coefficient |
343 |
| - elif op.gate == cirq.CNOT: |
344 |
| - self.tableau._CNOT(self.qubit_map[op.qubits[0]], |
345 |
| - self.qubit_map[op.qubits[1]]) |
346 |
| - self.ch_form._CNOT(self.qubit_map[op.qubits[0]], |
347 |
| - self.qubit_map[op.qubits[1]]) |
348 |
| - elif op.gate == cirq.CZ: |
349 |
| - self.tableau._CZ(self.qubit_map[op.qubits[0]], |
350 |
| - self.qubit_map[op.qubits[1]]) |
351 |
| - self.ch_form._CZ(self.qubit_map[op.qubits[0]], |
352 |
| - self.qubit_map[op.qubits[1]]) |
353 |
| - else: |
| 336 | + tableau_args = clifford.ActOnCliffordTableauArgs( |
| 337 | + self.tableau, [self.qubit_map[i] for i in op.qubits], |
| 338 | + np.random.RandomState(), {}) |
| 339 | + ch_form_args = clifford.ActOnStabilizerCHFormArgs( |
| 340 | + self.ch_form, [self.qubit_map[i] for i in op.qubits]) |
| 341 | + try: |
| 342 | + act_on(op, tableau_args) |
| 343 | + act_on(op, ch_form_args) |
| 344 | + except TypeError: |
354 | 345 | raise ValueError('%s cannot be run with Clifford simulator.' %
|
355 | 346 | str(op.gate)) # type: ignore
|
356 |
| - |
357 |
| - def apply_single_qubit_unitary(self, op: 'cirq.Operation'): |
358 |
| - qubit = self.qubit_map[op.qubits[0]] |
359 |
| - if op.gate == cirq.I: |
360 |
| - return |
361 |
| - |
362 |
| - if op.gate == cirq.X: |
363 |
| - self._apply_X(qubit) |
364 |
| - return |
365 |
| - |
366 |
| - if op.gate == cirq.Y: |
367 |
| - self._apply_Y(qubit) |
368 |
| - return |
369 |
| - |
370 |
| - if op.gate == cirq.Z: |
371 |
| - self._apply_Z(qubit) |
372 |
| - return |
373 |
| - |
374 |
| - if op.gate == cirq.H: |
375 |
| - self._apply_H(qubit) |
376 |
| - return |
377 |
| - |
378 |
| - u = unitary(op) |
379 |
| - clifford_gate = SingleQubitCliffordGate.from_unitary(u) |
380 |
| - if clifford_gate is None: |
381 |
| - raise ValueError('%s cannot be run with Clifford simulator.' % |
382 |
| - str(op.gate)) |
383 |
| - |
384 |
| - h = unitary(ops.H) |
385 |
| - s = unitary(ops.S) |
386 |
| - applied_unitary = np.eye(2) |
387 |
| - for axis, quarter_turns in clifford_gate.decompose_rotation(): |
388 |
| - for _ in range(quarter_turns % 4): |
389 |
| - if axis == pauli_gates.X: |
390 |
| - self._apply_H(qubit) |
391 |
| - self._apply_S(qubit) |
392 |
| - self._apply_H(qubit) |
393 |
| - applied_unitary = h @ s @ h @ applied_unitary |
394 |
| - elif axis == pauli_gates.Y: |
395 |
| - self._apply_S(qubit) |
396 |
| - self._apply_S(qubit) |
397 |
| - self._apply_H(qubit) |
398 |
| - applied_unitary = h @ s @ s @ applied_unitary |
399 |
| - else: |
400 |
| - assert axis == pauli_gates.Z |
401 |
| - self._apply_S(qubit) |
402 |
| - applied_unitary = s @ applied_unitary |
403 |
| - |
404 |
| - max_idx = max(np.ndindex(*u.shape), key=lambda t: abs(u[t])) |
405 |
| - phase_shift = u[max_idx] / applied_unitary[max_idx] |
406 |
| - self.ch_form.omega *= phase_shift |
407 |
| - |
408 |
| - def _apply_H(self, qubit: int): |
409 |
| - self.tableau._H(qubit) |
410 |
| - self.ch_form._H(qubit) |
411 |
| - |
412 |
| - def _apply_S(self, qubit: int): |
413 |
| - self.tableau._S(qubit) |
414 |
| - self.ch_form._S(qubit) |
415 |
| - |
416 |
| - def _apply_X(self, qubit: int): |
417 |
| - self.tableau._X(qubit) |
418 |
| - self.ch_form._X(qubit) |
419 |
| - |
420 |
| - def _apply_Z(self, qubit: int): |
421 |
| - self.tableau._Z(qubit) |
422 |
| - self.ch_form._Z(qubit) |
423 |
| - |
424 |
| - def _apply_Y(self, qubit: int): |
425 |
| - self.tableau._Y(qubit) |
426 |
| - self.ch_form._Y(qubit) |
| 347 | + return |
427 | 348 |
|
428 | 349 | @deprecated_parameter(
|
429 | 350 | deadline='v0.10.0',
|
|
0 commit comments