예제 #1
0
파일: qpdf.py 프로젝트: tuliplan/qibo
def qpdf_hamiltonian(nqubits, z_qubit=0):
    """Precomputes Hamiltonian.

    Args:
        nqubits (int): number of qubits.
        z_qubit (int): qubit where the Z measurement is applied, must be z_qubit < nqubits

    Returns:
        An Hamiltonian object.
    """
    eye = matrices.I
    if z_qubit == 0:
        h = matrices.Z
        for _ in range(nqubits - 1):
            h = np.kron(eye, h)

    elif z_qubit == nqubits - 1:
        h = eye
        for _ in range(nqubits - 2):
            h = np.kron(eye, h)
        h = np.kron(matrices.Z, h)
    else:
        h = eye
        for _ in range(nqubits - 1):
            if _ + 1 == z_qubit:
                h = np.kron(matrices.Z, h)
            else:
                h = np.kron(eye, h)
    return Hamiltonian(nqubits, h)
예제 #2
0
    def construct_terms(terms):
        """Helper method for `from_symbolic`.

        Constructs the term dictionary by using the same
        :class:`qibo.abstractions.hamiltonians.Hamiltonian` object for terms that
        have equal matrix representation. This is done for efficiency during
        the exponentiation of terms.

        Args:
            terms (dict): Dictionary that maps tuples of targets to the matrix
                          that acts on these on targets.

        Returns:
            terms (dict): Dictionary that maps tuples of targets to the
                          Hamiltonian term that acts on these on targets.
        """
        from qibo.hamiltonians import Hamiltonian
        unique_matrices = []
        hterms = {}
        for targets, matrix in terms.items():
            flag = True
            for m, h in unique_matrices:
                if K.np.array_equal(matrix, m):
                    ham = h
                    flag = False
                    break
            if flag:
                ham = Hamiltonian(len(targets), matrix, numpy=True)
                unique_matrices.append((matrix, ham))
            hterms[targets] = ham
        return hterms
예제 #3
0
def test_trotter_hamiltonian_initialization_errors():
    """Test errors in initialization of ``TrotterHamiltonian``."""
    # Wrong type of terms
    with pytest.raises(TypeError):
        ham = TrotterHamiltonian({(0, 1): "abc"})
    # Wrong type of parts
    with pytest.raises(TypeError):
        ham = TrotterHamiltonian([(0, 1)])
    # Wrong number of target qubits
    with pytest.raises(ValueError):
        ham = TrotterHamiltonian({(0, 1): TFIM(nqubits=3, numpy=True)})
    # Same targets multiple times
    h = TFIM(nqubits=2, numpy=True)
    with pytest.raises(ValueError):
        ham = TrotterHamiltonian({(0, 1): h}, {(0, 1): h})
    # Different term matrix types
    h2 = Hamiltonian(2, np.eye(4, dtype=np.float32), numpy=True)
    with pytest.raises(TypeError):
        ham = TrotterHamiltonian({(0, 1): h, (1, 2): h2})
    # ``from_twoqubit_term`` initialization with nqubits < 0
    with pytest.raises(ValueError):
        ham = TrotterHamiltonian.from_twoqubit_term(-2, h)
    # ``from_twoqubit_term`` initialization with more than 2 targets
    h = TFIM(nqubits=3, numpy=True)
    with pytest.raises(ValueError):
        ham = TrotterHamiltonian.from_twoqubit_term(4, h)
예제 #4
0
    def from_symbolic(cls, symbolic_hamiltonian, symbol_map, ground_state=None):
        """Creates a ``TrotterHamiltonian`` from a symbolic Hamiltonian.

        We refer to the :ref:`How to define custom Hamiltonians using symbols? <symbolicham-example>`
        example for more details.

        Args:
            symbolic_hamiltonian (sympy.Expr): The full Hamiltonian written
                with symbols.
            symbol_map (dict): Dictionary that maps each symbol that appears in
                the Hamiltonian to a pair of (target, matrix).
            ground_state (Callable): Optional callable with no arguments that
                returns the ground state of this ``TrotterHamiltonian``.
                See :class:`qibo.base.hamiltonians.TrotterHamiltonian` for more
                details.

        Returns:
            A :class:`qibo.base.hamiltonians.TrotterHamiltonian` object that
            implements the given symbolic Hamiltonian.
        """
        from qibo.hamiltonians import Hamiltonian
        terms, constant = _SymbolicHamiltonian(
          symbolic_hamiltonian, symbol_map).trotter_terms()
        terms = {k: Hamiltonian(len(k), v, numpy=True)
                 for k, v in terms.items()}
        return cls.from_dictionary(terms, ground_state=ground_state) + constant
 def __init__(self, layers, domain, ansatz, function):
     self.function = function
     super().__init__(layers, domain, ansatz)
     self.target = self.function(self.domain)
     self.target = 2 * (self.target - np.min(self.target)) / (
         np.max(self.target) - np.min(self.target)) - 1
     self.H = Hamiltonian(1, matrices._Z)
     self.classical = globals()[f"classical_real_{self.ansatz}"]
    def __init__(self, layers, domain, function, ansatz):
        self.function = function
        super().__init__(layers, domain, ansatz)
        self.target = np.array(list(self.function(self.domain)))
        self.target = 2 * (self.target - np.min(self.target)) / (
            np.max(self.target) - np.min(self.target)) - 1

        self.H = Hamiltonian(1, matrices._Z)
        self.classical = classical_real_Weighted_2D
    def __init__(self, layers, domain, ansatz, real, imag):
        self.f_real = real
        self.f_imag = imag
        # self.function.name = lambda:self.real.name + '_' + self.imag.name
        super().__init__(layers, domain, ansatz)
        self.real = self.f_real(self.domain)
        self.real = 2 * (self.real - np.min(self.real)) / (
            np.max(self.real) - np.min(self.real)) - 1

        self.imag = self.f_imag(self.domain)
        self.imag = 2 * (self.imag - np.min(self.imag)) / (
            np.max(self.imag) - np.min(self.imag)) - 1

        self.target = self.real + 1j * self.imag
        self.target /= np.max(np.abs(self.target))

        self.H = [Hamiltonian(1, matrices._X), Hamiltonian(1, matrices._Y)]
        self.classical = globals()[f"classical_complex_{self.ansatz}"]
예제 #8
0
def test_trotter_hamiltonian_make_compatible_onequbit_terms():
    """Check ``make_compatible`` when the two-qubit Hamiltonian has one-qubit terms."""
    term1 = Hamiltonian(1, matrices.Z, numpy=True)
    term2 = Hamiltonian(2, np.kron(matrices.Z, matrices.Z), numpy=True)
    terms = {
        (0, 1): term2,
        (0, 2): -0.5 * term2,
        (1, 2): 2 * term2,
        (1, ): 0.35 * term1,
        (2, 3): 0.25 * term2,
        (2, ): 0.5 * term1,
        (3, ): term1
    }
    tham = TrotterHamiltonian.from_dictionary(terms) + 1.5
    xham = X(nqubits=4, trotter=True)
    cxham = tham.make_compatible(xham)
    assert not tham.is_compatible(xham)
    assert tham.is_compatible(cxham)
    np.testing.assert_allclose(xham.dense.matrix, cxham.dense.matrix)
예제 #9
0
def test_trotter_hamiltonian_three_qubit_term(backend):
    """Test creating ``TrotterHamiltonian`` with three qubit term."""
    import qibo
    from scipy.linalg import expm
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    m1 = utils.random_numpy_hermitian(3)
    m2 = utils.random_numpy_hermitian(2)
    m3 = utils.random_numpy_hermitian(1)

    term1 = Hamiltonian(3, m1, numpy=True)
    term2 = Hamiltonian(2, m2, numpy=True)
    term3 = Hamiltonian(1, m3, numpy=True)
    parts = [{(0, 1, 2): term1}, {(2, 3): term2, (1, ): term3}]
    trotter_h = TrotterHamiltonian(*parts)

    # Test that the `TrotterHamiltonian` dense matrix is correct
    eye = np.eye(2, dtype=m1.dtype)
    mm1 = np.kron(m1, eye)
    mm2 = np.kron(np.kron(eye, eye), m2)
    mm3 = np.kron(np.kron(eye, m3), np.kron(eye, eye))
    target_h = Hamiltonian(4, mm1 + mm2 + mm3)
    np.testing.assert_allclose(trotter_h.dense.matrix, target_h.matrix)

    dt = 1e-2
    initial_state = utils.random_numpy_state(4)
    if backend == "custom":
        with pytest.raises(NotImplementedError):
            circuit = trotter_h.circuit(dt=dt)
    else:
        circuit = trotter_h.circuit(dt=dt)
        final_state = circuit(np.copy(initial_state))

        u = [expm(-0.5j * dt * m) for m in [mm1, mm2, mm3]]
        target_state = u[2].dot(u[1].dot(u[0])).dot(initial_state)
        target_state = u[0].dot(u[1].dot(u[2])).dot(target_state)
        np.testing.assert_allclose(final_state, target_state)

    qibo.set_backend(original_backend)
예제 #10
0
def test_hamiltonian_initialization():
    """Testing hamiltonian initialization errors."""
    import tensorflow as tf
    dtype = K.dtypes('DTYPECPX')
    with pytest.raises(TypeError):
        H = Hamiltonian(2, "test")
    H1 = Hamiltonian(2, np.eye(4))
    H1 = Hamiltonian(2, np.eye(4), numpy=True)
    H1 = Hamiltonian(2, tf.eye(4, dtype=dtype))
    H1 = Hamiltonian(2, tf.eye(4, dtype=dtype), numpy=True)
    with pytest.raises(ValueError):
        H1 = Hamiltonian(-2, np.eye(4))
    with pytest.raises(RuntimeError):
        H2 = Hamiltonian(np.eye(2), np.eye(4))
    with pytest.raises(ValueError):
        H3 = Hamiltonian(4, np.eye(10))