Example #1
0
def test_simplify_circuit_exponents_with_non_self_inverse_gates():
    qreg = LineQubit.range(2)
    # Make a circuit with gates which are not self-inverse
    circuit = Circuit([S.on(qreg[0]), T.on(qreg[1])])

    inverse_circuit = cirq.inverse(circuit)
    inverse_repr = inverse_circuit.__repr__()
    inverse_qasm = inverse_circuit._to_qasm_output().__str__()

    # Simplify the circuit (it should not change this circuit)
    _simplify_circuit_exponents(inverse_circuit)

    # Check inverse_circuit did not change
    simplified_repr = inverse_circuit.__repr__()
    simplified_qasm = inverse_circuit._to_qasm_output().__str__()
    assert simplified_repr == inverse_repr
    assert simplified_qasm == inverse_qasm
Example #2
0
def test_comments():
    parser = QasmParser()

    parsed_qasm = parser.parse(
        """
    //this is the format
    OPENQASM 2.0;
    // this is some other comment
    include "qelib1.inc";
    // and something at the end of the file
    // multiline
    """
    )

    assert parsed_qasm.supportedFormat
    assert parsed_qasm.qelib1Include
    ct.assert_same_circuits(parsed_qasm.circuit, Circuit())
 def exponentiation_circuit(param):
     circuit = Circuit()
     if is_constant(pauli_string):
         PHASE = ZPowGate(exponent=(-param * coeff)/np.pi)
         circuit.append([X(GridQubit(0, 0))],
                        strategy=InsertStrategy.EARLIEST)
         circuit.append([PHASE(GridQubit(0, 0))],
                        strategy=InsertStrategy.EARLIEST)
         circuit.append([X(GridQubit(0, 0))],
                        strategy=InsertStrategy.EARLIEST)
         circuit.append([PHASE(GridQubit(0, 0))],
                        strategy=InsertStrategy.EARLIEST)
     elif is_zero(pauli_string):
         pass
     else:
         circuit += exponentiate_general_case(pauli_string, param)
     return circuit
Example #4
0
def test_multiple_creg_declaration():
    qasm = """
     OPENQASM 2.0; 
     include "qelib1.inc";
     creg a_classical_register [1337];
     qreg a_quantum_register [1337];
     creg c[42];
"""
    parser = QasmParser()

    parsed_qasm = parser.parse(qasm)

    assert parsed_qasm.supportedFormat is True
    assert parsed_qasm.qelib1Include is True
    ct.assert_same_circuits(parsed_qasm.circuit, Circuit())
    assert parsed_qasm.qregs == {'a_quantum_register': 1337}
    assert parsed_qasm.cregs == {'a_classical_register': 1337, 'c': 42}
Example #5
0
def test_to_from_braket_common_two_qubit_gates(common_gate):
    """These gates should stay the same (i.e., not get decomposed) when
    converting Cirq -> Braket -> Cirq.
    """
    cirq_circuit = Circuit(common_gate.on(*LineQubit.range(2)))
    test_circuit = from_braket(to_braket(cirq_circuit))
    testing.assert_allclose_up_to_global_phase(
        protocols.unitary(test_circuit),
        protocols.unitary(cirq_circuit),
        atol=1e-7,
    )

    # Cirq AAPowGate has a different global phase than braket AA which gets
    # lost in translation. Here, AA = XX, YY, or ZZ.
    if not isinstance(common_gate,
                      (ops.XXPowGate, ops.YYPowGate, ops.ZZPowGate)):
        assert _equal(test_circuit, cirq_circuit, require_qubit_equality=True)
Example #6
0
    def test_symbolic_gate(self):
        sym_circuit = Circuit()
        qubits = [GridQubit(i, j) for i in range(3) for j in range(3)]

        gate = GlobalPhaseGate(sympy.Symbol("rad"))
        sym_circuit.append(gate.on(qubits[0]))

        print(sym_circuit)

        rad_list = np.random.rand(10) * 5
        for rad in rad_list:
            simulator = Simulator()
            circuit = cirq.resolve_parameters(sym_circuit, {"rad": rad})
            result = simulator.simulate(circuit)
            self.assertTrue(
                np.allclose(result.final_state,
                            np.exp(1.0j * rad * np.pi) * np.array([1, 0])))
Example #7
0
def test_aqt_sampler_empty_circuit():
    num_points = 10
    max_angle = np.pi
    repetitions = 1000
    num_qubits = 4
    device, _qubits = get_aqt_device(num_qubits)
    sampler = AQTSamplerLocalSimulator()
    sampler.simulate_ideal = True
    circuit = Circuit(device=device)
    sweep = study.Linspace(key='theta',
                           start=0.1,
                           stop=max_angle / np.pi,
                           length=num_points)
    with pytest.raises(RuntimeError):
        _results = sampler.run_sweep(circuit,
                                     params=sweep,
                                     repetitions=repetitions)
Example #8
0
def test_ms_crosstalk_n_noise():
    num_qubits = 4
    noise_mod = AQTNoiseModel()
    device, qubits = get_aqt_device(num_qubits)
    circuit = Circuit(device=device)
    circuit.append(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 #9
0
    def expectation(all_qubits_in_circuit, cirq_circuit, cirq_pauli_sum):
        """
        Computes the expectation value of `cirq_pauli_sum` over the distribution
        generated from `cirq_circuit`.
        The expectation value is calculated by calculating <psi|O|psi>

        Parameters
        ---------
        all_qubits_in_circuit   :   (list) list of all qubits in `cirq_circuit`
        cirq_circuit            :   (Circuit) represents the paramterized circuit for the ansatz 
        cirq_pauli_sum          :   (CirqPauliSum or ndarray) CirqPauliSum representing the Pauli
                                    operator for which the expectation value is to be calculated
                                    or a numpy matrix representing the Hamiltonian 
                                    tensored up to the appropriate size.

        Returns
        -------
        expectation.real        :   (float) represents the expectation value of cirq_pauli_sum 
                                    given the distribution generated from `cirq_circuit`.
        """
        if isinstance(cirq_pauli_sum, np.ndarray):
            simulator = Simulator()
            simulation_result = simulator.simulate(cirq_circuit)
            cirq_circuit_amplitudes = simulation_result.final_state
            cirq_circuit_amplitudes = np.reshape(
                cirq_circuit_amplitudes, (-1, 1))
            average_exp = np.conj(cirq_circuit_amplitudes).T.dot(
                cirq_pauli_sum.dot(cirq_circuit_amplitudes)).real
            return average_exp
        else:
            operator_circuits = []
            operator_coeffs = []
            for p_string in cirq_pauli_sum.pauli_strings:
                op_circuit = Circuit()
                for qubit, pauli in p_string.items():
                    gate = pauli
                    op_circuit.append(
                        [gate(qubit)], strategy=InsertStrategy.EARLIEST)
                operator_circuits.append(op_circuit)
                operator_coeffs.append(p_string.coefficient)
            result_overlaps = VQE.calculate_expectation(
                all_qubits_in_circuit, cirq_circuit, operator_circuits)
            result_overlaps = list(result_overlaps)
            expectation = sum(
                list(map(lambda x: x[0]*x[1], zip(result_overlaps, operator_coeffs))))
            return expectation.real
Example #10
0
def test_depolarizing_representation_with_choi(gate: Gate, noise: float):
    """Tests the representation by comparing exact Choi matrices."""
    qreg = LineQubit.range(gate.num_qubits())
    ideal_choi = _operation_to_choi(gate.on(*qreg))
    op_rep = represent_operation_with_global_depolarizing_noise(
        Circuit(gate.on(*qreg)), noise,
    )
    choi_components = []
    for noisy_op, coeff in op_rep.basis_expansion.items():
        implementable_circ = noisy_op.circuit()
        # Apply noise after each sequence.
        # NOTE: noise is not applied after each operation.
        depolarizing_op = DepolarizingChannel(noise, len(qreg))(*qreg)
        implementable_circ.append(depolarizing_op)
        sequence_choi = _circuit_to_choi(implementable_circ)
        choi_components.append(coeff * sequence_choi)
    combination_choi = np.sum(choi_components, axis=0)
    assert np.allclose(ideal_choi, combination_choi, atol=10 ** -6)
Example #11
0
    def simulate_samples(self, repetitions: int) -> study.Result:
        """Samples the circuit

        Args:
            repetitions: Number of times the circuit is simulated

        Returns:
            Result from Cirq.Simulator
        """
        if self.simulate_ideal:
            noise_model = devices.NO_NOISE
        else:
            noise_model = AQTNoiseModel()
        if self.circuit == Circuit():
            raise RuntimeError('simulate ideal called without a valid circuit')
        sim = DensityMatrixSimulator(noise=noise_model)
        result = sim.run(self.circuit, repetitions=repetitions)
        return result
Example #12
0
def represent_operations_in_circuit_with_local_depolarizing_noise(
    ideal_circuit: QPROGRAM, noise_level: float
) -> List[OperationRepresentation]:
    """Iterates over all unique operations of the input ``ideal_circuit`` and,
    for each of them, generates the corresponding quasi-probability
    representation (linear combination of implementable noisy operations).

    This function assumes that the tensor product of ``k`` single-qubit
    depolarizing channels affects each implemented operation, where
    ``k`` is the number of qubits associated to the operation.

    This function internally calls
    :func:`represent_operation_with_local_depolarizing_noise` (more details
    about the quasi-probability representation can be found in its docstring).

    Args:
        ideal_circuit: The ideal circuit, whose ideal operations should be
            represented.
        noise_level: The (gate-independent) depolarizing noise level.

    Returns:
        The list of quasi-probability representations associated to
        the operations of the input ``ideal_circuit``.

    .. note::
        Measurement gates are ignored (not represented).

    .. note::
        The returned representations are always defined in terms of
        Cirq circuits, even if the input is not a ``cirq.Circuit``.
    """
    circ, _ = convert_to_mitiq(ideal_circuit)

    representations = []
    for op in set(circ.all_operations()):
        if is_measurement(op):
            continue
        representations.append(
            represent_operation_with_local_depolarizing_noise(
                Circuit(op),
                noise_level,
            )
        )
    return representations
Example #13
0
def test_aqt_sampler_sim():
    theta = sympy.Symbol('theta')
    num_points = 10
    max_angle = np.pi
    repetitions = 1000
    num_qubits = 4
    device, qubits = get_aqt_device(num_qubits)
    sampler = AQTSamplerLocalSimulator()
    sampler.simulate_ideal = True
    circuit = Circuit(X(qubits[3])**theta, device=device)
    sweep = study.Linspace(key='theta',
                           start=0.1,
                           stop=max_angle / np.pi,
                           length=num_points)
    results = sampler.run_sweep(circuit, params=sweep, repetitions=repetitions)
    excited_state_probs = np.zeros(num_points)
    for i in range(num_points):
        excited_state_probs[i] = np.mean(results[i].measurements['m'])
    assert excited_state_probs[-1] == 0.25
 def get_single_qubit_gate_layer(self, params):
     single_qubit_gate_layer = Circuit()
     alpha = params[0]
     beta = params[1]
     gamma = params[2]
     single_qubit_gate = np.array(
         [[
             np.exp(complex(0, beta)) * np.cos(alpha),
             np.exp(complex(0, gamma)) * np.sin(alpha)
         ],
          [
              -1 * np.exp(complex(0, -1 * gamma)) * np.sin(alpha),
              np.exp(complex(0, -1 * beta)) * np.cos(alpha)
          ]])
     G = SingleQubitMatrixGate(single_qubit_gate)
     for qubit in self.qubits:
         single_qubit_gate_layer.append([G(qubit)],
                                        strategy=InsertStrategy.EARLIEST)
     return single_qubit_gate_layer
Example #15
0
    def generate_circuit_from_list(self, json_string: str):
        """Generates a list of cirq operations from a json string.

        The default behavior is to add a measurement to any qubit at the end
        of the circuit as there are no measurements defined in the AQT API.

        Args:
            json_string: json that specifies the sequence
        """
        self.circuit = Circuit()
        json_obj = json.loads(json_string)
        for gate_list in json_obj:
            gate = gate_list[0]
            angle = gate_list[1]
            qubits = [self.qubit_list[i] for i in gate_list[2]]
            self.circuit.append(gate_dict[gate].on(*qubits)**angle)
        # TODO: Better solution for measurement at the end. Issue #2199
        self.circuit.append(
            ops.measure(*[qubit for qubit in self.qubit_list], key='m'))
Example #16
0
 def __init__(self,
              num_qubits: int,
              circuit: Circuit = Circuit(),
              simulate_ideal: bool = False,
              noise_dict: Union[dict, None] = None):
     """Initializes the AQT simulator
     Args:
         num_qubits: Number of qubits
         circuit: Optional, circuit to be simulated.
         Last moment needs to be a measurement over all qubits with key 'm'
         simulate_ideal: If True, an ideal circuit will be simulated
     """
     self.circuit = circuit
     self.num_qubits = num_qubits
     self.qubit_list = LineQubit.range(num_qubits)
     if noise_dict is None:
         noise_dict = get_default_noise_dict()
     self.noise_dict = noise_dict
     self.simulate_ideal = simulate_ideal
Example #17
0
def scale_parameters(
    circ: Circuit,
    scale_factor: float,
    sigma: float,
    seed: Optional[int] = None,
) -> Circuit:
    """Adds parameter noise to a circuit with level noise.
    This adds noise to the actual parameter instead of
    adding an parameter channel.

    Args:
        circ: The quantum program as a Cirq circuit object. All measurements
            should be in the last moment of the circuit.
        scale_factor: Amount to scale the base noise level of parameters by.
        sigma: Base noise level (variance) in parameter rotations
        seed: random seed

    Returns:
        The input circuit with scaled rotation angles

    """
    final_moments = []
    noise = (scale_factor - 1) * sigma
    rng = np.random.RandomState(seed)
    for moment in circ:
        curr_moment = []
        for op in moment.operations:
            gate = copy.deepcopy(op.gate)
            qubits = op.qubits
            if isinstance(gate, MeasurementGate):
                curr_moment.append(gate(*qubits))
            else:
                assert isinstance(gate, EigenGate)
                base_gate = _get_base_gate(gate)
                param = gate.exponent * np.pi
                error = rng.normal(loc=0.0, scale=np.sqrt(noise))
                new_param = param + error
                curr_moment.append(
                    base_gate(exponent=new_param / np.pi)(*qubits)
                )
        final_moments.append(Moment(curr_moment))
    return Circuit(final_moments)
Example #18
0
def test_extensions():
    # We test that an extension is being applied, by created an incorrect
    # gate with an extension.

    class WrongH(CompositeGate):
        def default_decompose(self,
                              qubits: Sequence[cirq.QubitId]) -> cirq.OP_TREE:
            return X(Q1)

    extensions = Extensions(
        desired_to_actual_to_wrapper={CompositeGate: {
            H: lambda e: WrongH()
        }})

    circuit = Circuit()
    circuit.append([WrongH()(Q1)])

    simulator = xmon_simulator.XmonSimulator()
    results = simulator.simulate(circuit, extensions=extensions)
    np.testing.assert_almost_equal(results.final_state, np.array([0, -1j]))
Example #19
0
def test_scale_with_measurement():
    """Tests that we ignore measurement gates.

    Test circuit:
    0: ───H───T───@───M───
                  │   │
    1: ───H───M───┼───┼───
                  │   │
    2: ───H───────X───M───

    """
    qreg = LineQubit.range(3)
    circ = Circuit(
        [ops.H.on_each(qreg)],
        [ops.T.on(qreg[0])],
        [ops.measure(qreg[1])],
        [ops.CNOT.on(qreg[0], qreg[2])],
        [ops.measure(qreg[0], qreg[2])],
    )
    scaled = scale_parameters(circ, scale_factor=1, sigma=0.001)
    assert _equal(circ, scaled)
Example #20
0
def qubit_ops_to_circuit(ops: 'QubitOperator',
                         qpu: List[LineQubit]) -> 'Circuit':
    """Generate a circuit that can be run on a Cirq simulator from the ops
    passed

    Args:
        ops (Qubit Operator) - a product of operations to compile into a
            circuit
        qpu (Qid) - the quantum processing unit that this circuit will be run
            on

    Returns:
        (circuit) - returns a circuit to run in cirq
    """
    gates = []
    for operation in ops:
        gate_type = operation[1]
        qubit = qpu[operation[0]]
        gates.append(qubit_op_to_gate(gate_type, qubit))
    moment = [Moment(gates)]
    return Circuit(moment)
Example #21
0
def test_r_gate():
    qasm = """
     OPENQASM 2.0;
     include "qelib1.inc";
     qreg q[1];
     r(pi, pi / 2.0) q[0];    
"""
    parser = QasmParser()

    q0 = cirq.NamedQubit('q_0')

    expected_circuit = Circuit()
    expected_circuit.append(QasmUGate(1.0, 0.0, 0.0)(q0))

    parsed_qasm = parser.parse(qasm)

    assert parsed_qasm.supportedFormat
    assert parsed_qasm.qelib1Include

    ct.assert_same_circuits(parsed_qasm.circuit, expected_circuit)
    assert parsed_qasm.qregs == {'q': 1}
Example #22
0
def scale_parameters(
    circuit: QPROGRAM,
    scale_factor: float,
    base_variance: float,
    seed: Optional[int] = None,
) -> Circuit:
    """Applies parameter-noise scaling to the input circuit,
    assuming that each gate has the same base level of noise.

    Args:
        circuit: The circuit to scale as a QPROGRAM. All measurements
            should be in the last moment of the circuit.
        scale_factor: The amount to scale the base noise level by.
        base_variance: The base level (variance) of parameter noise,
            assumed to be the same for each gate of the circuit.
        seed: Optional seed for random number generator.

    Returns:
        The parameter noise scaled circuit.
    """
    final_moments = []
    noise = (scale_factor - 1) * base_variance
    rng = np.random.RandomState(seed)
    for moment in circuit:
        curr_moment = []
        for op in moment.operations:  # type: ignore
            gate = copy.deepcopy(op.gate)
            qubits = op.qubits
            if isinstance(gate, MeasurementGate):
                curr_moment.append(gate(*qubits))
            else:
                assert isinstance(gate, EigenGate)
                base_gate = _get_base_gate(gate)
                param = gate.exponent * np.pi
                error = rng.normal(loc=0.0, scale=np.sqrt(noise))
                new_param = param + error
                curr_moment.append(
                    base_gate(exponent=new_param / np.pi)(*qubits))
        final_moments.append(Moment(curr_moment))
    return Circuit(final_moments)
Example #23
0
def _generate_parameter_calibration_circuit(qubits: List[Qid], depth: int,
                                            gate: EigenGate) -> Circuit:
    """Generates a circuit which should be the identity. Given a rotation
    gate R(param), it applies R(2 * pi / depth) depth times, resulting
    in R(2*pi). Requires that the gate is periodic in 2*pi.

    Args:
        qubits: A list of qubits.
        depth: The length of the circuit to create.
        gate: The base gate to apply several times, must be periodic
            in 2*pi.

    Returns:
        A parameter calibration circuit that can be used for estimating
        the parameter noise of the input gate.
    """
    num_qubits = gate().num_qubits()
    if num_qubits != len(qubits):
        raise CircuitMismatchException(
            "Number of qubits does not match domain size of gate.")
    return Circuit(
        gate(exponent=2 * np.pi / depth).on(*qubits) for _ in range(depth))
Example #24
0
def test_expressions(expr: str):
    qasm = f"""OPENQASM 2.0;
     qreg q[1];
     U({expr}, 2 * pi, pi / 2.0) q[0];
"""

    parser = QasmParser()

    q0 = cirq.NamedQubit('q_0')

    expected_circuit = Circuit()
    expected_circuit.append(QasmUGate(float(sympy.sympify(expr)) / np.pi, 2.0, 1 / 2.0)(q0))

    parsed_qasm = parser.parse(qasm)

    assert parsed_qasm.supportedFormat
    assert not parsed_qasm.qelib1Include

    ct.assert_allclose_up_to_global_phase(
        cirq.unitary(parsed_qasm.circuit), cirq.unitary(expected_circuit), atol=1e-10
    )
    assert parsed_qasm.qregs == {'q': 1}
Example #25
0
def test_three_qubit_gates(qasm_gate: str, cirq_gate: cirq.TwoQubitGate):
    qasm = """
     OPENQASM 2.0;
     include "qelib1.inc";       
     qreg q1[2];
     qreg q2[2];
     qreg q3[2];
     {0} q1[0], q1[1], q2[0];
     {0} q1, q2[0], q3[0];
     {0} q1, q2, q3;      
""".format(
        qasm_gate
    )
    parser = QasmParser()

    q1_0 = cirq.NamedQubit('q1_0')
    q1_1 = cirq.NamedQubit('q1_1')
    q2_0 = cirq.NamedQubit('q2_0')
    q2_1 = cirq.NamedQubit('q2_1')
    q3_0 = cirq.NamedQubit('q3_0')
    q3_1 = cirq.NamedQubit('q3_1')

    expected_circuit = Circuit()

    expected_circuit.append(cirq_gate(q1_0, q1_1, q2_0))

    expected_circuit.append(cirq_gate(q1_0, q2_0, q3_0))
    expected_circuit.append(cirq_gate(q1_1, q2_0, q3_0))

    expected_circuit.append(cirq_gate(q1_0, q2_0, q3_0))
    expected_circuit.append(cirq_gate(q1_1, q2_1, q3_1))

    parsed_qasm = parser.parse(qasm)

    assert parsed_qasm.supportedFormat
    assert parsed_qasm.qelib1Include

    ct.assert_same_circuits(parsed_qasm.circuit, expected_circuit)
    assert parsed_qasm.qregs == {'q1': 2, 'q2': 2, 'q3': 2}
def test_from_braket_non_parameterized_single_qubit_gates():
    braket_circuit = BKCircuit()
    instructions = [
        Instruction(braket_gates.I(), target=0),
        Instruction(braket_gates.X(), target=1),
        Instruction(braket_gates.Y(), target=2),
        Instruction(braket_gates.Z(), target=3),
        Instruction(braket_gates.H(), target=0),
        Instruction(braket_gates.S(), target=1),
        Instruction(braket_gates.Si(), target=2),
        Instruction(braket_gates.T(), target=3),
        Instruction(braket_gates.Ti(), target=0),
        Instruction(braket_gates.V(), target=1),
        Instruction(braket_gates.Vi(), target=2),
    ]
    for instr in instructions:
        braket_circuit.add_instruction(instr)
    cirq_circuit = from_braket(braket_circuit)

    for i, op in enumerate(cirq_circuit.all_operations()):
        assert np.allclose(
            instructions[i].operator.to_matrix(), protocols.unitary(op)
        )

    qreg = LineQubit.range(4)
    expected_cirq_circuit = Circuit(
        ops.I(qreg[0]),
        ops.X(qreg[1]),
        ops.Y(qreg[2]),
        ops.Z(qreg[3]),
        ops.H(qreg[0]),
        ops.S(qreg[1]),
        ops.S(qreg[2]) ** -1,
        ops.T(qreg[3]),
        ops.T(qreg[0]) ** -1,
        ops.X(qreg[1]) ** 0.5,
        ops.X(qreg[2]) ** -0.5,
    )
    assert _equal(cirq_circuit, expected_cirq_circuit)
Example #27
0
    def create_initial_state(self, driver_ref):
        """
        Generates a circuit representing the initial state of the QAOA algorithm
        on which the cost and driver operators are alternatively applied

        Parameters
        ----------
        driver_ref          :   (Circuit object) circuit representing the initial state. If driver_ref is None,
                                the function returns state representing equal superposition over
                                all qubits

        Returns
        -------
        circuit             :   (Circuit object) represents the initial state for the QAOA algorithm
        """
        if driver_ref is not None:
            return driver_ref

        circuit = Circuit()
        circuit.append([H(i) for i in self.qubits],
                       strategy=InsertStrategy.EARLIEST)
        return circuit
Example #28
0
def test_find_optimal_representation_depolarizing_two_qubit_gates(circ_type):
    """Test optimal representation agrees with a known analytic result."""
    for ideal_gate, noise_level in product([CNOT, CZ], [0.1, 0.5]):
        q = LineQubit.range(2)
        ideal_op = Circuit(ideal_gate(*q))
        implementable_circuits = [Circuit(ideal_op)]
        # Append two-qubit-gate with Paulis on one qubit
        for gate in [X, Y, Z]:
            implementable_circuits.append(Circuit([ideal_op, gate(q[0])]))
            implementable_circuits.append(Circuit([ideal_op, gate(q[1])]))
        # Append two-qubit gate with Paulis on both qubits
        for gate_a, gate_b in product([X, Y, Z], repeat=2):
            implementable_circuits.append(
                Circuit([ideal_op, gate_a(q[0]), gate_b(q[1])])
            )
        noisy_circuits = [
            circ + Circuit(DepolarizingChannel(noise_level).on_each(*q))
            for circ in implementable_circuits
        ]
        super_operators = [
            choi_to_super(_circuit_to_choi(circ)) for circ in noisy_circuits
        ]

        # Define circuits with native types
        implementable_native = [
            convert_from_mitiq(c, circ_type) for c in implementable_circuits
        ]
        ideal_op_native = convert_from_mitiq(ideal_op, circ_type)

        noisy_operations = [
            NoisyOperation(ideal, real)
            for ideal, real in zip(implementable_native, super_operators)
        ]

        # Find optimal representation
        noisy_basis = NoisyBasis(*noisy_operations)
        rep = find_optimal_representation(
            ideal_op_native, noisy_basis, tol=1.0e-8
        )
        # Expected analytical result
        expected_rep = represent_operation_with_local_depolarizing_noise(
            ideal_op_native,
            noise_level,
        )
        assert np.allclose(np.sort(rep.coeffs), np.sort(expected_rep.coeffs))
        assert rep == expected_rep
Example #29
0
def test_id_gate():
    qasm = """
     OPENQASM 2.0;
     include "qelib1.inc";
     qreg q[2];
     id q;           
"""
    parser = QasmParser()

    q0 = cirq.NamedQubit('q_0')
    q1 = cirq.NamedQubit('q_1')

    expected_circuit = Circuit()
    expected_circuit.append(cirq.IdentityGate(num_qubits=1)(q0))
    expected_circuit.append(cirq.IdentityGate(num_qubits=1)(q1))

    parsed_qasm = parser.parse(qasm)

    assert parsed_qasm.supportedFormat
    assert parsed_qasm.qelib1Include

    ct.assert_same_circuits(parsed_qasm.circuit, expected_circuit)
    assert parsed_qasm.qregs == {'q': 2}
Example #30
0
def test_non_identity_scale_2q():
    """Tests that when scale factor = 1, the circuit is the
    same.
    """
    qreg = LineQubit.range(2)
    circ = Circuit([ops.CNOT.on(qreg[0], qreg[1])])
    np.random.seed(42)
    stretch = 2
    base_noise = 0.001
    noises = np.random.normal(loc=0.0,
                              scale=np.sqrt((stretch - 1) * base_noise),
                              size=(1, ))
    np.random.seed(42)
    scaled = scale_parameters(circ,
                              scale_factor=stretch,
                              sigma=base_noise,
                              seed=42)
    result = []
    for moment in scaled:
        for op in moment.operations:
            gate = deepcopy(op.gate)
            param = gate.exponent
            result.append(param * np.pi - np.pi)
    assert np.all(np.isclose(result - noises, 0))