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)
示例#2
0
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)))
示例#3
0
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)
示例#4
0
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)