Example #1
0
def test_validate_scheduled_operation_XXPow_on_same_qubit():
    d = ion_device(3)
    q0 = cirq.LineQubit(0)
    q1 = cirq.LineQubit(1)
    q2 = cirq.LineQubit(2)
    s = cirq.Schedule(d, [
        cirq.ScheduledOperation.op_at_on(cirq.XX(q0, q1), cirq.Timestamp(), d),
        cirq.ScheduledOperation.op_at_on(cirq.XX(q1, q2), cirq.Timestamp(), d),
    ])
    with pytest.raises(ValueError):
        d.validate_schedule(s)
Example #2
0
def test_xx_diagrams():
    a = cirq.NamedQubit('a')
    b = cirq.NamedQubit('b')
    circuit = cirq.Circuit(cirq.XX(a, b), cirq.XX(a, b)**3, cirq.XX(a, b)**0.5)
    cirq.testing.assert_has_diagram(
        circuit,
        """
a: ───XX───XX───XX───────
      │    │    │
b: ───XX───XX───XX^0.5───
""",
    )
Example #3
0
def test_can_add_operation_into_moment():
    d = ion_device(3)
    q0 = cirq.LineQubit(0)
    q1 = cirq.LineQubit(1)
    q2 = cirq.LineQubit(2)
    q3 = cirq.LineQubit(3)
    circuit = cirq.Circuit()
    circuit.append(cirq.XX(q0, q1))
    for moment in circuit:
        assert not d.can_add_operation_into_moment(cirq.XX(q2, q0), moment)
        assert not d.can_add_operation_into_moment(cirq.XX(q1, q2), moment)
        assert d.can_add_operation_into_moment(cirq.XX(q2, q3), moment)
        assert d.can_add_operation_into_moment(cirq.Z(q3), moment)
Example #4
0
def test_xx_diagrams():
    a = cirq.NamedQubit('a')
    b = cirq.NamedQubit('b')
    circuit = cirq.Circuit(
        cirq.XX(a, b),
        cirq.XX(a, b)**3,
        cirq.XX(a, b)**0.5,
        cirq.XXPowGate(global_shift=-0.5).on(a, b),
    )
    cirq.testing.assert_has_diagram(
        circuit, """
a: ───XX───XX───XX───────MS(0.5π)───
      │    │    │        │
b: ───XX───XX───XX^0.5───MS(0.5π)───
""")
Example #5
0
def test_can_add_operation_into_moment_device_deprecated():
    with cirq.testing.assert_deprecated('can_add_operation_into_moment', deadline='v0.15', count=5):
        d = ion_device(3)
        q0 = cirq.LineQubit(0)
        q1 = cirq.LineQubit(1)
        q2 = cirq.LineQubit(2)
        q3 = cirq.LineQubit(3)
        circuit = cirq.Circuit()
        circuit.append(cirq.XX(q0, q1))
        for moment in circuit:
            assert not d.can_add_operation_into_moment(cirq.XX(q2, q0), moment)
            assert not d.can_add_operation_into_moment(cirq.XX(q1, q2), moment)
            assert d.can_add_operation_into_moment(cirq.XX(q2, q3), moment)
            assert d.can_add_operation_into_moment(cirq.Z(q3), moment)
        circuit = cirq.Circuit([cirq.X(q0)])
        assert d.can_add_operation_into_moment(cirq.XX(q1, q2), circuit[0])
Example #6
0
    def test_time_evolution(self):
        # Given
        hamiltonian = PauliSum([
            PauliTerm('X', 0) * PauliTerm('X', 1),
            PauliTerm('Y', 0, 0.5) * PauliTerm('Y', 1),
            PauliTerm('Z', 0, 0.3) * PauliTerm('Z', 1)
        ])
        time = 0.4
        order = 2

        circuit = cirq.Circuit()
        q1 = cirq.LineQubit(0)
        q2 = cirq.LineQubit(1)
        for _ in range(0, order):
            circuit.append(
                cirq.XX(q1, q2)**(hamiltonian.terms[0].coefficient * 2 * time /
                                  order / pi))
            circuit.append(
                cirq.YY(q1, q2)**(hamiltonian.terms[1].coefficient * 2 * time /
                                  order / pi))
            circuit.append(
                cirq.ZZ(q1, q2)**(hamiltonian.terms[2].coefficient * 2 * time /
                                  order / pi))
        u = circuit._unitary_()

        #When
        unitary_evolution = time_evolution(hamiltonian,
                                           time,
                                           trotter_order=order)
        u1 = unitary_evolution.to_unitary()

        # Then
        self.assertEqual(compare_unitary(u1, u, tol=1e-10), True)
Example #7
0
def test_decompose_parameterized_gates():
    theta = sympy.Symbol("theta")
    q = cirq.LineQubit.range(2)
    circuit = cirq.Circuit(cirq.H(q[0])**theta, cirq.XX(*q)**theta)
    d = ion_device(3)
    assert d.gateset.validate(d.decompose_circuit(circuit))
    assert d.gateset._decompose_two_qubit_operation(cirq.CZ(*q)**theta,
                                                    0) is NotImplemented
Example #8
0
def two_qubit_unitary(bits, symbols):
    """Make a Cirq circuit that creates an arbitrary two qubit unitary."""
    circuit = cirq.Circuit()
    circuit += one_qubit_unitary(bits[0], symbols[0:3])
    circuit += one_qubit_unitary(bits[1], symbols[3:6])
    circuit += [cirq.ZZ(*bits)**symbols[6]]
    circuit += [cirq.YY(*bits)**symbols[7]]
    circuit += [cirq.XX(*bits)**symbols[8]]
    circuit += one_qubit_unitary(bits[0], symbols[9:12])
    circuit += one_qubit_unitary(bits[1], symbols[12:])
    return circuit
def _all_operations(q0, q1, q2, q3, q4, include_measurements=True):
    return (
        cirq.Z(q0),
        cirq.Z(q0)**0.625,
        cirq.Y(q0),
        cirq.Y(q0)**0.375,
        cirq.X(q0),
        cirq.X(q0)**0.875,
        cirq.H(q1),
        cirq.CZ(q0, q1),
        cirq.CZ(q0, q1)**0.25,  # Requires 2-qubit decomposition
        cirq.CNOT(q0, q1),
        cirq.CNOT(q0, q1)**0.5,  # Requires 2-qubit decomposition
        cirq.SWAP(q0, q1),
        cirq.SWAP(q1, q0)**-1,
        cirq.SWAP(q0, q1)**0.75,  # Requires 2-qubit decomposition
        cirq.CCZ(q0, q1, q2),
        cirq.CCX(q0, q1, q2),
        cirq.CCZ(q0, q1, q2)**0.5,
        cirq.CCX(q0, q1, q2)**0.5,
        cirq.CSWAP(q0, q1, q2),
        cirq.XX(q0, q1),
        cirq.XX(q0, q1)**0.75,
        cirq.YY(q0, q1),
        cirq.YY(q0, q1)**0.75,
        cirq.ZZ(q0, q1),
        cirq.ZZ(q0, q1)**0.75,
        cirq.IdentityGate(1).on(q0),
        cirq.IdentityGate(3).on(q0, q1, q2),
        cirq.ISWAP(q2, q0),  # Requires 2-qubit decomposition
        cirq.PhasedXPowGate(phase_exponent=0.111, exponent=0.25).on(q1),
        cirq.PhasedXPowGate(phase_exponent=0.333, exponent=0.5).on(q1),
        cirq.PhasedXPowGate(phase_exponent=0.777, exponent=-0.5).on(q1),
        cirq.wait(q0, nanos=0),
        cirq.measure(q0, key='xX'),
        cirq.measure(q2, key='x_a'),
        cirq.measure(q3, key='X'),
        cirq.measure(q2, key='x_a'),
        cirq.measure(q1, q2, q3, key='multi', invert_mask=(False, True)),
    )
Example #10
0
def test_validate_scheduled_operation_adjacent_XXPow_Z():
    d = ion_device(3)
    q0 = cirq.LineQubit(0)
    q1 = cirq.LineQubit(1)
    q2 = cirq.LineQubit(2)
    s = cirq.Schedule(d, [
        cirq.ScheduledOperation.op_at_on(cirq.Z(q0), cirq.Timestamp(), d),
        cirq.ScheduledOperation.op_at_on(cirq.XX(q1, q2), cirq.Timestamp(), d),
        cirq.ScheduledOperation.op_at_on(cirq.X(q1), cirq.Timestamp(), d),
        cirq.ScheduledOperation.op_at_on(cirq.measure(q2), cirq.Timestamp(),
                                         d),
    ])
    d.validate_schedule(s)
Example #11
0
def test_aqt_sampler_ms():
    repetitions = 1000
    num_qubits = 4
    _, qubits = get_aqt_device(num_qubits)
    sampler = AQTSamplerLocalSimulator()
    circuit = cirq.Circuit(cirq.Z.on_each(*qubits), cirq.Z.on_each(*qubits))
    for _dummy in range(9):
        circuit.append(cirq.XX(qubits[0], qubits[1])**0.5)
    circuit.append(cirq.Z(qubits[0])**0.5)
    results = sampler.run(circuit, repetitions=repetitions)
    hist = results.histogram(key='m')
    assert hist[12] > repetitions / 3
    assert hist[0] > repetitions / 3
Example #12
0
def test_operations_to_part_lens():
    qubits = cirq.LineQubit.range(6)
    ops = [cirq.CZ(*qubits[1:3]), cirq.XX(*qubits[3:5])]
    part_lens = cca.gates.operations_to_part_lens(qubits, ops)
    assert part_lens == (1, 2, 2, 1)

    ops = cirq.CZ(qubits[1], qubits[3])
    with pytest.raises(ValueError):
        cca.gates.operations_to_part_lens(qubits, ops)

    ops = [cirq.CZ(*qubits[1:3]), cirq.CZ(*qubits[2:4])]
    with pytest.raises(ValueError):
        cca.gates.operations_to_part_lens(qubits, ops)
Example #13
0
def two_qubit_unitary(bits, symbols):
    """Make a Cirq circuit that creates an arbitrary two qubit unitary.
    Bits: 2
    Symbols: 15
    """
    # Corollary 6 of https://arxiv.org/pdf/quant-ph/0507171.pdf
    circuit = cirq.Circuit()
    circuit += one_qubit_unitary(bits[0], symbols[0:3])
    circuit += one_qubit_unitary(bits[1], symbols[3:6])
    circuit += [cirq.ZZ(*bits)**symbols[6]]
    circuit += [cirq.YY(*bits)**symbols[7]]
    circuit += [cirq.XX(*bits)**symbols[8]]
    circuit += one_qubit_unitary(bits[0], symbols[9:12])
    circuit += one_qubit_unitary(bits[1], symbols[12:])
    return circuit
Example #14
0
def test_ms_crosstalk_n_noise():
    num_qubits = 4
    noise_mod = AQTNoiseModel()
    device, qubits = get_aqt_device(num_qubits)
    circuit = cirq.Circuit(device=device)
    circuit.append(cirq.XX(qubits[1], qubits[2])**0.5)
    for moment in circuit.moments:
        noisy_moment = noise_mod.noisy_moment(moment, qubits)
    assert noisy_moment == [
        (cirq.XX**0.5).on(cirq.LineQubit(1), cirq.LineQubit(2)),
        cirq.depolarize(p=0.01).on(cirq.LineQubit(1)),
        cirq.depolarize(p=0.01).on(cirq.LineQubit(2)),
        (cirq.XX**0.015).on(cirq.LineQubit(1), cirq.LineQubit(0)),
        (cirq.XX**0.015).on(cirq.LineQubit(1), cirq.LineQubit(3)),
        (cirq.XX**0.015).on(cirq.LineQubit(2), cirq.LineQubit(0)),
        (cirq.XX**0.015).on(cirq.LineQubit(2), cirq.LineQubit(3)),
    ]
Example #15
0
    def test_time_evolution_with_symbolic_parameter(self):
        # Given
        hamiltonian = PauliSum([
            PauliTerm("X", 0) * PauliTerm("X", 1),
            PauliTerm("Y", 0, 0.5) * PauliTerm("Y", 1),
            PauliTerm("Z", 0, 0.3) * PauliTerm("Z", 1),
        ])
        time_symbol = sympy.Symbol("t")
        time_value = 0.4
        symbols_map = [(time_symbol, time_value)]
        order = 2

        circuit = cirq.Circuit()
        q1 = cirq.LineQubit(0)
        q2 = cirq.LineQubit(1)
        for _ in range(0, order):
            circuit.append(
                cirq.XX(q1, q2)**(hamiltonian.terms[0].coefficient * 2 *
                                  time_value / order / pi))
            circuit.append(
                cirq.YY(q1, q2)**(hamiltonian.terms[1].coefficient * 2 *
                                  time_value / order / pi))
            circuit.append(
                cirq.ZZ(q1, q2)**(hamiltonian.terms[2].coefficient * 2 *
                                  time_value / order / pi))
        target_unitary = circuit._unitary_()

        # When
        unitary_evolution_symbolic = time_evolution(hamiltonian,
                                                    time_symbol,
                                                    trotter_order=order)
        unitary_evolution = unitary_evolution_symbolic.evaluate(symbols_map)
        final_unitary = unitary_evolution.to_unitary()
        # Then
        self.assertEqual(
            compare_unitary(final_unitary, target_unitary, tol=1e-10), True)
        (cirq.ControlledGate(cirq.ControlledGate(cirq.CCZ))(*cirq.LineQubit.range(5)), True),
        (GateUsingWorkspaceForApplyUnitary()(cirq.NamedQubit('q1')), True),
        (GateAllocatingNewSpaceForResult()(cirq.NamedQubit('q1')), True),
        (
            cirq.MatrixGate(np.kron(*(cirq.unitary(cirq.H),) * 2), qid_shape=(4,)).on(
                cirq.NamedQid("q", 4)
            ),
            False,
        ),
        (
            cirq.MatrixGate(cirq.testing.random_unitary(4, random_state=1234)).on(
                cirq.NamedQubit('q1'), cirq.NamedQubit('q2')
            ),
            False,
        ),
        (cirq.XX(cirq.NamedQubit('q1'), cirq.NamedQubit('q2')) ** sympy.Symbol("s"), True),
        (cirq.DiagonalGate(sympy.symbols("s1, s2")).on(cirq.NamedQubit("q")), False),
    ],
)
def test_controlled_operation_is_consistent(
    gate: cirq.GateOperation, should_decompose_to_target: bool
):
    cb = cirq.NamedQubit('ctr')
    cgate = cirq.ControlledOperation([cb], gate)
    cirq.testing.assert_implements_consistent_protocols(cgate)
    cirq.testing.assert_decompose_ends_at_default_gateset(
        cgate, ignore_known_gates=not should_decompose_to_target
    )

    cgate = cirq.ControlledOperation([cb], gate, control_values=[0])
    cirq.testing.assert_implements_consistent_protocols(cgate)
Example #17
0
    def test_complex_pad(self):
        """Test trickier padding."""
        bit = cirq.GridQubit(0, 0)
        bit2 = cirq.GridQubit(0, 1)
        circuit = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('alpha'),
            cirq.Y(bit)**sympy.Symbol('alpha'),
            cirq.Z(bit)**sympy.Symbol('alpha'),
            cirq.XX(bit, bit2)**sympy.Symbol('alpha'))
        circuit2 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('beta'),
            cirq.Y(bit)**sympy.Symbol('beta'),
            cirq.Z(bit)**sympy.Symbol('beta'),
            cirq.XX(bit, bit2)**sympy.Symbol('alpha'))
        circuit3 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('alpha'),
            cirq.Y(bit)**sympy.Symbol('alpha'),
            cirq.Z(bit)**sympy.Symbol('alpha'),
            cirq.XX(bit, bit2)**sympy.Symbol('alpha'))
        inputs = util.convert_to_tensor([circuit, circuit2, circuit3])
        symbols = tf.convert_to_tensor(['alpha', 'beta', 'gamma'])
        new = tf.convert_to_tensor(['new', 'old', 'nothing'])
        res = tfq_ps_util_ops.tfq_ps_symbol_replace(inputs, symbols, new)
        output = util.from_tensor(res)

        correct_000 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('new'),
            cirq.Y(bit)**sympy.Symbol('alpha'),
            cirq.Z(bit)**sympy.Symbol('alpha'),
            cirq.XX(bit, bit2)**sympy.Symbol('alpha'))
        correct_001 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('alpha'),
            cirq.Y(bit)**sympy.Symbol('new'),
            cirq.Z(bit)**sympy.Symbol('alpha'),
            cirq.XX(bit, bit2)**sympy.Symbol('alpha'))
        correct_002 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('alpha'),
            cirq.Y(bit)**sympy.Symbol('alpha'),
            cirq.Z(bit)**sympy.Symbol('new'),
            cirq.XX(bit, bit2)**sympy.Symbol('alpha'))
        correct_003 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('alpha'),
            cirq.Y(bit)**sympy.Symbol('alpha'),
            cirq.Z(bit)**sympy.Symbol('alpha'),
            cirq.XX(bit, bit2)**sympy.Symbol('new'))

        self.assertEqual(correct_000, output[0][0][0])
        self.assertEqual(correct_001, output[0][0][1])
        self.assertEqual(correct_002, output[0][0][2])
        self.assertEqual(correct_003, output[0][0][3])

        self.assertEqual(correct_000, output[2][0][0])
        self.assertEqual(correct_001, output[2][0][1])
        self.assertEqual(correct_002, output[2][0][2])
        self.assertEqual(correct_003, output[2][0][3])

        correct_110 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('old'),
            cirq.Y(bit)**sympy.Symbol('beta'),
            cirq.Z(bit)**sympy.Symbol('beta'),
            cirq.XX(bit, bit2)**sympy.Symbol('alpha'))
        correct_111 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('beta'),
            cirq.Y(bit)**sympy.Symbol('old'),
            cirq.Z(bit)**sympy.Symbol('beta'),
            cirq.XX(bit, bit2)**sympy.Symbol('alpha'))
        correct_112 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('beta'),
            cirq.Y(bit)**sympy.Symbol('beta'),
            cirq.Z(bit)**sympy.Symbol('old'),
            cirq.XX(bit, bit2)**sympy.Symbol('alpha'))
        correct_113 = cirq.Circuit()

        self.assertEqual(correct_110, output[1][1][0])
        self.assertEqual(correct_111, output[1][1][1])
        self.assertEqual(correct_112, output[1][1][2])
        self.assertEqual(correct_113, output[1][1][3])

        correct_100 = cirq.Circuit(
            cirq.X(bit)**sympy.Symbol('beta'),
            cirq.Y(bit)**sympy.Symbol('beta'),
            cirq.Z(bit)**sympy.Symbol('beta'),
            cirq.XX(bit, bit2)**sympy.Symbol('new'))
        correct_101 = cirq.Circuit()
        correct_102 = cirq.Circuit()
        correct_103 = cirq.Circuit()

        self.assertEqual(correct_100, output[1][0][0])
        self.assertEqual(correct_101, output[1][0][1])
        self.assertEqual(correct_102, output[1][0][2])
        self.assertEqual(correct_103, output[1][0][3])

        correct_220 = cirq.Circuit()
        correct_221 = cirq.Circuit()
        correct_222 = cirq.Circuit()
        correct_223 = cirq.Circuit()

        self.assertEqual(correct_220, output[2][2][0])
        self.assertEqual(correct_221, output[2][2][1])
        self.assertEqual(correct_222, output[2][2][2])
        self.assertEqual(correct_223, output[2][2][3])

        correct = cirq.Circuit()
        for i in range(3):
            for j in range(3):
                for k in range(3):
                    if i != j and (not (i == 2 and j == 0)) \
                        and (not (i == 1 and j == 0)):
                        self.assertEqual(correct, output[i][j][k])
Example #18
0
    def to_cirq(self, input_cirq_qubits=None):
        """Convert to a cirq gate.

        Args:
            input_cirq_qubits: list[cirq.LineQubit]
                (optional) a list of cirq Qubits that the gate can act on. If not provided
                the function will generate new cirq.LineQubit objects.
        Returns:
        A cirq Circuit object that corresponds to the specification of the quantum gate.
            In the special case the gate itself was natively generated from cirq, the function
            will faithfully reproduce the original GateOperation object, taking into account
            whether the gate acts on GridQubit objects or LineQubit objects.
            In the other cases the resulting cirq gate simply assumes that the qubits are
            LineQubit objects.
        """

        if self.name not in ALL_GATES:
            sys.exit("Gate {} currently not supported.".format(self.name))

        q_inds = []
        q_inds.append(self.qubits[0].index)
        if len(self.qubits) >= 2:
            q_inds.append(self.qubits[1].index)
        if len(self.qubits) >= 3:
            q_inds.append(self.qubits[2].index)

        cirq_qubits = []
        if input_cirq_qubits == None:
            for q in self.qubits:
                if q.info["label"] == "cirq":
                    qkey = q.info["QubitKey"]
                    if q.info["QubitType"] == "GridQubit":
                        cirq_qubits.append(cirq.GridQubit(qkey[0], qkey[1]))
                    if q.info["QubitType"] == "LineQubit":
                        cirq_qubits.append(cirq.LineQubit(qkey))
                else:
                    cirq_qubits.append(cirq.LineQubit(q.index))
        else:
            cirq_qubits = [
                input_cirq_qubits[x] for x in [q.index for q in self.qubits]
            ]

        if len(self.params) > 0:
            params = self.params

        # single-qubit gates
        if self.name == "I":  # Identity
            return cirq.I(cirq_qubits[0])
        if self.name == "X":  # Pauli X
            return cirq.X(cirq_qubits[0])
        if self.name == "Y":  # Pauli Y
            return cirq.Y(cirq_qubits[0])
        if self.name == "Z":  # Pauli Z
            return cirq.Z(cirq_qubits[0])
        if self.name == "H":  # Hadamard
            return cirq.H(cirq_qubits[0])
        if self.name == "S":  # S gate
            return cirq.S(cirq_qubits[0])
        if self.name == "T":  # T gate
            return cirq.T(cirq_qubits[0])
        if self.name == "Rx":  # Single-qubit X rotation
            return cirq.rx(params[0])(cirq_qubits[0])
        if self.name == "Ry":  # Single-qubit Y rotation
            return cirq.ry(params[0])(cirq_qubits[0])
        if self.name == "Rz":  # Single-qubit Z rotation
            return cirq.rz(params[0])(cirq_qubits[0])
        if self.name == "PHASE":  # Phase gate
            return cirq.Z(cirq_qubits[0])**(params[0] / pi)
        if self.name == "ZXZ":  # PhasedXPowGate gate
            g = cirq.PhasedXPowGate(phase_exponent=params[0] / pi,
                                    exponent=params[1] / pi)
            return g(cirq_qubits[0])
        if self.name == "RH":  # HPowGate
            g = cirq.H**(params[0] / pi)
            return g(cirq_qubits[0])
        if self.name == "Da":  # Damping alpha gate
            g = DampingAlpha(params[0])
            return g(cirq_qubits[0])
        if self.name == "Db":  # Damping beta gate
            g = DampingBeta(params[0])
            return g(cirq_qubits[0])

        # two-qubit gates
        if self.name == "CNOT":
            return cirq.CNOT(cirq_qubits[0], cirq_qubits[1])
        if self.name == "CZ":
            return cirq.CZ(cirq_qubits[0], cirq_qubits[1])
        if self.name == "CPHASE":
            return cirq.CZPowGate(exponent=params[0] / pi)(cirq_qubits[0],
                                                           cirq_qubits[1])
        if self.name == "SWAP":
            return cirq.SWAP(cirq_qubits[0], cirq_qubits[1])
        if self.name == "XX":
            return cirq.XX(cirq_qubits[0],
                           cirq_qubits[1])**(params[0] * 2 / pi)
        if self.name == "YY":
            return cirq.YY(cirq_qubits[0],
                           cirq_qubits[1])**(params[0] * 2 / pi)
        if self.name == "ZZ":
            return cirq.ZZ(cirq_qubits[0],
                           cirq_qubits[1])**(params[0] * 2 / pi)
Example #19
0
def xxz_chain(qubits, boundary_condition="closed", data_dir=None):
    """1D XXZ model quantum data set.

    $$
    H = \sum_{i} \sigma_i^x \sigma_{i+1}^x + \sigma_i^y \sigma_{i+1}^y +
    \Delta\sigma_i^z \sigma_{i+1}^z
    $$

    Contains 76 circuit parameterizations corresponding to
    the ground states of the 1D XXZ chain for g in [0.3,1.8].
    This dataset contains 76 datapoints. Each datapoint is represented by a
    circuit (`cirq.Circuit`), a label (Python `float`) a Hamiltonian
    (`cirq.PauliSum`) and some additional metadata. Each Hamiltonian in a
    datapoint is a 1D XXZ chain with boundary condition `boundary_condition` on
    `qubits` whos order parameter dictates the value of label. The circuit in a
    datapoint prepares (an approximation to) the ground state of the Hamiltonian
    in the datapoint.

    Example usage:

    >>> qbs = cirq.GridQubit.rect(4, 1)
    >>> circuits, labels, pauli_sums, addinfo  =
    ...     tfq.datasets.xxz_chain(qbs, "closed")

    You can print the available order parameters

    >>> [info.g for info in addinfo]
    [0.30, 0.32, 0.34, ... ,1.76, 1.78, 1.8]

    and the circuit corresponding to the ground state for a certain order
    parameter

    >>> print(circuits[10])
                           ┌──────────────────┐   ┌──────────────────┐
    (0, 0): ───X───H───@─────────────ZZ─────────────────────YY────────── ...
                       │             │                      │
    (1, 0): ───X───────X────ZZ───────┼─────────────YY───────┼─────────── ...
                            │        │             │        │
    (2, 0): ───X───H───@────ZZ^-0.922┼─────────────YY^-0.915┼─────────── ...
                       │             │                      │
    (3, 0): ───X───────X─────────────ZZ^-0.922──────────────YY^-0.915─── ...
                           └──────────────────┘   └──────────────────┘

    The labels indicate the phase of the system
    >>> labels[10]
    0

    Additionally, you can obtain the `cirq.PauliSum` representation of the
    Hamiltonian

    >>> print(pauli_sums[10])
    0.400*Z((0, 0))*Z((1, 0))+0.400*Z((1, 0))*Z((2, 0))+ ...
    +1.000*Y((0, 0))*Y((3, 0))+1.000*X((0, 0))*X((3, 0))

    The fourth output, `addinfo`, contains additional information
    about each instance of the system (see `tfq.datasets.spin_system.SpinSystem`
    ).

    For instance, you can print the ground state obtained from
    exact diagonalization

    >>> addinfo[10].gs
    [-8.69032854e-18-6.58023246e-20j  4.54546402e-17+3.08736567e-17j
     -9.51026525e-18+2.42638062e-17j  4.52284042e-02+3.18111120e-01j
                                    ...
      4.52284042e-02+3.18111120e-01j -6.57974275e-18-3.84526414e-17j
     -1.60673943e-17+5.79767820e-17j  2.86193021e-17-5.06694574e-17j]

    with corresponding ground state energy

    >>> addinfo[10].gs_energy
    -6.744562646538039

    You can also inspect the parameters

    >>> addinfo[10].params
    {'theta_0': 1.0780547, 'theta_1': 0.99271035, 'theta_2': 1.0854135, ...

    and change them to experiment with different parameter values by using
    the unresolved variational circuit returned by xxzchain
    >>> new_params = {}
    ... for symbol_name, value in addinfo[10].params.items():
    ...    new_params[symbol_name] = 0.5 * value
    >>> new_params
    {'theta_0': 0.5390273332595825, 'theta_1': 0.49635517597198486, ...
    >>> new_circuit = cirq.resolve_parameters(addinfo[10].var_circuit,
    ... new_params)
    >>> print(new_circuit)
                           ┌──────────────────┐   ┌──────────────────┐
    (0, 0): ───X───H───@─────────────ZZ─────────────────────YY────────── ...
                       │             │                      │
    (1, 0): ───X───────X────ZZ───────┼─────────────YY───────┼─────────── ...
                            │        │             │        │
    (2, 0): ───X───H───@────ZZ^(7/13)┼─────────────YY^0.543 ┼─────────── ...
                       │             │                      │
    (3, 0): ───X───────X─────────────ZZ^(7/13)──────────────YY^0.543 ─── ...
                           └──────────────────┘   └──────────────────┘
    Args:
        qubits: Python `lst` of `cirq.GridQubit`s. Supported number of spins
            are [4, 8, 12, 16].
        boundary_condition: Python `str` indicating the boundary condition
            of the chain. Supported boundary conditions are ["closed"].
        data_dir: Optional Python `str` location where to store the data on
            disk. Defaults to `/tmp/.keras`.
    Returns:
        A Python `lst` cirq.Circuit of depth len(qubits) / 2 with resolved
            parameters.
        A Python `lst` of labels, 0, for the critical metallic phase
            (`Delta<=1`) and 1 for the insulating phase (`Delta>1`).
        A Python `lst` of `cirq.PauliSum`s.
        A Python `lst` of `namedtuple` instances containing the following
            fields:
        - `g`: Numpy `float` order parameter.
        - `gs`: Complex `np.ndarray` ground state wave function from
            exact diagonalization.
        - `gs_energy`: Numpy `float` ground state energy from exact
            diagonalization.
        - `res_energy`: Python `float` residual between the circuit energy
            and the exact energy from exact diagonalization.
        - `fidelity`: Python `float` overlap between the circuit state
            and the exact ground state from exact diagonalization.
        - `params`: Dict with Python `str` keys and Numpy`float` values.
            Contains $M \times P $ parameters. Here $M$ is the number of
            parameters per circuit layer and $P$ the circuit depth.
        - `var_circuit`: Variational `cirq.Circuit` quantum circuit with
            unresolved Sympy parameters.
    """

    supported_n = [4, 8, 12, 16]
    supported_bc = ["closed"]
    if any(isinstance(q, list) for q in qubits):
        raise TypeError("qubits must be a one-dimensional list")

    if not all(isinstance(q, cirq.GridQubit) for q in qubits):
        raise TypeError("qubits must be a list of cirq.GridQubit objects.")

    nspins = len(qubits)
    depth = nspins // 2
    if nspins not in supported_n:
        raise ValueError("Supported number of spins are {}, received {}".format(
            supported_n, nspins))

    if boundary_condition not in supported_bc:
        raise ValueError(
            "Supported boundary conditions are {}, received {}".format(
                supported_bc, boundary_condition))

    data_path = _download_spin_data('XXZ_chain', boundary_condition, nspins,
                                    data_dir)

    name_generator = unique_name()

    # 4 * N/2 parameters.
    symbol_names = [next(name_generator) for _ in range(2 * nspins)]
    symbols = [sympy.Symbol(name) for name in symbol_names]

    # Define the circuit.
    circuit = cirq.Circuit(cirq.X.on_each(qubits))
    even_qubits = qubits[::2]
    odd_qubits = qubits[1::2]
    circuit.append(cirq.H(qubits[i]) for i in range(0, nspins, 2))
    circuit.append(cirq.CNOT(q1, q2) for q1, q2 in zip(even_qubits, odd_qubits))

    for d in range(depth):
        for q1, q2 in zip(odd_qubits, even_qubits[1:]):
            circuit.append(cirq.ZZ(q1, q2)**(symbols[d]))
            circuit.append(cirq.YY(q1, q2)**(symbols[d + depth]))
            circuit.append(cirq.XX(q1, q2)**(symbols[d + depth]))
        if boundary_condition == "closed":
            circuit.append(cirq.ZZ(qubits[-1], qubits[0])**(symbols[d]))
            circuit.append(cirq.YY(qubits[-1], qubits[0])**(symbols[d + depth]))
            circuit.append(cirq.XX(qubits[-1], qubits[0])**(symbols[d + depth]))
        for q1, q2 in zip(even_qubits, odd_qubits):
            circuit.append(cirq.ZZ(q1, q2)**(symbols[d + 2 * depth]))
            circuit.append(cirq.YY(q1, q2)**(symbols[d + 3 * depth]))
            circuit.append(cirq.XX(q1, q2)**(symbols[d + 3 * depth]))
    # Initiate lists.
    resolved_circuits = []
    hamiltonians = []
    order_parameters = []
    additional_info = []
    labels = []
    # Load the data and append to the lists.
    for i, directory in enumerate(x for x in os.listdir(data_path)):
        # The folders are named according to the order value data they contain.
        g = float(directory)
        with open(os.path.join(data_path, directory, "stats.txt"), "r") as file:
            lines = file.readlines()
            res_e = float(lines[0].split("=")[1].strip("\n"))
            fidelity = float(lines[2].split("=")[1].strip("\n"))
        order_parameters.append(g)
        params = np.load(os.path.join(data_path, directory, "params.npy")) \
                 / np.pi
        # Parameters are stored as np.float32, but cirq expects np.float64
        # See https://github.com/quantumlib/Cirq/issues/3359
        params = params.astype(np.float)
        additional_info.append(
            SpinSystemInfo(g=g,
                           gs=np.load(
                               os.path.join(data_path, directory,
                                            "groundstate.npy"))[:, 0],
                           gs_energy=np.load(
                               os.path.join(data_path, directory,
                                            "energy.npy"))[0],
                           res_energy=res_e,
                           fidelity=fidelity,
                           params=dict(zip(symbol_names, params.flatten())),
                           var_circuit=circuit))
        # Resolve the circuit parameters.
        resolved_circuit = cirq.resolve_parameters(circuit,
                                                   additional_info[i].params)
        resolved_circuits.append(resolved_circuit)
        # Make the PauliSum.
        paulisum = sum(order_parameters[i] * cirq.Z(q1) * cirq.Z(q2) +
                       cirq.Y(q1) * cirq.Y(q2) + cirq.X(q1) * cirq.X(q2)
                       for q1, q2 in zip(qubits, qubits[1:]))

        if boundary_condition == "closed":
            paulisum += order_parameters[i] * cirq.Z(qubits[0]) * cirq.Z(
                qubits[-1]) + cirq.Y(qubits[0]) * cirq.Y(qubits[-1]) + cirq.X(
                    qubits[0]) * cirq.X(qubits[-1])
        hamiltonians.append(paulisum)

        # Set labels for the different phases.
        if order_parameters[i] <= 1.0:
            labels.append(0)
        else:
            labels.append(1)

    # Make sure that the data is ordered from g=0.2 to g=1.8.
    _, resolved_circuits, labels, hamiltonians, additional_info = zip(*sorted(
        zip(order_parameters, resolved_circuits, labels, hamiltonians,
            additional_info)))

    return resolved_circuits, labels, hamiltonians, additional_info
Example #20
0
def matrix_to_sycamore_operations(
        target_qubits: List[cirq.GridQubit],
        matrix: np.ndarray) -> Tuple[cirq.OP_TREE, List[cirq.GridQubit]]:
    """A method to convert a unitary matrix to a list of Sycamore operations.

    This method will return a list of `cirq.Operation`s using the qubits and (optionally) ancilla
    qubits to implement the unitary matrix `matrix` on the target qubits `qubits`.
    The operations are also supported by `cirq.google.gate_sets.SYC_GATESET`.

    Args:
        target_qubits: list of qubits the returned operations will act on. The qubit order defined by the list
            is assumed to be used by the operations to implement `matrix`.
        matrix: a matrix that is guaranteed to be unitary and of size (2**len(qs), 2**len(qs)).
    Returns:
        A tuple of operations and ancilla qubits allocated.
            Operations: In case the matrix is supported, a list of operations `ops` is returned.
                `ops` acts on `qs` qubits and for which `cirq.unitary(ops)` is equal to `matrix` up
                to certain tolerance. In case the matrix is not supported, it might return NotImplemented to
                reduce the noise in the judge output.
            Ancilla qubits: In case ancilla qubits are allocated a list of ancilla qubits. Otherwise
                an empty list.
        .
    """
    def optimize_circuit(circ):
        ouut = []
        converter = cirq.google.ConvertToSycamoreGates()
        for _ in circ.all_operations():
            ouut.append(converter.convert(_))
        return cirq.google.optimized_for_sycamore(
            cirq.Circuit(ouut), optimizer_type="sycamore"), []

    if np.trace(matrix) == len(matrix):
        return [], []

    if len(matrix) == 2:
        try:
            comparison = matrix == cirq.unitary(cirq.Z)
            if (comparison.all()): return cirq.Z(target_qubits[0]), []

            comparison = matrix == cirq.unitary(cirq.X)
            if (comparison.all()): return cirq.X(target_qubits[0]), []

            comparison = matrix == cirq.unitary(cirq.Y)
            if (comparison.all()): return cirq.Y(target_qubits[0]), []

            comparison = matrix == cirq.unitary(cirq.H)
            if (comparison.all()): return cirq.H.on(target_qubits[0]), []

            comparison = matrix == cirq.unitary(cirq.S)
            if (comparison.all()): return cirq.S(target_qubits[0]), []

            comparison = matrix == cirq.unitary(cirq.T)
            if (comparison.all()): return cirq.T(target_qubits[0]), []

        except [TypeError, ValueError]:
            return NotImplemented, []

    if len(matrix) == 4:
        try:
            comparison = matrix == cirq.unitary(cirq.CNOT)
            if (comparison.all()):
                return optimize_circuit(
                    cirq.Circuit(cirq.CNOT(target_qubits[0],
                                           target_qubits[1])))

            comparison = matrix == cirq.unitary(cirq.XX)
            if (comparison.all()):
                return optimize_circuit(
                    cirq.Circuit(cirq.XX(target_qubits[0], target_qubits[1])))

            comparison = matrix == cirq.unitary(cirq.YY)
            if (comparison.all()):
                return optimize_circuit(
                    cirq.Circuit(cirq.YY(target_qubits[0], target_qubits[1])))

            comparison = matrix == cirq.unitary(cirq.ZZ)
            if (comparison.all()):
                return optimize_circuit(
                    cirq.Circuit(cirq.ZZ(target_qubits[0], target_qubits[1])))

            comparison = matrix == cirq.unitary(cirq.google.SYC)
            if (comparison.all()):
                return optimize_circuit(
                    cirq.Circuit(
                        cirq.google.SYC(target_qubits[0], target_qubits[1])))

        except TypeError:
            return NotImplemented, []

    if len(matrix) == 8:
        try:
            comparison = matrix == cirq.unitary(cirq.CCX)
            if (comparison.all()):
                return optimize_circuit(
                    cirq.Circuit(
                        cirq.CCX(target_qubits[0], target_qubits[1],
                                 target_qubits[2])))

            comparison = matrix == cirq.unitary(cirq.CSWAP)
            if (comparison.all()):
                return optimize_circuit(
                    cirq.Circuit(
                        cirq.CSWAP(target_qubits[0], target_qubits[1],
                                   target_qubits[2])))

            comparison = matrix == cirq.unitary(cirq.CCZ)
            if (comparison.all()):
                return optimize_circuit(
                    cirq.Circuit(
                        cirq.CCZ(target_qubits[0], target_qubits[1],
                                 target_qubits[2])))

            comparison = matrix == cirq.unitary(
                cirq.ControlledGate(cirq.ISWAP**0.5, 1))
            if (comparison.all()):
                return cirq.ControlledGate(cirq.ISWAP**0.5, 1)

        except TypeError:
            return NotImplemented, []

    if len(matrix) == 16:
        try:
            comparison = matrix == cirq.unitary(
                cirq.ControlledGate(cirq.ISWAP**0.5, 2))
            if (comparison.all()):
                return optimize_circuit(
                    cirq.Circuit(
                        cirq.ControlledGate(sub_gate=cirq.ISWAP**0.5).on(
                            target_qubits[2], target_qubits[0],
                            target_qubits[1])))

        except TypeError:
            return NotImplemented, []

    return NotImplemented, []
        (cirq.ControlledGate(cirq.ControlledGate(
            cirq.CCZ))(*cirq.LineQubit.range(5)), True),
        (GateUsingWorkspaceForApplyUnitary()(cirq.NamedQubit('q1')), True),
        (GateAllocatingNewSpaceForResult()(cirq.NamedQubit('q1')), True),
        (
            cirq.MatrixGate(np.kron(*(cirq.unitary(cirq.H), ) * 2),
                            qid_shape=(4, )).on(cirq.NamedQid("q", 4)),
            False,
        ),
        (
            cirq.MatrixGate(cirq.testing.random_unitary(
                4, random_state=1234)).on(cirq.NamedQubit('q1'),
                                          cirq.NamedQubit('q2')),
            False,
        ),
        (cirq.XX(cirq.NamedQubit('q1'), cirq.NamedQubit('q2'))**
         sympy.Symbol("s"), True),
        (cirq.DiagonalGate(sympy.symbols("s1, s2")).on(
            cirq.NamedQubit("q")), False),
    ],
)
def test_controlled_operation_is_consistent(gate: cirq.GateOperation,
                                            should_decompose_to_target: bool):
    cb = cirq.NamedQubit('ctr')
    cgate = cirq.ControlledOperation([cb], gate)
    cirq.testing.assert_implements_consistent_protocols(cgate)
    cirq.testing.assert_decompose_ends_at_default_gateset(
        cgate, ignore_known_gates=not should_decompose_to_target)

    cgate = cirq.ControlledOperation([cb], gate, control_values=[0])
    cirq.testing.assert_implements_consistent_protocols(cgate)
Example #22
0
def test_known_two_qubit_op_decomposition(op, theta_range):
    for theta_val in theta_range:
        op_resolved = cirq.resolve_parameters(op, {'theta': theta_val}, recursive=False)
        known_2q_circuit = cirq.Circuit(cg.known_2q_op_to_sycamore_operations(op_resolved))
        matrix_2q_circuit = cirq.Circuit(
            cg.two_qubit_matrix_to_sycamore_operations(q[0], q[1], cirq.unitary(op_resolved))
        )
        assert_implements(known_2q_circuit, op_resolved)
        assert_implements(matrix_2q_circuit, op_resolved)


@pytest.mark.parametrize(
    'op',
    [
        cirq.CircuitOperation(cirq.FrozenCircuit(cirq.SWAP(*q), cirq.ZZ(*q), cirq.SWAP(*q))),
        cirq.X(q[0]),
        cirq.XX(*q) ** theta,
        cirq.FSimGate(0.25, 0.85).on(*q),
        cirq.XX(*q),
        cirq.YY(*q),
        *[cirq.testing.random_unitary(4, random_state=1234) for _ in range(10)],
    ],
)
def test_unknown_two_qubit_op_decomposition(op):
    assert cg.known_2q_op_to_sycamore_operations(op) is None
    if cirq.has_unitary(op) and cirq.num_qubits(op) == 2:
        matrix_2q_circuit = cirq.Circuit(
            cg.two_qubit_matrix_to_sycamore_operations(q[0], q[1], cirq.unitary(op))
        )
        assert_implements(matrix_2q_circuit, op)
Example #23
0
def _get_circuit_proto_pairs():
    q0 = cirq.GridQubit(0, 0)
    q1 = cirq.GridQubit(0, 1)

    pairs = [
        # HPOW and aliases.
        (cirq.Circuit(cirq.HPowGate(exponent=0.3)(q0)),
         _build_gate_proto("HP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.HPowGate(exponent=sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("HP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.HPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("HP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.H(q0)),
         _build_gate_proto("HP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0'])),

        # XPOW and aliases.
        (cirq.Circuit(cirq.XPowGate(exponent=0.3)(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.XPowGate(exponent=sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.XPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.X(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0'])),

        # YPOW and aliases
        (cirq.Circuit(cirq.YPowGate(exponent=0.3)(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.YPowGate(exponent=sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.YPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.Y(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0'])),

        # ZPOW and aliases.
        (cirq.Circuit(cirq.ZPowGate(exponent=0.3)(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.ZPowGate(exponent=sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.ZPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.Z(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0'])),

        # XXPow and aliases
        (cirq.Circuit(cirq.XXPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("XXP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.XXPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("XXP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.XXPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("XXP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.XX(q0, q1)),
         _build_gate_proto("XXP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # YYPow and aliases
        (cirq.Circuit(cirq.YYPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("YYP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.YYPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("YYP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.YYPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("YYP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.YY(q0, q1)),
         _build_gate_proto("YYP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # ZZPow and aliases
        (cirq.Circuit(cirq.ZZPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("ZZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.ZZPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("ZZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.ZZPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("ZZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.ZZ(q0, q1)),
         _build_gate_proto("ZZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # CZPow and aliases
        (cirq.Circuit(cirq.CZPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("CZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.CZPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("CZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.CZPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("CZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.CZ(q0, q1)),
         _build_gate_proto("CZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # CNOTPow and aliases
        (cirq.Circuit(cirq.CNotPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("CNP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.CNotPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("CNP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.CNotPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("CNP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.CNOT(q0, q1)),
         _build_gate_proto("CNP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # SWAPPow and aliases
        (cirq.Circuit(cirq.SwapPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("SP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.SwapPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("SP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.SwapPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("SP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.SWAP(q0, q1)),
         _build_gate_proto("SP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # ISWAPPow and aliases
        (cirq.Circuit(cirq.ISwapPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("ISP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.ISwapPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("ISP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.ISwapPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("ISP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.ISWAP(q0, q1)),
         _build_gate_proto("ISP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # PhasedXPow and aliases
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=0.9,
                                exponent=0.3,
                                global_shift=0.2)(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], [0.9, 1.0, 0.3, 1.0, 0.2], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=sympy.Symbol('alpha'),
                                exponent=0.3)(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], ['alpha', 1.0, 0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=3.1 * sympy.Symbol('alpha'),
                                exponent=0.3)(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], ['alpha', 3.1, 0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=0.9,
                                exponent=sympy.Symbol('beta'))(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], [0.9, 1.0, 'beta', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=0.9,
                                exponent=5.1 * sympy.Symbol('beta'))(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], [0.9, 1.0, 'beta', 5.1, 0.0], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=3.1 * sympy.Symbol('alpha'),
                                exponent=5.1 * sympy.Symbol('beta'))(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], ['alpha', 3.1, 'beta', 5.1, 0.0], ['0_0'])),

        # RX, RY, RZ with symbolization is tested in special cases as the
        # string comparison of the float converted sympy.pi does not happen
        # smoothly. See: test_serialize_deserialize_special_case_one_qubit
        (cirq.Circuit(cirq.rx(np.pi)(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, -0.5], ['0_0'])),
        (cirq.Circuit(cirq.ry(np.pi)(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, -0.5], ['0_0'])),
        (cirq.Circuit(cirq.rz(np.pi)(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, -0.5], ['0_0'])),

        # Identity
        (cirq.Circuit(cirq.I(q0)),
         _build_gate_proto("I", ['unused'], [True], ['0_0'])),

        # FSimGate
        (cirq.Circuit(cirq.FSimGate(theta=0.1, phi=0.2)(q0, q1)),
         _build_gate_proto("FSIM",
                           ['theta', 'theta_scalar', 'phi', 'phi_scalar'],
                           [0.1, 1.0, 0.2, 1.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.FSimGate(theta=2.1 * sympy.Symbol("alpha"),
                          phi=1.3 * sympy.Symbol("beta"))(q0, q1)),
         _build_gate_proto("FSIM",
                           ['theta', 'theta_scalar', 'phi', 'phi_scalar'],
                           ['alpha', 2.1, 'beta', 1.3], ['0_0', '0_1'])),
    ]

    return pairs
print(qc)
ndtotext_print(qc.unitary())
# exit()

# class ISWAP(cirq.ISwapPowGate):
#     def __init__(self, target):
#         super(ISWAP, self).__init__()

qubits = cirq.GridQubit.rect(2, 2)
C1, C2, T1, T2 = qubits
qc = cirq.Circuit()

# qc = B2A_basis(qc, C1, C2)  # Change output matrix to B-basis (easier to check for mistakes)
# qc = B2A_basis(qc, T1, T2)
# --- Very first one ---
qc.append(cirq.XX(T1, T2))
qc.append(cirq.ZPowGate().on(T2).controlled_by(C1, C2, T1)**(t/π)) # NOTICE: Cancel out π
qc.append(cirq.XX(T1, T2))

qc.append(cirq.XX(C1, C2))
qc.append(cirq.ZPowGate().on(C1).controlled_by(C2, T1, T2)**(-t/π))
qc.append(cirq.XX(C1, C2))
# --- Very first one end ---
# --- Second two ---
A2B_basis(qc, C1, C2)  # This is to do the oper |11> <-> |+>, |00> <-> |->
A2B_basis(qc, T1, T2)
X_on_all(qc, qubits)
B2A_basis(qc, C1, C2)
B2A_basis(qc, T1, T2)
# CCiSWAP(t) then CCiSWAP(-t)
qc.append(cirq.ISwapPowGate().on(T1, T2).controlled_by(C1, C2)**(-2*t/π))  # NOTICE: Swapped signs and cancel out π/2


# A simple Quantum circuit using cirq

input_qubits = cirq.GridQubit.rect(1, 2)  # 1x2 grid.
model_circuit = cirq.Circuit()

alpha1 = sympy.Symbol('a1')
model_circuit.append(cirq.rx(alpha1)(input_qubits[0]))

alpha2 = sympy.Symbol('a2')
model_circuit.append(cirq.rx(alpha2)(input_qubits[1]))

alpha3 = sympy.Symbol('a3')
model_circuit.append(cirq.XX(input_qubits[1],input_qubits[0])**alpha3)

alpha4 = sympy.Symbol('a4')
model_circuit.append(cirq.H(input_qubits[0])**alpha4)

alpha5 = sympy.Symbol('a5')
model_circuit.append(cirq.H(input_qubits[1])**alpha5)

model_readout = [cirq.X(input_qubits[0]),cirq.X(input_qubits[1])]


print(model_circuit)


DataList = ["HLine","VLine", "Triangle", "Circle"]
methodList = ["Ground_Truth","Quantum", "Hybrid", "Single_Dense"]
Example #26
0
def test_cirq_to_circuit() -> None:
    q0 = cq.LineQubit(0)
    q1 = cq.LineQubit(1)
    q2 = cq.LineQubit(2)

    gate = cirq_to_circuit(cq.Circuit(cq.X(q0)))[0]
    assert isinstance(gate, qf.X)
    assert gate.qubits == (0, )

    gate = cirq_to_circuit(cq.Circuit(cq.X(q1)**0.4))[0]
    assert isinstance(gate, qf.XPow)
    assert gate.qubits == (1, )

    gate = cirq_to_circuit(cq.Circuit(cq.CZ(q1, q0)))[0]
    assert isinstance(gate, qf.CZ)
    assert gate.qubits == (1, 0)

    gate = cirq_to_circuit(cq.Circuit(cq.CZ(q1, q0)**0.3))[0]
    assert isinstance(gate, qf.CZPow)
    assert gate.qubits == (1, 0)
    assert gate.param("t") == 0.3

    gate = cirq_to_circuit(cq.Circuit(cq.CNOT(q0, q1)))[0]
    assert isinstance(gate, qf.CNot)
    assert gate.qubits == (0, 1)

    gate = cirq_to_circuit(cq.Circuit(cq.CNOT(q0, q1)**0.25))[0]
    assert isinstance(gate, qf.CNotPow)
    assert gate.qubits == (0, 1)
    assert gate.param("t") == 0.25

    gate = cirq_to_circuit(cq.Circuit(cq.SWAP(q0, q1)))[0]
    assert isinstance(gate, qf.Swap)

    gate = cirq_to_circuit(cq.Circuit(cq.ISWAP(q0, q1)))[0]
    assert isinstance(gate, qf.ISwap)

    gate = cirq_to_circuit(cq.Circuit(cq.CSWAP(q0, q1, q2)))[0]
    assert isinstance(gate, qf.CSwap)

    gate = cirq_to_circuit(cq.Circuit(cq.CCX(q0, q1, q2)))[0]
    assert isinstance(gate, qf.CCNot)

    gate = cirq_to_circuit(cq.Circuit(cq.CCZ(q0, q1, q2)))[0]
    assert isinstance(gate, qf.CCZ)

    gate = cirq_to_circuit(cq.Circuit(cq.I(q0)))[0]
    assert isinstance(gate, qf.I)

    gate = cirq_to_circuit(cq.Circuit(cq.XX(q0, q2)))[0]
    assert isinstance(gate, qf.XX)
    assert gate.param("t") == 1.0

    gate = cirq_to_circuit(cq.Circuit(cq.XX(q0, q2)**0.3))[0]
    assert isinstance(gate, qf.XX)
    assert gate.param("t") == 0.3

    gate = cirq_to_circuit(cq.Circuit(cq.YY(q0, q2)))[0]
    assert isinstance(gate, qf.YY)
    assert gate.param("t") == 1.0

    gate = cirq_to_circuit(cq.Circuit(cq.YY(q0, q2)**0.3))[0]
    assert isinstance(gate, qf.YY)
    assert gate.param("t") == 0.3

    gate = cirq_to_circuit(cq.Circuit(cq.ZZ(q0, q2)))[0]
    assert isinstance(gate, qf.ZZ)
    assert gate.param("t") == 1.0

    gate = cirq_to_circuit(cq.Circuit(cq.ZZ(q0, q2)**0.3))[0]
    assert isinstance(gate, qf.ZZ)
    assert gate.param("t") == 0.3

    # Check that cirq's parity gates are the same as QF's XX, YY, ZZ
    # up to parity
    U = (cq.XX(q0, q2)**0.8)._unitary_()
    gate0 = qf.Unitary(U, [0, 1])
    assert qf.gates_close(gate0, qf.XX(0.8, 0, 1))

    U = (cq.YY(q0, q2)**0.3)._unitary_()
    gate0 = qf.Unitary(U, [0, 1])
    assert qf.gates_close(gate0, qf.YY(0.3, 0, 1))

    U = (cq.ZZ(q0, q2)**0.2)._unitary_()
    gate0 = qf.Unitary(U, [0, 1])
    assert qf.gates_close(gate0, qf.ZZ(0.2, 0, 1))
Example #27
0
    for i, gate in enumerate(gates):
        a += gate
        b -= gate

        prefix = gates[:i + 1]
        expected_a = cirq.LinearCombinationOfGates(collections.Counter(prefix))
        expected_b = -expected_a

        assert_linear_combinations_are_equal(a, expected_a)
        assert_linear_combinations_are_equal(b, expected_b)


@pytest.mark.parametrize('op', (
    cirq.X(q0),
    cirq.Y(q1),
    cirq.XX(q0, q1),
    cirq.CZ(q0, q1),
    cirq.FREDKIN(q0, q1, q2),
    cirq.ControlledOperation((q0, q1), cirq.H(q2)),
    cirq.ParallelGateOperation(cirq.X, (q0, q1, q2)),
    cirq.PauliString({
        q0: cirq.X,
        q1: cirq.Y,
        q2: cirq.Z
    }),
))
def test_empty_linear_combination_of_operations_accepts_all_operations(op):
    combination = cirq.LinearCombinationOfOperations({})
    combination[op] = -0.5j
    assert len(combination) == 1
Example #28
0
import os
import string
import qdata.parser as parser
import qdata.ir as ir
import math
import sys

sys.setrecursionlimit(2000)
# Define mappings for operators from a .qasm name to a cirq operator.
gate_operators = {
    'h': lambda qubits: cirq.H(*qubits),
    'x': lambda qubits: cirq.X(*qubits),
    'cx': lambda qubits: cirq.CNOT(*qubits),
    'zz': lambda qubits: cirq.ZZ(*qubits),
    'yy': lambda qubits: cirq.YY(*qubits),
    'xx': lambda qubits: cirq.XX(*qubits),
}
# Define mappings for operators from a .qasm name to a cirq operator.
parsed_operators = {
    'x': lambda qubits: cirq.X(*qubits),
    'y': lambda qubits: cirq.Y(*qubits),
    'z': lambda qubits: cirq.Z(*qubits),
}


def operator_parser_paulisum(operator):
    """
    Return a function that implements the operator defined in the .qasm file.

    Args:
        operator:
Example #29
0
    def test_cirq_qsim_all_supported_gates(self):
        q0 = cirq.GridQubit(1, 1)
        q1 = cirq.GridQubit(1, 0)
        q2 = cirq.GridQubit(0, 1)
        q3 = cirq.GridQubit(0, 0)

        circuit = cirq.Circuit(
            cirq.Moment([
                cirq.H(q0),
                cirq.H(q1),
                cirq.H(q2),
                cirq.H(q3),
            ]),
            cirq.Moment([
                cirq.T(q0),
                cirq.T(q1),
                cirq.T(q2),
                cirq.T(q3),
            ]),
            cirq.Moment([
                cirq.CZPowGate(exponent=0.7, global_shift=0.2)(q0, q1),
                cirq.CXPowGate(exponent=1.2, global_shift=0.4)(q2, q3),
            ]),
            cirq.Moment([
                cirq.XPowGate(exponent=0.3, global_shift=1.1)(q0),
                cirq.YPowGate(exponent=0.4, global_shift=1)(q1),
                cirq.ZPowGate(exponent=0.5, global_shift=0.9)(q2),
                cirq.HPowGate(exponent=0.6, global_shift=0.8)(q3),
            ]),
            cirq.Moment([
                cirq.CX(q0, q2),
                cirq.CZ(q1, q3),
            ]),
            cirq.Moment([
                cirq.X(q0),
                cirq.Y(q1),
                cirq.Z(q2),
                cirq.S(q3),
            ]),
            cirq.Moment([
                cirq.XXPowGate(exponent=0.4, global_shift=0.7)(q0, q1),
                cirq.YYPowGate(exponent=0.8, global_shift=0.5)(q2, q3),
            ]),
            cirq.Moment([cirq.I(q0),
                         cirq.I(q1),
                         cirq.IdentityGate(2)(q2, q3)]),
            cirq.Moment([
                cirq.rx(0.7)(q0),
                cirq.ry(0.2)(q1),
                cirq.rz(0.4)(q2),
                cirq.PhasedXPowGate(phase_exponent=0.8,
                                    exponent=0.6,
                                    global_shift=0.3)(q3),
            ]),
            cirq.Moment([
                cirq.ZZPowGate(exponent=0.3, global_shift=1.3)(q0, q2),
                cirq.ISwapPowGate(exponent=0.6, global_shift=1.2)(q1, q3),
            ]),
            cirq.Moment([
                cirq.XPowGate(exponent=0.1, global_shift=0.9)(q0),
                cirq.YPowGate(exponent=0.2, global_shift=1)(q1),
                cirq.ZPowGate(exponent=0.3, global_shift=1.1)(q2),
                cirq.HPowGate(exponent=0.4, global_shift=1.2)(q3),
            ]),
            cirq.Moment([
                cirq.SwapPowGate(exponent=0.2, global_shift=0.9)(q0, q1),
                cirq.PhasedISwapPowGate(phase_exponent=0.8, exponent=0.6)(q2,
                                                                          q3),
            ]),
            cirq.Moment([
                cirq.PhasedXZGate(x_exponent=0.2,
                                  z_exponent=0.3,
                                  axis_phase_exponent=1.4)(q0),
                cirq.T(q1),
                cirq.H(q2),
                cirq.S(q3),
            ]),
            cirq.Moment([
                cirq.SWAP(q0, q2),
                cirq.XX(q1, q3),
            ]),
            cirq.Moment([
                cirq.rx(0.8)(q0),
                cirq.ry(0.9)(q1),
                cirq.rz(1.2)(q2),
                cirq.T(q3),
            ]),
            cirq.Moment([
                cirq.YY(q0, q1),
                cirq.ISWAP(q2, q3),
            ]),
            cirq.Moment([
                cirq.T(q0),
                cirq.Z(q1),
                cirq.Y(q2),
                cirq.X(q3),
            ]),
            cirq.Moment([
                cirq.FSimGate(0.3, 1.7)(q0, q2),
                cirq.ZZ(q1, q3),
            ]),
            cirq.Moment([
                cirq.ry(1.3)(q0),
                cirq.rz(0.4)(q1),
                cirq.rx(0.7)(q2),
                cirq.S(q3),
            ]),
            cirq.Moment([
                cirq.MatrixGate(
                    np.array([[0, -0.5 - 0.5j, -0.5 - 0.5j, 0],
                              [0.5 - 0.5j, 0, 0, -0.5 + 0.5j],
                              [0.5 - 0.5j, 0, 0, 0.5 - 0.5j],
                              [0, -0.5 - 0.5j, 0.5 + 0.5j, 0]]))(q0, q1),
                cirq.MatrixGate(
                    np.array([[0.5 - 0.5j, 0, 0, -0.5 + 0.5j],
                              [0, 0.5 - 0.5j, -0.5 + 0.5j, 0],
                              [0, -0.5 + 0.5j, -0.5 + 0.5j, 0],
                              [0.5 - 0.5j, 0, 0, 0.5 - 0.5j]]))(q2, q3),
            ]),
            cirq.Moment([
                cirq.MatrixGate(np.array([[1, 0], [0, 1j]]))(q0),
                cirq.MatrixGate(np.array([[0, -1j], [1j, 0]]))(q1),
                cirq.MatrixGate(np.array([[0, 1], [1, 0]]))(q2),
                cirq.MatrixGate(np.array([[1, 0], [0, -1]]))(q3),
            ]),
            cirq.Moment([
                cirq.riswap(0.7)(q0, q1),
                cirq.givens(1.2)(q2, q3),
            ]),
            cirq.Moment([
                cirq.H(q0),
                cirq.H(q1),
                cirq.H(q2),
                cirq.H(q3),
            ]),
        )

        simulator = cirq.Simulator()
        cirq_result = simulator.simulate(circuit)

        qsim_simulator = qsimcirq.QSimSimulator()
        qsim_result = qsim_simulator.simulate(circuit)

        assert cirq.linalg.allclose_up_to_global_phase(
            qsim_result.state_vector(), cirq_result.state_vector())
Example #30
0
    def to_cirq(self, input_cirq_qubits=None):
        """Convert to a cirq gate.

        Args:
            input_cirq_qubits: list[cirq.LineQubit]
                (optional) a list of cirq Qubits that the gate can act on. If not provided
                the function will generate new cirq.LineQubit objects.
        Returns:
        A cirq Circuit object that corresponds to the specification of the quantum gate.
            In the special case the gate itself was natively generated from cirq, the function
            will faithfully reproduce the original GateOperation object, taking into account
            whether the gate acts on GridQubit objects or LineQubit objects.
            In the other cases the resulting cirq gate simply assumes that the qubits are
            LineQubit objects.
        """

        if self.name not in ALL_GATES:
            sys.exit('Gate {} currently not supported.'.format(self.name))

        q_inds = []
        q_inds.append(self.qubits[0].index)
        if len(self.qubits) >= 2:
            q_inds.append(self.qubits[1].index)
        if len(self.qubits) >= 3:
            q_inds.append(self.qubits[2].index)

        cirq_qubits = []
        if input_cirq_qubits == None:
            for q in self.qubits:
                if q.info['label'] == 'cirq':
                    qkey = q.info['QubitKey']
                    if q.info['QubitType'] == 'GridQubit':
                        cirq_qubits.append(cirq.GridQubit(qkey[0], qkey[1]))
                    if q.info['QubitType'] == 'LineQubit':
                        cirq_qubits.append(cirq.LineQubit(qkey))
                else:
                    cirq_qubits.append(cirq.LineQubit(q.index))
        else:
            cirq_qubits = [
                input_cirq_qubits[x] for x in [q.index for q in self.qubits]
            ]

        if len(self.params) > 0:
            params = self.params

        # single-qubit gates
        if self.name == 'X':  # Pauli X
            return cirq.X(cirq_qubits[0])
        if self.name == 'Y':  # Pauli Y
            return cirq.Y(cirq_qubits[0])
        if self.name == 'Z':  # Pauli Z
            return cirq.Z(cirq_qubits[0])
        if self.name == 'H':  # Hadamard
            return cirq.H(cirq_qubits[0])
        if self.name == 'S':  # S gate
            return cirq.S(cirq_qubits[0])
        if self.name == 'T':  # T gate
            return cirq.T(cirq_qubits[0])
        if self.name == 'Rx':  # Single-qubit X rotation
            return cirq.Rx(params[0])(cirq_qubits[0])
        if self.name == 'Ry':  # Single-qubit Y rotation
            return cirq.Ry(params[0])(cirq_qubits[0])
        if self.name == 'Rz':  # Single-qubit Z rotation
            return cirq.Rz(params[0])(cirq_qubits[0])
        if self.name == 'PHASE':  # Phase gate
            return cirq.Z(cirq_qubits[0])**(params[0] / pi)
        if self.name == 'ZXZ':  # PhasedXPowGate gate
            g = cirq.PhasedXPowGate(phase_exponent=params[0] / pi,
                                    exponent=params[1] / pi)
            return g(cirq_qubits[0])
        if self.name == 'RH':  # HPowGate
            g = cirq.H**(params[0] / pi)
            return g(cirq_qubits[0])
        if self.name == 'Da':  # Damping alpha gate
            g = DampingAlpha(params[0])
            return g(cirq_qubits[0])
        if self.name == 'Db':  # Damping beta gate
            g = DampingBeta(params[0])
            return g(cirq_qubits[0])

        # two-qubit gates
        if self.name == 'CNOT':
            return cirq.CNOT(cirq_qubits[0], cirq_qubits[1])
        if self.name == 'CZ':
            return cirq.CZ(cirq_qubits[0], cirq_qubits[1])
        if self.name == 'CPHASE':
            return cirq.CZPowGate(exponent=params[0] / pi)(cirq_qubits[0],
                                                           cirq_qubits[1])
        if self.name == 'SWAP':
            return cirq.SWAP(cirq_qubits[0], cirq_qubits[1])
        if self.name == 'XX':
            return cirq.XX(cirq_qubits[0],
                           cirq_qubits[1])**(params[0] * 2 / pi)
        if self.name == 'YY':
            return cirq.YY(cirq_qubits[0],
                           cirq_qubits[1])**(params[0] * 2 / pi)
        if self.name == 'ZZ':
            return cirq.ZZ(cirq_qubits[0],
                           cirq_qubits[1])**(params[0] * 2 / pi)