예제 #1
0
def test_find_optimal_representation_no_superoperator_error():
    q = LineQubit(0)
    # Define noisy operation without superoperator matrix
    noisy_op = NoisyOperation(Circuit(X(q)))
    noisy_basis = NoisyBasis(noisy_op)
    with raises(ValueError, match="numerical superoperator matrix"):
        find_optimal_representation(Circuit(X(q)), noisy_basis)
예제 #2
0
def test_noisy_basis_add_bad_types():
    rng = np.random.RandomState(seed=1)
    noisy_basis = NoisyBasis(
        NoisyOperation.from_cirq(ideal=cirq.I, real=rng.rand(4, 4)),
        NoisyOperation.from_cirq(ideal=cirq.X, real=rng.rand(4, 4)),
    )

    with pytest.raises(TypeError, match="All basis elements must be of type"):
        noisy_basis.add(cirq.Y)
예제 #3
0
def test_extend_to_simple():
    rng = np.random.RandomState(seed=1)
    noisy_basis = NoisyBasis(
        NoisyOperation.from_cirq(ideal=cirq.I, real=rng.rand(4, 4)),
        NoisyOperation.from_cirq(ideal=cirq.X, real=rng.rand(4, 4)),
    )
    assert len(noisy_basis.elements) == 2

    noisy_basis.extend_to(cirq.LineQubit.range(1, 3))
    assert len(noisy_basis.elements) == 6
예제 #4
0
def test_noisy_basis_simple():
    rng = np.random.RandomState(seed=1)
    noisy_basis = NoisyBasis(
        NoisyOperation.from_cirq(ideal=cirq.I, real=rng.rand(4, 4)),
        NoisyOperation.from_cirq(ideal=cirq.X, real=rng.rand(4, 4)),
        NoisyOperation.from_cirq(ideal=cirq.Y, real=rng.rand(4, 4)),
        NoisyOperation.from_cirq(ideal=cirq.Z, real=rng.rand(4, 4)),
    )
    assert len(noisy_basis) == 4
    assert noisy_basis.all_qubits() == {cirq.LineQubit(0)}
예제 #5
0
def test_get_sequences_simple(length):
    rng = np.random.RandomState(seed=1)
    noisy_basis = NoisyBasis(
        NoisyOperation.from_cirq(ideal=cirq.I, real=rng.rand(4, 4)),
        NoisyOperation.from_cirq(ideal=cirq.X, real=rng.rand(4, 4)),
    )

    sequences = noisy_basis.get_sequences(length=length)
    assert all(isinstance(s, NoisyOperation) for s in sequences)
    assert len(sequences) == len(noisy_basis) ** length

    for sequence in sequences:
        assert len(sequence.ideal_circuit()) == length
예제 #6
0
def test_noisy_basis_add():
    rng = np.random.RandomState(seed=1)
    noisy_basis = NoisyBasis(
        NoisyOperation.from_cirq(ideal=cirq.I, real=rng.rand(4, 4)),
        NoisyOperation.from_cirq(ideal=cirq.X, real=rng.rand(4, 4)),
    )
    assert len(noisy_basis) == 2

    noisy_basis.add(
        NoisyOperation.from_cirq(ideal=cirq.Y, real=rng.rand(4, 4)),
        NoisyOperation.from_cirq(ideal=cirq.Z, real=rng.rand(4, 4)),
    )
    assert len(noisy_basis) == 4
예제 #7
0
def test_noisy_basis_simple():
    rng = np.random.RandomState(seed=1)
    noisy_basis = NoisyBasis(
        NoisyOperation.from_cirq(circuit=cirq.I, channel_matrix=rng.rand(4,
                                                                         4)),
        NoisyOperation.from_cirq(circuit=cirq.X, channel_matrix=rng.rand(4,
                                                                         4)),
        NoisyOperation.from_cirq(circuit=cirq.Y, channel_matrix=rng.rand(4,
                                                                         4)),
        NoisyOperation.from_cirq(circuit=cirq.Z, channel_matrix=rng.rand(4,
                                                                         4)),
    )
    assert len(noisy_basis) == 4
    assert noisy_basis.all_qubits() == {cirq.LineQubit(0)}
예제 #8
0
def test_pyquil_noisy_basis():
    rng = np.random.RandomState(seed=1)

    noisy_basis = NoisyBasis(
        NoisyOperation(ideal=pyquil.Program(pyquil.gates.I(0)),
                       real=rng.rand(4, 4)),
        NoisyOperation(ideal=pyquil.Program(pyquil.gates.Y(0)),
                       real=rng.rand(4, 4)),
    )
    assert len(noisy_basis) == 2

    for op in noisy_basis.elements:
        assert isinstance(op.ideal_circuit(), pyquil.Program)
        assert isinstance(op._ideal, cirq.Circuit)
예제 #9
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
예제 #10
0
def test_noisy_basis_add():
    rng = np.random.RandomState(seed=1)
    noisy_basis = NoisyBasis(
        NoisyOperation.from_cirq(circuit=cirq.I, channel_matrix=rng.rand(4,
                                                                         4)),
        NoisyOperation.from_cirq(circuit=cirq.X, channel_matrix=rng.rand(4,
                                                                         4)),
    )
    assert len(noisy_basis) == 2

    noisy_basis.add(
        NoisyOperation.from_cirq(circuit=cirq.Y, channel_matrix=rng.rand(4,
                                                                         4)),
        NoisyOperation.from_cirq(circuit=cirq.Z, channel_matrix=rng.rand(4,
                                                                         4)),
    )
    assert len(noisy_basis) == 4
예제 #11
0
def test_qiskit_noisy_basis():
    rng = np.random.RandomState(seed=1)

    qreg = qiskit.QuantumRegister(1)
    xcirc = qiskit.QuantumCircuit(qreg)
    _ = xcirc.x(qreg)
    zcirc = qiskit.QuantumCircuit(qreg)
    _ = zcirc.z(qreg)

    noisy_basis = NoisyBasis(
        NoisyOperation(ideal=xcirc, real=rng.rand(4, 4)),
        NoisyOperation(ideal=zcirc, real=rng.rand(4, 4)),
    )
    assert len(noisy_basis) == 2

    for op in noisy_basis.elements:
        assert isinstance(op.ideal_circuit(), qiskit.QuantumCircuit)
        assert isinstance(op._ideal, cirq.Circuit)
예제 #12
0
def test_pyquil_noisy_basis():
    rng = np.random.RandomState(seed=1)

    noisy_basis = NoisyBasis(
        NoisyOperation(
            circuit=pyquil.Program(pyquil.gates.I(0)),
            channel_matrix=rng.rand(4, 4),
        ),
        NoisyOperation(
            circuit=pyquil.Program(pyquil.gates.Y(0)),
            channel_matrix=rng.rand(4, 4),
        ),
    )
    assert len(noisy_basis) == 2

    for op in noisy_basis.elements:
        assert isinstance(op.circuit(), pyquil.Program)
        assert isinstance(op._circuit, cirq.Circuit)
예제 #13
0
def test_find_optimal_representation_single_qubit_amp_damping(circ_type):
    """Test optimal representation of agrees with a known analytic result."""
    for ideal_gate, noise_level in product([X, Y, H], [0.1, 0.3]):
        q = LineQubit(0)

        ideal_op = Circuit(ideal_gate(q))
        implementable_circuits = [Circuit(ideal_op)]
        # Add ideal gate followed by Paulis and reset
        for gate in [Z, reset]:
            implementable_circuits.append(Circuit([ideal_op, gate(q)]))

        noisy_circuits = [
            circ + Circuit(AmplitudeDampingChannel(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-7, initial_guess=[0, 0, 0]
        )
        # Expected analytical result
        expected_rep = _represent_operation_with_amplitude_damping_noise(
            ideal_op_native,
            noise_level,
        )
        assert np.allclose(np.sort(rep.coeffs), np.sort(expected_rep.coeffs))
        assert rep == expected_rep
예제 #14
0
def test_noisy_basis_bad_types(element):
    with pytest.raises(ValueError, match="must be of type `NoisyOperation`"):
        NoisyBasis(element)