Beispiel #1
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)
Beispiel #2
0
def test_gate_angle() -> None:
    gate0 = qf.RandomGate([1])
    gate1 = qf.RandomGate([1])
    qf.gate_angle(gate0, gate1)

    assert not qf.gates_close(gate0, gate1)
    assert qf.gates_close(gate0, gate0)
Beispiel #3
0
def test_canonical_decomposition() -> None:
    for tt1 in range(0, 6):
        for tt2 in range(tt1):
            for tt3 in range(tt2):
                t1, t2, t3 = tt1 / 12, tt2 / 12, tt3 / 12
                if t3 == 0 and t1 > 0.5:
                    continue
                coords = np.asarray((t1, t2, t3))

                circ0 = qf.Circuit()
                circ0 += qf.RandomGate([0])
                circ0 += qf.RandomGate([1])
                circ0 += qf.Can(t1, t2, t3, 0, 1)
                circ0 += qf.RandomGate([0])
                circ0 += qf.RandomGate([1])
                gate0 = circ0.asgate()

                circ1 = qf.canonical_decomposition(gate0)
                assert qf.gates_close(gate0, circ1.asgate())

                canon = circ1[1]
                new_coords = np.asarray(
                    [canon.param(n) for n in ["tx", "ty", "tz"]])
                assert np.allclose(coords, np.asarray(new_coords))

                coords2 = qf.canonical_coords(gate0)
                assert np.allclose(coords, np.asarray(coords2))
Beispiel #4
0
def test_decomp_sqrtswap_sandwich() -> None:
    circ0 = qf.Circuit()
    circ0 += qf.Can(1 / 4, 1 / 4, 1 / 4, 0, 1)
    circ0 += qf.RandomGate([0])
    circ0 += qf.RandomGate([1])
    circ0 += qf.Can(1 / 4, 1 / 4, 1 / 4, 0, 1)

    gate0 = circ0.asgate()
    circ1 = qf.canonical_decomposition(gate0)
    gate1 = circ1.asgate()
    assert qf.gates_close(gate0, gate1)
Beispiel #5
0
def test_bloch_decomposition() -> None:
    theta = 1.23

    gate0 = qf.Rn(theta, 1, 0, 0, 9)
    gate1 = qf.bloch_decomposition(gate0)[0]
    assert isinstance(gate1, qf.Gate)
    assert qf.gates_close(gate0, gate1)

    gate0 = qf.Rn(theta, 0, 1, 0, 9)
    gate1 = qf.bloch_decomposition(gate0)[0]
    assert isinstance(gate1, qf.Gate)
    assert qf.gates_close(gate0, gate1)

    gate0 = qf.Rn(theta, 0, 0, 1, 9)
    gate1 = qf.bloch_decomposition(gate0)[0]
    assert isinstance(gate1, qf.Gate)
    assert qf.gates_close(gate0, gate1)

    gate0 = qf.Rn(pi, np.sqrt(2), 0, np.sqrt(2), 9)
    gate1 = qf.bloch_decomposition(gate0)[0]
    assert isinstance(gate1, qf.Gate)
    assert qf.gates_close(gate0, gate1)

    for _ in range(REPS):
        gate3 = qf.RandomGate(qubits=[0])
        gate4 = qf.bloch_decomposition(gate3)[0]
        assert isinstance(gate4, qf.Gate)
        assert qf.gates_close(gate3, gate4)

    gate5 = qf.I(0)
    gate6 = qf.bloch_decomposition(gate5)[0]
    assert isinstance(gate6, qf.Gate)
    assert qf.gates_close(gate5, gate6)
Beispiel #6
0
def sandwich_decompositions(coords0, coords1, samples=SAMPLES):
    """Create composite gates, decompose, and return a list
    of canonical coordinates"""
    decomps = []
    for _ in range(samples):
        circ = qf.Circuit()
        circ += qf.Can(*coords0, 0, 1)
        circ += qf.RandomGate([0])
        circ += qf.RandomGate([1])
        circ += qf.Can(*coords1, 0, 1)
        gate = circ.asgate()

        coords = qf.canonical_coords(gate)
        decomps.append(coords)

    return decomps
Beispiel #7
0
def test_euler_decomposition() -> None:
    gate0 = qf.RandomGate([1])

    for order in ["XYX", "XZX", "YXY", "YZY", "ZXZ", "ZYZ"]:
        circ1 = qf.euler_decomposition(gate0, euler=order)
        gate1 = circ1.asgate()
        assert qf.gates_close(gate0, gate1)
Beispiel #8
0
def test_pauli_decompose_hermitian() -> None:
    gate = qf.X(0)
    H = gate.asoperator()
    pl = qf.pauli_decompose_hermitian(H)
    assert np.allclose(pl.asoperator(), H)

    gate = qf.X(0)
    op = gate.asoperator()
    H = -scipy.linalg.logm(op) / 1.0j
    pl = qf.pauli_decompose_hermitian(H)
    assert np.allclose(pl.asoperator(), H)

    N = 4
    gate2 = qf.RandomGate(range(N))
    op = gate2.asoperator()
    H = -scipy.linalg.logm(op) / 1.0j
    pl = qf.pauli_decompose_hermitian(H)
    assert np.allclose(pl.asoperator(), H)

    op = np.ones(shape=[2, 2, 2])
    with pytest.raises(ValueError):
        qf.pauli_decompose_hermitian(op)

    op = np.ones(shape=[4, 4])
    op[0, 1] = 10000
    with pytest.raises(ValueError):
        qf.pauli_decompose_hermitian(op)

    op = np.ones(shape=[3, 3])
    with pytest.raises(ValueError):
        qf.pauli_decompose_hermitian(op)
Beispiel #9
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)
Beispiel #10
0
def test_entropy() -> None:
    N = 4
    rho0 = qf.mixed_density(N)
    ent = qf.entropy(rho0, base=2)
    assert np.isclose(ent, N)

    # Entropy invariant to unitary evolution
    chan = qf.RandomGate(range(N)).aschannel()
    rho1 = chan.evolve(rho0)
    ent = qf.entropy(rho1, base=2)
    assert np.isclose(ent, N)
Beispiel #11
0
def test_canonical_decomp_sandwich() -> None:
    for _ in range(REPS):
        # Random CZ sandwich
        circ0 = qf.Circuit()
        circ0 += qf.RandomGate([0])
        circ0 += qf.RandomGate([1])
        circ0 += qf.CZ(0, 1)
        circ0 += qf.YPow(0.4, 0)
        circ0 += qf.YPow(0.25, 1)
        circ0 += qf.CZ(0, 1)
        circ0 += qf.RandomGate([0])
        circ0 += qf.RandomGate([1])

        gate0 = circ0.asgate()

        circ1 = qf.canonical_decomposition(gate0)
        gate1 = circ1.asgate()

        assert qf.gates_close(gate0, gate1)
        assert qf.almost_unitary(gate0)
Beispiel #12
0
def test_mutual_info() -> None:
    rho0 = qf.mixed_density(4)
    info0 = qf.mutual_info(rho0, qubits0=[0, 1], qubits1=[2, 3])

    # Information invariant to local unitary evolution
    chan = qf.RandomGate(range(2)).aschannel()
    rho1 = chan.evolve(rho0)
    info1 = qf.mutual_info(rho1, qubits0=[0, 1], qubits1=[2, 3])

    assert np.isclose(info0, info1)

    info2 = qf.mutual_info(rho1, qubits0=[0, 1])
    assert np.isclose(info0, info2)
Beispiel #13
0
def test_kronecker_decomposition() -> None:
    for _ in range(REPS):
        left = qf.RandomGate([1]).asoperator()
        right = qf.RandomGate([1]).asoperator()
        both = np.kron(left, right)
        gate0 = qf.Unitary(both, [0, 1])
        circ = qf.kronecker_decomposition(gate0)
        gate1 = circ.asgate()

        assert qf.gates_close(gate0, gate1)

    circ2 = qf.Circuit()
    circ2 += qf.Z(0)
    circ2 += qf.H(1)
    gate2 = circ2.asgate()
    circ3 = qf.kronecker_decomposition(gate2)
    gate3 = circ3.asgate()
    assert qf.gates_close(gate2, gate3)

    circ4 = qf.kronecker_decomposition(gate0, euler="XYX")
    gate4 = circ4.asgate()
    assert qf.gates_close(gate0, gate4)
def test_circuit_to_latex_error() -> None:
    circ = qf.Circuit([qf.RandomGate([0, 1, 2])])
    with pytest.raises(NotImplementedError):
        qf.circuit_to_latex(circ)
Beispiel #15
0
def test_circuit_to_cirq_unitary() -> None:
    gate0 = qf.RandomGate([4, 5])
    circ0 = qf.Circuit([gate0])
    cqc = circuit_to_cirq(circ0)
    circ1 = cirq_to_circuit(cqc)
    assert qf.circuits_close(circ0, circ1)
Beispiel #16
0
def test_canonical_decomp_random() -> None:
    for _ in range(REPS * 2):
        gate0 = qf.RandomGate([0, 1])
        gate1 = qf.canonical_decomposition(gate0).asgate()
        assert qf.gates_close(gate0, gate1)
Beispiel #17
0
def test_cnot_decomposition() -> None:
    for _ in range(REPS):
        gate0 = qf.RandomGate([4, 8])
        circ = qf.cnot_decomposition(gate0)
        gate1 = circ.asgate()
        assert qf.gates_close(gate0, gate1)
Beispiel #18
0
def test_zyz_decomposition() -> None:
    gate0 = qf.RandomGate([1])
    circ1 = qf.zyz_decomposition(gate0)
    gate1 = circ1.asgate()
    assert qf.gates_close(gate0, gate1)