Source code for colder.simulation.annealing


import numpy as np

import colder.backend

from typing import Union



[docs] class annealing: """ Quantum annealing simulation. The total evolution time is provided by arg `tau`. Either one argument must be provided between `P` (total steps) and `dt` (timestep). Example: .. highlight:: python .. code-block:: python import colder.simulation.annealing ann = colder.simulation.annealing.annealing(tau = 0.01, P = 200, backend = 'scipy') def H_t(t): # timedependent hamiltonian return ... psi0 = ... # the initial state psi_final = ann.run(H_t, psi0=psi0) """
[docs] def __init__(self, tau : float, P : Union[int,None] = None, dt : Union[float,None] = None, backend : str = 'scipy', backend_options : dict = {}) -> None: """ Initialize a quantum annealing simulation. The total evolution time is provided by arg `tau`. Either one argument must be provided between `P` (total steps) and `dt` (timestep). Args: tau (float): Total annealing time. P (Union[int,None], optional): Number of timesteps. Defaults to None. If provided, overrides the value of `dt`. dt (Union[float,None], optional): Timestep. Defaults to None. backend (str, optional): Select a backend. Defaults to 'qibo'. Available backends: `qibo`, `scipy`. backend_options (dict, optional): Dictionary of kwargs to pass to backend. Defaults to {}. Raises: Exception: Must provide either the timestep `dt` or the total number of steps `P`. If both values are prompted, `P` is taken in consideration. Exception: Not valid backend identifier. """ assert tau > 0, 'total annealing time must be positive' if P is None and dt is None: raise Exception('must provide at least the number of steps (P) or the timestep (dt).') self.tau = tau # total annealing time if P is None: self.dt = dt # effective time step self.P = tau//dt # number of steps else: self.P = P # number of steps self.dt = tau/P # effective time step self.backend_options = backend_options if backend == 'qibo': self.backend_time_evolution = colder.backend.qibo.routines.timedependent_evolution elif backend == 'scipy': self.backend_time_evolution = colder.backend.scipy.routines.timedependent_evolution #elif backend == 'sparse': # self.backend_time_evolution = colder.backend.sparse.routines.timedependent_evolution else: raise Exception('not valid backend identifier')
[docs] def run(self, H : callable, psi0 : Union[np.ndarray, str] = 'superpos', hook_function : Union[callable,None] = None) -> np.ndarray: """ Run the annealing simulation with time dependent hamiltonian. H must be a function of time. Args: H (callable): Function that returns the hamiltonian at time t. psi0 (Union[np.ndarray, str], optional): Initial state. Defaults to 'superpos'. hook_function (Union[callable,None], optional): Function to execute at each time step. Arguments must be `(t : float, state : np.ndarray)`. Defaults to None. Returns: np.ndarray: Evolved quantum state. """ return self.backend_time_evolution(H, T = self.tau, P = self.P, psi0 = psi0, *self.backend_options, hook_function = hook_function)