Skip to content

Commit

Permalink
Merge 2526f69 into e6de198
Browse files Browse the repository at this point in the history
  • Loading branch information
Strilanc committed May 22, 2017
2 parents e6de198 + 2526f69 commit d24cce2
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 1 deletion.
46 changes: 46 additions & 0 deletions src/fermilib/ops/_fermion_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,52 @@ def __init__(self, term=None, coefficient=1.):
'Invalid action in FermionOperator: '
'Must be 0 (lowering) or 1 (raising).')

@staticmethod
def additive_identity():
"""
Returns:
FermionOperator:
A fermion operator o with the property that o+x = x+o = x for
all fermion operators x.
"""
return FermionOperator(term=None)

@staticmethod
def multiplicative_identity():
"""
Returns:
FermionOperator:
A fermion operator u with the property that u*x = x*u = x for
all fermion operators x.
"""
return FermionOperator(term=())

@staticmethod
def sum(fermion_operators):
"""
Args:
fermion_operators (iterable[FermionOperator]): The summands.
Returns:
sum (FermionOperator)
"""
total = FermionOperator.additive_identity()
for op in fermion_operators:
total += op
return total

@staticmethod
def product(fermion_operators):
"""
Args:
fermion_operators (iterable[FermionOperator]): The factors.
Returns:
product (FermionOperator)
"""
total = FermionOperator.multiplicative_identity()
for op in fermion_operators:
total *= op
return total

def compress(self, abs_tol=EQ_TOLERANCE):
"""
Eliminates all terms with coefficients close to zero and removes
Expand Down
72 changes: 71 additions & 1 deletion src/fermilib/ops/_fermion_operator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,54 @@ def test_init_tuple_npcomplex128_coefficient(self):
self.assertEqual(len(fermion_op.terms), 1)
self.assertEqual(fermion_op.terms[loc_op], coefficient)

def test_multiplicative_identity(self):
u = FermionOperator.multiplicative_identity()
f = FermionOperator(((0, 1), (5, 0), (6, 1)), 0.6j)
g = FermionOperator(((0, 0), (5, 0), (6, 1)), 0.3j)
h = f + g
self.assertTrue(f.isclose(u * f))
self.assertTrue(f.isclose(f * u))
self.assertTrue(g.isclose(u * g))
self.assertTrue(g.isclose(g * u))
self.assertTrue(h.isclose(u * h))
self.assertTrue(h.isclose(h * u))

u *= h
self.assertTrue(h.isclose(u))
self.assertFalse(f.isclose(u))

# Method always returns new instances.
self.assertFalse(FermionOperator.multiplicative_identity().isclose(u))

def test_additive_identity(self):
o = FermionOperator.additive_identity()
f = FermionOperator(((0, 1), (5, 0), (6, 1)), 0.6j)
g = FermionOperator(((0, 0), (5, 0), (6, 1)), 0.3j)
h = f + g
self.assertTrue(f.isclose(o + f))
self.assertTrue(f.isclose(f + o))
self.assertTrue(g.isclose(o + g))
self.assertTrue(g.isclose(g + o))
self.assertTrue(h.isclose(o + h))
self.assertTrue(h.isclose(h + o))

o += h
self.assertTrue(h.isclose(o))
self.assertFalse(f.isclose(o))

# Method always returns new instances.
self.assertFalse(FermionOperator.additive_identity().isclose(o))

def test_additive_identity_is_multiplicative_nil(self):
o = FermionOperator.additive_identity()
u = FermionOperator.multiplicative_identity()
f = FermionOperator(((0, 1), (5, 0), (6, 1)), 0.6j)
g = FermionOperator(((0, 0), (5, 0), (6, 1)), 0.3j)
self.assertTrue(o.isclose(o * u))
self.assertTrue(o.isclose(o * f))
self.assertTrue(o.isclose(o * g))
self.assertTrue(o.isclose(o * (f + g)))

def test_init_str(self):
fermion_op = FermionOperator('0^ 5 12^', -1.)
correct = ((0, 1), (5, 0), (12, 1))
Expand Down Expand Up @@ -424,10 +472,32 @@ def test_add(self):
self.assertTrue(a.isclose(FermionOperator(term_a, 1.0)))
self.assertTrue(b.isclose(FermionOperator(term_b, 0.5)))

def test_sum(self):
a = FermionOperator(((1, 1), (3, 0), (8, 1)), 1.0)
b = FermionOperator(((1, 0), (3, 0), (8, 1)), 0.5)
c = FermionOperator(((1, 0), (3, 0), (5, 1)), 0.5)

self.assertTrue(FermionOperator.sum([]).isclose(FermionOperator.additive_identity()))
self.assertTrue(FermionOperator.sum([a]).isclose(a))
self.assertTrue(FermionOperator.sum([b]).isclose(b))
self.assertTrue(FermionOperator.sum([a, b]).isclose(a + b))
self.assertTrue(FermionOperator.sum([a, b, c]).isclose(a + b + c))

def test_product(self):
a = FermionOperator(((1, 1), (3, 0), (8, 1)), 1.0)
b = FermionOperator(((1, 0), (3, 0), (8, 1)), 0.5)
c = FermionOperator(((1, 0), (3, 0), (5, 1)), 0.5)

self.assertTrue(FermionOperator.product([]).isclose(FermionOperator.multiplicative_identity()))
self.assertTrue(FermionOperator.product([a]).isclose(a))
self.assertTrue(FermionOperator.product([b]).isclose(b))
self.assertTrue(FermionOperator.product([a, b]).isclose(a * b))
self.assertTrue(FermionOperator.product([a, b, c]).isclose(a * b * c))

def test_add_bad_addend(self):
op = FermionOperator((), 1.0)
with self.assertRaises(TypeError):
op = op + "0.5"
_ = op + "0.5"

def test_sub(self):
term_a = ((1, 1), (3, 1), (8, 1))
Expand Down

0 comments on commit d24cce2

Please sign in to comment.