qemcmc.model.energy_model ========================= .. py:module:: qemcmc.model.energy_model Classes ------- .. autoapisummary:: qemcmc.model.energy_model.EnergyModel Module Contents --------------- .. py:class:: EnergyModel(n: int, couplings: List[numpy.ndarray] = [], name: str = None, cost_function_signs: list = [-1, -1], model_type: str = 'ising') A base class for energy models for a classical energy function over n spins, defined by arbitrary-order coupling tensors. :param n: Number of spins :param couplings: List of numpy arrays representing interaction tensors. A 1D array encodes linear terms, a 2D array encodes pairwise terms (expected symmetric), and higher-rank tensors encode higher-order interactions. :param name: Optional label for the model (used in plotting / logging). :param cost_function_signs: Sign convention(s) used by downstream components (e.g. proposal/acceptance conventions). For example, `[-1, -1]` for linear and quadratic terms. :param model_type: Type of model, either 'ising' or 'binary'. This determines how the binary states are interpreted and how the energy is calculated. 'ising' models use spin values {-1, +1}, while 'binary' models use binary values {0, 1}. :type model_type: str .. rubric:: Notes - Energies are computed by mapping binary states ``{0,1}`` to spin values ``{-1,+1}`` internally. - Brute-force methods such as ``get_all_energies`` scale as O(2^n) and are intended only for small systems. .. py:attribute:: n .. py:attribute:: n_spins .. py:attribute:: couplings :value: [] .. py:attribute:: name :value: None .. py:attribute:: alphas .. py:attribute:: lowest_energy :value: None .. py:attribute:: normalised_couplings .. py:attribute:: cost_function_signs .. py:attribute:: initial_state :value: [] .. py:method:: get_initial_states(num_initial_states: int) Generates a list of random initial states. :param num_initial_states: The number of initial states to generate. :returns: A list of random initial states. :rtype: list .. py:method:: get_ground_state(num_reads=100, num_batches=10) Finds an approximate ground state using Simulated Annealing. .. py:method:: calculate_energy(state, couplings, cost_function_signs) Calculate the energy of a given state for an arbitrary-order Ising/binary model. :param state: State configuration. Can be: - Binary: "011", [0,1,1], (0,1,1), etc. - Spin: [-1,1,1], (-1,1,1), etc. :type state: array-like (str, list, tuple, np.array) :param couplings: List of coupling tensors where: - 1D arrays represent linear terms (h_i) - 2D arrays represent quadratic terms (J_ij) - 3D arrays represent cubic terms, etc. :type couplings: list of numpy arrays :returns: **float** :rtype: Total energy of the state .. py:method:: get_subgroup_couplings(subgroup: List[int], current_state: str, coupling_weights: List[float] = None) Calculates local couplings for a subgroup of spins. Spins outside the specified subgroup are treated as frozen constants, and their values are absorbed into the couplings of the subgroup. This is useful for calculating local effective Hamiltonians. :param subgroup: A list of indices of the spins in the subgroup. :type subgroup: List[int] :param current_state: The current state of the full system, as a binary string. :type current_state: str :param coupling_weights: Optional weights for the couplings. This can be used to effectively remove certain couplings from the proposal (e.g., constraints) by setting their weight to 0. It is important not to normalize the couplings after applying these weights. :type coupling_weights: List[float], optional :returns: A new list of coupling tensors for the subgroup. :rtype: List[np.ndarray] .. rubric:: Notes It might seem off to do the reweighting at this point, but here are reasons why I [SF] did it! Basically, when you get the subgroup couplings, the terms jumble up, so the returned local coupling list necessarily does not respect the order etc. of the different terms in the original. .. py:method:: calculate_alpha(n: int, couplings: list = None, eps: float = 1e-15) -> numpy.ndarray Compute alpha = sqrt(n) / sqrt(sum of squares of UNIQUE coupling coefficients), assuming coupling tensors are symmetric representations. Any non-symmetric 2-body input raises ValueError. :param n: Number of spins. :type n: int :param couplings: Couplings to use. Defaults to self.couplings if not provided. :type couplings: list[np.ndarray], optional :param eps: Small threshold to avoid division by zero. :type eps: float :returns: An array of normalising factors for each term in the couplings list. :rtype: np.ndarray .. py:method:: get_energy(state: str) -> float Returns the energy of a given state .. py:method:: get_all_energies() -> numpy.ndarray Calculate the energies for all possible spin states. This method generates all possible spin states for the system and calculates the energy for each state. :returns: An array containing the energies of all possible spin states. :rtype: np.ndarray .. py:method:: get_lowest_energies(num_states: int, return_configurations: bool = False) -> Tuple[numpy.ndarray, numpy.ndarray] Retrieve the lowest energy states and their degeneracies. This method computes all possible energies and then finds the specified number of lowest energy states along with their degeneracies. :param num_states (int): :type num_states (int): The number of lowest energy states to retrieve. :param return_configurations (bool): :type return_configurations (bool): Whether to also return the corresponding configurations of the lowest energy states. Defaults to False. :returns: - The first array contains the lowest energy values. - The second array contains the degeneracies of the corresponding energy values. :rtype: Tuple[np.ndarray, np.ndarray] .. rubric:: Notes This method is intended for small instances due to its brute-force nature, which is extremely memory intensive and slow. .. py:method:: find_lowest_values(arr: numpy.ndarray, num_values: int = 5) Find the lowest unique values in an array and their degeneracies. :param arr (np.ndarray): :type arr (np.ndarray): The input array from which to find the lowest values. :param num_values (int: :type num_values (int: The number of lowest unique values to find. Defaults to 5. :param optional): :type optional): The number of lowest unique values to find. Defaults to 5. :returns: - lowest_values (np.ndarray): The lowest unique values in the array. - degeneracy (np.ndarray): The counts of each of the lowest unique values. :rtype: Tuple[lowest_values (np.ndarray), degeneracy (np.ndarray)] .. py:method:: get_lowest_energy() Calculate and return the lowest energy from all possible energies. This method uses a brute force approach to find the lowest energy, making it extremely memory intensive and slow. It is recommended to use this method only for small instances. :returns: **float** :rtype: The lowest energy value. .. rubric:: Notes If the lowest energy has already been calculated and stored in `self.lowest_energy`, it will return that value directly to save computation time. .. py:method:: get_boltzmann_factor(state: str, beta: float = 1.0) -> float Get un-normalised boltzmann probability of a given state :param state: configuration of spins for which probability is to be calculated :type state: str :param beta: inverse temperature (1/T) at which the probability is to be calculated. :type beta: float :rtype: float corresponding to the un-normalised boltzmann probability of the given state. .. py:method:: get_boltzmann_factor_from_energy(E, beta: float = 1.0) -> float Get un-normalized Boltzmann probability for a given energy. :param E: Energy for which the Boltzmann factor is to be calculated. :type E: float :param beta: Inverse temperature (1/T) at which the probability is to be calculated. :type beta: float :returns: The un-normalized Boltzmann probability for the given energy. :rtype: float