Skip to content

Lindblad Master Equation

Vicentini Filippo requested to merge github/fork/PhilipVinc/improve_dm into v2.1

Created by: PhilipVinc

This is still WIP, but I would like some preliminary feedback on this as it requires some changes to core netket classes.

The PR mainly updates the density matrix to the new interface and gets rid of lookup tables, and defines a new operator, LocalLindblad which will behave like a standard operator with a doubled space.

My aim at the moment is to get the Lindblad ME to work with what is currently implemented at the moment. This mainly means faking all methods such as LogVal, Nvisible... to behave as if it was a standard machine defined on a doubled space.

Connections (in operators) are handled similarly, by assuming that rows are the first half entries of the configuration and columns are the second half.

Changes to netket core:

  • AbstractHilbert has a new virtual method called UpdateConfRowCol to efficiently update the row and columns of a configuration given the connections, to change from a doubled Hilbert space. There is a standard (slow) implementation, and more efficient ones are defined for Spins and CustomHilbert.
  • Add LocalOperator copy constructor, which was previously commented out. I need it to initialize the Lindblad.

as of now, in python it is possible to construct a machine and do the following:

import netket as nk
import numpy as np
from netket.machine import NdmSpinPhase
from netket.hilbert import Spin
from netket.graph import Hypercube

vv = np.random.rand(18)
vl = vv[0:9]
vr = vv[9:18]

vv2 = np.random.rand(3, 18)
vl2 = vv2[:,0:9]
vr2 = vv2[:,9:18]

g = Hypercube(length=9, n_dim=1)
hi = Spin(s=0.5, total_sz=0.5, graph=g)
ma = NdmSpinPhase(hilbert=hi,alpha=1, beta=2)
ma.init_random_parameters()
assert (ma.log_val(vv) == ma.log_val(vl, vr))
assert (ma.log_val(vv2) == ma.log_val(vl2, vr2)).all()

assert (ma.der_log(vv) == ma.der_log(vl, vr)).all()
assert (ma.der_log(vv2) == ma.der_log(vl2, vr2)).all()

Right now you can also pass the density matrix to a sampler and it will sweep it correctly.

construct the machine sampling the diagonal of the density matrix

dd = ma.diagonal()
dd.log_val(vl)

For how to construct the Liouvillian, at the moment you pass the hamiltonian and then add every jump operator one by one. I'd like to make him accept a list of operators, but I did not yet figure out how to do the python bindings for this one. Who's the expert on python bindings?

ha = nk.operator.LocalOperator(hi)

for i in range(L):
    ha += nk.operator.LocalOperator(hi, sx, [i])
    ha += nk.operator.LocalOperator(hi, np.kron(sz, sz), [i, (i + 1) % L])


# Create the lindbladian with no jump operators
lind = nk.operator.LocalLindbladian(ha)

# Add a sigmam jump operator on each site
for i in range(L):
    j_op = nk.operator.LocalOperator(hi, sigmam, [i])
    lind.add_jump_op(j_op)

The method FindConn of LocalLindbladian is an horrible mess that I have to figure out how to simplify...

Lastly: the VMC driver. I either plug into the existing driver and plug a lot of if/else statements checking for the class, or I create another driver (my preferred take). If I create another driver, there will be a lot of shared functionality among the two, so it would make sense to create a base python class from which the two derive, but if you are already working on that part of netket It's best too coordinate a bit.

F

Merge request reports