Example #1
0
def test_stdgates(gatet: Type[qf.StdGate]) -> None:

    # Test creation
    gate = _randomize_gate(gatet)

    # Test correct number of qubits
    assert gate.qubit_nb == gatet.cv_qubit_nb

    # Test hermitian conjugate
    inv_gate = gate.H
    gate.tensor
    inv_gate.tensor

    # Test inverse
    eye = gate @ inv_gate
    assert qf.gates_close(qf.IdentityGate(range(gate.qubit_nb)), eye)
    assert qf.gates_phase_close(qf.IdentityGate(range(gate.qubit_nb)), eye)

    # Test pow
    assert qf.gates_close(gate ** -1, inv_gate)
    assert qf.gates_close((gate ** 0.5) ** 2, gate)
    assert qf.gates_close((gate ** 0.3) @ (gate ** 0.7), gate)

    hgate = qf.Unitary((gate ** 0.5).tensor, gate.qubits)
    assert qf.gates_close(hgate @ hgate, gate)
Example #2
0
def test_gate_mul() -> None:
    # three cnots same as one swap
    gate0 = qf.IdentityGate([0, 1])

    gate1 = qf.CNot(1, 0)
    gate2 = qf.CNot(0, 1)
    gate3 = qf.CNot(1, 0)

    gate = gate1 @ gate0
    gate = gate2 @ gate
    gate = gate3 @ gate
    assert qf.gates_close(gate, qf.Swap(0, 1))

    # Again, but with labels
    gate0 = qf.IdentityGate(["a", "b"])

    gate1 = qf.CNot("b", "a")
    gate2 = qf.CNot("a", "b")
    gate3 = qf.CNot("b", "a")

    gate = gate1 @ gate0
    gate = gate2 @ gate
    gate = gate3 @ gate
    assert qf.gates_close(gate, qf.Swap("a", "b"))

    gate4 = qf.X("a")
    _ = gate4 @ gate

    with pytest.raises(NotImplementedError):
        _ = gate4 @ 3  # type: ignore
Example #3
0
def test_identitygate() -> None:
    qubits = [3, 4, 5, 6, 7, 8]
    gate = qf.IdentityGate(qubits)
    ket0 = qf.random_state(qubits)
    ket1 = gate.run(ket0)
    assert qf.states_close(ket0, ket1)

    circ = qf.Circuit(gate.decompose())
    assert len(circ) == 6

    for n in range(1, 6):
        assert qf.IdentityGate(list(range(n))).qubit_nb == n

    assert gate.hamiltonian.is_zero()

    assert gate ** 2 is gate
Example #4
0
def test_identity() -> None:
    chan = qf.IdentityGate([1]).aschannel()
    rho = qf.random_density(2)
    after = chan.evolve(rho)
    assert qf.densities_close(rho, after)

    assert chan.name == "Channel"
Example #5
0
def test_fubini_study_angle() -> None:

    for _ in range(REPS):
        theta = random.uniform(-np.pi, +np.pi)

        ang = qf.fubini_study_angle(qf.I(0).tensor, qf.Rx(theta, 0).su().tensor)
        assert np.isclose(2 * ang / abs(theta), 1.0)

        ang = qf.fubini_study_angle(qf.I(0).tensor, qf.Ry(theta, 0).tensor)
        assert np.isclose(2 * ang / abs(theta), 1.0)

        ang = qf.fubini_study_angle(qf.I(0).tensor, qf.Rz(theta, 0).tensor)
        assert np.isclose(2 * ang / abs(theta), 1.0)

        ang = qf.fubini_study_angle(qf.Swap(0, 1).tensor, qf.PSwap(theta, 0, 1).tensor)

        assert np.isclose(2 * ang / abs(theta), 1.0)

        ang = qf.fubini_study_angle(qf.I(0).tensor, qf.PhaseShift(theta, 0).tensor)
        assert np.isclose(2 * ang / abs(theta), 1.0)

        assert qf.fubini_study_close(qf.Rz(theta, 0).tensor, qf.Rz(theta, 0).tensor)

    for n in range(1, 6):
        eye = qf.IdentityGate(list(range(n)))
        assert np.isclose(qf.fubini_study_angle(eye.tensor, eye.tensor), 0.0)

    with pytest.raises(ValueError):
        qf.fubini_study_angle(qf.RandomGate([1]).tensor, qf.RandomGate([0, 1]).tensor)
Example #6
0
def test_decomp_stdgates() -> None:
    gate0 = qf.IdentityGate([0, 1])
    gate1 = qf.canonical_decomposition(gate0).asgate()
    assert qf.gates_close(gate0, gate1)

    gate2 = qf.CNot(0, 1)
    gate3 = qf.canonical_decomposition(gate2).asgate()
    assert qf.gates_close(gate2, gate3)

    gate4 = qf.Swap(0, 1)
    gate5 = qf.canonical_decomposition(gate4).asgate()
    assert qf.gates_close(gate4, gate5)

    gate6 = qf.ISwap(0, 1)
    gate7 = qf.canonical_decomposition(gate6).asgate()
    assert qf.gates_close(gate6, gate7)

    gate8 = qf.CNot(0, 1)**0.5
    gate9 = qf.canonical_decomposition(gate8).asgate()
    assert qf.gates_close(gate8, gate9)

    gate10 = qf.Swap(0, 1)**0.5
    gate11 = qf.canonical_decomposition(gate10).asgate()
    assert qf.gates_close(gate10, gate11)

    gate12 = qf.ISwap(0, 1)**0.5
    gate13 = qf.canonical_decomposition(gate12).asgate()
    assert qf.gates_close(gate12, gate13)
Example #7
0
def test_inverse_random() -> None:
    K = 4
    for _ in range(REPS):
        gate = qf.RandomGate(range(K))
        inv = gate.H
        gate1 = inv @ gate
        # TODO: almost_identity
        assert qf.gates_close(qf.IdentityGate([0, 1, 2, 3]), gate1)
Example #8
0
def test_multiswapgate() -> None:
    # Should be same as a swap.
    perm0 = qf.MultiSwapGate([0, 1], [1, 0])
    gate0 = qf.Swap(0, 1)
    assert qf.gates_close(perm0.asgate(), gate0)
    assert qf.gates_close(perm0.asgate(), perm0.H.asgate())

    perm1 = qf.MultiSwapGate.from_gates(qf.Circuit([gate0]))
    assert qf.gates_close(perm0.asgate(), perm1.asgate())

    perm2 = qf.MultiSwapGate.from_gates(qf.Circuit([perm1]))
    assert qf.gates_close(perm0, perm2)

    with pytest.raises(ValueError):
        qf.MultiSwapGate.from_gates(qf.Circuit(qf.CNot(0, 1)))

    N = 8
    qubits_in = list(range(N))
    qubits_out = np.random.permutation(qubits_in)

    permN = qf.MultiSwapGate(qubits_in, qubits_out)
    assert qf.gates_close(perm0.asgate(), perm1.asgate())
    iden = qf.Circuit([permN, permN.H])
    assert qf.almost_identity(iden.asgate())
    assert qf.circuits_close(iden, qf.Circuit([qf.IdentityGate(qubits_in)]))

    swaps = qf.Circuit(permN.decompose())
    # Add identity so we don't lose qubits
    swaps += qf.IdentityGate(permN.qubits_in)
    permN2 = qf.MultiSwapGate.from_gates(swaps)

    assert qf.circuits_close(swaps, qf.Circuit([permN]))
    assert qf.circuits_close(swaps, qf.Circuit([permN2]))
    assert qf.circuits_close(qf.Circuit([permN]), qf.Circuit([permN2]))

    with pytest.raises(ValueError):
        _ = qf.MultiSwapGate([0, 1], [1, 2])

    # Channels
    assert qf.channels_close(perm0.aschannel(), gate0.aschannel())

    rho0 = qf.random_state([0, 1, 3]).asdensity()
    rho1 = perm0.evolve(rho0)
    rho2 = gate0.aschannel().evolve(rho0)
    assert qf.densities_close(rho1, rho2)
Example #9
0
def test_cnot_reverse() -> None:
    # Hadamards reverse control on CNot
    gate0 = qf.H(0) @ qf.IdentityGate([0, 1])
    gate0 = qf.H(1) @ gate0
    gate0 = qf.CNot(1, 0) @ gate0
    gate0 = qf.H(0) @ gate0
    gate0 = qf.H(1) @ gate0

    assert qf.gates_close(qf.CNot(0, 1), gate0)
def test_gradient_errors() -> None:
    circ = qf.Circuit()
    circ += qf.CPhase(0.2, 0, 1)  # Not (currently) differentiable
    qubits = circ.qubits
    ket0 = qf.zero_state(qubits)
    ket1 = qf.random_state(qubits)

    with pytest.raises(ValueError):
        qf.state_fidelity_gradients(ket0, ket1, circ)

    with pytest.raises(ValueError):
        qf.parameter_shift_circuits(circ, 0)

    with pytest.raises(ValueError):
        qf.expectation_gradients(ket0, circ, qf.IdentityGate([0, 1]))
def test_CPhase_gates() -> None:
    for _ in range(REPS):
        theta = random.uniform(-4 * np.pi, +4 * np.pi)

        gate11 = qf.ControlGate([0], qf.PhaseShift(theta, 1))
        assert qf.gates_close(gate11, qf.CPhase(theta, 0, 1))

        gate00 = qf.X(0) @ qf.IdentityGate([0, 1])
        gate00 = qf.X(1) @ gate00
        gate00 = gate11 @ gate00
        gate00 = qf.X(0) @ gate00
        gate00 = qf.X(1) @ gate00
        assert qf.gates_close(gate00, qf.CPhase00(theta))

        gate10 = qf.X(0) @ qf.IdentityGate([0, 1])
        gate10 = qf.X(1) @ gate10
        gate10 = qf.CPhase01(theta, 0, 1) @ gate10
        gate10 = qf.X(0) @ gate10
        gate10 = qf.X(1) @ gate10
        assert qf.gates_close(gate10, qf.CPhase10(theta))

        gate0 = qf.CPhase(theta) ** 2
        gate1 = qf.CPhase(theta * 2)
        assert qf.gates_close(gate0, gate1)
Example #12
0
def test_xy() -> None:
    assert qf.gates_close(qf.XY(0, 0, 1), qf.IdentityGate([0, 1]))
    assert qf.gates_close(qf.XY(-0.5, 0, 1), qf.ISwap(0, 1))
    assert qf.gates_close(qf.XY(0.5, 0, 1), qf.ISwap(0, 1).H)
Example #13
0
def test_channel_chi() -> None:
    chan = qf.IdentityGate([0, 1, 2]).aschannel()
    chi = chan.chi()
    assert chi.shape == (64, 64)