Skip to content
This repository has been archived by the owner on Dec 7, 2021. It is now read-only.

Commit

Permalink
Make CircuitOp use Operator rather than unitary simulator to get matrix
Browse files Browse the repository at this point in the history
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 #1218
  • Loading branch information
jlapeyre committed Aug 31, 2020
1 parent 384f567 commit 466bd48
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
10 changes: 5 additions & 5 deletions qiskit/aqua/operators/primitive_ops/circuit_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,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

Expand Down Expand Up @@ -141,14 +142,13 @@ 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))

# TODO: Check order of qubits. The note below refers to using the unitary simulator.
# But, we have replaced this code with qiskit.quantum_info.Operator
# 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)
Expand Down
8 changes: 8 additions & 0 deletions test/aqua/operators/test_evolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import numpy as np
import scipy.linalg

import qiskit
from qiskit.circuit import ParameterVector, Parameter

from qiskit.aqua.operators import (X, Y, Z, I, CX, H, ListOp, CircuitOp, Zero, EvolutionFactory,
Expand All @@ -31,6 +32,13 @@
class TestEvolution(QiskitAquaTestCase):
"""Evolution tests."""

def test_exp_i(self):
""" exponential of Pauli test """
op = Z.exp_i()
gate = op.to_circuit().data[0][0]
self.assertIsInstance(gate, qiskit.circuit.library.RZGate)
self.assertEqual(gate.params[0], 2)

def test_pauli_evolution(self):
""" pauli evolution test """
op = (-1.052373245772859 * I ^ I) + \
Expand Down
9 changes: 9 additions & 0 deletions test/aqua/operators/test_op_construction.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from test.aqua import QiskitAquaTestCase
import itertools
import scipy
from scipy.stats import unitary_group
import numpy as np
from ddt import ddt, data
Expand Down Expand Up @@ -203,6 +204,14 @@ def test_to_matrix(self):
np.testing.assert_array_almost_equal(
op6.to_matrix(), op5.to_matrix() + Operator.from_label('+r').data)

def test_circuit_op_to_matrix(self):
""" test CircuitOp.to_matrix """
qc = QuantumCircuit(1)
qc.rz(1.0, 0)
qcop = CircuitOp(qc)
np.testing.assert_array_almost_equal(
qcop.to_matrix(), scipy.linalg.expm(-0.5j * Z.to_matrix()))

def test_matrix_to_instruction(self):
"""Test MatrixOp.to_instruction yields an Instruction object."""
matop = (H ^ 3).to_matrix_op()
Expand Down

0 comments on commit 466bd48

Please sign in to comment.