def test_print_operation_representation_two_qubits_neg(): qreg = cirq.LineQubit.range(2) ideal = cirq.Circuit(cirq.CNOT(*qreg)) noisy_a = NoisyOperation.from_cirq( circuit=cirq.Circuit(cirq.H.on_each(qreg[0]), cirq.CNOT( *qreg), cirq.H.on_each(qreg[1]))) noisy_b = NoisyOperation.from_cirq( circuit=cirq.Circuit(cirq.Z.on_each(qreg[1]))) decomp = OperationRepresentation( ideal=ideal, basis_expansion={ noisy_a: -0.5, noisy_b: 1.5, }, ) print(str(decomp)) expected = f""" 0: ───@─── │ 1: ───X─── ={" "} -0.500 0: ───H───@─────── │ 1: ───────X───H─── +1.500 1: ───Z───""" # Remove initial newline expected = expected[1:] assert str(decomp) == expected
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_print_cirq_operation_representation(): ideal = cirq.Circuit(cirq.H(cirq.LineQubit(0))) noisy_xop = NoisyOperation.from_cirq(circuit=cirq.X, channel_matrix=np.zeros(shape=(4, 4))) noisy_zop = NoisyOperation.from_cirq(circuit=cirq.Z, channel_matrix=np.zeros(shape=(4, 4))) # Positive first coefficient decomp = OperationRepresentation( ideal=ideal, basis_expansion={ noisy_xop: 0.5, noisy_zop: 0.5, }, ) expected = r"0: ───H─── = 0.500*(0: ───X───)+0.500*(0: ───Z───)" assert str(decomp) == expected # Negative first coefficient decomp = OperationRepresentation( ideal=ideal, basis_expansion={ noisy_xop: -0.5, noisy_zop: 1.5, }, ) expected = r"0: ───H─── = -0.500*(0: ───X───)+1.500*(0: ───Z───)" assert str(decomp) == expected # Empty representation decomp = OperationRepresentation(ideal=ideal, basis_expansion={}) expected = r"0: ───H─── = 0.000" assert str(decomp) == expected # Small coefficient approximation decomp = OperationRepresentation( ideal=ideal, basis_expansion={ noisy_xop: 1.00001, noisy_zop: 0.00001 }, ) expected = r"0: ───H─── = 1.000*(0: ───X───)" assert str(decomp) == expected # Small coefficient approximation different position decomp = OperationRepresentation( ideal=ideal, basis_expansion={ noisy_xop: 0.00001, noisy_zop: 1.00001 }, ) expected = r"0: ───H─── = 1.000*(0: ───Z───)" # Small coefficient approximation different position decomp = OperationRepresentation( ideal=ideal, basis_expansion={noisy_xop: 0.00001}, ) expected = r"0: ───H─── = 0.000" assert str(decomp) == expected
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_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_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_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_representation_coeff_of_nonexistant_operation(): qbit = cirq.LineQubit(0) ideal = cirq.Circuit(cirq.X(qbit)) noisy_xop = NoisyOperation.from_cirq(circuit=cirq.X, channel_matrix=np.zeros(shape=(4, 4))) decomp = OperationRepresentation(ideal=ideal, basis_expansion=dict([(noisy_xop, 0.5)])) noisy_zop = NoisyOperation.from_cirq(circuit=cirq.Z, channel_matrix=np.zeros(shape=(4, 4))) with pytest.raises(ValueError, match="does not appear in the basis"): decomp.coeff_of(noisy_zop)
def get_test_representation(): ideal = cirq.Circuit(cirq.H(cirq.LineQubit(0))) noisy_xop = NoisyOperation.from_cirq( ideal=cirq.X, real=np.zeros(shape=(4, 4)) ) noisy_zop = NoisyOperation.from_cirq( ideal=cirq.Z, real=np.zeros(shape=(4, 4)) ) decomp = OperationRepresentation( ideal=ideal, basis_expansion={noisy_xop: 0.5, noisy_zop: -0.5} ) return ideal, noisy_xop, noisy_zop, decomp
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_transform_qubits_single_qubit(qubit, real): gate = cirq.H noisy_op = NoisyOperation.from_cirq(gate, real) assert set(noisy_op.qubits) != {qubit} noisy_op.transform_qubits(qubit) assert set(noisy_op.qubits) == {qubit}
def test_print_cirq_operation_representation(): ideal = cirq.Circuit(cirq.H(cirq.LineQubit(0))) noisy_xop = NoisyOperation.from_cirq( ideal=cirq.X, real=np.zeros(shape=(4, 4)) ) noisy_zop = NoisyOperation.from_cirq( ideal=cirq.Z, real=np.zeros(shape=(4, 4)) ) decomp = OperationRepresentation( ideal=ideal, basis_expansion={noisy_xop: 0.5, noisy_zop: 0.5, }, ) expected = r"0: ───H─── = 0.500*0: ───X───+0.500*0: ───Z───" assert str(decomp) == expected
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_representation_bad_type_for_basis_expansion(): ideal = cirq.Circuit(cirq.H(cirq.LineQubit(0))) noisy_xop = NoisyOperation.from_cirq(circuit=cirq.X, channel_matrix=np.zeros(shape=(4, 4))) with pytest.raises(TypeError, match="All keys of `basis_expansion` must"): OperationRepresentation(ideal=ideal, basis_expansion=dict([(1.0, noisy_xop)]))
def test_representation_sample_zero_coefficient(): ideal = cirq.Circuit(cirq.H(cirq.LineQubit(0))) noisy_xop = NoisyOperation.from_cirq(circuit=cirq.X, channel_matrix=np.zeros(shape=(4, 4))) noisy_zop = NoisyOperation.from_cirq(circuit=cirq.Z, channel_matrix=np.zeros(shape=(4, 4))) decomp = OperationRepresentation( ideal=ideal, basis_expansion={ noisy_xop: 0.5, noisy_zop: 0.0, # This should never be sampled. }, ) random_state = np.random.RandomState(seed=1) for _ in range(500): noisy_op, sign, coeff = decomp.sample(random_state=random_state) assert sign == 1 assert coeff == 0.5 assert np.allclose(noisy_op.ideal_unitary, cirq.unitary(cirq.X))
def test_extend_to_single_qubit(real): qbit, qreg = cirq.LineQubit(0), cirq.LineQubit.range(1, 10) ideal = cirq.Z.on(qbit) noisy_op_on_one_qubit = NoisyOperation.from_cirq(ideal, real) noisy_ops_on_all_qubits = noisy_op_on_one_qubit.extend_to(qreg) assert isinstance(noisy_ops_on_all_qubits, list) assert len(noisy_ops_on_all_qubits) == 10 for op in noisy_ops_on_all_qubits: assert _equal(op.ideal_circuit(), cirq.Circuit(ideal)) assert np.allclose(op.ideal_unitary, cirq.unitary(ideal)) if real is not None: assert np.allclose(op.real_matrix, real)
def test_init_with_op_tree(): qreg = cirq.LineQubit.range(2) ideal_ops = [cirq.H.on(qreg[0]), cirq.CNOT.on(*qreg)] real = np.zeros(shape=(16, 16)) noisy_op = NoisyOperation.from_cirq(ideal_ops, real) assert isinstance(noisy_op._circuit, cirq.Circuit) assert _equal( noisy_op.circuit(), cirq.Circuit(ideal_ops), require_qubit_equality=True, ) assert set(noisy_op.qubits) == set(qreg) assert np.allclose(noisy_op.ideal_unitary, cirq.unitary(cirq.Circuit(ideal_ops))) assert np.allclose(noisy_op.channel_matrix, real) assert noisy_op.channel_matrix is not real
def test_init_with_operation(qubit): ideal_op = cirq.H.on(qubit) real = np.zeros(shape=(4, 4)) noisy_op = NoisyOperation.from_cirq(ideal_op, real) assert isinstance(noisy_op._ideal, cirq.Circuit) assert _equal( noisy_op.ideal_circuit(), cirq.Circuit(ideal_op), require_qubit_equality=True, ) assert noisy_op.qubits == (qubit,) assert np.allclose(noisy_op.ideal_unitary, cirq.unitary(ideal_op)) assert np.allclose(noisy_op.real_matrix, real) assert noisy_op.real_matrix is not real assert noisy_op._native_type == "cirq" assert _equal(noisy_op._native_ideal, noisy_op.ideal_circuit())
def test_init_with_gate(): ideal_gate = cirq.Z real = np.zeros(shape=(4, 4)) noisy_op = NoisyOperation.from_cirq(ideal_gate, real) assert isinstance(noisy_op._ideal, cirq.Circuit) assert _equal( noisy_op.ideal_circuit(), cirq.Circuit(ideal_gate.on(cirq.LineQubit(0))), require_qubit_equality=False, ) assert noisy_op.qubits == (cirq.LineQubit(0),) assert np.allclose(noisy_op.ideal_unitary, cirq.unitary(cirq.Z)) assert np.allclose(noisy_op.real_matrix, real) assert noisy_op.real_matrix is not real assert noisy_op._native_type == "cirq" assert _equal(noisy_op._native_ideal, noisy_op.ideal_circuit())
def test_noisy_operation_str(): noisy_op = NoisyOperation.from_cirq(circuit=cirq.I, channel_matrix=np.identity(4)) assert isinstance(noisy_op.__str__(), str)
def test_init_with_bad_types(): ideal_ops = [cirq.H, cirq.CNOT] real = np.zeros(shape=(16, 16)) with pytest.raises(ValueError, match="must be cirq.CIRCUIT_LIKE"): NoisyOperation.from_cirq(ideal_ops, real)
def test_noisy_operation_str(): noisy_op = NoisyOperation.from_cirq(ideal=cirq.I, real=np.identity(4)) assert isinstance(noisy_op.__str__(), str)