Qiskit / qiskit-aer

Aer is a high performance simulator for quantum circuits that includes noise models
https://qiskit.github.io/qiskit-aer/
Apache License 2.0
480 stars 354 forks source link

`QuantumCircuit.reverse_bits()` affects the state vector but not the density matrix #2190

Open king-p3nguin opened 2 months ago

king-p3nguin commented 2 months ago

Informations

What is the current behavior?

QuantumCircuit.reverse_bits() affects the bit order in the state vector but not the density matrix

Steps to reproduce the problem

from qiskit import QuantumCircuit
from qiskit.circuit.random import random_circuit
from qiskit_aer import AerSimulator
import numpy as np
np.set_printoptions(linewidth=100, precision=3)

def get_state_vector(circuit: QuantumCircuit):
    simulator = AerSimulator(method="statevector")
    result = simulator.run(circuit).result()
    return result.data(0)["statevector"]

def get_density_matrix(circuit: QuantumCircuit):
    simulator = AerSimulator(method="density_matrix")
    result = simulator.run(circuit).result()
    return result.data(0)["density_matrix"]

num_qubits = 2
depth = 1
seed = 2

circuit = random_circuit(num_qubits, depth, seed=seed)
circuit.save_statevector()
print(get_state_vector(circuit))

circuit = circuit.reverse_bits()
print(get_state_vector(circuit)) # reversing bits affects the state vector

circuit = random_circuit(num_qubits, depth, seed=seed)
circuit.save_density_matrix()
print(get_density_matrix(circuit))

circuit = circuit.reverse_bits()
print(get_density_matrix(circuit)) # reversing bits does not affect the density matrix

Output:

Statevector([0.592+0.j   , 0.   -0.806j, 0.   +0.j   , 0.   +0.j   ],
            dims=(2, 2))
Statevector([0.592+0.j   , 0.   +0.j   , 0.   -0.806j, 0.   +0.j   ],
            dims=(2, 2))
DensityMatrix([[0.35+0.j   , 0.  +0.477j, 0.  +0.j   , 0.  +0.j   ],
               [0.  -0.477j, 0.65+0.j   , 0.  +0.j   , 0.  +0.j   ],
               [0.  +0.j   , 0.  +0.j   , 0.  +0.j   , 0.  +0.j   ],
               [0.  +0.j   , 0.  +0.j   , 0.  +0.j   , 0.  +0.j   ]],
              dims=(2, 2))
DensityMatrix([[0.35+0.j   , 0.  +0.477j, 0.  +0.j   , 0.  +0.j   ],
               [0.  -0.477j, 0.65+0.j   , 0.  +0.j   , 0.  +0.j   ],
               [0.  +0.j   , 0.  +0.j   , 0.  +0.j   , 0.  +0.j   ],
               [0.  +0.j   , 0.  +0.j   , 0.  +0.j   , 0.  +0.j   ]],
              dims=(2, 2))

What is the expected behavior?

The effect of QuantumCircuit.reverse_bits() on the result should be consistent (should be unified to either have no effect on the order of bits in both Statevector and DensityMatrix, or to have an effect).

enum-class commented 2 months ago

In this code I can see it is ok,

circuit = random_circuit(num_qubits, depth, seed=seed)
circuit2 = circuit.reverse_bits()

circuit.save_density_matrix()

print(get_density_matrix(circuit))

circuit2.save_density_matrix()
print(get_density_matrix(circuit2)) 

output:

DensityMatrix([[0.35+0.j   , 0.  +0.477j, 0.  +0.j   , 0.  +0.j   ],
               [0.  -0.477j, 0.65+0.j   , 0.  +0.j   , 0.  +0.j   ],
               [0.  +0.j   , 0.  +0.j   , 0.  +0.j   , 0.  +0.j   ],
               [0.  +0.j   , 0.  +0.j   , 0.  +0.j   , 0.  +0.j   ]],
              dims=(2, 2))
DensityMatrix([[0.35+0.j   , 0.  +0.j   , 0.  +0.477j, 0.  +0.j   ],
               [0.  +0.j   , 0.  +0.j   , 0.  +0.j   , 0.  +0.j   ],
               [0.  -0.477j, 0.  +0.j   , 0.65+0.j   , 0.  +0.j   ],
               [0.  +0.j   , 0.  +0.j   , 0.  +0.j   , 0.  +0.j   ]],
              dims=(2, 2))
enum-class commented 2 months ago

maybe reverse_bits() do not copy the circuit correctly