def test_pauli_string_expectation_value_pure_state_with_coef(): qs = cirq.LineQubit.range(4) qubit_index_map = {q: i for i, q in enumerate(qs)} circuit = cirq.Circuit.from_ops( cirq.X(qs[1]), cirq.H(qs[2]), cirq.X(qs[3]), cirq.H(qs[3]), ) wavefunction = circuit.apply_unitary_effect_to_state(qubit_order=qs) density_matrix = np.outer(wavefunction, np.conj(wavefunction)) z0z1 = cirq.pauli_string_expectation(cirq.Z(qs[0]) * cirq.Z(qs[1]) * .123) z0z2 = cirq.pauli_string_expectation(cirq.Z(qs[0]) * cirq.Z(qs[2]) * -1) z1x2 = cirq.pauli_string_expectation(-cirq.Z(qs[1]) * cirq.X(qs[2])) np.testing.assert_allclose( z0z1.value_derived_from_wavefunction(wavefunction, qubit_index_map), -0.123) np.testing.assert_allclose( z0z2.value_derived_from_wavefunction(wavefunction, qubit_index_map), 0) np.testing.assert_allclose( z1x2.value_derived_from_wavefunction(wavefunction, qubit_index_map), 1) np.testing.assert_allclose( z0z1.value_derived_from_density_matrix(density_matrix, qubit_index_map), -0.123) np.testing.assert_allclose( z0z2.value_derived_from_density_matrix(density_matrix, qubit_index_map), 0) np.testing.assert_allclose( z1x2.value_derived_from_density_matrix(density_matrix, qubit_index_map), 1)
def test_compute_samples_displays(dtype): a, b, c = cirq.LineQubit.range(3) circuit = cirq.Circuit.from_ops( cirq.X(a), cirq.H(b), cirq.X(c), cirq.H(c), cirq.pauli_string_expectation(cirq.PauliString({c: cirq.X}), key='x3'), cirq.pauli_string_expectation(cirq.PauliString({ a: cirq.Z, b: cirq.X }), num_samples=10, key='approx_z1x2'), cirq.pauli_string_expectation(cirq.PauliString({ a: cirq.Z, c: cirq.X }), num_samples=10, key='approx_z1x3'), ) simulator = cirq.DensityMatrixSimulator(dtype=dtype) result = simulator.compute_samples_displays(circuit) assert 'x3' not in result.display_values np.testing.assert_allclose(result.display_values['approx_z1x2'], -1, atol=1e-7) np.testing.assert_allclose(result.display_values['approx_z1x3'], 1, atol=1e-7)
def test_pauli_string_expectation_helper(): qubits = cirq.LineQubit.range(9) qubit_pauli_map = {q: cirq.Pauli.by_index(q.x) for q in qubits} pauli_string = cirq.PauliString(qubit_pauli_map, -1) assert (cirq.pauli_string_expectation(pauli_string, key='a') == cirq.pauli_string_expectation(pauli_string, key='a')) assert (cirq.pauli_string_expectation(pauli_string, 5, key='a') == cirq.pauli_string_expectation(pauli_string, 5, key='a'))
def test_with_qubits(): old_qubits = cirq.LineQubit.range(9) new_qubits = cirq.LineQubit.range(9, 18) qubit_pauli_map = {q: cirq.Pauli.by_index(q.x) for q in old_qubits} pauli_string = cirq.PauliString(qubit_pauli_map, -1) assert (cirq.pauli_string_expectation(pauli_string).with_qubits( *new_qubits) == cirq.pauli_string_expectation( pauli_string.with_qubits(*new_qubits))) assert (cirq.pauli_string_expectation( pauli_string, num_samples=1).with_qubits( *new_qubits) == cirq.pauli_string_expectation( pauli_string.with_qubits(*new_qubits), num_samples=1))
def test_properties(): qubits = cirq.LineQubit.range(9) qubit_pauli_map = {q: cirq.Pauli.by_index(q.x) for q in qubits} pauli_string = cirq.PauliString(qubit_pauli_map, -1) pauli_string_expectation = cirq.pauli_string_expectation(pauli_string, key='a') assert pauli_string_expectation.qubits == tuple(qubits) assert pauli_string_expectation.key == 'a' approx_pauli_string_expectation = cirq.pauli_string_expectation( pauli_string, num_samples=5, key='a') assert approx_pauli_string_expectation.qubits == tuple(qubits) assert approx_pauli_string_expectation.num_samples == 5 assert approx_pauli_string_expectation.key == 'a'
def test_pauli_string_expectation_value_mixed_state_linearity(): n_qubits = 10 wavefunction1 = cirq.testing.random_superposition(2**n_qubits) wavefunction2 = cirq.testing.random_superposition(2**n_qubits) rho1 = np.outer(wavefunction1, np.conj(wavefunction1)) rho2 = np.outer(wavefunction2, np.conj(wavefunction2)) density_matrix = rho1 + rho2 qubits = cirq.LineQubit.range(n_qubits) qubit_index_map = {q: i for i, q in enumerate(qubits)} paulis = [cirq.X, cirq.Y, cirq.Z] pauli_string_expectation = cirq.pauli_string_expectation( cirq.PauliString({q: np.random.choice(paulis) for q in qubits})) a = pauli_string_expectation.value_derived_from_wavefunction( wavefunction1, qubit_index_map) b = pauli_string_expectation.value_derived_from_wavefunction( wavefunction2, qubit_index_map) c = pauli_string_expectation.value_derived_from_density_matrix( density_matrix, qubit_index_map) np.testing.assert_allclose(a + b, c)
def test_approx_pauli_string_expectation_value_with_coef( measurements, value, coefficient): display = cirq.pauli_string_expectation(cirq.PauliString( {}, coefficient=coefficient), num_samples=1) assert display.value_derived_from_samples( measurements) == value * coefficient
def hhl_circuit(A, C, t, register_size, *input_prep_gates): """ Constructs the HHL circuit. A is the input Hermitian matrix. C and t are tunable parameters for the algorithm. register_size is the size of the eigenvalue register. input_prep_gates is a list of gates to be applied to |0> to generate the desired input state |b>. """ ancilla = cirq.GridQubit(0, 0) # to store eigenvalues of the matrix register = [cirq.GridQubit(i + 1, 0) for i in range(register_size)] # to store input and output vectors memory = cirq.GridQubit(register_size + 1, 0) c = cirq.Circuit() hs = HamiltonianSimulation(A, t) pe = PhaseEstimation(register_size + 1, hs) c.append([gate(memory) for gate in input_prep_gates]) c.append([ pe(*(register + [memory])), EigenRotation(register_size + 1, C, t)(*(register + [ancilla])), pe(*(register + [memory]))**-1, cirq.measure(ancilla) ]) # Pauli observable display c.append([ cirq.pauli_string_expectation(cirq.PauliString({ancilla: cirq.Z}), key='a'), cirq.pauli_string_expectation(cirq.PauliString({memory: cirq.X}), key='x'), cirq.pauli_string_expectation(cirq.PauliString({memory: cirq.Y}), key='y'), cirq.pauli_string_expectation(cirq.PauliString({memory: cirq.Z}), key='z'), ]) return c
def test_compute_displays(dtype): qubits = cirq.LineQubit.range(4) circuit = cirq.Circuit.from_ops( cirq.pauli_string_expectation( cirq.PauliString({qubits[3]: cirq.Z}), key='z3' ), cirq.X(qubits[1]), cirq.pauli_string_expectation( cirq.PauliString({qubits[0]: cirq.Z, qubits[1]: cirq.Z}), key='z0z1' ), cirq.pauli_string_expectation( cirq.PauliString({qubits[0]: cirq.Z, qubits[1]: cirq.X}), key='z0x1' ), cirq.H(qubits[2]), cirq.X(qubits[3]), cirq.H(qubits[3]), cirq.pauli_string_expectation( cirq.PauliString({qubits[1]: cirq.Z, qubits[2]: cirq.X}), key='z1x2' ), cirq.pauli_string_expectation( cirq.PauliString({qubits[0]: cirq.X, qubits[1]: cirq.Z}), key='x0z1' ), cirq.pauli_string_expectation( cirq.PauliString({qubits[3]: cirq.X}), key='x3' ), cirq.pauli_string_expectation( cirq.PauliString({qubits[1]: cirq.Z, qubits[2]: cirq.X}), num_samples=1, key='approx_z1x2' ), ) simulator = cirq.DensityMatrixSimulator(dtype=dtype) initial_state = cirq.sim.density_matrix_utils.to_valid_density_matrix( 0, num_qubits=len(qubits), dtype=dtype) result = simulator.compute_displays(circuit, initial_state=initial_state) np.testing.assert_allclose(result.display_values['z3'], 1, atol=1e-7) np.testing.assert_allclose(result.display_values['z0z1'], -1, atol=1e-7) np.testing.assert_allclose(result.display_values['z0x1'], 0, atol=1e-7) np.testing.assert_allclose(result.display_values['z1x2'], -1, atol=1e-7) np.testing.assert_allclose(result.display_values['x0z1'], 0, atol=1e-7) np.testing.assert_allclose(result.display_values['x3'], -1, atol=1e-7) np.testing.assert_allclose(result.display_values['approx_z1x2'], -1, atol=1e-7)
def test_compute_displays(dtype): qubits = cirq.LineQubit.range(4) circuit = cirq.Circuit.from_ops( cirq.pauli_string_expectation( cirq.PauliString({qubits[3]: cirq.Z}), key='z3' ), cirq.X(qubits[1]), cirq.pauli_string_expectation( cirq.PauliString({qubits[0]: cirq.Z, qubits[1]: cirq.Z}), key='z0z1' ), cirq.pauli_string_expectation( cirq.PauliString({qubits[0]: cirq.Z, qubits[1]: cirq.X}), key='z0x1' ), cirq.H(qubits[2]), cirq.X(qubits[3]), cirq.H(qubits[3]), cirq.pauli_string_expectation( cirq.PauliString({qubits[1]: cirq.Z, qubits[2]: cirq.X}), key='z1x2' ), cirq.pauli_string_expectation( cirq.PauliString({qubits[0]: cirq.X, qubits[1]: cirq.Z}), key='x0z1' ), cirq.pauli_string_expectation( cirq.PauliString({qubits[3]: cirq.X}), key='x3' ), cirq.pauli_string_expectation( cirq.PauliString({qubits[1]: cirq.Z, qubits[2]: cirq.X}), num_samples=1, key='approx_z1x2' ), ) simulator = cirq.Simulator(dtype=dtype) result = simulator.compute_displays(circuit) np.testing.assert_allclose(result.display_values['z3'], 1, atol=1e-7) np.testing.assert_allclose(result.display_values['z0z1'], -1, atol=1e-7) np.testing.assert_allclose(result.display_values['z0x1'], 0, atol=1e-7) np.testing.assert_allclose(result.display_values['z1x2'], -1, atol=1e-7) np.testing.assert_allclose(result.display_values['x0z1'], 0, atol=1e-7) np.testing.assert_allclose(result.display_values['x3'], -1, atol=1e-7) np.testing.assert_allclose(result.display_values['approx_z1x2'], -1, atol=1e-7)
def test_approx_pauli_string_expectation_measurement_basis_change(paulis): qubits = cirq.LineQubit.range(2) display = cirq.pauli_string_expectation(cirq.PauliString({ qubits[0]: paulis[0], qubits[1]: paulis[1] }), num_samples=1) matrix = np.kron(cirq.unitary(paulis[0]), cirq.unitary(paulis[1])) circuit = cirq.Circuit.from_ops(display.measurement_basis_change()) unitary = circuit.to_unitary_matrix(qubit_order=qubits) ZZ = np.diag([1, -1, -1, 1]) np.testing.assert_allclose( np.dot(unitary, np.dot(matrix, unitary.T.conj())), ZZ)
def test_pauli_string_expectation_value_pure_state(): qubits = cirq.LineQubit.range(4) qubit_index_map = {q: i for i, q in enumerate(qubits)} circuit = cirq.Circuit.from_ops( cirq.X(qubits[1]), cirq.H(qubits[2]), cirq.X(qubits[3]), cirq.H(qubits[3]), ) wavefunction = circuit.apply_unitary_effect_to_state(qubit_order=qubits) density_matrix = np.outer(wavefunction, np.conj(wavefunction)) z0z1 = cirq.pauli_string_expectation( cirq.PauliString({ qubits[0]: cirq.Z, qubits[1]: cirq.Z })) z0z2 = cirq.pauli_string_expectation( cirq.PauliString({ qubits[0]: cirq.Z, qubits[2]: cirq.Z })) z0z3 = cirq.pauli_string_expectation( cirq.PauliString({ qubits[0]: cirq.Z, qubits[3]: cirq.Z })) z0x1 = cirq.pauli_string_expectation( cirq.PauliString({ qubits[0]: cirq.Z, qubits[1]: cirq.X })) z1x2 = cirq.pauli_string_expectation( cirq.PauliString({ qubits[1]: cirq.Z, qubits[2]: cirq.X })) x0z1 = cirq.pauli_string_expectation( cirq.PauliString({ qubits[0]: cirq.X, qubits[1]: cirq.Z })) x3 = cirq.pauli_string_expectation(cirq.PauliString({qubits[3]: cirq.X})) np.testing.assert_allclose( z0z1.value_derived_from_wavefunction(wavefunction, qubit_index_map), -1) np.testing.assert_allclose( z0z2.value_derived_from_wavefunction(wavefunction, qubit_index_map), 0) np.testing.assert_allclose( z0z3.value_derived_from_wavefunction(wavefunction, qubit_index_map), 0) np.testing.assert_allclose( z0x1.value_derived_from_wavefunction(wavefunction, qubit_index_map), 0) np.testing.assert_allclose( z1x2.value_derived_from_wavefunction(wavefunction, qubit_index_map), -1) np.testing.assert_allclose( x0z1.value_derived_from_wavefunction(wavefunction, qubit_index_map), 0) np.testing.assert_allclose( x3.value_derived_from_wavefunction(wavefunction, qubit_index_map), -1) np.testing.assert_allclose( z0z1.value_derived_from_density_matrix(density_matrix, qubit_index_map), -1) np.testing.assert_allclose( z0z2.value_derived_from_density_matrix(density_matrix, qubit_index_map), 0) np.testing.assert_allclose( z0z3.value_derived_from_density_matrix(density_matrix, qubit_index_map), 0) np.testing.assert_allclose( z0x1.value_derived_from_density_matrix(density_matrix, qubit_index_map), 0) np.testing.assert_allclose( z1x2.value_derived_from_density_matrix(density_matrix, qubit_index_map), -1) np.testing.assert_allclose( x0z1.value_derived_from_density_matrix(density_matrix, qubit_index_map), 0) np.testing.assert_allclose( x3.value_derived_from_density_matrix(density_matrix, qubit_index_map), -1)
def test_approx_pauli_string_expectation_value(measurements, value): display = cirq.pauli_string_expectation(cirq.PauliString({}), num_samples=1) assert display.value_derived_from_samples(measurements) == value