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.

unset_grid()

Resets grid parameters to their default values.

Attributes

H

transposes and conjugates the matrix exponential.

Ns

number of states in the (symmetry-reduced) Hilbert space spanned by basis.

O

Returns the operator to be exponentiated.

T

transposes the matrix exponential.

a

constant (c-number) multiplying the operator to be exponentiated, exp(a*O).

get_shape

shape of the hamiltonian object, always equal to (Ns,Ns).

grid

grid containing equidistant points to evaluate the matrix exponential at.

iterate

shows if iterate option is on/off.

ndim

number of dimensions, always equal to 2.

step

step size between equidistant grid points.

property H

transposes and conjugates the matrix exponential.

Type:

exp_op

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 T

transposes the matrix exponential.

Type:

exp_op

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()
copy()[source]

Returns a deep copy of exp_op object.

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

transpose(copy=False)[source]

Transposes exp_op operator.

Returns:
exp_op

\(\exp(a\mathcal{O})_{ij}\mapsto \exp(a\mathcal{O})_{ji}\)

Notes

This function does NOT conjugate the exponentiated operator.

Examples

>>> expO_tran = expO.transpose()
unset_grid()[source]

Resets grid parameters to their default values.

Examples

>>> expO = exp_op(O,start=0.0,stop=6.0,num=601,endpoint=True)
>>> print(expO.grid)
>>> expO.unset_grid()
>>> print(expO.grid)