quspin.operators.exp_op
- class quspin.operators.exp_op(O, a=1.0, start=None, stop=None, num=None, endpoint=None, iterate=False)[source]
Bases:
object
Constructs matrix exponentials of quantum operators.
The exp_op class does not calculate the actual matrix exponential but instead computes the action of the matrix exponential through its Taylor series. This is slower but for sparse arrays it is more memory efficient. All of the functions make use of the expm_multiply function in Scipy’s sparse library.
This class also allows the option to specify a grid of points on a line in the complex plane via the optional arguments. If this is specified, then an array grid is created via the function numpy.linspace, and the exponential is evaluated for all points on te grid: exp(a*grid[i]*O).
Notes
To calculate the matrix exponential itself, use the function method exp_op.get_mat().
For a faster computations, look up the tools.expm_multiply_parallel function.
Examples
The Example below shows how to compute the time-evolvution of a state under a constant Hamiltonian. This is done using the matrix exponential to define the evolution operator and then applying it directly onto the initial state.
1from quspin.basis import spin_basis_1d # Hilbert space spin basis 2import numpy as np # generic math functions 3 4# 5##### define model parameters ##### 6L = 4 # system size 7J = 1.0 # spin interaction 8g = 0.809 # transverse field 9h = 0.9045 # parallel field 10# 11##### construct basis 12basis = spin_basis_1d(L=L) 13# define PBC site-coupling lists for operators 14x_field = [[g, i] for i in range(L)] 15z_field = [[h, i] for i in range(L)] 16J_nn = [[J, i, (i + 1) % L] for i in range(L)] # PBC 17# static and dynamic lists 18static = [["zz", J_nn], ["z", z_field], ["x", x_field]] 19dynamic = [] 20###### construct Hamiltonian 21H = hamiltonian(static, dynamic, dtype=np.float64, basis=basis) 22# 23###### compute evolution operator as matrix exponential 24start, stop, N_t = 0.0, 4.0, 21 # time vector parameters 25# define evolution operator 26U = exp_op(H, a=-1j, start=start, stop=stop, num=N_t, endpoint=True, iterate=True) 27print(U) 28# 29# compute domain wall initial state 30dw_str = "".join("1" for i in range(L // 2)) + "".join("0" for i in range(L - L // 2)) 31i_0 = basis.index(dw_str) # find index of product state in basis 32psi = np.zeros(basis.Ns) # allocate space for state 33psi[i_0] = 1.0 # set MB state to be the given product state 34# 35##### calculate time-evolved state by successive application of matrix exponential 36psi_t = U.dot( 37 psi 38) # create generator object to apply matrix exponential on the initial state 39print(psi_t) 40for psi_i in psi_t: 41 print("evolved state:", psi_i)
- __init__(O, a=1.0, start=None, stop=None, num=None, endpoint=None, iterate=False)[source]
Initialises the exp_op object (matrix exponential of the operator O).
- Parameters:
- Oobj
numpy.ndarray, scipy.spmatrix, hamiltonian, quantum_operator object: the operator to compute the matrix exponential of.
- anumpy.dtype, optional
Prefactor to go in front of the operator in the exponential: exp(a*O). Can be a complex number. Default is a = 1.0.
- startscalar, optional
Specifies the starting point for a grid of points to evaluate the matrix exponential at.
- stopscalar, optional
Specifies the end point of for a grid of points to evaluate the matrix exponential at.
- numint, optional
Specifies the number of grid points between start and stop. Default is num = 50.
- endpointbool, optional
Wehether or not the value stop is included in the set of grid points. Note that this changes the grid step size.
- iteratebool, optional
If set to True class methods return generators which will iterate over the grid points.
If set to False, a list of all the evaluated points is produced. This is more memory efficient but at the sacrifice of speed.
Default is False.
Methods
__init__
(O[, a, start, stop, num, endpoint, ...])Initialises the exp_op object (matrix exponential of the operator O).
conj
()Conjugates exp_op operator.
copy
()Returns a deep copy of exp_op object.
dot
(other[, shift])Left-multiply operator by matrix exponential.
getH
([copy])Calculates hermitian conjugate of exp_op operator.
get_mat
([dense])Calculates matrix corresponding to matrix exponential object: exp(a*O).
rdot
(other[, shift])Right-multiply an operator by matrix exponential.
sandwich
(other[, shift])Sandwich operator between matrix exponentials.
set_a
(new_a)Resets attribute a to multiply the operator in exp(a*O).
set_grid
(start, stop[, num, endpoint])Resets attribute grid to evaluate the operator for every i in exp(a*O*grid[i]).
set_iterate
(Value)Resets iterate attribute.
transpose
([copy])Transposes exp_op operator.
Resets grid parameters to their default values.
Attributes
transposes and conjugates the matrix exponential.
number of states in the (symmetry-reduced) Hilbert space spanned by basis.
Returns the operator to be exponentiated.
transposes the matrix exponential.
constant (c-number) multiplying the operator to be exponentiated, exp(a*O).
shape of the hamiltonian object, always equal to (Ns,Ns).
grid containing equidistant points to evaluate the matrix exponential at.
shows if iterate option is on/off.
number of dimensions, always equal to 2.
step size between equidistant grid points.
- property Ns
number of states in the (symmetry-reduced) Hilbert space spanned by basis.
- Type:
int
- property O
Returns the operator to be exponentiated.
- Type:
obj
- property a
constant (c-number) multiplying the operator to be exponentiated, exp(a*O).
- Type:
numpy.dtype
- conj()[source]
Conjugates exp_op operator.
- Returns:
exo_op
\(\left[\exp(a\mathcal{O})_{ij}\right]\mapsto \left[\exp(a\mathcal{O})_{ij}\right]^*\)
Notes
This function does NOT transpose the exponentiated operator.
Examples
>>> expO_conj = expO.conj()
- dot(other, shift=None, **call_kwargs)[source]
Left-multiply operator by matrix exponential.
Let the matrix exponential object be \(\exp(\mathcal{O})\) and let the operator be \(A\). Then this funcion implements:
\[\exp(\mathcal{O}) A\]- Parameters:
- otherobj
The operator \(A\) which multiplies from the right the matrix exponential \(\exp(\mathcal{O})\).
- shiftscalar
Shifts operator to be exponentiated by a constant shift times te identity matrix: \(\exp(\mathcal{O} - \mathrm{shift}\times\mathrm{Id})\).
- call_kwargsobj, optional
- extra keyword arguments which include:
time (scalar) - if the operator O to be exponentiated is a hamiltonian object. pars (dict) - if the operator O to be exponentiated is a quantum_operator object.
- Returns:
- obj
matrix exponential multiplied by other from the right.
Examples
>>> expO = exp_op(O) >>> A = exp_op(O,a=2j).get_mat() >>> print(expO.dot(A))
- getH(copy=False)[source]
Calculates hermitian conjugate of exp_op operator.
- Parameters:
- copybool, optional
Whether to return a deep copy of the original object. Default is copy = False.
- Returns:
exp_op
\(\exp(a\mathcal{O})_{ij}\mapsto \exp(a\mathcal{O})_{ij}^*\)
Examples
>>> expO_herm = expO.getH()
- get_mat(dense=False, **call_kwargs)[source]
Calculates matrix corresponding to matrix exponential object: exp(a*O).
- Parameters:
- densebool
Whether or not to return a dense or a sparse array. Detault is dense = False.
- call_kwargsobj, optional
- extra keyword arguments which include:
time (scalar) - if the operator O to be exponentiated is a hamiltonian object. pars (dict) - if the operator O to be exponentiated is a quantum_operator object.
- Returns:
- obj
Can be either one of
numpy.ndarray: dense array if dense = True.
scipy.sparse.csc: sparse array if dense = False.
Examples
>>> expO = exp_op(O) >>> print(expO.get_mat(time=0.0)) >>> print(expO.get_mat(time=0.0,dense=True))
- property get_shape
shape of the hamiltonian object, always equal to (Ns,Ns).
- Type:
tuple
- property grid
grid containing equidistant points to evaluate the matrix exponential at.
- Type:
numpy.array
- property iterate
shows if iterate option is on/off.
- Type:
bool
- property ndim
number of dimensions, always equal to 2.
- Type:
int
- rdot(other, shift=None, **call_kwargs)[source]
Right-multiply an operator by matrix exponential.
Let the matrix exponential object be \(\exp(\mathcal{O})\) and let the operator be \(A\). Then this funcion implements:
\[A \exp(\mathcal{O})\]- Parameters:
- otherobj
The operator \(A\) which multiplies from the left the matrix exponential \(\exp(\mathcal{O})\).
- shiftscalar
Shifts operator to be exponentiated by a constant shift times the identity matrix: \(\exp(\mathcal{O} - \mathrm{shift}\times\mathrm{Id})\).
- call_kwargsobj, optional
- extra keyword arguments which include:
time (scalar) - if the operator O to be exponentiated is a hamiltonian object. pars (dict) - if the operator O to be exponentiated is a quantum_operator object.
- Returns:
- obj
matrix exponential multiplied by other from the left.
Notes
For hamiltonian objects A, this function is the same as A.dot(expO).
Examples
>>> expO = exp_op(O) >>> A = exp_op(O,a=2j).get_mat() >>> print(expO.rdot(A)) >>> print(A.dot(expO))
- sandwich(other, shift=None, **call_kwargs)[source]
Sandwich operator between matrix exponentials.
Let the matrix exponential object be \(\exp(\mathcal{O})\) and let the operator to be sandwiched be \(C\). Then this funcion implements:
\[\exp(\mathcal{O})^\dagger C \exp(\mathcal{O})\]- Parameters:
- otherobj
The operator \(C\) to be sandwiched by the matrix exponentials \(\exp(\mathcal{O})^\dagger\) and \(\exp(\mathcal{O})\).
- shiftscalar
Shifts operator to be exponentiated by a constant shift times the identity matrix: \(\exp(\mathcal{O} - \mathrm{shift}\times\mathrm{Id})\).
- call_kwargsobj, optional
- extra keyword arguments which include:
time (scalar) - if the operator O to be exponentiated is a hamiltonian object. pars (dict) - if the operator O to be exponentiated is a quantum_operator object.
- Returns:
- obj
operator other sandwiched between matrix exponential exp_op and its hermitian conjugate.
Notes
The matrix exponential to multiply \(C\) from the left is hermitian conjugated.
Examples
>>> expO = exp_op(O,a=1j) >>> A = exp_op(O.T.conj()) >>> print(expO.sandwich(A))
- set_a(new_a)[source]
Resets attribute a to multiply the operator in exp(a*O).
- Parameters:
- new_anumpy.dtype
New value for a.
Examples
>>> expO = exp_op(O,a=1.0) >>> print(expO.a) >>> expO.set_a(2.0) >>> print(expO.a)
- set_grid(start, stop, num=None, endpoint=None)[source]
Resets attribute grid to evaluate the operator for every i in exp(a*O*grid[i]).
- Parameters:
- startscalar, optional
Specifies the new starting point for a grid of points to evaluate the matrix exponential at.
- stopscalar, optional
Specifies the new end point of for a grid of points to evaluate the matrix exponential at.
- numint, optional
Specifies the new number of grid points between start and stop. Default is num = 50.
- endpointbool, optional
Wehether or not the value stop is included in the set of grid points. Note that this changes the grid step size.
Examples
>>> expO = exp_op(O,start=0.0,stop=6.0,num=601,endpoint=True) >>> print(expO.grid) >>> expO.set_grid(start=2.0,stop=4.0,num=200,endpoint=False) >>> print(expO.grid)
- set_iterate(Value)[source]
Resets iterate attribute.
- Parameters:
- Valuebool
New value for iterate attribute.
Examples
>>> expO = exp_op(O,iterate=True) >>> print(expO.iterate) >>> expO.set_a(False) >>> print(expO.iterate)
- property step
step size between equidistant grid points.
- Type:
float