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_weights_and_exponent(weights):
    exponents = np.linspace(-1, 1, 8)
    gates = tuple(
        ofc.QuarticFermionicSimulationGate(
            weights / exponent, exponent=exponent, absorb_exponent=True)
        for exponent in exponents)

    for g1, g2 in itertools.combinations(gates, 2):
        assert cirq.approx_eq(g1, g2, atol=1e-100)

    for i, (gate, exponent) in enumerate(zip(gates, exponents)):
        assert gate.exponent == 1
        new_exponent = exponents[-i]
        new_gate = gate._with_exponent(new_exponent)
        assert new_gate.exponent == new_exponent
def test_quartic_fermionic_simulation_unitary(weights, exponent):
    generator = np.zeros((1 << 4, ) * 2, dtype=np.complex128)

    # w0 |1001><0110| + h.c.
    generator[9, 6] = weights[0]
    generator[6, 9] = weights[0].conjugate()
    # w1 |1010><0101| + h.c.
    generator[10, 5] = weights[1]
    generator[5, 10] = weights[1].conjugate()
    # w2 |1100><0011| + h.c.
    generator[12, 3] = weights[2]
    generator[3, 12] = weights[2].conjugate()
    expected_unitary = la.expm(-1j * exponent * generator)

    gate = ofc.QuarticFermionicSimulationGate(weights, exponent=exponent)
    actual_unitary = cirq.unitary(gate)

    assert np.allclose(expected_unitary, actual_unitary)
def test_quartic_fermionic_simulation_eq():
    eq = cirq.testing.EqualsTester()

    eq.add_equality_group(
        ofc.QuarticFermionicSimulationGate((1.2, 0.4, -0.4), exponent=0.5),
        ofc.QuarticFermionicSimulationGate((0.3, 0.1, -0.1), exponent=2),
        ofc.QuarticFermionicSimulationGate((-0.6, -0.2, 0.2), exponent=-1),
        ofc.QuarticFermionicSimulationGate((0.6, 0.2, 2 * np.pi - 0.2)),
    )

    eq.add_equality_group(
        ofc.QuarticFermionicSimulationGate((-0.6, 0.0, 0.3), exponent=0.5))

    eq.make_equality_group(lambda: ofc.QuarticFermionicSimulationGate(
        (0.1, -0.3, 0.0), exponent=0.0))
    eq.make_equality_group(lambda: ofc.QuarticFermionicSimulationGate(
        (1., -1., 0.5), exponent=0.75))
def test_quartic_fermionic_simulation_gate_text_diagram():
    gate = ofc.QuarticFermionicSimulationGate((1, 1, 1))
    qubits = cirq.LineQubit.range(6)
    circuit = cirq.Circuit([gate(*qubits[:4]), gate(*qubits[-4:])])

    assert super(type(gate), gate).wire_symbol(False) == type(gate).__name__
    for G in (gate, gate._with_exponent('e')):
        assert (super(type(G), G)._diagram_exponent(
            cirq.CircuitDiagramInfoArgs.UNINFORMED_DEFAULT) == G._exponent)

    expected_text_diagram = """
0: ───⇊⇈(1, 1, 1)─────────────────
      │
1: ───⇊⇈──────────────────────────
      │
2: ───⇊⇈────────────⇊⇈(1, 1, 1)───
      │             │
3: ───⇊⇈────────────⇊⇈────────────
                    │
4: ─────────────────⇊⇈────────────
                    │
5: ─────────────────⇊⇈────────────
""".strip()
    cirq.testing.assert_has_diagram(circuit, expected_text_diagram)

    expected_text_diagram = """
0: ---a*a*aa(1, 1, 1)---------------------
      |
1: ---a*a*aa------------------------------
      |
2: ---a*a*aa------------a*a*aa(1, 1, 1)---
      |                 |
3: ---a*a*aa------------a*a*aa------------
                        |
4: ---------------------a*a*aa------------
                        |
5: ---------------------a*a*aa------------
""".strip()
    cirq.testing.assert_has_diagram(circuit,
                                    expected_text_diagram,
                                    use_unicode_characters=False)
def test_quartic_fermionic_simulation_gate_text_diagram():
    gate = ofc.QuarticFermionicSimulationGate((1,1,1))
    qubits = cirq.LineQubit.range(6)
    circuit = cirq.Circuit.from_ops(
            [gate(*qubits[:4]), gate(*qubits[-4:])])

    actual_text_diagram = circuit.to_text_diagram()
    expected_text_diagram = """
0: ───⇊⇈────────
      │
1: ───⇊⇈────────
      │
2: ───⇊⇈───⇊⇈───
      │    │
3: ───⇊⇈───⇊⇈───
           │
4: ────────⇊⇈───
           │
5: ────────⇊⇈───
    """.strip()
    assert actual_text_diagram == expected_text_diagram

    actual_text_diagram = circuit.to_text_diagram(use_unicode_characters=False)
    expected_text_diagram = """
0: ---a*a*aa------------
      |
1: ---a*a*aa------------
      |
2: ---a*a*aa---a*a*aa---
      |        |
3: ---a*a*aa---a*a*aa---
               |
4: ------------a*a*aa---
               |
5: ------------a*a*aa---
    """.strip()
    assert actual_text_diagram == expected_text_diagram
Exemple #7
0
def test_quartic_fermionic_simulation_apply_unitary(weights, exponent):
    gate = ofc.QuarticFermionicSimulationGate(weights, exponent=exponent)
    cirq.testing.assert_has_consistent_apply_unitary(gate, atol=5e-6)
Exemple #8
0
def test_quartic_fermionic_simulation_decompose(weights):
    cirq.testing.assert_decompose_is_consistent_with_unitary(
        ofc.QuarticFermionicSimulationGate(weights))
Exemple #9
0
def test_quartic_fermionic_simulation_init_with_multiple_args_fails():
    with pytest.raises(ValueError):
        _ = ofc.QuarticFermionicSimulationGate((1, 1, 1),
                                               exponent=1.0,
                                               duration=np.pi / 2)
Exemple #10
0
def test_quartic_fermionic_simulation_consistency():
    ofc.testing.assert_implements_consistent_protocols(
        ofc.QuarticFermionicSimulationGate())
Exemple #11
0
                                           exponent=exponent)
        for exponent in exponents)

    for g1 in gates:
        for g2 in gates:
            assert cirq.approx_eq(g1, g2, atol=1e-100)

    for i, (gate, exponent) in enumerate(zip(gates, exponents)):
        assert gate.exponent == 1
        new_exponent = exponents[-i]
        new_gate = gate._with_exponent(new_exponent)
        assert new_gate.exponent == new_exponent


quartic_fermionic_simulation_simulator_test_cases = [
    (ofc.QuarticFermionicSimulationGate(
        (0, 0, 0)), 1., np.ones(16) / 4., np.ones(16) / 4., 5e-6),
    (ofc.QuarticFermionicSimulationGate((0.2, -0.1, 0.7)), 0.,
     np.array([1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) / 4.,
     np.array([1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) / 4.,
     5e-6),
    (ofc.QuarticFermionicSimulationGate((0.2, -0.1, 0.7)), 0.3,
     np.array([1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) / 4.,
     np.array([
         1, -1, -1, -np.exp(0.21j), -1, -np.exp(-0.03j),
         np.exp(-0.06j), 1, 1,
         np.exp(-0.06j),
         np.exp(-0.03j), 1,
         np.exp(0.21j), 1, 1, 1
     ]) / 4., 5e-6),
    (ofc.QuarticFermionicSimulationGate((1. / 3, 0, 0)), 1.,
     np.array([0, 0, 0, 0, 0, 0, 1., 0, 0, 1., 0, 0, 0, 0, 0, 0]) / np.sqrt(2),