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)
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)
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
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)}
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
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
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)}
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)
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
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
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)
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)
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
def test_noisy_basis_bad_types(element): with pytest.raises(ValueError, match="must be of type `NoisyOperation`"): NoisyBasis(element)