From 436ba5f4812031eed62e6cce1ad1380913e74c47 Mon Sep 17 00:00:00 2001 From: John Lapeyre Date: Sat, 12 Sep 2020 07:37:39 -0700 Subject: [PATCH] Use Operator rather than unitary simulator to convert circuit to unitary matrix (Qiskit/qiskit-aqua#1224) * Fix factor of 2 error in converting exp_i to rotation gates * Make CircuitOp use Operator rather than unitary simulator to get matrix The unitary simulator does not account for the global phase in a circuit. qiskit.quantum_info.Operator does account for global phase when converting (when possible) a circuit to a unitary matrix. Closes Qiskit/qiskit-aqua#1218 * Remove note on reversing order of qubits Using Operator(QuantumCircuit) gives the same qubit ordering that the previous unitary-simulator-based code did. I removed the comment entirely because the behavior depends only on Operator(QuantumCircuit), which is not obscure. --- qiskit/aqua/operators/primitive_ops/circuit_op.py | 12 +++--------- qiskit/aqua/operators/primitive_ops/pauli_op.py | 6 +++--- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/qiskit/aqua/operators/primitive_ops/circuit_op.py b/qiskit/aqua/operators/primitive_ops/circuit_op.py index da7006d22fa9..7d5140ccce2a 100644 --- a/qiskit/aqua/operators/primitive_ops/circuit_op.py +++ b/qiskit/aqua/operators/primitive_ops/circuit_op.py @@ -16,7 +16,8 @@ import logging import numpy as np -from qiskit import QuantumCircuit, BasicAer, execute +import qiskit +from qiskit import QuantumCircuit from qiskit.circuit.library import IGate from qiskit.circuit import Instruction, ParameterExpression @@ -139,14 +140,7 @@ def to_matrix(self, massive: bool = False) -> np.ndarray: ' in this case {0}x{0} elements.' ' Set massive=True if you want to proceed.'.format(2 ** self.num_qubits)) - # NOTE: not reversing qubits!! We generally reverse endianness when converting between - # circuit or Pauli representation and matrix representation, but we don't need to here - # because the Unitary simulator already presents the endianness of the circuit unitary in - # forward endianness. - unitary_backend = BasicAer.get_backend('unitary_simulator') - unitary = execute(self.to_circuit(), - unitary_backend, - optimization_level=0).result().get_unitary() + unitary = qiskit.quantum_info.Operator(self.to_circuit()).data # pylint: disable=cyclic-import from ..operator_globals import EVAL_SIG_DIGITS return np.round(unitary * self.coeff, decimals=EVAL_SIG_DIGITS) diff --git a/qiskit/aqua/operators/primitive_ops/pauli_op.py b/qiskit/aqua/operators/primitive_ops/pauli_op.py index 4910a9b851c3..38edf71b2ba8 100644 --- a/qiskit/aqua/operators/primitive_ops/pauli_op.py +++ b/qiskit/aqua/operators/primitive_ops/pauli_op.py @@ -220,13 +220,13 @@ def exp_i(self) -> OperatorBase: else self.coeff # Y rotation if corrected_x[sig_qubit_index] and corrected_z[sig_qubit_index]: - rot_op = PrimitiveOp(RYGate(coeff)) + rot_op = PrimitiveOp(RYGate(2 * coeff)) # Z rotation elif corrected_z[sig_qubit_index]: - rot_op = PrimitiveOp(RZGate(coeff)) + rot_op = PrimitiveOp(RZGate(2 * coeff)) # X rotation elif corrected_x[sig_qubit_index]: - rot_op = PrimitiveOp(RXGate(coeff)) + rot_op = PrimitiveOp(RXGate(2 * coeff)) from ..operator_globals import I left_pad = I.tensorpower(sig_qubit_index)