def test_init_sparse_label(self, labels, pre_processing): """Test __init__ with sparse label""" dense_label, sparse_label = labels fer_op = FermionicOp(pre_processing(sparse_label), register_length=len(dense_label)) targ = FermionicOp(dense_label) self.assertFermionEqual(fer_op, targ)
def test_matmul(self, label1, label2): """Test matrix multiplication""" fer_op = FermionicOp(label1) @ FermionicOp(label2) mapping = { "II": "I", "I+": "+", "I-": "-", "IN": "N", "IE": "E", "+I": "+", "++": 0, "+-": "N", "+N": 0, "+E": "+", "-I": "-", "-+": "E", "--": 0, "-N": "-", "-E": 0, "NI": "N", "N+": "+", "N-": 0, "NN": "N", "NE": 0, "EI": "E", "E+": 0, "E-": "-", "EN": 0, "EE": "E", } result = mapping[label1 + label2] expected = [(result, 1)] if result != 0 else [("I", 0)] self.assertListEqual(fer_op.to_list(), expected)
def _create_base_op_from_labels(coeff, length: int, coeffs_with_ops) -> FermionicOp: label = ['I'] * length base_op = coeff * FermionicOp(''.join(label)) for i, op in coeffs_with_ops: label_i = label.copy() label_i[i] = op base_op @= FermionicOp(''.join(label_i)) return base_op
def test_mul(self): """Test __mul__, and __rmul__""" fer_op = FermionicOp("+-") * 2 self.assertEqual(fer_op.to_list(), [("+-", 2)]) fer_op = (2 + 1j) * FermionicOp([("+N", 3), ("E-", 1)]) self.assertEqual(fer_op.to_list(), [("+N", (6 + 3j)), ("E-", (2 + 1j))])
def test_add(self): """Test __add__""" fer_op = 3 * FermionicOp("+N") + FermionicOp("E-") self.assertListEqual(fer_op.to_list(), [("+N", 3), ("E-", 1)]) fer_op = sum( FermionicOp(label) for label in ['NIII', 'INII', 'IINI', 'IIIN']) self.assertListEqual(fer_op.to_list(), [('NIII', 1), ('INII', 1), ('IINI', 1), ('IIIN', 1)])
def test_init_multiple_digits(self): """Test __init__ for sparse label with multiple digits""" actual = FermionicOp([("-_2 +_10", 1 + 2j), ("-_12", 56)], register_length=13) desired = [ ("II-IIIIIII+II", 1 + 2j), ("IIIIIIIIIIII-", 56), ] self.assertListEqual(actual.to_list(), desired)
def test_add(self): """Test __add__""" fer_op = 3 * FermionicOp("+N") + FermionicOp("E-") targ = FermionicOp([("+N", 3), ("E-", 1)]) self.assertFermionEqual(fer_op, targ) fer_op = sum( FermionicOp(label) for label in ["NIII", "INII", "IINI", "IIIN"]) targ = FermionicOp([("NIII", 1), ("INII", 1), ("IINI", 1), ("IIIN", 1)]) self.assertFermionEqual(fer_op, targ)
def test_mul(self): """Test __mul__, and __rmul__""" with self.subTest("rightmul"): fer_op = FermionicOp("+-") * 2 targ = FermionicOp([("+-", 2)]) self.assertFermionEqual(fer_op, targ) with self.subTest("left mul"): fer_op = (2 + 1j) * FermionicOp([("+N", 3), ("E-", 1)]) targ = FermionicOp([("+N", (6 + 3j)), ("E-", (2 + 1j))]) self.assertFermionEqual(fer_op, targ)
def test_adjoint(self): """Test adjoint method and dagger property""" with self.subTest("adjoint"): fer_op = ~FermionicOp([("+N", 3), ("N-", 1), ("--", 2 + 4j)]) targ = FermionicOp([("-N", 3), ("N+", 1), ("++", (-2 + 4j))]) self.assertFermionEqual(fer_op, targ) with self.subTest("dagger"): fer_op = FermionicOp([("+-", 1), ("II", 2j)]).dagger targ = FermionicOp([("-+", -1), ("II", -2j)]) self.assertFermionEqual(fer_op, targ)
def test_reduce(self): """Test reduce""" fer_op = FermionicOp("N") + FermionicOp("E") + FermionicOp("N") reduced_op = fer_op.reduce() self.assertSetEqual(frozenset(reduced_op.to_list()), frozenset([("N", 2), ("E", 1)])) fer_op = FermionicOp(("+", 1)) + FermionicOp(("-", 1j)) + FermionicOp( ("+", 1j)) reduced_op = fer_op.reduce() self.assertSetEqual(frozenset(reduced_op.to_list()), frozenset([("+", 1 + 1j), ("-", 1j)]))
def test_matmul_multi(self): """Test matrix multiplication""" fer_op = FermionicOp("+-") @ FermionicOp("-I") self.assertListEqual(fer_op.to_list(), [("N-", -1)]) fer_op = (FermionicOp("+N") + FermionicOp("E-")) @ (FermionicOp("II") + FermionicOp("-+")) self.assertListEqual(fer_op.to_list(), [("+N", 1), ("N+", 1), ("E-", 1), ("-E", -1)])
def test_matmul_multi(self): """Test matrix multiplication""" with self.subTest("single matmul"): fer_op = FermionicOp("+-") @ FermionicOp("-I") targ = FermionicOp([("N-", -1)]) self.assertFermionEqual(fer_op, targ) with self.subTest("multi matmul"): fer_op = FermionicOp("+-") @ FermionicOp("-I") fer_op = (FermionicOp("+N") + FermionicOp("E-")) @ ( FermionicOp("II") + FermionicOp("-+")) targ = FermionicOp([("+N", 1), ("N+", 1), ("E-", 1), ("-E", -1)]) self.assertFermionEqual(fer_op, targ)
def test_adjoint(self): """Test adjoint method and dagger property""" fer_op = FermionicOp([("+N", 3), ("N-", 1), ("--", 2 + 4j)]).adjoint() self.assertListEqual(fer_op.to_list(), [("-N", 3), ("N+", 1), ("++", (-2 + 4j))]) fer_op = FermionicOp([("+-", 1), ("II", 2j)]).dagger self.assertListEqual(fer_op.to_list(), [('-+', -1), ('II', -2j)])
def _build_ferm_op_helper(one_body_integrals: np.ndarray, two_body_integrals: np.ndarray) -> FermionicOp: one_body_base_ops_labels = _create_one_body_base_ops(one_body_integrals) two_body_base_ops_labels = _create_two_body_base_ops( two_body_integrals) if two_body_integrals is not None else [] base_ops_labels = one_body_base_ops_labels + two_body_base_ops_labels initial_label_with_ceoff = ('I' * len(one_body_integrals), 0) # TODO the initial label should be eliminated once QMolecule is refactored (currently # has_dipole_integrals() checks for None only but zero-matrices happen instead of None and # initial labels prevents from an empty labels list when building a FermionicOp) base_ops_labels.append(initial_label_with_ceoff) fermionic_op = FermionicOp(base_ops_labels) return fermionic_op
def test_pow(self): """Test __pow__""" with self.subTest("square trivial"): fer_op = FermionicOp([("+N", 3), ("E-", 1)])**2 targ = FermionicOp([("II", 0)]) self.assertFermionEqual(fer_op, targ) with self.subTest("square nontrivial"): fer_op = FermionicOp([("+N", 3), ("N-", 1)])**2 targ = FermionicOp([("+-", -3)]) self.assertFermionEqual(fer_op, targ) with self.subTest("3rd power"): fer_op = (3 * FermionicOp("IIII"))**3 targ = FermionicOp([("IIII", 27)]) self.assertFermionEqual(fer_op, targ) with self.subTest("0th power"): fer_op = FermionicOp([("+N", 3), ("E-", 1)])**0 targ = FermionicOp([("II", 1)]) self.assertFermionEqual(fer_op, targ)
def test_neg(self): """Test __neg__""" fer_op = -FermionicOp("+N-EII") self.assertListEqual(fer_op.to_list(), [("+N-EII", -1)])
def test_init_invalid(self): """Test invalid __init__""" with self.assertRaises(QiskitNatureError): FermionicOp("test")
def test_init_multiterm(self): """Test __init__ with multi terms""" labels = [("N", 2), ("-", 3.14)] self.assertListEqual(FermionicOp(labels).to_list(), labels)
def test_init_invalid_label(self): """Test __init__ with invalid label""" with self.assertRaises(QiskitNatureError): FermionicOp("INX") with self.assertRaises(QiskitNatureError): FermionicOp([("++", 1), ("EF", 1)])
def test_init(self, label, pre_processing): """Test __init__""" fer_op = FermionicOp(pre_processing(label)) self.assertListEqual(fer_op.to_list(), [(label, 1)]) self.assertFermionEqual(eval(repr(fer_op)), fer_op) # pylint: disable=eval-used
def test_sub(self): """Test __sub__""" fer_op = 3 * FermionicOp("++") - 2 * FermionicOp("--") self.assertListEqual(fer_op.to_list(), [("++", 3), ("--", -2)])
def test_pow(self): """Test __pow__""" fer_op = FermionicOp([("+N", 3), ("E-", 1)])**2 self.assertListEqual(fer_op.to_list(), [("II", 0)]) fer_op = FermionicOp([("+N", 3), ("N-", 1)])**2 self.assertListEqual(fer_op.to_list(), [("+-", -3)]) fer_op = (3 * FermionicOp("IIII"))**3 self.assertListEqual(fer_op.to_list(), [("IIII", 27)]) fer_op = FermionicOp([("+N", 3), ("E-", 1)])**0 self.assertListEqual(fer_op.to_list(), [("II", 1)])
def test_div(self): """Test __truediv__""" fer_op = FermionicOp([("+N", 3), ("E-", 1)]) / 3 targ = FermionicOp([("+N", 1.0), ("E-", 1 / 3)]) self.assertFermionEqual(fer_op, targ)
def test_init_invalid_label(self, label, register_length): """Test __init__ with invalid label""" with self.assertRaises(ValueError): FermionicOp(label, register_length=register_length)
def test_neg(self): """Test __neg__""" fer_op = -FermionicOp("+N-EII") targ = FermionicOp([("+N-EII", -1)]) self.assertFermionEqual(fer_op, targ)
def test_div(self): """Test __truediv__""" fer_op = FermionicOp([("+N", 3), ("E-", 1)]) / 3 self.assertEqual(fer_op.to_list(), [("+N", 1.0), ("E-", 0.3333333333333333)])
def test_sub(self): """Test __sub__""" fer_op = 3 * FermionicOp("++") - 2 * FermionicOp("--") targ = FermionicOp([("++", 3), ("--", -2)]) self.assertFermionEqual(fer_op, targ)
def test_reduce(self): """Test reduce""" with self.subTest("reduce integer"): fer_op = FermionicOp("N") + FermionicOp("E") + FermionicOp("N") reduced_op = fer_op.reduce() targ = FermionicOp([("N", 2), ("E", 1)]) self.assertFermionEqual(reduced_op, targ) with self.subTest("reduce complex"): fer_op = FermionicOp( "+") + 1j * FermionicOp("-") + 1j * FermionicOp("+") reduced_op = fer_op.reduce() targ = FermionicOp([("+", 1 + 1j), ("-", 1j)]) self.assertFermionEqual(reduced_op, targ)
def test_init(self, label): """Test __init__""" self.assertListEqual(FermionicOp(label).to_list(), [(label, 1)])
def assertFermionEqual(self, first: FermionicOp, second: FermionicOp): """Fail if two FermionicOps are different. Note that this equality check is approximated since the true equality check is costly. """ self.assertSetEqual(frozenset(first.to_list()), frozenset(second.to_list()))