Skip to content

Commit

Permalink
Adding global_phase gate in qiskit-terra (#9251)
Browse files Browse the repository at this point in the history
* created gphase.py file

* completed glbalphase file & test_gate_defin

* adding GphaseGate in @DaTa in test_gate_defn

* added reno add-global-phase

* added inv and matrix test in test_exten

* test_gphase_inv

* tox lint edit

* renamed GLobalPhaseGate to Global_Phase_Gate

* Changed the name to more competable GlobalPhaseGate class

* # pylint: disable=E1101

* # pylint: disable=no-member

* # pylint: error fixed

* including phase in super

* changed float to ParameterExp

* modified test_globalphaseGate

* phase to params[0]

* renamed global_phase.py to gphase

* test gphase new in extentions_std

* debug 1

* debug 2

* debug 3 instructions set

* debug 4

* debug 5

* debug 6

* debug 6 instructions set

* debug 7

* debug 7

* added gphase in quantumcircuit.py

* added method gphase in quantumcircuit.py

* test_gphase_inv

* gphase debug1

* gphase debug2

* gphase debug3

* inverse mtd in gphase.py

* added _array in gphase.py

* gphase.py array debug1

* test_matrix gphase complex dtype

* test_matrix in @DDT

* test_gphase_matrix

* changed gphase to global_phase

* removed extra comma l871

* typo in reno fixed

* modified reno

* Delete .vs directory

Deleted .vs directory

* Added test to check compatibility of gate with qc.attri

* debugged pylint error1

* debugged pylint error2

* debugged pylint error2a

* debugged -epy error debug1

* debugged -epy error debug 1

* debugged -epy error debug 2

* restored test_gate_definations

* Revert "restored test_gate_definations"

This reverts commit 642877b.

* reverted mistakely edited the file on Github

* Delete .vs directory

Deleted .vs directory

* restored test_gate_definations

* Revert "restored test_gate_definations"

This reverts commit 642877b.

* reverted mistakely edited the file on Github

* retrived test_gate_definitions

* PR modifications new

* commit feb 13

* range in append

* [] in append

* [0] in append

* [0]->[]

* [0]

* []

* Operator(qc)

* fixed test_ex_std

* resolved changes suggested by Cryolis

* Update global_phase.py

Typo in year

* Added transpiler consistancy test

* restored the docstring

* prevented cyclic imports and other changes

* Fix spacing in docs

* Fix lint

* Add test of controlling global phase

---------

Co-authored-by: Jake Lishman <[email protected]>
  • Loading branch information
sumit-kale and jakelishman authored Apr 17, 2023
1 parent c4602ea commit da92478
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 4 deletions.
1 change: 1 addition & 0 deletions qiskit/circuit/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
XGate
YGate
ZGate
GlobalPhaseGate
Standard Directives
===================
Expand Down
3 changes: 2 additions & 1 deletion qiskit/circuit/library/standard_gates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from .x import MCXGate, MCXGrayCode, MCXRecursive, MCXVChain
from .y import YGate, CYGate
from .z import ZGate, CZGate, CCZGate

from .global_phase import GlobalPhaseGate
from .multi_control_rotation_gates import mcrx, mcry, mcrz


Expand Down Expand Up @@ -80,6 +80,7 @@ def get_standard_gate_name_mapping():
CYGate(),
CZGate(),
CCZGate(),
GlobalPhaseGate(Parameter("ϴ")),
HGate(),
PhaseGate(Parameter("ϴ")),
RCCXGate(),
Expand Down
62 changes: 62 additions & 0 deletions qiskit/circuit/library/standard_gates/global_phase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Global Phase Gate"""

from typing import Optional
import numpy
from qiskit.circuit.gate import Gate
from qiskit.circuit.quantumregister import QuantumRegister
from qiskit.circuit.quantumcircuit import QuantumCircuit
from qiskit.circuit.parameterexpression import ParameterValueType


class GlobalPhaseGate(Gate):
r"""The global phase gate (:math:`e^{i\theta}`).
Can be applied to a :class:`~qiskit.circuit.QuantumCircuit`
**Mathamatical Representation:**
.. math::
\text{GlobalPhaseGate}\ =
\begin{pmatrix}
e^{i\theta}
\end{pmatrix}
"""

def __init__(self, phase: ParameterValueType, label: Optional[str] = None):
"""
Args:
phase: The value of phase it takes.
label: An optional label for the gate.
"""
super().__init__("global_phase", 0, [phase], label=label)

def _define(self):

q = QuantumRegister(0, "q")
qc = QuantumCircuit(q, name=self.name, global_phase=self.params[0])

self.definition = qc

def inverse(self):
r"""Return inverted GLobalPhaseGate gate.
:math:`\text{GlobalPhaseGate}(\lambda){\dagger} = \text{GlobalPhaseGate}(-\lambda)`
"""
return GlobalPhaseGate(-self.params[0])

def __array__(self, dtype=complex):
"""Return a numpy.array for the global_phase gate."""
theta = self.params[0]
return numpy.array([[numpy.exp(1j * theta)]], dtype=dtype)
2 changes: 1 addition & 1 deletion qiskit/quantum_info/operators/operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def compose(self, other, qargs=None, front=False):
tensor = np.reshape(self.data, self._op_shape.tensor_shape)
mat = np.reshape(other.data, other._op_shape.tensor_shape)
indices = [num_indices - 1 - qubit for qubit in qargs]
final_shape = [np.product(output_dims), np.product(input_dims)]
final_shape = [int(np.product(output_dims)), int(np.product(input_dims))]
data = np.reshape(
Operator._einsum_matmul(tensor, mat, indices, shift, right_mul), final_shape
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
features:
- |
Added :class:`.GlobalPhaseGate` which can be applied to add a global phase
on the :class:`.QuantumCircuit`.
16 changes: 16 additions & 0 deletions test/python/circuit/test_controlled_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
C3SXGate,
C4XGate,
MCPhaseGate,
GlobalPhaseGate,
)
from qiskit.circuit._utils import _compute_control_matrix
import qiskit.circuit.library.standard_gates as allGates
Expand Down Expand Up @@ -223,6 +224,21 @@ def test_special_cases_equivalent_to_controlled_base_gate(self):
# CX is treated like a primitive within Terra, and doesn't have a definition.
self.assertTrue(Operator(special_case_gate.definition).equiv(naive_operator))

def test_global_phase_control(self):
"""Test creation of a GlobalPhaseGate."""
base = GlobalPhaseGate(np.pi / 7)
expected_1q = PhaseGate(np.pi / 7)
self.assertEqual(Operator(base.control()), Operator(expected_1q))

expected_2q = PhaseGate(np.pi / 7).control()
self.assertEqual(Operator(base.control(2)), Operator(expected_2q))

expected_open = QuantumCircuit(1)
expected_open.x(0)
expected_open.p(np.pi / 7, 0)
expected_open.x(0)
self.assertEqual(Operator(base.control(ctrl_state=0)), Operator(expected_open))

def test_circuit_append(self):
"""Test appending a controlled gate to a quantum circuit."""
circ = QuantumCircuit(5)
Expand Down
49 changes: 47 additions & 2 deletions test/python/circuit/test_extensions_standard.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import numpy as np
from scipy.linalg import expm
from ddt import data, ddt, unpack

from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister, execute
from qiskit.exceptions import QiskitError
from qiskit.circuit.exceptions import CircuitError
Expand All @@ -36,11 +35,14 @@
RZGate,
XGate,
YGate,
GlobalPhaseGate,
)
from qiskit import BasicAer
from qiskit.quantum_info import Pauli
from qiskit.quantum_info.operators.predicates import matrix_equal, is_unitary_matrix
from qiskit.utils.optionals import HAS_TWEEDLEDUM
from qiskit.quantum_info import Operator
from qiskit import transpile


class TestStandard1Q(QiskitTestCase):
Expand Down Expand Up @@ -851,6 +853,50 @@ def test_z_reg_inv(self):
self.assertEqual(instruction_set[1].qubits, (self.qr[1],))
self.assertEqual(instruction_set[2].operation.params, [])

def test_global_phase(self):
qc = self.circuit
qc.append(GlobalPhaseGate(0.1), [])
self.assertEqual(self.circuit[0].operation.name, "global_phase")
self.assertEqual(self.circuit[0].operation.params, [0.1])
self.assertEqual(self.circuit[0].qubits, ())

def test_global_phase_inv(self):
instruction_set = self.circuit.append(GlobalPhaseGate(0.1), []).inverse()
self.assertEqual(len(instruction_set), 1)
self.assertEqual(instruction_set[0].operation.params, [-0.1])

def test_global_phase_matrix(self):
"""Test global_phase matrix."""
theta = 0.1
np.testing.assert_allclose(
np.array(GlobalPhaseGate(theta)),
np.array([[np.exp(1j * theta)]], dtype=complex),
atol=1e-7,
)

def test_global_phase_consistency(self):
"""Tests compatibility of GlobalPhaseGate with QuantumCircuit.global_phase"""
theta = 0.1
qc1 = QuantumCircuit(0, global_phase=theta)
qc2 = QuantumCircuit(0)
qc2.append(GlobalPhaseGate(theta), [])
np.testing.assert_allclose(
Operator(qc1),
Operator(qc2),
atol=1e-7,
)

def test_transpile_global_phase_consistency(self):
"""Tests compatibility of transpiled GlobalPhaseGate with QuantumCircuit.global_phase"""
qc1 = QuantumCircuit(0, global_phase=0.3)
qc2 = QuantumCircuit(0, global_phase=0.2)
qc2.append(GlobalPhaseGate(0.1), [])
np.testing.assert_allclose(
Operator(transpile(qc1, basis_gates=["u"])),
Operator(transpile(qc2, basis_gates=["u"])),
atol=1e-7,
)


@ddt
class TestStandard2Q(QiskitTestCase):
Expand Down Expand Up @@ -1375,7 +1421,6 @@ def test_to_matrix(self):
def test_to_matrix_op(self):
"""test gates implementing to_matrix generate matrix which matches
definition using Operator."""
from qiskit.quantum_info import Operator
from qiskit.circuit.library.generalized_gates.gms import MSGate
from qiskit.circuit.library.generalized_gates.pauli import PauliGate
from qiskit.circuit.library.pauli_evolution import PauliEvolutionGate
Expand Down

0 comments on commit da92478

Please sign in to comment.