`PauliList.evolve` raises exception when evolving certain Clifford circuits.
See original GitHub issueEnvironment
- Qiskit Terra version: 0.21.1
- Python version: 3.9
- Operating system: MacOS 11.6.7
What is happening?
There is a bug in the BasePauli/PauliList/Pauli
classes where the phase vector is sometimes set as dtype uint8
instead of int64
leading to errors when calling the evolve
function for circuits containing gates that modify the pauli phase vector.
Whether this happens or not seems to depend on how the Pauli is initialized (sometimes it will be initialized with uint8 phase vector, other times with int64 phase vector).
How can we reproduce the issue?
Minimal example
from qiskit import QuantumCircuit
import qiskit.quantum_info as qi
# Create circuit with gate that modifies Pauli phase
qc = QuantumCircuit(2)
qc.cz(0, 1)
# Generate random Pauli
pauli = qi.random_pauli(2, seed=123)
# Try and evolve
pauli.evolve(qc)
Give the exception:
---------------------------------------------------------------------------
UFuncTypeError Traceback (most recent call last)
/var/folders/lp/ftt3j6qs7s90j6h9wszq3jcw0000gn/T/ipykernel_71613/3628800509.py in <module>
7 pauli = qi.random_pauli(2, seed=123)
8 #qc = qi.random_clifford(4, seed=123).to_circuit()
----> 9 pauli.evolve(qc)
~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/pauli.py in evolve(self, other, qargs, frame)
597 other = Pauli(other)
598
--> 599 return Pauli(super().evolve(other, qargs=qargs, frame=frame))
600
601 # ---------------------------------------------------------------------
~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/base_pauli.py in evolve(self, other, qargs, frame)
277 if frame == "s":
278 return self.copy()._append_circuit(other, qargs=qargs)
--> 279 return self.copy()._append_circuit(other.inverse(), qargs=qargs)
280
281 def _evolve_clifford(self, other, qargs=None, frame="h"):
~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/base_pauli.py in _append_circuit(self, circuit, qargs)
585 # Get the integer position of the flat register
586 new_qubits = [qargs[bit_indices[tup]] for tup in instruction.qubits]
--> 587 self._append_circuit(instruction.operation, new_qubits)
588
589 # Since the individual gate evolution functions don't take mod
~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/base_pauli.py in _append_circuit(self, circuit, qargs)
558 if len(qargs) != 2:
559 raise QiskitError("Invalid qubits for 2-qubit gate.")
--> 560 return basis_2q[name](self, qargs[0], qargs[1])
561
562 # If not a Clifford basis gate we try to unroll the gate and
~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/base_pauli.py in _evolve_cz(base_pauli, q1, q2)
661 base_pauli._z[:, q1] ^= x2
662 base_pauli._z[:, q2] ^= x1
--> 663 base_pauli._phase += 2 * np.logical_and(x1, x2).T
664 return base_pauli
665
UFuncTypeError: Cannot cast ufunc 'add' output from dtype('int64') to dtype('uint8') with casting rule 'same_kind'
What should happen?
The dtype of the phase vector should always be the same, so that evolution and other methods that attempt to inplace modify the vector don’t cause exceptions for mismatched dtypes.
Any suggestions?
One fix would be to explicitly cast the phase vector when initializing base pauli
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:6 (3 by maintainers)
Top Results From Across the Web
qiskit.quantum_info.PauliList.evolve — Qiskit 0.32.1 documentation
Evolve the Pauli by a Clifford. This returns the Pauli P′=C.P.
Read more >arXiv:2002.12824v3 [quant-ph] 20 Jul 2020
We call these circuits 'super-Clifford circuits', since the Heisenberg time evolution of these operators corresponds to Clifford evolution ...
Read more >qiskit-terra Changelog - PyUp.io
Variational Quantum Time Evolution algorithm. (8152) - Add barrier labels and display in 3 circuit drawers (8440) - Adding Cliffords to QuantumCircuits as ......
Read more >Untitled
Kim clifford actress, Ultra cutting machines, Best treatment blue bottle sting, ... Airborne eo/ir sensors, Athlete evolution, Luc gaidoz champagne, ...
Read more >Report 03 08 2022_08_31 - qiskit-community/repo-monitor ...
... New Global Optimizer - Differential Evolution from Scipy ... 6b_process_tomography.ipynb legacy tutorial raises exception ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I tried : if dtype is None: dtype = np.int64(x.shape[axis])
No errors with this solution, print(pauli.evolve(qc)) shows ZY. So this solution works but casting could also create bug in itself. In any case I will start an PR and run all the tests to be sure.
As already discussed it is not necessary to modify the _count_y because dtype handling there looks correct for what the function does. The more correct solution is to ensure that whatever’s calling that is passing np.uint8 as the dtype when it’s going to bind the result to a uint8 context, or it manually cast. The caller can be found in the exception handling of the example:
In the example we use an evolve over the phase. This is done by the evolve_cz function. In line 663 the phase vector is set by: base_pauli._phase += 2 * np.logical_and(x1, x2).T
To cast the phase vector to a uint8 we can do: base_pauli._phase += np.uint8(2 * (np.logical_and(x1, x2).T))
Summary No change in the _count_y function but modification of the result of the _evolve_cz function. This works, I got the mathematically correct answer as before and we don’t have to change the phase vector from what it logically should be (u8) to something much wider (i64) with the problem of using to much data all the time.
I’ll be happy to go further with this PR if this is the way to go.