Qiskit-Extensions / monodromy

Computations in the monodromy polytope for quantum gate sets
Apache License 2.0
17 stars 9 forks source link

Distinct gates require distinct names building coverage sets #8

Closed evmckinney9 closed 1 year ago

evmckinney9 commented 1 year ago

There is an error when calling build_coverage_set() with a set of operations with different costs. It seems that the order in which I give list of the operations changes the correctness -even though the order should not matter.

Here is an example where the operations include 3 fractions iSwap gates in decreasing cost. Compared to when I give the operations in a different order - which seems incorrect because it tells me that I can make a 3/4th iSwap gate with cost 0.5 instead of the expected 0.75. Correct: image Incorrect: image


Fix:

Change the name generation in coverage._operation_to_circuit_polytope to something that distinguishes the two gates, like f"{operation.name}({operation.params[0]:.5f}")

I made these changes in my fork and will open a PR for this repo as well.

First, in _operation_to_circuit_polytope():

return CircuitPolytope(
        operations=[f"{operation.name}({operation.params[0]:.5f})"],
        instructions=[operation],
        cost=cost,
        convex_subpolytopes=convex_polytope.convex_subpolytopes,

Second, in build_coverage_set():

# assert that operations.operation are unique
if len(set([operation.operations[-1] for operation in operations])) != len(operations):
     raise ValueError("Operations must be unique.")
evmckinney9 commented 1 year ago

Looks like the examples already had this condition satisfied, from gateset.py, so the only necessary change is explicit checking.

def get_operations(*strengths):
    """
    Builds a family of XX-type operations, where each strength in `strengths` is
    specified as a fraction of the "full strength" XX-type operation, CX.
    """
    return [
        CircuitPolytope(
            convex_subpolytopes=exactly(
                Fraction( 1, 4) * strength,
                Fraction( 1, 4) * strength,
                Fraction(-1, 4) * strength
            ).convex_subpolytopes,
            cost=operation_cost(strength),
            operations=[f"{str(strength)} XX"],
        ) for strength in set(strengths)
    ]