Skip to content

Commit a1e426e

Browse files
committed
switching to alternative Jordan-Wigner convention for fermionic creation and annihilation operators (Z strings on the left)
1 parent 70b5e96 commit a1e426e

2 files changed

Lines changed: 41 additions & 41 deletions

File tree

pytenet/hamiltonian.py

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -301,34 +301,34 @@ class OID(IntEnum):
301301
# construct operator graph
302302
nid_next = 0
303303
# identity and Z strings from the left and right
304-
identity_l = {}
305-
z_string_r = {}
306-
for i in range(L):
307-
identity_l[i] = OpGraphNode(nid_next, [], [], 0)
308-
nid_next += 1
304+
identity_r = {}
305+
z_string_l = {}
309306
for i in range(1, L + 1):
310-
z_string_r[i] = OpGraphNode(nid_next, [], [], 1 if use_creation_op else -1)
307+
identity_r[i] = OpGraphNode(nid_next, [], [], 0)
308+
nid_next += 1
309+
for i in range(L):
310+
z_string_l[i] = OpGraphNode(nid_next, [], [], -1 if use_creation_op else 1)
311311
nid_next += 1
312312
# initialize graph with nodes
313-
graph = OpGraph(list(identity_l.values()) +
314-
list(z_string_r.values()),
315-
[], [identity_l[0].nid, z_string_r[L].nid])
313+
graph = OpGraph(list(identity_r.values()) +
314+
list(z_string_l.values()),
315+
[], [z_string_l[0].nid, identity_r[L].nid])
316316
# edges
317317
eid_next = 0
318318
# identities
319-
for i in range(L - 1):
319+
for i in range(1, L):
320320
graph.add_connect_edge(
321-
OpGraphEdge(eid_next, [identity_l[i].nid, identity_l[i + 1].nid], [(OID.I, 1.)]))
321+
OpGraphEdge(eid_next, [identity_r[i].nid, identity_r[i + 1].nid], [(OID.I, 1.)]))
322322
eid_next += 1
323323
# Z strings
324-
for i in range(1, L):
324+
for i in range(L - 1):
325325
graph.add_connect_edge(
326-
OpGraphEdge(eid_next, [z_string_r[i].nid, z_string_r[i + 1].nid], [(OID.Z, 1.)]))
326+
OpGraphEdge(eid_next, [z_string_l[i].nid, z_string_l[i + 1].nid], [(OID.Z, 1.)]))
327327
eid_next += 1
328328
# creation or annihilation operators
329329
for i in range(L):
330330
graph.add_connect_edge(
331-
OpGraphEdge(eid_next, [identity_l[i].nid, z_string_r[i + 1].nid], [(OID.C if use_creation_op else OID.A, coeff[i])]))
331+
OpGraphEdge(eid_next, [z_string_l[i].nid, identity_r[i + 1].nid], [(OID.C if use_creation_op else OID.A, coeff[i])]))
332332
eid_next += 1
333333
assert graph.is_consistent()
334334

@@ -367,56 +367,56 @@ def linear_spin_fermionic_mpo(coeff, ftype: str, sigma: int) -> MPO:
367367
# operator map
368368
class OID(IntEnum):
369369
Id = 0
370-
CZ = 1
371-
AZ = 2
372-
IC = 3
373-
IA = 4
370+
CI = 1
371+
AI = 2
372+
ZC = 3
373+
ZA = 4
374374
ZZ = 5
375375
opmap = {
376376
OID.Id: np.identity(4),
377-
OID.CZ: np.kron(a_dag, Z ),
378-
OID.AZ: np.kron(a_ann, Z ),
379-
OID.IC: np.kron(id2, a_dag),
380-
OID.IA: np.kron(id2, a_ann),
377+
OID.CI: np.kron(a_dag, id2),
378+
OID.AI: np.kron(a_ann, id2),
379+
OID.ZC: np.kron(Z, a_dag),
380+
OID.ZA: np.kron(Z, a_ann),
381381
OID.ZZ: np.kron(Z, Z ),
382382
}
383383

384384
# construct operator graph
385385
nid_next = 0
386386
# identity and Z strings from the left and right
387-
identity_l = {}
388-
z_string_r = {}
389-
for i in range(L):
390-
identity_l[i] = OpGraphNode(nid_next, [], [], 0)
391-
nid_next += 1
387+
identity_r = {}
388+
z_string_l = {}
392389
for i in range(1, L + 1):
393-
qnum = encode_quantum_number_pair(1 if use_creation_op else -1, sigma if use_creation_op else -sigma)
394-
z_string_r[i] = OpGraphNode(nid_next, [], [], qnum)
390+
identity_r[i] = OpGraphNode(nid_next, [], [], 0)
391+
nid_next += 1
392+
for i in range(L):
393+
qnum = encode_quantum_number_pair(-1 if use_creation_op else 1, -sigma if use_creation_op else sigma)
394+
z_string_l[i] = OpGraphNode(nid_next, [], [], qnum)
395395
nid_next += 1
396396
# initialize graph with nodes
397-
graph = OpGraph(list(identity_l.values()) +
398-
list(z_string_r.values()),
399-
[], [identity_l[0].nid, z_string_r[L].nid])
397+
graph = OpGraph(list(identity_r.values()) +
398+
list(z_string_l.values()),
399+
[], [z_string_l[0].nid, identity_r[L].nid])
400400
# edges
401401
eid_next = 0
402402
# identities
403-
for i in range(L - 1):
403+
for i in range(1, L):
404404
graph.add_connect_edge(
405-
OpGraphEdge(eid_next, [identity_l[i].nid, identity_l[i + 1].nid], [(OID.Id, 1.)]))
405+
OpGraphEdge(eid_next, [identity_r[i].nid, identity_r[i + 1].nid], [(OID.Id, 1.)]))
406406
eid_next += 1
407407
# Z strings
408-
for i in range(1, L):
408+
for i in range(L - 1):
409409
graph.add_connect_edge(
410-
OpGraphEdge(eid_next, [z_string_r[i].nid, z_string_r[i + 1].nid], [(OID.ZZ, 1.)]))
410+
OpGraphEdge(eid_next, [z_string_l[i].nid, z_string_l[i + 1].nid], [(OID.ZZ, 1.)]))
411411
eid_next += 1
412412
# creation or annihilation operators
413413
for i in range(L):
414414
if use_creation_op:
415-
oid = (OID.CZ if sigma == 1 else OID.IC)
415+
oid = (OID.CI if sigma == 1 else OID.ZC)
416416
else:
417-
oid = (OID.AZ if sigma == 1 else OID.IA)
417+
oid = (OID.AI if sigma == 1 else OID.ZA)
418418
graph.add_connect_edge(
419-
OpGraphEdge(eid_next, [identity_l[i].nid, z_string_r[i + 1].nid], [(oid, coeff[i])]))
419+
OpGraphEdge(eid_next, [z_string_l[i].nid, identity_r[i + 1].nid], [(oid, coeff[i])]))
420420
eid_next += 1
421421
assert graph.is_consistent()
422422

test/test_hamiltonian.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,11 +435,11 @@ def generate_fermi_operators(L: int):
435435
c = sparse.identity(1)
436436
for j in range(L):
437437
if j < i:
438-
c = sparse.kron(c, I)
438+
c = sparse.kron(c, Z)
439439
elif j == i:
440440
c = sparse.kron(c, U)
441441
else:
442-
c = sparse.kron(c, Z)
442+
c = sparse.kron(c, I)
443443
clist.append(c)
444444
# corresponding annihilation operators
445445
alist = [c.conj().T for c in clist]

0 commit comments

Comments
 (0)