示例#1
0
def test_entropy_bad_state_type(backend):
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    entropy = callbacks.EntanglementEntropy([0])
    with pytest.raises(TypeError):
        _ = entropy("test")
    qibo.set_backend(original_backend)
def test_entropy_product_state():
    """Check that the |++> state has zero entropy."""
    entropy = callbacks.EntanglementEntropy()
    state = np.ones(4) / 2.0

    result = entropy(state).numpy()
    np.testing.assert_allclose(result, 0, atol=_atol)
def test_entropy_multiple_executions(accelerators):
    """Check entropy calculation when the callback is used in multiple executions."""
    entropy = callbacks.EntanglementEntropy([0])

    target_c = Circuit(2)
    target_c.add([gates.RY(0, 0.1234), gates.CNOT(0, 1)])
    target_state = target_c().numpy()

    c = Circuit(2, accelerators)
    c.add(gates.RY(0, 0.1234))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    state = c()
    np.testing.assert_allclose(state.numpy(), target_state)

    target_c = Circuit(2)
    target_c.add([gates.RY(0, 0.4321), gates.CNOT(0, 1)])
    target_state = target_c().numpy()

    c = Circuit(2, accelerators)
    c.add(gates.RY(0, 0.4321))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    state = c()
    np.testing.assert_allclose(state.numpy(), target_state)

    def target_entropy(t):
        cos = np.cos(t / 2.0)**2
        sin = np.sin(t / 2.0)**2
        return -cos * np.log2(cos) - sin * np.log2(sin)

    target = [0, target_entropy(0.1234), 0, target_entropy(0.4321)]
    np.testing.assert_allclose(entropy[:].numpy(), target, atol=_atol)
示例#4
0
def test_entropy_singlet_state(backend):
    """Check that the singlet state has maximum entropy."""
    from qibo import K
    entropy = callbacks.EntanglementEntropy([0])
    state = np.zeros(4)
    state[0], state[-1] = 1, 1
    state = K.cast(state / np.sqrt(2))
    result = entropy(state)
    K.assert_allclose(result, 1.0)
def test_entropy_switch_partition():
    """Check that partition is switched to the largest counterpart."""
    entropy = callbacks.EntanglementEntropy([0])
    # Prepare ghz state of 5 qubits
    state = np.zeros(2**5)
    state[0], state[-1] = 1, 1
    state = state / np.sqrt(2)

    result = entropy(state).numpy()
    np.testing.assert_allclose(result, 1.0)
示例#6
0
def test_entropy_product_state(backend):
    """Check that the |++> state has zero entropy."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    entropy = callbacks.EntanglementEntropy()
    state = np.ones(4) / 2.0

    result = entropy(state)
    np.testing.assert_allclose(result, 0, atol=_atol)
    qibo.set_backend(original_backend)
示例#7
0
def test_entropy_large_circuit(backend, accelerators):
    """Check that entropy calculation works for variational like circuit."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    thetas = np.pi * np.random.random((3, 8))
    target_entropy = callbacks.EntanglementEntropy([0, 2, 4, 5])
    c1 = Circuit(8)
    c1.add((gates.RY(i, thetas[0, i]) for i in range(8)))
    c1.add((gates.CZ(i, i + 1) for i in range(0, 7, 2)))
    state1 = c1()
    e1 = target_entropy(state1)

    c2 = Circuit(8)
    c2.add((gates.RY(i, thetas[1, i]) for i in range(8)))
    c2.add((gates.CZ(i, i + 1) for i in range(1, 7, 2)))
    c2.add(gates.CZ(0, 7))
    state2 = (c1 + c2)()
    e2 = target_entropy(state2)

    c3 = Circuit(8)
    c3.add((gates.RY(i, thetas[2, i]) for i in range(8)))
    c3.add((gates.CZ(i, i + 1) for i in range(0, 7, 2)))
    state3 = (c1 + c2 + c3)()
    e3 = target_entropy(state3)

    entropy = callbacks.EntanglementEntropy([0, 2, 4, 5])
    c = Circuit(8, accelerators)
    c.add(gates.CallbackGate(entropy))
    c.add((gates.RY(i, thetas[0, i]) for i in range(8)))
    c.add((gates.CZ(i, i + 1) for i in range(0, 7, 2)))
    c.add(gates.CallbackGate(entropy))
    c.add((gates.RY(i, thetas[1, i]) for i in range(8)))
    c.add((gates.CZ(i, i + 1) for i in range(1, 7, 2)))
    c.add(gates.CZ(0, 7))
    c.add(gates.CallbackGate(entropy))
    c.add((gates.RY(i, thetas[2, i]) for i in range(8)))
    c.add((gates.CZ(i, i + 1) for i in range(0, 7, 2)))
    c.add(gates.CallbackGate(entropy))
    state = c()

    np.testing.assert_allclose(state3, state)
    np.testing.assert_allclose(entropy[:], [0, e1, e2, e3])
    qibo.set_backend(original_backend)
示例#8
0
def test_getitem_bad_indexing(backend):
    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2)
    c.add(gates.RY(0, 0.1234))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    final_state = c()
    entropy[0]
    with pytest.raises(IndexError):
        entropy[1]
    with pytest.raises(IndexError):
        entropy["a"]
示例#9
0
def test_entropy_in_compiled_circuit(backend):
    """Check that entropy calculation works when circuit is compiled."""
    from qibo import get_backend
    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2)
    c.add(gates.CallbackGate(entropy))
    c.add(gates.H(0))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    c.compile()
    final_state = c()
    K.assert_allclose(entropy[:], [0, 0, 1.0], atol=_atol)
def test_entropy_singlet_state():
    """Check that the singlet state has maximum entropy."""
    entropy = callbacks.EntanglementEntropy([0])
    state = np.zeros(4)
    state[0], state[-1] = 1, 1
    state = state / np.sqrt(2)
    # Pass the state as `tf.Tensor` to test this functionality as well
    import tensorflow as tf
    from qibo.config import DTYPES
    state = tf.convert_to_tensor(state, dtype=DTYPES.get('DTYPECPX'))

    result = entropy(state).numpy()
    np.testing.assert_allclose(result, 1.0)
示例#11
0
def test_entropy_in_circuit(accelerators):
    """Check that entropy calculation works in circuit."""
    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2, accelerators)
    c.add(gates.CallbackGate(entropy))
    c.add(gates.H(0))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    state = c()

    target = [0, 0, 1.0]
    np.testing.assert_allclose(entropy[:].numpy(), target, atol=_atol)
示例#12
0
def test_entropy_switch_partition(backend):
    """Check that partition is switched to the largest counterpart."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    entropy = callbacks.EntanglementEntropy([0])
    # Prepare ghz state of 5 qubits
    state = np.zeros(2**5)
    state[0], state[-1] = 1, 1
    state = state / np.sqrt(2)

    result = entropy(state)
    np.testing.assert_allclose(result, 1.0)
    qibo.set_backend(original_backend)
示例#13
0
def test_entropy_numerical(backend):
    """Check that entropy calculation does not fail for tiny eigenvalues."""
    from qibo import K
    eigvals = np.array([-1e-10, -1e-15, -2e-17, -1e-18, -5e-60, 1e-48, 4e-32,
                        5e-14, 1e-14, 9.9e-13, 9e-13, 5e-13, 1e-13, 1e-12,
                        1e-11, 1e-10, 1e-9, 1e-7, 1, 4, 10])
    rho = K.cast(np.diag(eigvals))
    callback = callbacks.EntanglementEntropy()
    result = callback.entropy(rho)

    mask = eigvals > 0
    target = - (eigvals[mask] * np.log2(eigvals[mask])).sum()
    K.assert_allclose(result, target)
示例#14
0
def test_callbacks_fusion(backend):
    """Check entropy calculation in fused circuit."""
    from qibo import callbacks
    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(5)
    c.add(gates.H(0))
    c.add(gates.X(1))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    fused_c = c.fuse()
    K.assert_allclose(fused_c(), c())
    target_entropy = [0.0, 1.0, 0.0, 1.0]
    K.assert_allclose(entropy[:], target_entropy, atol=1e-7)
def test_entropy_bad_indexing():
    """Check exceptions in ``Callback.__getitem__``."""
    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2)
    c.add(gates.RY(0, 0.1234))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    state = c()

    entropy[0]
    with pytest.raises(IndexError):
        entropy[1]
    with pytest.raises(IndexError):
        entropy["a"]
示例#16
0
def test_entropy_numerical():
    """Check that entropy calculation does not fail for tiny eigenvalues."""
    import tensorflow as tf
    from qibo.config import DTYPES
    eigvals = np.array([-1e-10, -1e-15, -2e-17, -1e-18, -5e-60, 1e-48, 4e-32,
                        5e-14, 1e-14, 9.9e-13, 9e-13, 5e-13, 1e-13, 1e-12,
                        1e-11, 1e-10, 1e-9, 1e-7, 1, 4, 10])
    rho = tf.convert_to_tensor(np.diag(eigvals), dtype=DTYPES.get('DTYPECPX'))
    callback = callbacks.EntanglementEntropy()
    result = callback.entropy(rho).numpy()

    mask = eigvals > 0
    target = - (eigvals[mask] * np.log2(eigvals[mask])).sum()

    np.testing.assert_allclose(result, target)
def test_entropy_in_circuit(accelerators):
    """Check that entropy calculation works in circuit."""
    entropy = callbacks.EntanglementEntropy([0], compute_spectrum=True)
    c = Circuit(2, accelerators)
    c.add(gates.CallbackGate(entropy))
    c.add(gates.H(0))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    state = c()

    target = [0, 0, 1.0]
    np.testing.assert_allclose(entropy[:].numpy(), target, atol=_atol)

    target_spectrum = [0, 0, np.log(2), np.log(2)]
    entropy_spectrum = np.concatenate(entropy.spectrum).ravel().tolist()
    np.testing.assert_allclose(entropy_spectrum, target_spectrum, atol=_atol)
示例#18
0
def test_entropy_in_circuit(backend, density_matrix):
    """Check that entropy calculation works in circuit."""
    entropy = callbacks.EntanglementEntropy([0], compute_spectrum=True)
    c = Circuit(2, density_matrix=density_matrix)
    c.add(gates.CallbackGate(entropy))
    c.add(gates.H(0))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    state = c()

    target = [0, 0, 1.0]
    K.assert_allclose(entropy[:], target, atol=_atol)

    target_spectrum = [0, 0, np.log(2), np.log(2)]
    entropy_spectrum = np.concatenate(entropy.spectrum).ravel().tolist()
    K.assert_allclose(entropy_spectrum, target_spectrum, atol=_atol)
示例#19
0
def test_fuse_with_callback(accelerators):
    """Check entropy calculation in fused circuit."""
    from qibo import callbacks
    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2, accelerators)
    c.add(gates.H(0))
    c.add(gates.X(1))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))

    fused_c = c.fuse()
    target_state = c()
    final_state = fused_c()
    np.testing.assert_allclose(final_state, target_state)
    target_entropy = [0.0, 1.0, 0.0, 1.0]
    np.testing.assert_allclose(entropy[:], target_entropy, atol=1e-7)
示例#20
0
def test_entropy_in_distributed_circuit(backend, accelerators, gateconf, target_entropy):
    """Check that various entropy configurations work in distributed circuit."""
    target_c = Circuit(4)
    target_c.add([gates.H(0), gates.CNOT(0, 1)])
    target_state = target_c()

    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(4, accelerators)
    for gate in gateconf:
        if gate == "H":
            c.add(gates.H(0))
        elif gate == "CNOT":
            c.add(gates.CNOT(0, 1))
        elif gate == "entropy":
            c.add(gates.CallbackGate(entropy))
    final_state = c()
    K.assert_allclose(final_state, target_state)
    K.assert_allclose(entropy[:], target_entropy, atol=_atol)
示例#21
0
def test_entropy_in_distributed_circuit():
    """Check that various entropy configurations work in distributed circuit."""
    target_c = Circuit(2)
    target_c.add([gates.H(0), gates.CNOT(0, 1)])
    target_state = target_c().numpy()
    accelerators = {"/GPU:0": 1, "/GPU:1": 1}

    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2, accelerators)
    c.add([gates.H(0), gates.CNOT(0, 1), gates.CallbackGate(entropy)])
    final_state = c().numpy()
    np.testing.assert_allclose(final_state, target_state)
    np.testing.assert_allclose(entropy[:].numpy(), [1.0], atol=_atol)

    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2, accelerators)
    c.add([gates.H(0), gates.CallbackGate(entropy), gates.CNOT(0, 1)])
    final_state = c().numpy()
    np.testing.assert_allclose(final_state, target_state)
    np.testing.assert_allclose(entropy[:].numpy(), [0.0], atol=_atol)

    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2, accelerators)
    c.add([gates.CallbackGate(entropy), gates.H(0), gates.CNOT(0, 1)])
    final_state = c().numpy()
    np.testing.assert_allclose(final_state, target_state)
    np.testing.assert_allclose(entropy[:].numpy(), [0.0], atol=_atol)

    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2, accelerators)
    c.add([gates.CallbackGate(entropy), gates.H(0),
           gates.CNOT(0, 1), gates.CallbackGate(entropy)])
    final_state = c().numpy()
    np.testing.assert_allclose(final_state, target_state)
    np.testing.assert_allclose(entropy[:].numpy(), [0, 1.0], atol=_atol)

    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2, accelerators)
    c.add([gates.H(0), gates.CallbackGate(entropy),
           gates.CNOT(0, 1), gates.CallbackGate(entropy)])
    final_state = c().numpy()
    np.testing.assert_allclose(final_state, target_state)
    np.testing.assert_allclose(entropy[:].numpy(), [0, 1.0], atol=_atol)

    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2, accelerators)
    c.add([gates.CallbackGate(entropy), gates.H(0),
           gates.CallbackGate(entropy), gates.CNOT(0, 1)])
    final_state = c().numpy()
    np.testing.assert_allclose(final_state, target_state)
    np.testing.assert_allclose(entropy[:].numpy(), [0, 0], atol=_atol)
def test_entropy_random_state():
    """Check that entropy calculation agrees with numpy."""
    # Generate a random positive and hermitian density matrix
    rho = np.random.random((8, 8)) + 1j * np.random.random((8, 8))
    rho = rho + rho.conj().T
    _, u = np.linalg.eigh(rho)
    s = 5 * np.random.random(8)
    s = s / s.sum()
    rho = u.dot(np.diag(s)).dot(u.conj().T)

    callback = callbacks.EntanglementEntropy(compute_spectrum=True)
    result = callback._entropy(rho)
    target = -(s * np.log2(s)).sum()
    np.testing.assert_allclose(result.numpy(), target)

    ref_eigvals = np.linalg.eigvalsh(rho)
    masked_eigvals = ref_eigvals[np.where(ref_eigvals > EIGVAL_CUTOFF)]
    ref_spectrum = -np.log(masked_eigvals)
    np.testing.assert_allclose(callback.spectrum[0].numpy(), ref_spectrum)
def test_entropy_in_compiled_circuit():
    """Check that entropy calculation works when circuit is compiled."""
    import qibo
    original_backend = qibo.get_backend()
    qibo.set_backend("matmuleinsum")
    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2)
    c.add(gates.CallbackGate(entropy))
    c.add(gates.H(0))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    c.compile()
    state = c()
    qibo.set_backend("custom")

    target = [0, 0, 1.0]
    np.testing.assert_allclose(entropy[:].numpy(), target, atol=_atol)
    qibo.set_backend(original_backend)
示例#24
0
def test_entropy_in_compiled_circuit(backend):
    """Check that entropy calculation works when circuit is compiled."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(2)
    c.add(gates.CallbackGate(entropy))
    c.add(gates.H(0))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    if backend == "custom":
        with pytest.raises(RuntimeError):
            c.compile()
    else:
        c.compile()
        final_state = c()
        np.testing.assert_allclose(entropy[:], [0, 0, 1.0], atol=_atol)
    qibo.set_backend(original_backend)
示例#25
0
def test_entropy_density_matrix(backend):
    from qibo.tests.utils import random_density_matrix
    rho = random_density_matrix(4)
    # this rho is not always positive. Make rho positive for this application
    _, u = np.linalg.eigh(rho)
    rho = u.dot(np.diag(5 * np.random.random(u.shape[0]))).dot(u.conj().T)
    # this is a positive rho

    entropy = callbacks.EntanglementEntropy([1, 3])
    entropy.density_matrix = True
    final_ent = entropy(rho)

    rho = rho.reshape(8 * (2,))
    reduced_rho = np.einsum("abcdafch->bdfh", rho).reshape((4, 4))
    eigvals = np.linalg.eigvalsh(reduced_rho).real
    # assert that all eigenvalues are non-negative
    assert (eigvals >= 0).prod()
    mask = eigvals > 0
    target_ent = - (eigvals[mask] * np.log2(eigvals[mask])).sum()
    K.assert_allclose(final_ent, target_ent)
示例#26
0
def test_circuit_gate_generator_errors(backend, accelerators):
    from qibo import callbacks
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)

    smallc = Circuit(2, accelerators=accelerators)
    smallc.add((gates.H(i) for i in range(2)))
    with pytest.raises(ValueError):
        next(smallc.on_qubits(0, 1, 2))

    smallc = Circuit(2, accelerators=accelerators)
    smallc.add(gates.Flatten(np.ones(4) / np.sqrt(2)))
    with pytest.raises(NotImplementedError):
        next(smallc.on_qubits(0, 1))

    smallc = Circuit(4, accelerators=accelerators)
    smallc.add(gates.CallbackGate(callbacks.EntanglementEntropy([0, 1])))
    with pytest.raises(NotImplementedError):
        next(smallc.on_qubits(0, 1, 2, 3))
    qibo.set_backend(original_backend)
示例#27
0
def test_entropy_multiple_executions(backend, accelerators):
    """Check entropy calculation when the callback is used in multiple executions."""
    target_c = Circuit(4)
    target_c.add([gates.RY(0, 0.1234), gates.CNOT(0, 1)])
    target_state = target_c()

    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(4, accelerators)
    c.add(gates.RY(0, 0.1234))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    state = c()
    K.assert_allclose(state, target_state)

    target_c = Circuit(4)
    target_c.add([gates.RY(0, 0.4321), gates.CNOT(0, 1)])
    target_state = target_c()

    c = Circuit(4, accelerators)
    c.add(gates.RY(0, 0.4321))
    c.add(gates.CallbackGate(entropy))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CallbackGate(entropy))
    state = c()
    K.assert_allclose(state, target_state)

    def target_entropy(t):
        cos = np.cos(t / 2.0) ** 2
        sin = np.sin(t / 2.0) ** 2
        return - cos * np.log2(cos) - sin * np.log2(sin)

    target = [0, target_entropy(0.1234), 0, target_entropy(0.4321)]
    K.assert_allclose(entropy[:], target, atol=_atol)

    c = Circuit(8, accelerators)
    with pytest.raises(RuntimeError):
        c.add(gates.CallbackGate(entropy))
        state = c()
示例#28
0
def test_entanglement_entropy(backend):
    """Check that entanglement entropy calculation works for density matrices."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    rho = utils.random_density_matrix(4)
    # this rho is not always positive. Make rho positive for this application
    _, u = np.linalg.eigh(rho)
    rho = u.dot(np.diag(5 * np.random.random(u.shape[0]))).dot(u.conj().T)
    # this is a positive rho

    entropy = callbacks.EntanglementEntropy([1, 3])
    entropy.density_matrix = True
    final_ent = entropy(rho)

    rho = rho.reshape(8 * (2, ))
    reduced_rho = np.einsum("abcdafch->bdfh", rho).reshape((4, 4))
    eigvals = np.linalg.eigvalsh(reduced_rho).real
    # assert that all eigenvalues are non-negative
    assert (eigvals >= 0).prod()
    mask = eigvals > 0
    target_ent = -(eigvals[mask] * np.log2(eigvals[mask])).sum()
    np.testing.assert_allclose(final_ent, target_ent)
    qibo.set_backend(original_backend)
def test_state_invalid_type():
    """Check that ``TypeError`` is raised for bad state type."""
    entropy = callbacks.EntanglementEntropy([0])
    # Prepare ghz state of 5 qubits
    with pytest.raises(TypeError):
        result = entropy([0, 1, 0, 0])
示例#30
0
def test_callback_gate_errors():
    from qibo import callbacks
    entropy = callbacks.EntanglementEntropy([0])
    gate = gates.CallbackGate(entropy)
    with pytest.raises(ValueError):
        gate.construct_unitary()