Skip to content

Commit 391a066

Browse files
committed
implemented commutator function + tests
1 parent f8a632e commit 391a066

File tree

4 files changed

+87
-27
lines changed

4 files changed

+87
-27
lines changed

src/qrisp/operators/qubit/qubit_hamiltonian.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,23 @@ def subs(self, subs_dict):
425425
#
426426
# Miscellaneous
427427
#
428+
429+
def commutator(self, other):
430+
431+
res = 0
432+
433+
for term_self, coeff_self in self.terms_dict.items():
434+
for term_other, coeff_other in other.terms_dict.items():
435+
res += coeff_self*coeff_other*term_self.commutator(term_other)
436+
437+
min_coeff_self = min([abs(coeff) for coeff in self.terms_dict.values()])
438+
min_coeff_other = min([abs(coeff) for coeff in other.terms_dict.values()])
439+
440+
res.apply_threshold(min_coeff_self*min_coeff_other/2)
441+
442+
return res
443+
444+
428445

429446
def apply_threshold(self,threshold):
430447
"""
@@ -501,7 +518,7 @@ def recursive_TP(keys,term_dict):
501518
M = sp.csr_matrix((1,1))
502519
M[0,0] = res
503520
return M
504-
elif factor_amount < max(participating_indices):
521+
elif participating_indices and factor_amount < max(participating_indices):
505522
raise Exception("Tried to compute Hermitian matrix with factor_amount variable lower than the largest factor index")
506523

507524
keys = list(range(factor_amount))
@@ -512,10 +529,9 @@ def recursive_TP(keys,term_dict):
512529
M = sp.csr_matrix((2**dim, 2**dim))
513530
for k in range(m):
514531
M += complex(coeffs[k])*recursive_TP(keys.copy(),term_dicts[k])
515-
516-
res = ((M + M.transpose().conjugate())/2)
517-
res.sum_duplicates()
518-
return res
532+
# res = ((M + M.transpose().conjugate())/2)
533+
# res.sum_duplicates()
534+
return M
519535

520536
def ground_state_energy(self):
521537
"""

src/qrisp/operators/qubit/qubit_term.py

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,6 @@ def is_identity(self):
5555
#
5656
# Simulation
5757
#
58-
59-
# Assume that the operator is diagonal after change of basis
60-
# Implements exp(i*coeff*\prod_j Z_j) where the product goes over all indices j in self.factor_dict
61-
# @lifted
62-
def simulate(self, coeff, qarg):
63-
64-
def parity(qarg, indices):
65-
n = len(indices)
66-
for i in range(n-1):
67-
cx(qarg[indices[i]],qarg[indices[i+1]])
68-
69-
if not self.is_identity():
70-
indices = list(self.factor_dict.keys())
71-
with conjugate(parity)(qarg, indices):
72-
rz(-2*coeff,qarg[indices[-1]])
73-
else:
74-
gphase(coeff,qarg[0])
75-
76-
# @lifted
7758
def simulate(self, coeff, qv, do_change_of_basis = True):
7859

7960
from qrisp import h, cx, rz, mcp, conjugate, control, QuantumBool, mcx, x, p, s, QuantumEnvironment, gphase
@@ -393,6 +374,8 @@ def __mul__(self, other):
393374
keys = set(a.keys()) | set(b.keys())
394375
for key in keys:
395376
factor, coeff = PAULI_TABLE[a.get(key,"I"),b.get(key,"I")]
377+
if coeff == 0:
378+
return QubitTerm({}), 0
396379
if factor != "I":
397380
result_factor_dict[key]=factor
398381
result_coeff *= coeff
@@ -425,8 +408,18 @@ def subs(self, subs_dict):
425408
return QubitTerm(result_factor_dict), result_coeff
426409

427410
#
428-
# Commutativity checks
411+
# Commutativity
429412
#
413+
def commutator(self, other):
414+
from qrisp.operators.qubit import QubitHamiltonian
415+
416+
term_0, coeff_0 = self*other
417+
term_1, coeff_1 = other*self
418+
419+
temp = QubitHamiltonian({term_0 : coeff_0}) - QubitHamiltonian({term_1 : coeff_1})
420+
temp.apply_threshold(0.5)
421+
422+
return temp
430423

431424
def commute(self, other):
432425
"""
@@ -461,7 +454,7 @@ def commute_qw(self, other):
461454
keys.update(set(b.keys()))
462455

463456
for key in keys:
464-
if a.get(key,"I")!="I" and b.get(key,"I")!="I" and a.get(key,"I")!=b.get(key,"I"):
457+
if not PAULI_TABLE[a.get(key,"I"), b.get(key,"I")] == PAULI_TABLE[b.get(key,"I"), a.get(key,"I")]:
465458
return False
466459
return True
467460

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""
2+
\********************************************************************************
3+
* Copyright (c) 2024 the Qrisp authors
4+
*
5+
* This program and the accompanying materials are made available under the
6+
* terms of the Eclipse Public License 2.0 which is available at
7+
* http://www.eclipse.org/legal/epl-2.0.
8+
*
9+
* This Source Code may also be made available under the following Secondary
10+
* Licenses when the conditions for such availability set forth in the Eclipse
11+
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
12+
* with the GNU Classpath Exception which is
13+
* available at https://www.gnu.org/software/classpath/license.html.
14+
*
15+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
16+
********************************************************************************/
17+
"""
18+
19+
from qrisp import QuantumVariable, x, QPE
20+
from qrisp.operators import X, Y, Z, A, C, P0, P1
21+
import numpy as np
22+
from numpy.linalg import norm
23+
24+
def test_qubit_hamiltonian_commutator():
25+
26+
def verify_commutator(H1, H2):
27+
commutator_hamiltonian = H1.commutator(H2)
28+
29+
commutator_matrix = commutator_hamiltonian.to_sparse_matrix(factor_amount = 3).todense()
30+
31+
H1_matrix = H1.to_sparse_matrix(factor_amount = 3).todense()
32+
H2_matrix = H2.to_sparse_matrix(factor_amount = 3).todense()
33+
34+
assert norm(commutator_matrix - (H1_matrix @ H2_matrix - H2_matrix @ H1_matrix)) < 1E-5
35+
36+
operator_list = [lambda x : 1, X, Y, Z, A, C, P0, P1]
37+
38+
counter = 0
39+
operator_list = [lambda x : 1, X, Y, Z, A, C, P0, P1]
40+
for O0 in operator_list:
41+
for O1 in operator_list:
42+
for O2 in operator_list:
43+
for O3 in operator_list:
44+
H1 = O0(0)*O1(1)
45+
H2 = O2(0)*O3(1)
46+
47+
if 1 in [H1, H2]:
48+
continue
49+
verify_commutator(H1, H2)
50+
counter += 1
51+

tests/hamiltonian_tests/test_qubit_hamiltonian_simulation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def verify_trotterization(H):
5252

5353
# Compute hermitean matrix
5454
H_matrix = H.to_sparse_matrix().todense()
55-
55+
H_matrix = (H_matrix + H_matrix.transpose().conjugate())/2
5656
# Compute unitary matrix
5757
U_matrix = expm(1j*H_matrix)
5858

0 commit comments

Comments
 (0)