Skip to content

Gate decompositions ignore global phase #4275

@smite

Description

@smite

Description of the issue

It seems that gate decompositions ignore global phase (global_shift). Normally this is OK since global phases are not physically observable, but it has to be accounted for to properly decompose controlled gates, where the global phase turns into an observable relative phase.

How to reproduce the issue

import cirq
import numpy as np

np.set_printoptions(precision=3, linewidth=150)


def dist(U, V):
    """Frobenius-norm distance of two unitaries modulo global phase.
    """
    return 2 * (len(U) - np.abs(np.trace(U.T.conj() @ V)))


def check_decomposition(op):
    """Check whether op and its decomposition have the same unitary propagator.
    """
    # op on its own
    temp = cirq.Circuit(op)
    print(temp)
    U = temp._unitary_()

    # op decomposed
    dec = cirq.Circuit(cirq.protocols.decompose(op))
    print(dec)
    V = dec._unitary_()

    # compare the propagators
    diff = np.linalg.norm(U - V, 'fro')
    print('difference using norm:', diff)
    diff_modulo_phase = dist(U, V)
    print('difference modulo global phase:', diff_modulo_phase)
    assert diff_modulo_phase < 1e-6, 'Decomposition broken!'


a = cirq.NamedQubit('a')
b = cirq.NamedQubit('b')

s = 0.3  # add some global phase to the gate
op = cirq.HPowGate(exponent=1, global_shift=s)

check_decomposition(op.on(a))
print()
check_decomposition(op.controlled(1).on(a, b))
a: ───H─── a: ───Y^0.5───X─── difference using norm: 1.2840790438404122 difference modulo global phase: 0.0

a: ───@───

b: ───H───
a: ───@───────@───
│ │
b: ───Y^0.5───X───
difference using norm: 1.2840790438404122
difference modulo global phase: 0.8719478064930559
Traceback (most recent call last):
...
AssertionError: Decomposition broken!

Cirq version

0.11.0

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions