Source code for PhaseEstimation.annni_model

""" This module implements the base functions for treating the Hamiltonian of the ANNNI Ising-model """
import pennylane as qml
from pennylane import numpy as np

from typing import Tuple, List

##############


[docs]def get_H( N: int, L: float, K: float, ring: bool = False ) -> qml.ops.qubit.hamiltonian.Hamiltonian: """ Set up Hamiltonian: H = J1* (- Σsigma^i_x*sigma_x^{i+1} - (h/J1) * Σsigma^i_z - (J2/J1) * Σsigma^i_x*sigma_x^{i+2} ) [where J1 = 1, (h/J1) = Lambda(/L), (J2/J1) = K] Parameters ---------- N : int Number of spins of the Ising Chain L : float h/J1 parameter K : float J1/J2 parameter ring : bool If False, system has open-boundaries condition Returns ------- pennylane.ops.qubit.hamiltonian.Hamiltonian Hamiltonian Pennylane class for the (Transverse) Ising Chain """ # Interaction of spins with magnetic field H = -L * qml.PauliZ(0) for i in range(1, N): H = H - L * qml.PauliZ(i) # Interaction between spins (neighbouring): for i in range(0, N - 1): H = H + (-1) * (qml.PauliX(i) @ qml.PauliX(i + 1)) # Interaction between spins (next-neighbouring): for i in range(0, N - 2): H = H + (-1) * K * (qml.PauliX(i) @ qml.PauliX(i + 2)) # If ring == True, the 'chain' needs to be closed if ring: # Nearest interaction between last spin and first spin -particles H = H + (-1) * (qml.PauliX(N - 1) @ qml.PauliX(0)) # Next nearest interactions: H = H + (-1) * K * (qml.PauliX(N - 2) @ qml.PauliX(0)) H = H + (-1) * K * (qml.PauliX(N - 1) @ qml.PauliX(1)) return H
[docs]def build_Hs( N: int, n_hs: int, n_kappas: int, h_max: float = 2, kappa_max: float = 1, ring: bool = False ) -> Tuple[ List[qml.ops.qubit.hamiltonian.Hamiltonian], List[List[int]], List[int], List[Tuple[int, float, float]], int, ]: """ Sets up np.ndarray of pennylane Hamiltonians with different parameters total_states = n_kappas * n_hs kappa can have n_kappas values from 0 to - abs(kappa_max) (NB the sign) h can have n_hs values from 0 to h_max Parameters ---------- N : int Number of spins of the Ising Chain n_hs : int Number of different values of h the hamiltonian can have h_max : float Maximum value of h, the values will range from 0 to h_max n_kappas : int Number of different values of kappa the hamiltonian can have kappa_max : float Maximum value of kappa ring : bool If False, system has open-boundaries condition Returns ------- np.array Array of pennylane Hamiltonians np.array Array of labels for analytical solutions np.array Array for the recycle rule np.array Array for the states parameters """ # Set up arrays of the parameters K and Ls kappa_values = np.linspace(0, -np.abs(kappa_max), n_kappas) h_values = np.linspace(0, h_max, n_hs) Hs = [] # Array of the Pennylane hamiltonians labels = [] # Array of the labels: # > [1,1] for paramagnetic states # > [0,1] for ferromagnetic states # > [1,0] for antiphase states # > [None,None] for states with no analytical solutions anni_params = [] # Array of parameters [N, L, K] for kappa in kappa_values: for h in h_values: anni_params.append([N, h, kappa]) Hs.append(get_H(int(N), float(h), float(kappa), ring)) # Append the known labels (phases of the model) if kappa == 0: if h < 1: labels.append([0, 1]) # Ferromagnetic else: labels.append([1, 1]) # Paramagnetic elif h == 0: if kappa < -0.5: labels.append([1, 0]) # Antiphase else: labels.append([0, 1]) # Ferromagnetic else: labels.append([-1, -1]) # Array of indices for the order of states to train through VQE # INDICES RECYCLE RULE # +--------------+ +--------------+ # | 4 9 14 19 | | 4 5 14 15 | # | 3 8 13 18 | | 3 6 13 16 | # | 2 7 12 17 | ==> | 2 7 12 17 | # | 1 6 11 16 | | 1 8 11 18 | # | 0 5 10 15 | | 0 9 10 19 | # +--------------+ +--------------+ recycle_rule = [] k_index = 0 while k_index < n_kappas: # k_index = 0 (going up) # [0, 1, 2, 3, 4] recycle_rule.append(np.arange(k_index * n_hs, (k_index + 1) * n_hs).astype(int)) k_index += 1 if k_index >= n_kappas: break # k_index = 1 (going down) # [9, 8, 7, 6, 5] recycle_rule.append(np.arange((k_index + 1) * n_hs - 1, k_index * n_hs - 1, -1).astype(int)) k_index += 1 if k_index >= n_kappas: break return ( Hs, np.array(labels), np.array(recycle_rule).flatten(), np.array(anni_params), n_hs * n_kappas, n_hs, n_kappas, h_max, kappa_max, )