def random_fermionic_simulation_gate(order): exponent = random_real() if order == 2: weights = (random_complex(), random_real()) return ofc.QuadraticFermionicSimulationGate(weights, exponent=exponent) weights = random_complex(3) if order == 3: return ofc.CubicFermionicSimulationGate(weights, exponent=exponent) if order == 4: return ofc.QuarticFermionicSimulationGate(weights, exponent=exponent)
def test_cubic_fermionic_simulation_gate_equality(): eq = cirq.testing.EqualsTester() eq.add_equality_group( ofc.CubicFermionicSimulationGate()**0.5, ofc.CubicFermionicSimulationGate((1, ) * 3, exponent=0.5), ofc.CubicFermionicSimulationGate((0.5, ) * 3)) eq.add_equality_group(ofc.CubicFermionicSimulationGate((1j, 0, 0)), ) eq.add_equality_group( ofc.CubicFermionicSimulationGate((sympy.Symbol('s'), 0, 0), exponent=2), ofc.CubicFermionicSimulationGate((2 * sympy.Symbol('s'), 0, 0), exponent=1)) eq.add_equality_group( ofc.CubicFermionicSimulationGate((0, 0.7, 0), global_shift=2), ofc.CubicFermionicSimulationGate((0, 0.35, 0), global_shift=1, exponent=2)) eq.add_equality_group(ofc.CubicFermionicSimulationGate((1, 1, 1))) eq.add_equality_group( ofc.CubicFermionicSimulationGate(((1 + 2 * np.pi), 1, 1)))
def test_cubic_fermionic_simulation_gate_consistency_special( exponent, control): weights = tuple(np.eye(1, 3, control)[0] * 0.5 * np.pi) general_gate = ofc.CubicFermionicSimulationGate(weights, exponent=exponent) general_unitary = cirq.unitary(general_gate) indices = np.dot(list(itertools.product((0, 1), repeat=3)), (2**np.roll(np.arange(3), -control))[::-1]) special_gate = ofc.CXXYYPowGate(exponent=exponent) special_unitary = (cirq.unitary(special_gate)[indices[:, np.newaxis], indices]) assert np.allclose(general_unitary, special_unitary)
def test_cubic_fermionic_simulation_gate_consistency_docstring( weights, exponent): generator = np.zeros((8, 8), dtype=np.complex128) # w0 |110><101| + h.c. generator[6, 5] = weights[0] generator[5, 6] = weights[0].conjugate() # w1 |110><011| + h.c. generator[6, 3] = weights[1] generator[3, 6] = weights[1].conjugate() # w2 |101><011| + h.c. generator[5, 3] = weights[2] generator[3, 5] = weights[2].conjugate() expected_unitary = la.expm(-1j * exponent * generator) gate = ofc.CubicFermionicSimulationGate(weights, exponent=exponent) actual_unitary = cirq.unitary(gate) assert np.allclose(expected_unitary, actual_unitary)
def test_cubic_fermionic_simulation_gate_text_diagram(): gate = ofc.CubicFermionicSimulationGate((1, 1, 1)) qubits = cirq.LineQubit.range(5) circuit = cirq.Circuit([gate(*qubits[:3]), gate(*qubits[2:5])]) 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: ───↕↓↑─────────────────────────── │ 2: ───↕↓↑────────────↕↓↑(1, 1, 1)─── │ 3: ──────────────────↕↓↑──────────── │ 4: ──────────────────↕↓↑──────────── """.strip() cirq.testing.assert_has_diagram(circuit, expected_text_diagram) expected_text_diagram = """ 0: ---na*a(1, 1, 1)------------------- | 1: ---na*a---------------------------- | 2: ---na*a------------na*a(1, 1, 1)--- | 3: -------------------na*a------------ | 4: -------------------na*a------------ """.strip() cirq.testing.assert_has_diagram(circuit, expected_text_diagram, use_unicode_characters=False)
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 = [ ofc.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 = ([ofc.CubicFermionicSimulationGate()] + [random_fermionic_simulation_gate(3) for _ in range(5)]) quartic_gates = ([ofc.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): ofc.testing.assert_implements_consistent_protocols(gate) generator = gate.qubit_generator_matrix expected_unitary = la.expm(-1j * gate.exponent * generator) actual_unitary = cirq.unitary(gate) assert np.allclose(expected_unitary, actual_unitary)