diff --git a/qiskit/synthesis/evolution/qdrift.py b/qiskit/synthesis/evolution/qdrift.py index 6642a68b8db6..968d15f87bce 100644 --- a/qiskit/synthesis/evolution/qdrift.py +++ b/qiskit/synthesis/evolution/qdrift.py @@ -83,8 +83,6 @@ def synthesize(self, evolution): size=(num_gates,), p=weights / lambd, ) - # Update the coefficients of sampled_ops - self.sampled_ops = [(op, evolution_time) for op, coeff in self.sampled_ops] # pylint: disable=cyclic-import from qiskit.circuit.library.pauli_evolution import PauliEvolutionGate @@ -94,7 +92,7 @@ def synthesize(self, evolution): insert_barriers=self.insert_barriers, atomic_evolution=self.atomic_evolution ) evolution_circuit = PauliEvolutionGate( - sum(SparsePauliOp(op) for op, coeff in self.sampled_ops), + sum(SparsePauliOp(np.sign(coeff) * op) for op, coeff in self.sampled_ops), time=evolution_time, synthesis=lie_trotter, ).definition diff --git a/releasenotes/notes/fix-qdrift-evolution-bceb9c4f182ab0f5.yaml b/releasenotes/notes/fix-qdrift-evolution-bceb9c4f182ab0f5.yaml new file mode 100644 index 000000000000..a86869a4e540 --- /dev/null +++ b/releasenotes/notes/fix-qdrift-evolution-bceb9c4f182ab0f5.yaml @@ -0,0 +1,3 @@ +fixes: + - | + Fix incorrect implemention of `qDRIFT`, negative coeffients of the Hamiltonian are now added back whereas they were always forced to be positive. diff --git a/test/python/circuit/library/test_evolution_gate.py b/test/python/circuit/library/test_evolution_gate.py index e407cf0341d9..88b0529ca7c2 100644 --- a/test/python/circuit/library/test_evolution_gate.py +++ b/test/python/circuit/library/test_evolution_gate.py @@ -155,17 +155,25 @@ def test_qdrift_manual(self, op, time, reps, sampled_ops): def test_qdrift_evolution(self): """Test QDrift on an example.""" - op = 0.1 * (Z ^ Z) + (X ^ I) + (I ^ X) + 0.2 * (X ^ X) + op = 0.1 * (Z ^ Z) - 3.2 * (X ^ I) - 1.0 * (I ^ X) + 0.2 * (X ^ X) reps = 20 - qdrift = PauliEvolutionGate( - op, time=0.5 / reps, synthesis=QDrift(reps=reps, seed=self.seed) - ).definition - exact = scipy.linalg.expm(-0.5j * op.to_matrix()).dot(np.eye(4)[0, :]) + time = 0.12 + num_samples = 300 + qdrift_energy = [] def energy(evo): return Statevector(evo).expectation_value(op.to_matrix()) - self.assertAlmostEqual(energy(exact), energy(qdrift), places=2) + for i in range(num_samples): + qdrift = PauliEvolutionGate( + op, time=time, synthesis=QDrift(reps=reps, seed=self.seed + i) + ).definition + + qdrift_energy.append(energy(qdrift)) + + exact = scipy.linalg.expm(-1j * time * op.to_matrix()).dot(np.eye(4)[0, :]) + + self.assertAlmostEqual(energy(exact), np.average(qdrift_energy), places=2) def test_passing_grouped_paulis(self): """Test passing a list of already grouped Paulis."""