colder.simulation package

Implements all the interface classes to handle an annealing simulation.

annealing module

class colder.simulation.annealing.annealing(tau: float, P: int | None = None, dt: float | None = None, backend: str = 'scipy', backend_options: dict = {})[source]

Bases: object

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

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)
__init__(tau: float, P: int | None = None, dt: float | None = None, backend: str = 'scipy', backend_options: dict = {}) None[source]

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).

Parameters:
  • 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.

run(H: callable, psi0: ndarray | str = 'superpos', hook_function: callable | None = None) ndarray[source]

Run the annealing simulation with time dependent hamiltonian. H must be a function of time.

Parameters:
  • 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:

Evolved quantum state.

Return type:

np.ndarray

COLD module

colder.simulation.cold.get_functions_from_schedule(schedules: dict) dict[source]

Extract the function for every interpolation.

colder.simulation.cold.check_hamiltonian_input(obj) hamiltonian_collection | None[source]

Check input obj to be hamiltonian_collection or hamiltonian. Otherwise returns None (to be handled).

class colder.simulation.cold.cold(system: hamiltonian_collection, ansatz: hamiltonian_collection, annealing_time: float, nspin: int, use_cache_agp: bool | cache_lcd_numpy | None = None, system_fargs: dict = {}, qoc_parameters: list | None = None, backend: str = 'scipy')[source]

Bases: object

COLD object to handle the annealing simulation and optimization.

Example

import colder.simulation.cold as ccold

tau : float = 0.01  # annealing time
nsteps : int = 200  # number of steps for discrete annealing simulation
Nk : int = 1  # frequencies to control in QOC functions

H = ...
ansatz = ...

csym = ccold.cold(
    system = H, ansatz = ansatz, annealing_time = tau, nspin = 5,
    system_fargs = {'tau' : tau, 'beta' : np.zeros(Nk)},
    # name of the parameter to treat as QOC parameter to optimize
    qoc_parameters = ['beta'],
    backend = 'scipy'
)

csym.be_ready()

psi0 = csym.get_psi_zero()
truegs = csym.get_psi_final()

# define the loss function to optimize
def loss_infidelity(psi, param):
# note: the input of this function are the final state psi and the optimized parameter (beta, in this case)
    infidelity = 1 - colder.quantum.math.fidelity(psi, truegs)
    return infidelity

x0 = np.random.uniform(size=Nk) # initial guess of parameters
optim = csym.run_cold_opti(init_parameters = x0,
    loss_function = loss_infidelity, psi0 = psi0, annealer_nsteps = nsteps,
)

Remark: the loss function to be optimized must accept as arguments the final state and the optimized parameter.

__init__(system: hamiltonian_collection, ansatz: hamiltonian_collection, annealing_time: float, nspin: int, use_cache_agp: bool | cache_lcd_numpy | None = None, system_fargs: dict = {}, qoc_parameters: list | None = None, backend: str = 'scipy') None[source]

Initialize a COLD annealing simulation.

Parameters:
  • system (colder.core.physics.hamiltonian_collection) – hamiltonian representing the system

  • ansatz (colder.core.physics.hamiltonian_collection) – hamiltonian representing the ansatz

  • annealing_time (float) – Total annealing time.

  • nspin (int) – Number of spins of the system.

  • use_cache_agp (Union[bool,cgauge.cache_lcd_numpy,None], optional) – If True/None, the adiabatic gauge potential will be cached after its computation. If False, the AGP will not be cached and will be recomputed at every initialization of the simulation. If a cache_lcd_numpy is provided, the argument AGP will be explicitly used as cached value. Defaults to None.

  • system_fargs (dict, optional) – Arguments to pass at system interpolated functions. Defaults to {}.

  • qoc_parameters (list, optional) – List of string containing the name of the parameter to use as QOC. Defaults to None.

  • backend (str, optional) – Choose a backend for simulations. Defaults to ‘qibo’.

make_schedule_interpolation(agp_samples: int = 50) None[source]

Compute the numerical interpolation of the system driving parameters.

Parameters:

agp_samples (int, optional) – Number of samples to use in the interpolation. Defaults to 50.

retrieve_functions_from_schedule()[source]

Retrieves the function from schedule objects, for both hamiltonian and ansatz.

compute_schedules(time: ndarray | None, default_time_points: int = 100) ndarray[source]

Given an array of time values, computes the schedule function values.

Parameters:
  • time (Union[np.ndarray,None) – Array of time values. If None, the time points will be generated in [0,annealing time].

  • default_time_points (int, optional) – Number of points to generate, if time array is not provided. Defaults to 100.

Returns:

System and ansatz parameters schedule.

Return type:

Union[np.ndarray, np.ndarray]

plot_schedules(npoints=101, plot_lcd=True, legend=True) None[source]

Plot the schedule functions.

Parameters:
  • npoints (int, optional) – Number of points to sample. Defaults to 101.

  • plot_lcd (bool, optional) – If True, plots the LCD terms. Defaults to True.

  • legend (bool, optional) – If True, legend is enabled. Defaults to True.

make_hamiltonians()[source]

Evaluates the static component of hamiltonians (both system and ansatz).

make_timedependent_hamiltonian() callable[source]

Return the timedependent function that computes the hamiltonian for any backend.

Raises:

Exception – The requirements to build the hamiltonian are not satisfied. Run make_hamiltonians() first.

Returns:

Function that return the timedependent hamiltonian at time t. Its first and only argument is t.

Return type:

callable

make_timedependent_hamiltonian_nogauge() callable[source]

Return the timedependent function that computes the hamiltonian for any backend. The returned hamiltonian will not have the ansatz AGP terms.

Raises:

Exception – The requirements to build the hamiltonian are not satisfied. Run make_hamiltonians() first.

Returns:

Function that return the timedependent hamiltonian at time t. Its first and only argument is t.

Return type:

callable

get_psi_zero() ndarray[source]

Computes the initial ground state of system hamiltonian via diagonalization.

Returns:

The ground state.

Return type:

np.ndarray

get_psi_final() ndarray[source]

Computes the final ground state of system hamiltonian via diagonalization.

Returns:

The ground state (at final annealing time).

Return type:

np.ndarray

get_spectrum(n_eig: int, nsteps: int = 100, use_H0: bool = False) ndarray[source]

Returns the spectrum of the system hamiltonian in nsteps between time 0 and total annealing time.

Parameters:
  • n_eig (int) – Number of eigenvalues to compute.

  • nsteps (int, optional) – Number of timesteps. Defaults to 100.

  • use_H0 (bool, optional) – If True, the hamiltonian is without the AGP. Defaults to False.

Returns:

Matrix of eigenvalues and simulation time, respectively.

Return type:

Union[np.ndarray, np.ndarray]

plot_spectrum(n_eig: int = 8, nsteps: int = 100, use_H0: bool = False) None[source]

Plots the spectrum of the system hamiltonian in nsteps between time 0 and total annealing time.

Parameters:
  • n_eig (int) – Number of eigenvalues to compute.

  • nsteps (int, optional) – Number of timesteps. Defaults to 100.

  • use_H0 (bool, optional) – If True, the hamiltonian is without the AGP. Defaults to False.

be_ready()[source]

Executes all the required pre-computation routines.

run(nsteps: int = 100, psi0: ndarray | None = None, dt: float | None = None, force_be_ready: bool = False, hook_function: callable | None = None) ndarray[source]

Run an annealing simulation for the current COLD object.

Parameters:
  • nsteps (int, optional) – Number of discretized annealing steps. Defaults to 100.

  • psi0 (Union[np.ndarray, None], optional) – Initial state. If None, the initial state is compute diagonalizing the hamiltonian without Gauge potential. Defaults to None.

  • force_be_ready (bool, optional) – If True, be_ready() is executed before the annealing run. Defaults to False.

  • hook_function (Union[callable,None], optional) – If not None, this function will be called at every step of the annealing schedule. The callable arguments must be (t : float, state : np.ndarray).

Raises:

Exception – Simulation object is not initialized. Run be_ready() method before calling this function to fix this issue.

Returns:

Final annealed state of the system.

Return type:

np.ndarray

make_cold_optimization_function(loss_function: callable, psi0: array, annealer_nsteps: int, loss_function_args: tuple = ()) callable[source]

Creates the function to be optimized, given a specific loss_function on the final state.

Parameters:
  • loss_function (callable) – Function to compute the loss. First input is the final state of annealing, second input is the current QOC parameters.

  • psi0 (np.array) – Initial annealing state.

  • annealer_nsteps (int) – Number of discrete annealing steps.

  • loss_function_args (tuple, optional) – Extra arguments to be passed to optimization function. Defaults to ().

Returns:

Function to be optimized.

Return type:

callable

run_cold_opti(loss_function: callable, annealer_nsteps: int, psi0: ndarray, init_parameters: array, options: dict = {}, method: str = 'Powell', loss_function_args: tuple = (), update_param: bool = True) OptimizeResult[source]

Run the COLD optimization with backend scipy.optimize.minimize.

Parameters:
  • loss_function (callable) – Loss function. Must take two arguments: psi (the final state of annealing) and params (parameters optimized by the routine).

  • annealer_nsteps (int) – Number of steps to perform in annealing time evolution.

  • psi0 (np.ndarray) – Initial state of annealing. It is strongly suggested to compute it manually outside this routine.

  • init_parameters (np.array) – Initial parameters.

  • options (dict, optional) – Options to be passed to the optimization routine. Defaults to {}.

  • method (str, optional) – Method of scipy.optimize.minimize to be used. Defaults to ‘Powell’.

  • loss_function_args (tuple, optional) – Extra arguments to be passed to loss_function. Defaults to ().

  • update_param (bool, optional) – If True, the parameters of the object are update with the result of optimization. Defaults to True.

Raises:

Exception – QOC parameters are not specified.

Returns:

Results of optimization, as provided by the backend module scipy.optimize.minimize.

Return type:

scipy.optimize._optimize.OptimizeResult

run_cold_opti_bayes(loss_function: callable, annealer_nsteps: int, psi0: ndarray, dimensions: list, optim_options: dict = {}, loss_function_args: tuple = (), update_param: bool = True) OptimizeResult[source]

Run the COLD optimization with Bayesian Gaussian backend (skopt.gp_minimize).

Parameters:
  • loss_function (callable) – Loss function. Must take two arguments: psi (the final state of annealing) and params (parameters optimized by the routine).

  • annealer_nsteps (int) – Number of steps to perform in annealing time evolution.

  • psi0 (np.ndarray) – Initial state of annealing. It is strongly suggested to compute it manually outside this routine.

  • dimensions (list) – Bounds on each dimension of the parameters, as required by skopt.gp_minimize.

  • optim_options (dict, optional) – _description_. Defaults to {}. Suggested args to control: n_calls and n_initial_points.

  • loss_function_args (tuple, optional) – Extra arguments to be passed to loss_function. Defaults to ().

  • update_param (bool, optional) – If True, the parameters of the object are update with the result of optimization. Defaults to True.

Raises:

Exception – QOC parameters are not specified.

Returns:

Results of optimization, as provided by the backend module scipy.optimize.minimize.

Return type:

scipy.optimize._optimize.OptimizeResult

numerical module

class colder.simulation.numerical.interpolator1D(x_data: array, y_data: array, bc_type: str = 'not-a-knot')[source]

Bases: object

__init__(x_data: array, y_data: array, bc_type: str = 'not-a-knot')[source]

Initialize a 1D spline interpolator from input sample data.

Parameters:
  • x_data (np.array) – Sample data, x.

  • y_data (np.array) – Sample data, y.

  • bc_type (str, optional) – Passed to scipy.interpolate.CubicSpline. Defaults to ‘not-a-knot’.

classmethod from_function(function: callable, x_range: tuple, n_interp_points: int = 50, fargs: dict = {}, *args, **kwargs)[source]

Initialize a 1D spline interpolator from input function and n points sampled in range x_range.

Parameters:
  • function (callable) – callable function to interpolate. The arguments must be (x_data, fargs).

  • x_range (tuple) – Tuple containing the range of x data to be sampled.

  • n_interp_points (int, optional) – How many x data points to sample. Defaults to 50.

  • fargs (dict, optional) – keyword dictionary passed to function. Defaults to {}.

Returns:

interpolator1D

Return type:

_type_

get_function() callable[source]

Returns a lambda function calling the spline function. The function first and only argument will be the x point.

Returns:

Lambda function wrapping the spline (interpolated) function.

Return type:

callable

get_derivative(ord: int = 1) callable[source]

Returns a lambda function calling the spline function for derivative of order ord.

Parameters:

ord (int, optional) – Order of the derivative. Defaults to 1.

Returns:

Lambda function wrapping the spline (interpolated) function.

Return type:

callable

plot(plot_derivative: bool = True, plot_data: bool = False, labels: List[str] = ['f', 'df'], plt_obj=None)[source]

Plot the interpolated functions.

Parameters:
  • plot_derivative (bool, optional) – If true, the derivatives are plotted. Defaults to True.

  • plot_data (bool, optional) – If true, plots the original points before interpolation. Defaults to False.

  • labels (List[str], optional) – Labels for the curve and their derivatives. Defaults to [“f”, “df”].

  • plt_obj (_type_, optional) – Use a matplotlib plt instance instead of the default one. Defaults to None.

Returns:

matplotlib.pyplot figure

Return type:

matplotlib.pyplot