quantumlib / Cirq

A Python framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
Apache License 2.0
4.29k stars 1.02k forks source link

Should analytical decompositions return an empty list when decomposing identity operation? #4831

Open tanujkhattar opened 2 years ago

tanujkhattar commented 2 years ago

We have many analytical decompositions in https://github.com/quantumlib/Cirq/tree/master/cirq-core/cirq/transformers/analytical_decompositions which are used to decompose a given unitary matrix / operation into a specific target gateset (eg: cz/fsim/sqrt_iswap etc.). The behavior of these decompositions when trying to decompose an identity operation currently differs across implementations -- some return an empty list while some return only single qubit ops and others return a longer decomposition. Eg:

>>> import cirq
>>> import numpy as np
>>> eye = np.eye(4)
>>> q0, q1 = cirq.LineQubit.range(2)
>>> cirq.two_qubit_matrix_to_sqrt_iswap_operations(q0, q1, eye)
[]
>>> cirq.two_qubit_matrix_to_operations(q0, q1, eye, allow_partial_czs=False, clean_operations=False)
[cirq.S(cirq.LineQubit(0)), (cirq.Z**1.5).on(cirq.LineQubit(0))]

There are also other inconsistencies in the API's of these analytical decompositions. For example:

  1. Calling a list of cleanup operations on the decomposed operation list:

    • two_qubit_matrix_to_operations has a default clean_operations=True flag in the constructor which calls a long list of cleanup operations on the list of final decomposed operations.
    • two_qubit_matrix_to_ion_operations does not have a configurable cleanup_operations=True flag and always calls the same list of cleanup operations on the final decomposed operations
    • two_qubit_matrix_to_sqrt_iswap_operations has no flag and does not call the cleanup operations on the final decomposed operations.
  2. API of the analytical decompositions:

    • two_qubit_matrix_to_* versions expect a q0, q1, mat
    • decompose_two_qubit_interaction_into_four_fsim_gates expects as Union['cirq.Operation', 'cirq.Gate', np.ndarray, Any] and a qubits: Sequence['cirq.Qid'] = None instead of q0, q1 etc.
    • decompose_cphase_into_two_fsim expects CZPowGate and FSimGates (not operations or matrices)
tanujkhattar commented 2 years ago