def test_symbolic_c_rz(self):
        gate = CRz(sympy.Symbol("θ"))

        qubits = cirq.LineQubit.range(2)
        control, target = qubits
        circuit_decomposed = cirq.Circuit()

        circuit_decomposed.append(
            cirq.decompose(gate.on(control, target),
                           keep=is_a_basic_operation))

        # print("Decomposed circuit of Rz(θ): \n{}".format(circuit_decomposed))
        self.assertEqual(
            str(circuit_decomposed),
            "0: ───────────────@────────────────@───\n"
            "                  │                │\n"
            "1: ───Rz(0.5*θ)───X───Rz(-0.5*θ)───X───")
def test_decomposition_with_parameterization(n):
    angles = sympy.symbols([f'x_{i}' for i in range(2**n)])
    exponent = sympy.Symbol('e')
    diagonal_gate = cirq.DiagonalGate(angles) ** exponent
    parameterized_op = diagonal_gate(*cirq.LineQubit.range(n))
    decomposed_circuit = cirq.Circuit(cirq.decompose(parameterized_op))
    for exponent_value in [-0.5, 0.5, 1]:
        for i in range(len(_candidate_angles) - 2**n + 1):
            resolver = {exponent: exponent_value}
            resolver.update(
                {angles[j]: x_j for j, x_j in enumerate(_candidate_angles[i : i + 2**n])}
            )
            resolved_op = cirq.resolve_parameters(parameterized_op, resolver)
            resolved_circuit = cirq.resolve_parameters(decomposed_circuit, resolver)
            np.testing.assert_allclose(
                cirq.unitary(resolved_op), cirq.unitary(resolved_circuit), atol=1e-8
            )
def test_parameterize(resolve_fn, global_shift):
    parameterized_gate = cirq.PhasedXPowGate(
        exponent=sympy.Symbol('a'), phase_exponent=sympy.Symbol('b'), global_shift=global_shift
    )
    assert cirq.pow(parameterized_gate, 5) == cirq.PhasedXPowGate(
        exponent=sympy.Symbol('a') * 5, phase_exponent=sympy.Symbol('b'), global_shift=global_shift
    )
    assert cirq.unitary(parameterized_gate, default=None) is None
    assert cirq.is_parameterized(parameterized_gate)
    q = cirq.NamedQubit("q")
    parameterized_decomposed_circuit = cirq.Circuit(cirq.decompose(parameterized_gate(q)))
    for resolver in cirq.Linspace('a', 0, 2, 10) * cirq.Linspace('b', 0, 2, 10):
        resolved_gate = resolve_fn(parameterized_gate, resolver)
        assert resolved_gate == cirq.PhasedXPowGate(
            exponent=resolver.value_of('a'),
            phase_exponent=resolver.value_of('b'),
            global_shift=global_shift,
        )
        np.testing.assert_allclose(
            cirq.unitary(resolved_gate(q)),
            cirq.unitary(resolve_fn(parameterized_decomposed_circuit, resolver)),
            atol=1e-8,
        )

    unparameterized_gate = cirq.PhasedXPowGate(
        exponent=0.1, phase_exponent=0.2, global_shift=global_shift
    )
    assert not cirq.is_parameterized(unparameterized_gate)
    assert cirq.is_parameterized(unparameterized_gate ** sympy.Symbol('a'))
    assert cirq.is_parameterized(unparameterized_gate ** (sympy.Symbol('a') + 1))

    resolver = {'a': 0.5j}
    with pytest.raises(ValueError, match='complex value'):
        resolve_fn(
            cirq.PhasedXPowGate(
                exponent=sympy.Symbol('a'), phase_exponent=0.2, global_shift=global_shift
            ),
            resolver,
        )
    with pytest.raises(ValueError, match='complex value'):
        resolve_fn(
            cirq.PhasedXPowGate(
                exponent=0.1, phase_exponent=sympy.Symbol('a'), global_shift=global_shift
            ),
            resolver,
        )
Exemple #4
0
def test_arc_probs(input_prob_q0, input_prob_q1, expected_prob_q2, decompose):
    q0, q1, q2 = cirq.LineQubit.range(3)
    gate = ccb.BayesianNetworkGate(
        [('q0', input_prob_q0), ('q1', input_prob_q1), ('q2', None)],
        [('q2', ('q0', 'q1'), [0.1, 0.2, 0.3, 0.4])],
    )
    if decompose:
        circuit = cirq.Circuit(cirq.decompose(gate.on(q0, q1, q2)))
    else:
        circuit = cirq.Circuit(gate.on(q0, q1, q2))

    result = cirq.Simulator().simulate(circuit, qubit_order=[q0, q1, q2], initial_state=0)

    probs = [abs(x) ** 2 for x in result.state_vector(copy=True)]

    actual_prob_q2_is_one = sum(probs[1::2])

    np.testing.assert_almost_equal(actual_prob_q2_is_one, expected_prob_q2, decimal=4)
Exemple #5
0
def test_multi_clifford_decompose_by_unitary():
    # Construct a random clifford gate:
    n, num_ops = 5, 20  # because we relied on unitary cannot test large-scale qubits
    gate_candidate = [cirq.X, cirq.Y, cirq.Z, cirq.H, cirq.S, cirq.CNOT, cirq.CZ]
    for _ in range(10):
        qubits = cirq.LineQubit.range(n)
        ops = []
        for _ in range(num_ops):
            g = np.random.randint(len(gate_candidate))
            indices = (np.random.randint(n),) if g < 5 else np.random.choice(n, 2, replace=False)
            ops.append(gate_candidate[g].on(*[qubits[i] for i in indices]))
        gate = cirq.CliffordGate.from_op_list(ops, qubits)
        decomposed_ops = cirq.decompose(gate.on(*qubits))
        circ = cirq.Circuit(decomposed_ops)
        circ.append(cirq.I.on_each(qubits))  # make sure the dimension aligned.
        cirq.testing.assert_allclose_up_to_global_phase(
            cirq.unitary(gate), cirq.unitary(circ), atol=1e-7
        )
Exemple #6
0
    def objective_function_monte_carlo_opt_env(self, params):
        self.u_params, self.v_params = (params[:self.n_state_params],
                                        params[self.n_state_params:])
        U = self.state_ansatz(self.D, u_params)
        V = self.env_ansatz(self.D, v_params)

        qbs = cirq.LineQubit.range(int(2 * np.log2(self.D) + 2))

        C = cirq.Circuit().from_ops(cirq.decompose(State(U, V, 2)(*qbs)))

        noise = cirq.ConstantQubitNoiseModel(
            cirq.depolarize(self.depolarizing_prob))

        noisy_circuit = cirq.Circuit()
        for moment in C:
            noisy_circuit.append(noise.noisy_moment(moment, qbs))

        return self.H.measure_energy(noisy_circuit, system_qubits,
                                     self.n_samples)
Exemple #7
0
def act_gate_batch_on_qubits(
    gate_batch: GateBatch,
    qubits: typing.Iterable[cirq.Qid],
    decompose_in_elementary_ops: bool = True,
    as_circuits: bool = True
) -> typing.Union[GateOperationBatch, CircuitBatch]:
    """
    Act a batch of gates on `qubits`.

    :param gate_batch:
        A batch of gates, whose shape is (batch_size, num_qubits). Any term
        in the batch contains `num_qubits` 1-qubit gates, which will be acted
        on each qubit in `qubits` in order.
    :param qubits:
        The qubits which the gates will act on.
    :param decompose_in_elementary_ops:
        Tells whether the gates in `gate_batch` should be decomposed into
        elementary operations.
    :param as_circuits:
        Tells whether the applied operations will be constructed as circuits.
        If False, the function will return a batch of series of operations;
        if True,  the function will return a batch of circuits.
    :return:
        The result of `gate_batch` being acted on `qubits`. See `as_circuits`
        for more details.

    """
    op_batch = []
    for gate_series in gate_batch:
        op = []
        for gate, q in zip(gate_series, qubits):
            if decompose_in_elementary_ops:
                op.append(cirq.decompose(gate(q)))
            else:
                op.append(gate(q))

        if as_circuits:
            op_batch.append(cirq.Circuit(op))
        else:
            op_batch.append(op)

    return op_batch
Exemple #8
0
def test_scope_extern_mismatch():
    q = cirq.LineQubit(0)
    inner = cirq.Circuit(
        cirq.measure(q, key='a'),
        cirq.X(q).with_classical_controls('b'),
    )
    middle = cirq.Circuit(
        cirq.measure(q, key=cirq.MeasurementKey('b', ('0', ))),
        cirq.CircuitOperation(inner.freeze(), repetitions=2),
    )
    outer_subcircuit = cirq.CircuitOperation(middle.freeze(), repetitions=2)
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    internal_control_keys = [
        str(condition) for op in circuit.all_operations()
        for condition in cirq.control_keys(op)
    ]
    assert internal_control_keys == ['b', 'b', 'b', 'b']
    assert cirq.control_keys(outer_subcircuit) == {cirq.MeasurementKey('b')}
    assert cirq.control_keys(circuit) == {cirq.MeasurementKey('b')}
    cirq.testing.assert_has_diagram(
        cirq.Circuit(outer_subcircuit),
        """
      [                  [ 0: ───M('a')───X─── ]             ]
      [ 0: ───M('0:b')───[                ║    ]──────────── ]
0: ───[                  [ b: ════════════^═══ ](loops=2)    ]────────────
      [                  ║                                   ]
      [ b: ══════════════╩══════════════════════════════════ ](loops=2)
      ║
b: ═══╩═══════════════════════════════════════════════════════════════════
""",
        use_unicode_characters=True,
    )
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ───M('0:0:b')───M('0:0:a')───X───M('0:1:a')───X───M('1:0:b')───M('1:0:a')───X───M('1:1:a')───X───
                                ║                ║                             ║                ║
b: ═════════════════════════════^════════════════^═════════════════════════════^════════════════^═══
""",
        use_unicode_characters=True,
    )
    assert circuit == cirq.Circuit(cirq.decompose(outer_subcircuit))
def test_tag_propagation():
    # Tags are not propagated from the CircuitOperation to its components.
    # TODO: support tag propagation for better serialization.
    a, b, c = cirq.LineQubit.range(3)
    circuit = cirq.FrozenCircuit(
        cirq.X(a),
        cirq.H(b),
        cirq.H(c),
        cirq.CZ(a, c),
    )
    op = cirq.CircuitOperation(circuit)
    test_tag = 'test_tag'
    op = op.with_tags(test_tag)

    assert test_tag in op.tags

    # TODO: Tags must propagate during decomposition.
    sub_ops = cirq.decompose(op)
    for op in sub_ops:
        assert test_tag not in op.tags
    def multiply(self):
        circuit = cirq.Circuit()
        #for gate-counting purposes
        toffcount = 0
        # step 1: toffolis
        for i in range(0, self.size):
            circuit.append(
                cirq.decompose(cirq.TOFFOLI(self.B[0], self.A[i],
                                            self.out[i])))
            toffcount += 1
        # step 2 (and 3):
        for i in range(1, self.size):
            circuit += ctrl_add(self.B[i], self.A,
                                self.out[i:i + self.size +
                                         2]).construct_circuit()

        print("Toffoli count in multiply: ")
        print(toffcount)

        return circuit
Exemple #11
0
def test_scope_local():
    q = cirq.LineQubit(0)
    inner = cirq.Circuit(
        cirq.measure(q, key='a'),
        cirq.X(q).with_classical_controls('a'),
    )
    middle = cirq.Circuit(cirq.CircuitOperation(inner.freeze(), repetitions=2))
    outer_subcircuit = cirq.CircuitOperation(middle.freeze(), repetitions=2)
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    internal_control_keys = [
        str(condition) for op in circuit.all_operations()
        for condition in cirq.control_keys(op)
    ]
    assert internal_control_keys == ['0:0:a', '0:1:a', '1:0:a', '1:1:a']
    assert not cirq.control_keys(outer_subcircuit)
    assert not cirq.control_keys(circuit)
    cirq.testing.assert_has_diagram(
        cirq.Circuit(outer_subcircuit),
        """
      [       [ 0: ───M───X─── ]             ]
0: ───[ 0: ───[       ║   ║    ]──────────── ]────────────
      [       [ a: ═══@═══^═══ ](loops=2)    ](loops=2)
""",
        use_unicode_characters=True,
    )
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ───────M───X───M───X───M───X───M───X───
          ║   ║   ║   ║   ║   ║   ║   ║
0:0:a: ═══@═══^═══╬═══╬═══╬═══╬═══╬═══╬═══
                  ║   ║   ║   ║   ║   ║
0:1:a: ═══════════@═══^═══╬═══╬═══╬═══╬═══
                          ║   ║   ║   ║
1:0:a: ═══════════════════@═══^═══╬═══╬═══
                                  ║   ║
1:1:a: ═══════════════════════════@═══^═══
""",
        use_unicode_characters=True,
    )
    assert circuit == cirq.Circuit(cirq.decompose(outer_subcircuit))
Exemple #12
0
def test_decompose_repeated_nested_measurements():
    # Details of this test described at
    # https://tinyurl.com/measurement-repeated-circuitop#heading=h.sbgxcsyin9wt.
    a = cirq.LineQubit(0)

    op1 = (cirq.CircuitOperation(cirq.FrozenCircuit(cirq.measure(
        a, key='A'))).with_measurement_key_mapping({
            'A': 'B'
        }).repeat(2, ['zero', 'one']))

    op2 = (cirq.CircuitOperation(
        cirq.FrozenCircuit(cirq.measure(a, key='P'),
                           op1)).with_measurement_key_mapping({
                               'B': 'C',
                               'P': 'Q'
                           }).repeat(2, ['zero', 'one']))

    op3 = (cirq.CircuitOperation(
        cirq.FrozenCircuit(cirq.measure(a, key='X'),
                           op2)).with_measurement_key_mapping({
                               'C': 'D',
                               'X': 'Y'
                           }).repeat(2, ['zero', 'one']))

    expected_circuit = cirq.Circuit(
        cirq.measure(a, key='zero-Y'),
        cirq.measure(a, key='zero-zero-Q'),
        cirq.measure(a, key='zero-zero-zero-D'),
        cirq.measure(a, key='zero-zero-one-D'),
        cirq.measure(a, key='zero-one-Q'),
        cirq.measure(a, key='zero-one-zero-D'),
        cirq.measure(a, key='zero-one-one-D'),
        cirq.measure(a, key='one-Y'),
        cirq.measure(a, key='one-zero-Q'),
        cirq.measure(a, key='one-zero-zero-D'),
        cirq.measure(a, key='one-zero-one-D'),
        cirq.measure(a, key='one-one-Q'),
        cirq.measure(a, key='one-one-zero-D'),
        cirq.measure(a, key='one-one-one-D'),
    )
    assert cirq.Circuit(cirq.decompose(op3)) == expected_circuit
Exemple #13
0
def test_autodecompose_deprecated():
    dev = ValidatingTestDevice(
        allowed_qubit_types=(cirq.LineQubit, ),
        allowed_gates=(
            cirq.XPowGate,
            cirq.ZPowGate,
            cirq.CZPowGate,
            cirq.YPowGate,
            cirq.MeasurementGate,
        ),
        qubits=set(cirq.LineQubit.range(3)),
        name='test',
        validate_locality=False,
        auto_decompose_gates=(cirq.CCXPowGate, ),
    )

    a, b, c = cirq.LineQubit.range(3)
    circuit = cirq.Circuit(cirq.CCX(a, b, c), device=dev)
    decomposed = cirq.decompose(cirq.CCX(a, b, c))
    assert circuit.moments == cirq.Circuit(decomposed).moments

    with pytest.raises(ValueError,
                       match="Unsupported gate type: cirq.TOFFOLI"):
        dev = ValidatingTestDevice(
            allowed_qubit_types=(cirq.LineQubit, ),
            allowed_gates=(
                cirq.XPowGate,
                cirq.ZPowGate,
                cirq.CZPowGate,
                cirq.YPowGate,
                cirq.MeasurementGate,
            ),
            qubits=set(cirq.LineQubit.range(3)),
            name='test',
            validate_locality=False,
            auto_decompose_gates=tuple(),
        )

        a, b, c = cirq.LineQubit.range(3)
        cirq.Circuit(cirq.CCX(a, b, c), device=dev)
Exemple #14
0
def test_layered_circuit_operations_with_controls_in_between():
    q = cirq.LineQubit(0)
    outer_subcircuit = cirq.CircuitOperation(
        cirq.Circuit(
            cirq.CircuitOperation(cirq.FrozenCircuit(
                cirq.X(q),
                cirq.Y(q),
            )).with_classical_controls('m')).freeze())
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    cirq.testing.assert_has_diagram(
        cirq.Circuit(outer_subcircuit),
        """
      [ 0: ───[ 0: ───X───Y─── ].with_classical_controls(m)─── ]
0: ───[       ║                                                ]───
      [ m: ═══╩═══════════════════════════════════════════════ ]
      ║
m: ═══╩════════════════════════════════════════════════════════════
""",
        use_unicode_characters=True,
    )
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ───[ 0: ───X───Y─── ].with_classical_controls(m)───
      ║
m: ═══╩═══════════════════════════════════════════════
""",
        use_unicode_characters=True,
    )
    cirq.testing.assert_has_diagram(
        cirq.Circuit(cirq.decompose(outer_subcircuit)),
        """
0: ───X───Y───
      ║   ║
m: ═══^═══^═══
""",
        use_unicode_characters=True,
    )
Exemple #15
0
def test_scope_extern_wrapping_with_non_repeating_subcircuits():
    def wrap(*ops):
        return cirq.CircuitOperation(cirq.FrozenCircuit(*ops))

    def wrap_frozen(*ops):
        return cirq.FrozenCircuit(wrap(*ops))

    q = cirq.LineQubit(0)
    inner = wrap_frozen(
        wrap(cirq.measure(q, key='a')),
        wrap(cirq.X(q).with_classical_controls('b')),
    )
    middle = wrap_frozen(
        wrap(cirq.measure(q, key=cirq.MeasurementKey('b'))),
        wrap(cirq.CircuitOperation(inner, repetitions=2)),
    )
    outer_subcircuit = cirq.CircuitOperation(middle, repetitions=2)
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    internal_control_keys = [
        str(condition) for op in circuit.all_operations()
        for condition in cirq.control_keys(op)
    ]
    assert internal_control_keys == ['0:b', '0:b', '1:b', '1:b']
    assert not cirq.control_keys(outer_subcircuit)
    assert not cirq.control_keys(circuit)
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ─────M───M('0:0:a')───X───M('0:1:a')───X───M───M('1:0:a')───X───M('1:1:a')───X───
        ║                ║                ║   ║                ║                ║
0:b: ═══@════════════════^════════════════^═══╬════════════════╬════════════════╬═══
                                              ║                ║                ║
1:b: ═════════════════════════════════════════@════════════════^════════════════^═══
""",
        use_unicode_characters=True,
    )
    assert circuit == cirq.Circuit(cirq.decompose(outer_subcircuit))
Exemple #16
0
def test_gate_decomposition(gate: cirq.Gate,
                            testcase: unittest.TestCase,
                            print_circuit=True,
                            expected_unitary=None):
    qubits = cirq.LineQubit.range(2)
    control, target = qubits
    circuit_compressed = cirq.Circuit()
    circuit_decomposed = cirq.Circuit()

    circuit_compressed.append(gate.on(control, target))
    circuit_decomposed.append(
        cirq.decompose(gate.on(control, target), keep=is_a_basic_operation))

    if print_circuit:
        print("Compressed circuit: \n{}".format(circuit_compressed))
        print("Decomposed circuit: \n{}".format(circuit_decomposed))

        print(cirq.unitary(circuit_compressed).round(3))
        print(cirq.unitary(circuit_decomposed).round(3))

    testcase.assertTrue(
        np.allclose((cirq.unitary(circuit_compressed)
                     if expected_unitary is None else expected_unitary),
                    cirq.unitary(circuit_decomposed)))
Exemple #17
0
    def optimize_circuit(self, circuit: circuits.Circuit):
        #Write qasm file from circuit
        circuit = Circuit(
            decompose(circuit,
                      intercepting_decomposer=decompose_library,
                      keep=need_to_keep))
        qasm_str = cirq.qasm(circuit)
        f = open("temp.qasm", "w")
        f.write(qasm_str)
        f.close()

        #Call VOQC optimizations from input list and go from rzq to rz
        t = self.function_call("temp.qasm")
        rzq_to_rz("temp2.qasm")
        #Get Cirq Circuit from qasm file
        with open("temp2.qasm", "r") as f:
            c = f.read()
        circ = circuit_from_qasm(c)

        #Remove temporary files
        os.remove("temp.qasm")
        os.remove("temp2.qasm")

        return circ
Exemple #18
0
def test_default_validation_and_inverse():
    class TestGate(cirq.Gate):

        def _num_qubits_(self):
            return 2

        def _decompose_(self, qubits):
            a, b = qubits
            yield cirq.Z(a)
            yield cirq.S(b)
            yield cirq.X(a)

        def __eq__(self, other):
            return isinstance(other, TestGate)

        def __repr__(self):
            return 'TestGate()'

    a, b = cirq.LineQubit.range(2)

    with pytest.raises(ValueError, match='number of qubits'):
        TestGate().on(a)

    t = TestGate().on(a, b)
    i = t**-1
    assert i**-1 == t
    assert t**-1 == i
    assert cirq.decompose(i) == [cirq.X(a), cirq.S(b)**-1, cirq.Z(a)]
    cirq.testing.assert_allclose_up_to_global_phase(
        cirq.unitary(i),
        cirq.unitary(t).conj().T,
        atol=1e-8)

    cirq.testing.assert_implements_consistent_protocols(
        i,
        local_vals={'TestGate': TestGate})
Exemple #19
0
def test_decompose():
    qreg = cirq.LineQubit.range(3)
    op = cirq.ParallelGateOperation(cirq.X, qreg)
    assert cirq.decompose(op) == cirq.X.on_each(*qreg)
def test_decompose_nested():
    a, b, c, d = cirq.LineQubit.range(4)
    exp1 = sympy.Symbol('exp1')
    exp_half = sympy.Symbol('exp_half')
    exp_one = sympy.Symbol('exp_one')
    exp_two = sympy.Symbol('exp_two')
    circuit1 = cirq.FrozenCircuit(cirq.X(a)**exp1, cirq.measure(a, key='m1'))
    op1 = cirq.CircuitOperation(circuit1)
    circuit2 = cirq.FrozenCircuit(
        op1.with_qubits(a).with_measurement_key_mapping({'m1': 'ma'}),
        op1.with_qubits(b).with_measurement_key_mapping({'m1': 'mb'}),
        op1.with_qubits(c).with_measurement_key_mapping({'m1': 'mc'}),
        op1.with_qubits(d).with_measurement_key_mapping({'m1': 'md'}),
    )
    op2 = cirq.CircuitOperation(circuit2)
    circuit3 = cirq.FrozenCircuit(
        op2.with_params({exp1: exp_half}),
        op2.with_params({
            exp1: exp_one
        }).with_measurement_key_mapping({
            'ma': 'ma1'
        }).with_measurement_key_mapping({
            'mb': 'mb1'
        }).with_measurement_key_mapping({
            'mc': 'mc1'
        }).with_measurement_key_mapping({'md': 'md1'}),
        op2.with_params({
            exp1: exp_two
        }).with_measurement_key_mapping({
            'ma': 'ma2'
        }).with_measurement_key_mapping({
            'mb': 'mb2'
        }).with_measurement_key_mapping({
            'mc': 'mc2'
        }).with_measurement_key_mapping({'md': 'md2'}),
    )
    op3 = cirq.CircuitOperation(circuit3)

    final_op = op3.with_params({exp_half: 0.5, exp_one: 1.0, exp_two: 2.0})

    expected_circuit1 = cirq.Circuit(
        op2.with_params({
            exp1: 0.5,
            exp_half: 0.5,
            exp_one: 1.0,
            exp_two: 2.0
        }),
        op2.with_params({
            exp1: 1.0,
            exp_half: 0.5,
            exp_one: 1.0,
            exp_two: 2.0
        }).with_measurement_key_mapping({
            'ma': 'ma1'
        }).with_measurement_key_mapping({
            'mb': 'mb1'
        }).with_measurement_key_mapping({
            'mc': 'mc1'
        }).with_measurement_key_mapping({'md': 'md1'}),
        op2.with_params({
            exp1: 2.0,
            exp_half: 0.5,
            exp_one: 1.0,
            exp_two: 2.0
        }).with_measurement_key_mapping({
            'ma': 'ma2'
        }).with_measurement_key_mapping({
            'mb': 'mb2'
        }).with_measurement_key_mapping({
            'mc': 'mc2'
        }).with_measurement_key_mapping({'md': 'md2'}),
    )

    result_ops1 = cirq.decompose_once(final_op)
    assert cirq.Circuit(result_ops1) == expected_circuit1

    expected_circuit = cirq.Circuit(
        cirq.X(a)**0.5,
        cirq.measure(a, key='ma'),
        cirq.X(b)**0.5,
        cirq.measure(b, key='mb'),
        cirq.X(c)**0.5,
        cirq.measure(c, key='mc'),
        cirq.X(d)**0.5,
        cirq.measure(d, key='md'),
        cirq.X(a)**1.0,
        cirq.measure(a, key='ma1'),
        cirq.X(b)**1.0,
        cirq.measure(b, key='mb1'),
        cirq.X(c)**1.0,
        cirq.measure(c, key='mc1'),
        cirq.X(d)**1.0,
        cirq.measure(d, key='md1'),
        cirq.X(a)**2.0,
        cirq.measure(a, key='ma2'),
        cirq.X(b)**2.0,
        cirq.measure(b, key='mb2'),
        cirq.X(c)**2.0,
        cirq.measure(c, key='mc2'),
        cirq.X(d)**2.0,
        cirq.measure(d, key='md2'),
    )
    assert cirq.Circuit(cirq.decompose(final_op)) == expected_circuit
    # Verify that mapped_circuit gives the same operations.
    assert final_op.mapped_circuit(deep=True) == expected_circuit
Exemple #21
0
def test_decompose():
    a = cirq.NamedQubit('a')
    b = cirq.NamedQubit('b')
    m = cirq.Moment(cirq.X(a), cirq.X(b))
    assert list(cirq.decompose(m)) == list(m.operations)
Exemple #22
0
def add_swap_test(
    state1: typing.Union[cirq.Qid, typing.Iterable[cirq.Qid]],
    state2: typing.Union[cirq.Qid, typing.Iterable[cirq.Qid]],
    circuit: cirq.Circuit,
    auxiliary_qubit: typing.Optional[cirq.Qid] = None,
    auxiliary_qubit_type: typing.Optional[
        typing.Union[typing.Type[cirq.GridQubit], typing.Type[cirq.LineQubit]]
    ] = cirq.GridQubit,
    cswap_in_elementary_gates: bool = False
) -> typing.Tuple[str, cirq.Qid]:
    """
    Add a SWAP test between two quantum states `state1` and `state2`, and then add
    the test into `circuit`.

    999: ───H───@───H───M('SWAP test measure')───
                │
    1: ─────────SWAP─────────────────────────────
                │
    2: ─────────SWAP─────────────────────────────

    :param state1:
        Quantum state to be tested.
    :param state2:
        Quantum state to be tested.
    :param circuit:
        The quantum circuit to which the SWAP test is to be appended.
    :param auxiliary_qubit:
        The auxiliary qubit.
        If being None, it will be created by `generate_auxiliary_qubit`.
        If being a `cirq.Qid` object, then it will be used as the auxiliary
        qubit of our SWAP test, and the argument `auxiliary_qubit_type` will be
        ignored.
        Note: `auxiliary_qubit` and `auxiliary_qubit_type` can not both be
        `None` at the same time.
    :param auxiliary_qubit_type:
        The type of the auxiliary qubit of SWAP test. Only LineQubit and
        GridQubit are supported.
        If `auxiliary_qubit` is None, this argument will be used to create the
        auxiliary qubit.
        If `auxiliary_qubit` is a `cirq.Qid` object, then this argument will be
        ignored.
        Note: `auxiliary_qubit` and `auxiliary_qubit_type` can not both be
        `None` at the same time.
    :param cswap_in_elementary_gates:
        Tells whether the CSWAP gate will be represented in elementary gates.
    :return:
        The string key of the measurement.

    """
    if isinstance(state1, cirq.Qid):
        state1 = [state1]
    if isinstance(state2, cirq.Qid):
        state2 = [state2]

    if len(state1) != len(state2):
        raise ValueError(
            "Qubit lengths of the two target states must equal, "
            "but {} != {}.".format(len(state1), len(state2))
        )

    if auxiliary_qubit is None:
        auxiliary_qubit = generate_auxiliary_qubit(circuit, auxiliary_qubit_type)
    measurement_name = "SWAP test measure "

    existed_swap_measurement_ids = {int(key[len(measurement_name):])
                                    for key in get_all_measurement_keys(circuit)
                                    if key.startswith(measurement_name)}
    swap_measurement_id = (max(existed_swap_measurement_ids) + 1
                           if len(existed_swap_measurement_ids) != 0
                           else 0)
    measurement_name += str(swap_measurement_id)

    circuit.append(cirq.H(auxiliary_qubit))
    for qubit1, qubit2 in zip(state1, state2):
        cswap_op = cirq.CSWAP.on(auxiliary_qubit, qubit1, qubit2)
        if cswap_in_elementary_gates:
            circuit.append(
                cirq.decompose(cswap_op)
            )
        else:
            circuit.append(cswap_op)

    circuit.append([
        cirq.H(auxiliary_qubit),
        cirq.measure(auxiliary_qubit, key=measurement_name)
    ])

    return measurement_name, auxiliary_qubit
def test_parameterized_repeat_side_effects():
    q = cirq.LineQubit(0)
    op = cirq.CircuitOperation(
        cirq.FrozenCircuit(
            cirq.X(q).with_classical_controls('c'), cirq.measure(q, key='m')),
        repetitions=sympy.Symbol('a'),
    )

    # Control keys can be calculated because they only "lift" if there's a matching
    # measurement, in which case they're not returned here.
    assert cirq.control_keys(op) == {cirq.MeasurementKey('c')}

    # "local" params do not bind to the repetition param.
    assert cirq.parameter_names(op.with_params({'a': 1})) == {'a'}

    # Check errors that require unrolling the circuit.
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        cirq.measurement_key_objs(op)
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        cirq.measurement_key_names(op)
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        op.mapped_circuit()
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        cirq.decompose(op)

    # Not compatible with repetition ids
    with pytest.raises(ValueError,
                       match='repetition ids with parameterized repetitions'):
        op.with_repetition_ids(['x', 'y'])
    with pytest.raises(ValueError,
                       match='repetition ids with parameterized repetitions'):
        op.repeat(repetition_ids=['x', 'y'])

    # TODO(daxfohl): This should work, but likely requires a new protocol that returns *just* the
    # name of the measurement keys. (measurement_key_names returns the full serialized string).
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        cirq.with_measurement_key_mapping(op, {'m': 'm2'})

    # Everything should work once resolved
    op = cirq.resolve_parameters(op, {'a': 2})
    assert set(map(str, cirq.measurement_key_objs(op))) == {'0:m', '1:m'}
    assert op.mapped_circuit() == cirq.Circuit(
        cirq.X(q).with_classical_controls('c'),
        cirq.measure(q, key=cirq.MeasurementKey.parse_serialized('0:m')),
        cirq.X(q).with_classical_controls('c'),
        cirq.measure(q, key=cirq.MeasurementKey.parse_serialized('1:m')),
    )
    assert cirq.decompose(op) == cirq.decompose(
        cirq.Circuit(
            cirq.X(q).with_classical_controls('c'),
            cirq.measure(q, key=cirq.MeasurementKey.parse_serialized('0:m')),
            cirq.X(q).with_classical_controls('c'),
            cirq.measure(q, key=cirq.MeasurementKey.parse_serialized('1:m')),
        ))
Exemple #24
0
def test_sympy_scope():
    q = cirq.LineQubit(0)
    a, b, c, d = sympy.symbols('a b c d')
    inner = cirq.Circuit(
        cirq.measure(q, key='a'),
        cirq.X(q).with_classical_controls(a & b).with_classical_controls(c
                                                                         | d),
    )
    middle = cirq.Circuit(
        cirq.measure(q, key='b'),
        cirq.measure(q, key=cirq.MeasurementKey('c', ('0', ))),
        cirq.CircuitOperation(inner.freeze(), repetitions=2),
    )
    outer_subcircuit = cirq.CircuitOperation(middle.freeze(), repetitions=2)
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    internal_controls = [
        str(k) for op in circuit.all_operations()
        for k in cirq.control_keys(op)
    ]
    assert set(internal_controls) == {
        '0:0:a', '0:1:a', '1:0:a', '1:1:a', '0:b', '1:b', 'c', 'd'
    }
    assert cirq.control_keys(outer_subcircuit) == {'c', 'd'}
    assert cirq.control_keys(circuit) == {'c', 'd'}
    assert circuit == cirq.Circuit(cirq.decompose(outer_subcircuit))
    cirq.testing.assert_has_diagram(
        cirq.Circuit(outer_subcircuit),
        """
      [                      [ 0: ───M───X(conditions=[c | d, a & b])─── ]             ]
      [                      [       ║   ║                               ]             ]
      [                      [ a: ═══@═══^══════════════════════════════ ]             ]
      [                      [           ║                               ]             ]
      [ 0: ───M───M('0:c')───[ b: ═══════^══════════════════════════════ ]──────────── ]
      [       ║              [           ║                               ]             ]
      [       ║              [ c: ═══════^══════════════════════════════ ]             ]
0: ───[       ║              [           ║                               ]             ]────────────
      [       ║              [ d: ═══════^══════════════════════════════ ](loops=2)    ]
      [       ║              ║                                                         ]
      [ b: ═══@══════════════╬════════════════════════════════════════════════════════ ]
      [                      ║                                                         ]
      [ c: ══════════════════╬════════════════════════════════════════════════════════ ]
      [                      ║                                                         ]
      [ d: ══════════════════╩════════════════════════════════════════════════════════ ](loops=2)
      ║
c: ═══╬═════════════════════════════════════════════════════════════════════════════════════════════
      ║
d: ═══╩═════════════════════════════════════════════════════════════════════════════════════════════
""",
        use_unicode_characters=True,
    )

    # pylint: disable=line-too-long
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ───────M───M('0:0:c')───M───X(conditions=[c | d, 0:0:a & 0:b])───M───X(conditions=[c | d, 0:1:a & 0:b])───M───M('1:0:c')───M───X(conditions=[c | d, 1:0:a & 1:b])───M───X(conditions=[c | d, 1:1:a & 1:b])───
          ║                ║   ║                                    ║   ║                                    ║                ║   ║                                    ║   ║
0:0:a: ═══╬════════════════@═══^════════════════════════════════════╬═══╬════════════════════════════════════╬════════════════╬═══╬════════════════════════════════════╬═══╬════════════════════════════════════
          ║                    ║                                    ║   ║                                    ║                ║   ║                                    ║   ║
0:1:a: ═══╬════════════════════╬════════════════════════════════════@═══^════════════════════════════════════╬════════════════╬═══╬════════════════════════════════════╬═══╬════════════════════════════════════
          ║                    ║                                        ║                                    ║                ║   ║                                    ║   ║
0:b: ═════@════════════════════^════════════════════════════════════════^════════════════════════════════════╬════════════════╬═══╬════════════════════════════════════╬═══╬════════════════════════════════════
                               ║                                        ║                                    ║                ║   ║                                    ║   ║
1:0:a: ════════════════════════╬════════════════════════════════════════╬════════════════════════════════════╬════════════════@═══^════════════════════════════════════╬═══╬════════════════════════════════════
                               ║                                        ║                                    ║                    ║                                    ║   ║
1:1:a: ════════════════════════╬════════════════════════════════════════╬════════════════════════════════════╬════════════════════╬════════════════════════════════════@═══^════════════════════════════════════
                               ║                                        ║                                    ║                    ║                                        ║
1:b: ══════════════════════════╬════════════════════════════════════════╬════════════════════════════════════@════════════════════^════════════════════════════════════════^════════════════════════════════════
                               ║                                        ║                                                         ║                                        ║
c: ════════════════════════════^════════════════════════════════════════^═════════════════════════════════════════════════════════^════════════════════════════════════════^════════════════════════════════════
                               ║                                        ║                                                         ║                                        ║
d: ════════════════════════════^════════════════════════════════════════^═════════════════════════════════════════════════════════^════════════════════════════════════════^════════════════════════════════════
""",
        use_unicode_characters=True,
    )
Exemple #25
0
    def _base_iterator(self,
                       circuit,
                       qubit_order,
                       initial_state,
                       perform_measurements=True):
        qubits = cirq.QubitOrder.as_qubit_order(qubit_order).order_for(
            circuit.all_qubits())
        num_qubits = len(qubits)
        qid_shape = cirq.qid_shape(qubits)
        qubit_map = {q: i for i, q in enumerate(qubits)}
        if isinstance(initial_state, int):
            state_val = initial_state
        else:
            state_val = cirq.big_endian_digits_to_int(initial_state,
                                                      base=qid_shape)
        state = np.array(list(
            cirq.big_endian_int_to_digits(state_val, base=qid_shape)),
                         dtype=np.uint8)
        if len(circuit) == 0:
            yield ClassicalSimulatorStep(state, {}, qubit_map)

        def on_stuck(bad_op):
            return TypeError(
                "Can't simulate unknown operations that don't specify a "
                "unitary or a decomposition. {!r}".format(bad_op))

        def keep(op):
            return ((cirq.num_qubits(op) <= 32 and
                     (cirq.has_unitary(op) or cirq.has_mixture(op)))
                    or cirq.is_measurement(op)
                    or isinstance(op.gate, cirq.ResetChannel))

        def simulate_op(op, temp_state):
            indices = [qubit_map[q] for q in op.qubits]
            if isinstance(op.gate, cirq.ResetChannel):
                self._simulate_reset(op, temp_state, indices)
            elif cirq.is_measurement(op):
                if perform_measurements:
                    self._simulate_measurement(op, temp_state, indices,
                                               measurements)
            else:
                decomp_ops = cirq.decompose_once(op, default=None)
                if decomp_ops is None:
                    self._simulate_from_matrix(op, temp_state, indices)
                else:
                    try:
                        temp2_state = temp_state.copy()
                        for sub_op in cirq.flatten_op_tree(decomp_ops):
                            simulate_op(sub_op, temp2_state)
                        temp_state[...] = temp2_state
                    except ValueError:
                        # Non-classical unitary in the decomposition
                        self._simulate_from_matrix(op, temp_state, indices)

        for moment in circuit:
            measurements = defaultdict(list)
            known_ops = cirq.decompose(moment,
                                       keep=keep,
                                       on_stuck_raise=on_stuck)
            for op in known_ops:
                simulate_op(op, state)
            yield ClassicalSimulatorStep(state.copy(), measurements, qubit_map)
Exemple #26
0
def op_grad(
    operation: cirq.GateOperation, parameter: sympy.Symbol
) -> typing.Union[LinearCombinationOfOperations, GradNotImplemented]:
    if not cirq.is_parameterized(operation):
        return ZERO_OP.copy()

    gate = operation.gate
    qubits = operation.qubits

    if isinstance(gate, cirq.XPowGate):
        # dXPow(e=f(t), s) / dt = i π (s + 1 / 2 - X / 2) * (df(t)/dt) XPow(e=f(t), s)
        # Note that: Rx(θ) = XPowGate(exponent=θ/pi, global_shift=-0.5)
        partial = sympy.diff(gate.exponent, parameter)
        coeff_i = 1.0j * sympy.pi * (gate._global_shift + 0.5)
        coeff_x = -1.0j / 2 * sympy.pi
        if partial == 0:
            return ZERO_OP.copy()
        return LinearCombinationOfOperations({
            (cirq.X.on(*qubits), operation):
            coeff_x * partial,
            (cirq.I.on(*qubits), operation):
            coeff_i * partial
        })

    elif isinstance(gate, cirq.YPowGate):
        # dYPow(e=f(t), s) / dt = i π (s + 1 / 2 - Y / 2) * (df(t)/dt) YPow(e=f(t), s)
        # Note that: Ry(θ) = YPowGate(exponent=θ/pi, global_shift=-0.5)
        partial = sympy.diff(gate.exponent, parameter)
        coeff_i = 1.0j * sympy.pi * (gate._global_shift + 0.5)
        coeff_y = -1.0j / 2 * sympy.pi
        if partial == 0:
            return ZERO_OP.copy()
        return LinearCombinationOfOperations({
            (cirq.Y.on(*qubits), operation):
            coeff_y * partial,
            (cirq.I.on(*qubits), operation):
            coeff_i * partial
        })

    elif isinstance(gate, cirq.ZPowGate):
        # dZPow(e=f(t), s) / dt = i π (s + 1 / 2 - Z / 2) * (df(t)/dt) ZPow(e=f(t), s)
        # Note that: Ry(θ) = ZPowGate(exponent=θ/pi, global_shift=-0.5)
        partial = sympy.diff(gate.exponent, parameter)
        coeff_i = 1.0j * sympy.pi * (gate._global_shift + 0.5)
        coeff_z = -1.0j / 2 * sympy.pi
        if partial == 0:
            return ZERO_OP.copy()
        return LinearCombinationOfOperations({
            (cirq.Z.on(*qubits), operation):
            coeff_z * partial,
            (cirq.I.on(*qubits), operation):
            coeff_i * partial
        })

    elif isinstance(gate, GlobalPhaseGate):
        gate = typing.cast(GlobalPhaseGate, gate)
        # Ph(θ) = exp(i pi θ)
        # dPh(f(θ)) / dθ = [i pi df(θ) / dθ] exp(i pi f(θ))
        #                = [i pi df(θ) / dθ] Ph(f(θ))
        coeff = 1.0j * sympy.diff(gate.rad * sympy.pi, parameter)
        if coeff == 0:
            return ZERO_OP.copy()
        return LinearCombinationOfOperations({(operation, ): coeff})

    elif isinstance(gate, cirq.EigenGate):
        gate = typing.cast(cirq.EigenGate, gate)
        eigenvalues = {v for v, p in gate._eigen_components()}
        if eigenvalues == {0, 1}:
            e = gate.exponent
            s = gate._global_shift
            partial = sympy.diff(e, parameter)

            if partial == 0:
                return ZERO_OP.copy()

            num_qubits = gate.num_qubits()
            gate_e1_s0 = copy.deepcopy(gate)
            gate_e1_s0._exponent = 1.0
            gate_e1_s0._global_shift = 0.0  # Any better solutions?
            coeff = 0.5 * sympy.exp(1.0j * sympy.pi * (1 + s) * e)

            return 1.0j * sympy.pi * LinearCombinationOfOperations(
                {
                    (operation, ): s * partial,
                    (gate_e1_s0.on(*qubits), ): -coeff * partial,
                    (cirq.IdentityGate(num_qubits).on(*qubits), ):
                    coeff * partial
                })

        else:
            return GradNotImplemented(operation)

    elif isinstance(gate, GateBlock):
        gate = typing.cast(GateBlock, gate)

        generator_grad = op_tree_generator_grad(gate._op_generator, parameter)

        if isinstance(generator_grad, GradNotImplemented):
            return generator_grad

        if len(generator_grad) == 0:
            return ZERO_OP.copy()

        _grad = LinearCombinationOfOperations({})
        for generator, coeff in generator_grad.items():
            grad_gate = GateBlock(generator)

            _grad += LinearCombinationOfOperations({
                (grad_gate.on(*qubits), ):
                coeff
            })

            # print(grad_gate.diagram())

        return _grad

    elif isinstance(gate, cirq.ControlledGate):
        gate = typing.cast(cirq.ControlledGate, gate)

        sub_gate_qubits = qubits[gate.num_controls():]
        sub_op_grad = op_grad(gate.sub_gate.on(*sub_gate_qubits), parameter)

        if is_zero_op_or_grad_not_implemented(sub_op_grad):
            return sub_op_grad

        _gate_grad = LinearCombinationOfOperations({})
        op: cirq.GateOperation
        for op_series, coeff in sub_op_grad.items():
            _controlled_op_series = [
                cirq.ControlledGate(
                    op.gate, control_qubits=qubits[:gate.num_controls()]).on(
                        *sub_gate_qubits) for op in op_series
            ]
            _controlled_negative_op_series = copy.deepcopy(
                _controlled_op_series)
            _controlled_negative_op_series.insert(
                0,
                cirq.ControlledGate(
                    GlobalPhaseGate(rad=1),
                    control_qubits=qubits[:gate.num_controls()]).on(
                        *sub_gate_qubits))
            _gate_grad += LinearCombinationOfOperations(
                {
                    tuple(_controlled_op_series): coeff,
                    tuple(_controlled_negative_op_series): -coeff,
                }) / 2.0

        return _gate_grad

    # if `operation` is a basic and indecomposable operation whose grad is
    # not implemented
    elif is_an_indecomposable_operation(operation):
        return GradNotImplemented(operation)

    else:
        op_series = cirq.decompose(
            operation,
            keep=(lambda op: is_a_basic_operation(op) or
                  is_an_indecomposable_operation(op)),
            on_stuck_raise=None)  # type: typing.List[cirq.Operation]

        _grad = op_series_grad(op_series, parameter)
        return _grad
def test_decomposition_cost(op: cirq.Operation, max_two_cost: int):
    ops = tuple(cirq.flatten_op_tree(cirq.decompose(op)))
    two_cost = len([e for e in ops if len(e.qubits) == 2])
    over_cost = len([e for e in ops if len(e.qubits) > 2])
    assert over_cost == 0
    assert two_cost == max_two_cost
    x_train_circ = [encode_to_circuit(x) for x in train_x]
    x_test_circ = [encode_to_circuit(x) for x in test_x]

    # Convert input-data circuits to tensors
    x_train_tfcirc = tfq.convert_to_tensor(x_train_circ)
    x_test_tfcirc = tfq.convert_to_tensor(x_test_circ)

    # Make the rest of the circuit that applies the weights and U-gate
    qubits = cirq.GridQubit.rect(2, 2)
    C1, C2, T1, T2 = qubits
    model_circuit = cirq.Circuit()

    # First set of weights: w
    w = sp.symbols('w:11')
    gamma_encode(model_circuit, C2, T2, *w)
    # Apply U-gate
    t = sp.symbols('t')
    u = cirq.decompose(U(t).on(qubits[0], qubits[1]))
    print(cirq.to_json(u))
    model_circuit.append(u)

    # Assign readout qubits
    model_readout = cirq.Z(C2)

    # Make parametrized circuit model
    poc = tfq.layers.PQC(model_circuit, model_readout)

    # Build the model
    model = tf.keras.Sequential(
        [tf.keras.layers.Input(shape=(), dtype=tf.string), poc])
Exemple #29
0
def test_tagged_operation_forwards_protocols():
    """The results of all protocols applied to an operation with a tag should
    be equivalent to the result without tags.
    """
    q1 = cirq.GridQubit(1, 1)
    q2 = cirq.GridQubit(1, 2)
    h = cirq.H(q1)
    tag = 'tag1'
    tagged_h = cirq.H(q1).with_tags(tag)

    np.testing.assert_equal(cirq.unitary(tagged_h), cirq.unitary(h))
    assert cirq.has_unitary(tagged_h)
    assert cirq.decompose(tagged_h) == cirq.decompose(h)
    assert cirq.pauli_expansion(tagged_h) == cirq.pauli_expansion(h)
    assert cirq.equal_up_to_global_phase(h, tagged_h)
    assert np.isclose(cirq.channel(h), cirq.channel(tagged_h)).all()

    assert cirq.measurement_key(cirq.measure(q1, key='blah').with_tags(tag)) == 'blah'

    parameterized_op = cirq.XPowGate(exponent=sympy.Symbol('t'))(q1).with_tags(tag)
    assert cirq.is_parameterized(parameterized_op)
    resolver = cirq.study.ParamResolver({'t': 0.25})
    assert cirq.resolve_parameters(parameterized_op, resolver) == cirq.XPowGate(exponent=0.25)(
        q1
    ).with_tags(tag)
    assert cirq.resolve_parameters_once(parameterized_op, resolver) == cirq.XPowGate(exponent=0.25)(
        q1
    ).with_tags(tag)

    y = cirq.Y(q1)
    tagged_y = cirq.Y(q1).with_tags(tag)
    assert tagged_y ** 0.5 == cirq.YPowGate(exponent=0.5)(q1)
    assert tagged_y * 2 == (y * 2)
    assert 3 * tagged_y == (3 * y)
    assert cirq.phase_by(y, 0.125, 0) == cirq.phase_by(tagged_y, 0.125, 0)
    controlled_y = tagged_y.controlled_by(q2)
    assert controlled_y.qubits == (
        q2,
        q1,
    )
    assert isinstance(controlled_y, cirq.Operation)
    assert not isinstance(controlled_y, cirq.TaggedOperation)

    clifford_x = cirq.SingleQubitCliffordGate.X(q1)
    tagged_x = cirq.SingleQubitCliffordGate.X(q1).with_tags(tag)
    assert cirq.commutes(clifford_x, clifford_x)
    assert cirq.commutes(tagged_x, clifford_x)
    assert cirq.commutes(clifford_x, tagged_x)
    assert cirq.commutes(tagged_x, tagged_x)

    assert cirq.trace_distance_bound(y ** 0.001) == cirq.trace_distance_bound(
        (y ** 0.001).with_tags(tag)
    )

    flip = cirq.bit_flip(0.5)(q1)
    tagged_flip = cirq.bit_flip(0.5)(q1).with_tags(tag)
    assert cirq.has_mixture(tagged_flip)
    assert cirq.has_channel(tagged_flip)

    flip_mixture = cirq.mixture(flip)
    tagged_mixture = cirq.mixture(tagged_flip)
    assert len(tagged_mixture) == 2
    assert len(tagged_mixture[0]) == 2
    assert len(tagged_mixture[1]) == 2
    assert tagged_mixture[0][0] == flip_mixture[0][0]
    assert np.isclose(tagged_mixture[0][1], flip_mixture[0][1]).all()
    assert tagged_mixture[1][0] == flip_mixture[1][0]
    assert np.isclose(tagged_mixture[1][1], flip_mixture[1][1]).all()

    qubit_map = {q1: 'q1'}
    qasm_args = cirq.QasmArgs(qubit_id_map=qubit_map)
    assert cirq.qasm(h, args=qasm_args) == cirq.qasm(tagged_h, args=qasm_args)

    cirq.testing.assert_has_consistent_apply_unitary(tagged_h)
Exemple #30
0
  def translate_cirq_to_qsim(
      self,
      qubit_order: cirq.ops.QubitOrderOrList = cirq.ops.QubitOrder.DEFAULT
  ) -> qsim.Circuit:
    """
        Translates this Cirq circuit to the qsim representation.
        :qubit_order: Ordering of qubits
        :return: a C++ qsim Circuit object
        """

    qsim_circuit = qsim.Circuit()
    qsim_circuit.num_qubits = len(self.all_qubits())
    ordered_qubits = cirq.ops.QubitOrder.as_qubit_order(qubit_order).order_for(
        self.all_qubits())

    # qsim numbers qubits in reverse order from cirq
    ordered_qubits = list(reversed(ordered_qubits))

    def has_qsim_kind(op: cirq.ops.GateOperation):
      return _cirq_gate_kind(op.gate) != None

    def to_matrix(op: cirq.ops.GateOperation):
      mat = cirq.protocols.unitary(op.gate, None)
      if mat is None:
          return NotImplemented
      
      return cirq.ops.MatrixGate(mat).on(*op.qubits)

    qubit_to_index_dict = {q: i for i, q in enumerate(ordered_qubits)}
    time_offset = 0
    for moment in self:
      ops_by_gate = [
        cirq.decompose(op, fallback_decomposer=to_matrix, keep=has_qsim_kind)
        for op in moment
      ]
      moment_length = max(len(gate_ops) for gate_ops in ops_by_gate)

      # Gates must be added in time order.
      for gi in range(moment_length):
        for gate_ops in ops_by_gate:
          if gi >= len(gate_ops):
            continue
          qsim_op = gate_ops[gi]
          gate_kind = _cirq_gate_kind(qsim_op.gate)
          time = time_offset + gi
          qubits = [qubit_to_index_dict[q] for q in qsim_op.qubits]

          qsim_gate = qsim_op.gate
          qsim_qubits = qubits
          is_controlled = isinstance(qsim_op.gate, cirq.ops.ControlledGate)
          if is_controlled:
            control_qubits, control_values = _control_details(qsim_op.gate,
                                                              qubits)
            if control_qubits is None:
              # This gate has no valid control, and will be omitted.
              continue

            if qsim_gate.num_qubits() > 4:
              raise NotImplementedError(
              f'Received control gate on {gate.num_qubits()} target qubits; '
              + 'only up to 4-qubit gates are supported.')

            qsim_gate = qsim_gate.sub_gate
            qsim_qubits = qubits[qsim_op.gate.num_controls():]

          if gate_kind == qsim.kTwoQubitDiagonalGate or gate_kind == qsim.kThreeQubitDiagonalGate:
            qsim.add_diagonal_gate(time, qsim_qubits,
                                   qsim_gate._diag_angles_radians, qsim_circuit)
          elif gate_kind == qsim.kMatrixGate:
            flatten = lambda l : [val for i in l for val in [i.real, i.imag]]
            qsim.add_matrix_gate(time, qsim_qubits,
                                 flatten(list(cirq.unitary(qsim_gate).flat)),
                                 qsim_circuit)
          else:
            params = {
              p.strip('_'): val for p, val in vars(qsim_gate).items()
              if isinstance(val, float) or isinstance(val, int)
            }
            qsim.add_gate(gate_kind, time, qsim_qubits, params, qsim_circuit)

          if is_controlled:
            qsim.control_last_gate(control_qubits, control_values, qsim_circuit)
      time_offset += moment_length

    return qsim_circuit