def test_quadratic_fermionic_simulation_gate_text_diagram(): gate = openfermion.QuadraticFermionicSimulationGate((1, 1)) a, b, c = cirq.LineQubit.range(3) circuit = cirq.Circuit([gate(a, b), gate(b, c)]) assert super(type(gate), gate).wire_symbol(False) == type(gate).__name__ assert (super(type(gate), gate)._diagram_exponent( cirq.CircuitDiagramInfoArgs.UNINFORMED_DEFAULT) == gate._exponent) expected_text_diagram = """ 0: ───↓↑(1, 1)────────────── │ 1: ───↓↑─────────↓↑(1, 1)─── │ 2: ──────────────↓↑───────── """.strip() cirq.testing.assert_has_diagram(circuit, expected_text_diagram) expected_text_diagram = """ 0: ---a*a(1, 1)--------------- | 1: ---a*a---------a*a(1, 1)--- | 2: ---------------a*a--------- """.strip() cirq.testing.assert_has_diagram(circuit, expected_text_diagram, use_unicode_characters=False)
def random_fermionic_simulation_gate(order): exponent = random_real() if order == 2: weights = (random_complex(), random_real()) return openfermion.QuadraticFermionicSimulationGate(weights, exponent=exponent) weights = random_complex(3) if order == 3: return openfermion.CubicFermionicSimulationGate(weights, exponent=exponent) if order == 4: return openfermion.QuarticFermionicSimulationGate(weights, exponent=exponent)
def test_quadratic_fermionic_simulation_gate_unitary(weights, exponent): generator = np.zeros((4, 4), dtype=np.complex128) # w0 |10><01| + h.c. generator[2, 1] = weights[0] generator[1, 2] = weights[0].conjugate() # w1 |11><11| generator[3, 3] = weights[1] expected_unitary = la.expm(-1j * exponent * generator) gate = openfermion.QuadraticFermionicSimulationGate(weights, exponent=exponent) actual_unitary = cirq.unitary(gate) assert np.allclose(expected_unitary, actual_unitary) symbolic_gate = (openfermion.QuadraticFermionicSimulationGate( (sympy.Symbol('w0'), sympy.Symbol('w1')), exponent=sympy.Symbol('t'))) qubits = cirq.LineQubit.range(2) circuit = cirq.Circuit(symbolic_gate._decompose_(qubits)) resolver = {'w0': weights[0], 'w1': weights[1], 't': exponent} resolved_circuit = cirq.resolve_parameters(circuit, resolver) decomp_unitary = resolved_circuit.unitary(qubit_order=qubits) assert np.allclose(expected_unitary, decomp_unitary)
other_interaction_op = openfermion.InteractionOperator.zero( interaction_op.n_qubits) super(type(gate), gate).interaction_operator_generator(operator=other_interaction_op) other_interaction_op = openfermion.normal_ordered(interaction_op) assert interaction_op == other_interaction_op other_interaction_op = super(type(gate), gate).interaction_operator_generator() other_interaction_op = openfermion.normal_ordered(interaction_op) assert interaction_op == other_interaction_op random_quadratic_gates = [random_fermionic_simulation_gate(2) for _ in range(5)] manual_quadratic_gates = [ openfermion.QuadraticFermionicSimulationGate(weights) for weights in [cast(Tuple[float, float], (1, 1)), (1, 0), (0, 1), (0, 0)] ] quadratic_gates = random_quadratic_gates + manual_quadratic_gates cubic_gates = ([openfermion.CubicFermionicSimulationGate()] + [random_fermionic_simulation_gate(3) for _ in range(5)]) quartic_gates = ([openfermion.QuarticFermionicSimulationGate()] + [random_fermionic_simulation_gate(4) for _ in range(5)]) gates = quadratic_gates + cubic_gates + quartic_gates @pytest.mark.parametrize('gate', gates) def test_fermionic_simulation_gate(gate): openfermion.testing.assert_implements_consistent_protocols(gate) generator = gate.qubit_generator_matrix