Counterdiabatic Optimized Local Driving annealER
This package provides tool for Spin system simulation and optimization through a combination of Quantum Optimal Control and Counterdiabatic Driving technique (see the reference paper: Cepaite2023). The framework allows to prompt the system through a simplified interface and automatically compute the minimization of the Adiabatic Gauge Potential (AGP) for a given ansatz.
How to install
Clone from GitHub and move inside the project folder
git clone https://github.com/CERN-IT-INNOVATION/colder
cd colder
Install the required packages
pip install .
Get started
In this section we will discuss the main interface of colder, building examples to gradually introduce the user to its features. It is strongly suggested to integrate the information of this paragraphs with the provided examples, in order to see the full picture and grasp all the details of this interface.
Prompt systems through hamiltonians
The physics module of colder provides the interface to build generic systems of spins.
The hamiltonian object can be later used for all the next stages of analysis, i.e. building the gauge potential or simulating the quantum annealing schedule.
Let us start from the basics. Import the physics module.
import colder.core.physics as cphys
Suppose that you want to build the following hamiltonian,
which consists of two Pauli Z operators applied on 3 spins, multiplied by a coefficient A. The hamiltonian object would be written in colder as
H_z = cphys.hamiltonian('Z', [0,1,2], coeff='A')
Note that at this stage we are not specifying the total number of spins. This is because the colder hamiltonians are just storing the symbols for the later steps. The user will be asked to provide the total number of spins when needed.
In the same fashion, we can build hamiltonians which involve interaction of more spins. For instance,
would be written as
H_int = cphys.hamiltonian('ZZ', [ (0,1), (1,2) ], coeff='J')
The user can prompt more complex patterns just by changing the disposition of spin indices and the operator strings. For instance, the hamiltonian
writes as
H_fancy = cphys.hamiltonian('XY', [ (0,1), (2,0) ], coeff='p')
Finally, hamiltonian objects can be summed to compose more complex hamiltonians.
The user can perform this operation either using the + symbol, or invoking the hamiltonian_collection class:
H_sys = H_z + H_int
# result is the same as
H_sys = hamiltonian_collection(H_z, H_int)
The user can print on display a dummy expression of the hamiltonian object, using the expression() method.
Use of lattice module for spin indexing
Since the input of spin indices in hamiltonian objects is an essential but tiresome operation, we provide an interface that builds the lists of spins from scratch. Suppose that you have a 5 spin system, disposed in a linear chain.
>>> import colder.models.lattice as cll
>>> lattice = cll.chain(nspin = 5)
>>> lattice.single_site
[(0,), (1,), (2,), (3,), (4,)]
>>> lattice.nearest_neighbor
[(0, 1), (1, 2), (2, 3), (3, 4)]
The module also supports periodic boundary conditions, that can be set using the option periodic = True:
>>> import colder.models.lattice as cll
>>> lattice = cll.chain(nspin = 5, periodic = True)
>>> lattice.nearest_neighbor
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
Thus, the input of hamiltonians is simplified:
lattice = cll.chain(nspin = 3, periodic = False)
H_z = cphys.hamiltonian('Z', lattice.single_site, coeff='A')
H_int = cphys.hamiltonian('ZZ', lattice.nearest_neighbor, coeff='J')
H_sys = H_int + H_z
Timedependent coefficient
So far, we have prompted for each term of the hamiltonian a symbolic coefficient through a string.
For instance, in H_z = cphys.hamiltonian('Z', lattice.single_site, coeff='A') the coefficient is a symbol associated to the letter \(A\).
However, in order to execute an annealing schedule, that coefficient has to be a function of time.
In colder, the time dependence can be prompted as a regular Python function defined by the user.
The function has to be linked to each term of the hamiltonian using the coeff_function argument.
As a very minimal example, this is a valid coefficient function initialization:
tau = 0.1
def linear_function(t):
return t/tau
H_test = cphys.hamiltonian('ZZ', lattice.nearest_neighbor,
coeff = 'J', coeff_function = linear_function
)
- When building more complex systems, there are nevertheless some constraints to follow:
The first argument of the function must be the time
t. All the following arguments will be treated as extra arguments and have to be passed to the simulation object (see note after the example).All the coefficient functions in a
hamiltonian_collectionmust have the same I/O.The function has to be vector-safe (i.e. if the input
tis a numpy array, also the return value shall be a numpy array with same dimensions).
def xf(t, tau):
return Xfsys*scale_f(t, tau)
H_X = cphys.hamiltonian('X', lattice.single_site, coeff = 'X', coeff_function=xf)
def Jf(t, tau):
return -Jsys*np.ones_like(t)
# ^^^ trick to be vector-safe
def zf(t, tau):
return Z0sys*np.ones_like(t)
# ^^^ trick to be vector-safe
H_J = cphys.hamiltonian('ZZ', lattice.nearest_neighbor, coeff = 'J', coeff_function=Jf)
H_Z = cphys.hamiltonian('Z', lattice.single_site, coeff = 'Z', coeff_function=zf)
H = H_J + H_Z + H_X # the final system hamiltonian
As a final remark, you may notice that all the coefficient functions of H have the same I/O, and in particular they require an additional argument tau.
When running a colder simulation, that extra argument can be prompted using the argument system_fargs, for instance system_fargs = {'tau' : 0.01}.
Initialize a COLD simulation
After creating the system hamiltonian and the ansatz through the physics interface, the cold module allows to initialize a simulation.
import colder.simulation.cold as ccold
H = ...
ansatz = ...
tau : float = 0.01 # annealing time
nspin : int = 5
csym = ccold.cold(
system = H, ansatz = ansatz, annealing_time = tau, nspin = nspin,
# the following parameters are to be passed at the system coefficient functions as extra arguments
system_fargs = {'tau' : tau }
)
To see the simulation in action, I recommend to take a look at the Ising 1D example notebook.
Complete examples
The user will find Jupyter notebooks in the examples folder on the GitHub repository.