def test_circuit(boolean_str): boolean_expr = sympy_parser.parse_expr(boolean_str) var_names = cirq.parameter_names(boolean_expr) qubits = [cirq.NamedQubit(name) for name in var_names] # We use Sympy to evaluate the expression: n = len(var_names) expected = [] for binary_inputs in itertools.product([0, 1], repeat=n): subed_expr = boolean_expr for var_name, binary_input in zip(var_names, binary_inputs): subed_expr = subed_expr.subs(var_name, binary_input) expected.append(bool(subed_expr)) # We build a circuit and look at its output state vector: circuit = cirq.Circuit() circuit.append(cirq.H.on_each(*qubits)) hamiltonian_gate = cirq.BooleanHamiltonianGate({q.name: q for q in qubits}, [boolean_str], 0.1 * math.pi) assert hamiltonian_gate.num_qubits() == n circuit.append(hamiltonian_gate.on(*qubits)) phi = cirq.Simulator().simulate(circuit, qubit_order=qubits, initial_state=0).state_vector() actual = np.arctan2(phi.real, phi.imag) - math.pi / 2.0 > 0.0 # Compare the two: np.testing.assert_array_equal(actual, expected)
def test_gate_consistent(): gate = cirq.BooleanHamiltonianGate( ['a', 'b'], ['a'], 0.1, ) op = gate.on(*cirq.LineQubit.range(2)) cirq.testing.assert_implements_consistent_protocols(gate) cirq.testing.assert_implements_consistent_protocols(op)
def test_gate_with_custom_names(): q0, q1, q2, q3 = cirq.LineQubit.range(4) gate = cirq.BooleanHamiltonianGate(['a', 'b'], ['a'], 0.1) assert cirq.decompose(gate.on(q0, q1)) == [cirq.Rz(rads=-0.05).on(q0)] assert cirq.decompose_once_with_qubits(gate, (q0, q1)) == [cirq.Rz(rads=-0.05).on(q0)] assert cirq.decompose(gate.on(q2, q3)) == [cirq.Rz(rads=-0.05).on(q2)] assert cirq.decompose_once_with_qubits(gate, (q2, q3)) == [cirq.Rz(rads=-0.05).on(q2)] with pytest.raises(ValueError, match='Wrong number of qubits'): gate.on(q2) with pytest.raises(ValueError, match='Wrong shape of qids'): gate.on(q0, cirq.LineQid(1, 3))
def qaoa_max_cut_unitary( qubits, betas, gammas, graph, use_boolean_hamiltonian_gate): # Nodes should be integers if use_boolean_hamiltonian_gate: booleans = [f"x{i} ^ x{j}" for i, j in sorted(graph.edges)] param_names = [f"x{i}" for i in range(len(qubits))] for beta, gamma in zip(betas, gammas): yield cirq.BooleanHamiltonianGate(param_names, booleans, 2.0 * gamma).on(*qubits) yield cirq.rx(2 * beta).on_each(*qubits) else: for beta, gamma in zip(betas, gammas): yield (rzz(-0.5 * gamma).on(qubits[i], qubits[j]) for i, j in graph.edges) yield cirq.rx(2 * beta).on_each(*qubits)
def _boolean_hamiltonian_gate_op(qubit_map, boolean_strs, theta): return cirq.BooleanHamiltonianGate(parameter_names=list( qubit_map.keys()), boolean_strs=boolean_strs, theta=theta).on(*qubit_map.values())