def test_sat_or(): f = OR assert f() == {(): 1} assert f('x', 'y') == PUBO({('x', ): 1, ('y', ): 1, ('x', 'y'): -1}) assert (f({('x', 'y'): 1}, 'a') == PUBO({ ('x', 'y'): 1, ('a', ): 1, ('x', 'y', 'a'): -1 })) for n in range(1, 5): P = f(*tuple(range(n))) for i in range(1 << n): sol = decimal_to_boolean(i, n) if any(sol): assert P.value(sol) == 1 else: assert not P.value(sol) # testing type x, y = boolean_var(0), boolean_var(1) for model in BOOLEAN_MODELS: assert isinstance(f(model(x), y), model)
def test_set_mapping(): d = PUBO({('a', 'b'): 1, ('a', ): 2}) d.set_mapping({'a': 0, 'b': 2}) assert d.to_pubo() == {(0, 2): 1, (0, ): 2} d = PUBO({('a', 'b'): 1, ('a', ): 2}) d.set_reverse_mapping({0: 'a', 2: 'b'}) assert d.to_pubo() == {(0, 2): 1, (0, ): 2}
def test_symbols(): a, b = Symbol('a'), Symbol('b') d = PUBO() d[(0, )] -= a d[(0, 1)] += 2 d[(1, )] += b assert d == {(0, ): -a, (0, 1): 2, (1, ): b} assert d.subs(a, 2) == {(0, ): -2, (0, 1): 2, (1, ): b} assert d.subs(b, 1) == {(0, ): -a, (0, 1): 2, (1, ): 1} assert d.subs({a: -3, b: 4}) == {(0, ): 3, (0, 1): 2, (1, ): 4}
def test_create_var(): d = PUBO.create_var(0) assert d == {(0,): 1} assert d.name == 0 assert type(d) == PUBO d = PUBO.create_var('x') assert d == {('x',): 1} assert d.name == 'x' assert type(d) == PUBO
def test_pubo_update(): d = PUBO({('0', ): 1, ('0', 1): 2}) d.update({('0', '0'): 0, (1, '0'): 1, (1, 1): -1}) assert d in ({(1, '0'): 1, (1, ): -1}, {('0', 1): 1, (1, ): -1}) d = PUBO({(0, 0): 1, (0, 1): 2}) d.update(PUBO({(1, 0): 1, (1, 1): -1})) d -= 1 assert d == PUBO({(0, ): 1, (0, 1): 1, (1, ): -1, (): -1}) assert d.offset == -1
def test_pubo_on_qubo(): problem = PUBO({ ('a',): -1, ('b',): 2, ('a', 'b'): -3, ('b', 'c'): -4, (): -2 }) solution = {'c': 1, 'b': 1, 'a': 1} obj = -8 with assert_raises(ValueError): problem.to_pubo(deg=1) Problem(problem, solution, obj).runtests()
def test_pubo_addition(): temp = PUBO({('0', '0'): 1, ('0', 1): 2}) temp1 = {('0', ): -1, (1, '0'): 3} temp2 = {(1, '0'): 5}, {('0', 1): 5} temp3 = {('0', ): 2, (1, '0'): -1}, {('0', ): 2, ('0', 1): -1} # constant d = temp.copy() d += 5 assert d in ({ ('0', ): 1, (1, '0'): 2, (): 5 }, { ('0', ): 1, ('0', 1): 2, (): 5 }) # __add__ d = temp.copy() g = d + temp1 assert g in temp2 # __iadd__ d = temp.copy() d += temp1 assert d in temp2 # __radd__ d = temp.copy() g = temp1 + d assert g in temp2 # __sub__ d = temp.copy() g = d - temp1 assert g in temp3 # __isub__ d = temp.copy() d -= temp1 assert d in temp3 # __rsub__ d = temp.copy() g = temp1 - d assert g == PUBO(temp3[0]) * -1
def test_pubo_to_puso_to_pubo(): pubo = { (0, ): 1, (0, 1): 1, (1, ): -1, (1, 2): .5, (): -2, (2, ): 1, (0, 2, 3): -3, (0, 1, 2): -2 } assert pubo == puso_to_pubo(pubo_to_puso(pubo)) pubo = { ('0', ): 1, ('0', 1): 1, (1, ): -1, (1, '2'): .5, (): -2, ('2', ): 1, ('0', '2', 3): -3, ('0', 1, '2'): -2, ('0', '0', 1, '0', '2', '2'): -9, (4, 2, 4, 0, 2, 0, 0): 3 } # need to reformat pubo so it is sorted with the same hash and squashed key assert PUBO(pubo) == puso_to_pubo(pubo_to_puso(pubo))
def test_round(): d = PUBO({(0, ): 3.456, (1, ): -1.53456}) assert round(d) == {(0, ): 3, (1, ): -2} assert round(d, 1) == {(0, ): 3.5, (1, ): -1.5} assert round(d, 2) == {(0, ): 3.46, (1, ): -1.53} assert round(d, 3) == {(0, ): 3.456, (1, ): -1.535}
def test_normalize(): temp = {(0, ): 4, (1, ): -2} d = PUBO(temp) d.normalize() assert d == {k: v / 4 for k, v in temp.items()} temp = {(0, ): -4, (1, ): 2} d = PUBO(temp) d.normalize() assert d == {k: v / 4 for k, v in temp.items()}
def test_pubo_on_deg_3_pubo(): problem = PUBO({ ('a',): -1, ('b',): 2, ('a', 'b'): -3, ('b', 'c'): -4, (): -2, (0, 1, 2): 1, (0,): -1, (1,): -2, (2,): 1 }) solution = {'c': 1, 'b': 1, 'a': 1, 0: 1, 1: 1, 2: 0} obj = -11 Problem(problem, solution, obj).runtests()
def test_sat_one(): f = BUFFER assert f('x') == {('x', ): 1} assert f({('x', 'y'): 1}) == PUBO({('x', 'y'): 1}) # testing type x = boolean_var(0) for model in BOOLEAN_MODELS: assert isinstance(f(model(x)), model)
def test_sat_not(): f = NOT assert f('x') == {(): 1, ('x', ): -1} assert f({('x', 'y'): 1}) == 1 - PUBO({('x', 'y'): 1}) # testing type x = boolean_var(0) for model in BOOLEAN_MODELS: assert isinstance(f(model(x)), model)
def test_pubo_on_deg_5_pubo(): problem = PUBO({ ('a',): -1, ('b',): 2, ('a', 'b'): -3, ('b', 'c'): -4, (): -2, (0, 1, 2): 1, (0,): -1, (1,): -2, (2,): 1, ('a', 0, 4, 'b', 'c'): -3, (4, 2, 3, 'a', 'b'): 2, (4, 2, 3, 'b'): -1, ('c',): 4, (3,): 1, (0, 1): -2 }) solution = {0: 1, 1: 1, 'c': 1, 2: 0, 4: 1, 3: 0, 'b': 1, 'a': 1} obj = -12 Problem(problem, solution, obj).runtests()
def test_convert_solution_all_1s(): d = PUBO({(0, ): 1}) assert d.convert_solution({0: 0}) == {0: 0} assert d.convert_solution({0: -1}) == {0: 1} assert d.convert_solution({0: 1}) == {0: 1} assert d.convert_solution({0: 1}, True) == {0: 0}
def test_pubo_degree_reduction_pairs(): pubo = PUBO({ ('x0', 'x1'): -1, ('x1', ): 1, ('x1', 'x2'): -1, ('x2', ): 1, ('x3', 'x2'): -1, ('x3', ): 1, ('x4', 'x3'): -1, ('x4', ): 1, ('x4', 'x5'): -1, ('x5', ): 1, ('x5', 'x6'): -1, ('x6', ): 1, ('x7', 'x6'): -1, ('x7', ): 1, ('x8', 'x7'): -1, ('x8', ): 1, ('x9', 'x8'): -1, ('x9', ): 1 })**2 pairs = {('x0', 'x1'), ('x1', 'x2'), ('x2', 'x3'), ('x3', 'x4'), ('x4', 'x5'), ('x5', 'x6'), ('x6', 'x7'), ('x7', 'x8'), ('x8', 'x9')} qubo1 = pubo.to_qubo() qubo2 = pubo.to_qubo(pairs=pairs) assert qubo1.num_binary_variables - pubo.num_binary_variables > 9 assert qubo2.num_binary_variables - pubo.num_binary_variables == 9 quso1 = pubo.to_quso() quso2 = pubo.to_quso(pairs=pairs) assert quso1.num_binary_variables - pubo.num_binary_variables > 9 assert quso2.num_binary_variables - pubo.num_binary_variables == 9
def test_pubo_degree(): d = PUBO() assert d.degree == 0 d[(0, )] += 2 assert d.degree == 1 d[(1, )] -= 3 assert d.degree == 1 d[(1, 2)] -= 2 assert d.degree == 2 d[(1, 2, 4)] -= 2 assert d.degree == 3 d[(1, 2, 4, 5, 6)] += 2 assert d.degree == 5
def test_properties(): temp = PUBO({('0', '0'): 1, ('0', 1): 2}) assert not temp.offset d = PUBO() d[(0, )] += 1 d[(1, )] += 2 assert d == d.to_qubo() == {(0, ): 1, (1, ): 2} assert d.mapping == d.reverse_mapping == {0: 0, 1: 1} d.set_mapping({1: 0, 0: 1}) assert d.to_qubo() == {(1, ): 1, (0, ): 2} assert d.mapping == d.reverse_mapping == {0: 1, 1: 0}
def test_pretty_str(): def equal(expression, string): assert expression.pretty_str() == string x = [PUBO() + {(i,): 1} for i in range(3)] a, b = Symbol('a'), Symbol('b') equal(x[0], "x(0)") equal(-x[0], "-x(0)") equal(x[0] * 0, "0") equal(2*x[0]*x[1] - 3*x[2], "2 x(0) x(1) - 3 x(2)") equal(0*x[0] + 1, "1") equal(0*x[0] - 1, "-1") equal(0*x[0] + a, "(a)") equal(0*x[0] + a * b, "(a*b)") equal((a+b)*(x[0]*x[1] - x[2]), "(a + b) x(0) x(1) + (-a - b) x(2)") equal(2*x[0]*x[1] - x[2], "2 x(0) x(1) - x(2)") equal(-x[2] + x[0]*x[1], "-x(2) + x(0) x(1)") equal(-2*x[2] + 2*x[0]*x[1], "-2 x(2) + 2 x(0) x(1)")
def test_pubo_multiplication(): temp = PUBO({('0', '0'): 1, ('0', 1): 2}) temp1 = {('0', ): 3, (1, '0'): 6}, {('0', ): 3, ('0', 1): 6} temp2 = {('0', ): .5, (1, '0'): 1}, {('0', ): .5, ('0', 1): 1} # constant d = temp.copy() d += 3 d *= -2 assert d in ({ ('0', ): -2, (1, '0'): -4, (): -6 }, { ('0', ): -2, ('0', 1): -4, (): -6 }) # __mul__ d = temp.copy() g = d * 3 assert g in temp1 d = temp.copy() g = d * 0 assert g == {} # __imul__ d = temp.copy() d *= 3 assert d in temp1 d = temp.copy() d *= 0 assert d == {} # __rmul__ d = temp.copy() g = 3 * d assert g in temp1 d = temp.copy() g = 0 * d assert g == {} # __truediv__ d = temp.copy() g = d / 2 assert g in temp2 # __itruediv__ d = temp.copy() d /= 2 assert d in temp2 # __floordiv__ d = temp.copy() g = d // 2 assert g in ({(1, '0'): 1}, {('0', 1): 1}) # __ifloordiv__ d = temp.copy() d //= 2 assert d in ({(1, '0'): 1}, {('0', 1): 1}) # __mul__ but with dict d = temp.copy() d *= {(1, ): 2, ('0', '0'): -1} assert d in ({('0', ): -1, (1, '0'): 4}, {('0', ): -1, ('0', 1): 4}) # __pow__ d = temp.copy() d -= 2 d **= 2 assert d == {('0', ): -3, (): 4} d = temp.copy() assert d**3 == d * d * d
def test_to_enumerated(): d = PUBO({('a', 'b'): 1, ('a',): 2}) dt = d.to_enumerated() assert type(dt) == PUBOMatrix assert dt == d.to_pubo()
def test_pubo_default_valid(): d = PUBO() assert d[(0, 0)] == 0 d[(0, 0)] += 1 assert d == {(0, ): 1}
def test_pubo_checkkey(): with assert_raises(KeyError): PUBO({0: -1})
def test_pubo_num_binary_variables(): d = PUBO({(0, 0): 1, (0, 1, 2, 3, 5): 2}) assert d.num_binary_variables == 5 assert d.max_index == 4
def test_num_terms(): d = PUBO({(0, ): 1, (0, 3): 2, (0, 2): -1}) assert d.num_terms == len(d)
def test_pubo_remove_value_when_zero(): d = PUBO() d[(0, 0, 1, 2)] += 1 d[(0, 1, 2)] -= 1 assert d == {}
def test_properties(): temp = PUBO({('0', '0'): 1, ('0', 1): 2}) assert not temp.offset d = PUBO() d[(0,)] += 1 d[(1,)] += 2 assert d == d.to_qubo() == {(0,): 1, (1,): 2} assert d.mapping == d.reverse_mapping == {0: 0, 1: 1} d.set_mapping({1: 0, 0: 1}) assert d.to_qubo() == {(1,): 1, (0,): 2} assert d.mapping == d.reverse_mapping == {0: 1, 1: 0} # an old bug d = PUBO() d.set_mapping({0: 0}) d[(0,)] += 1 assert d.num_binary_variables == 1 assert d.variables == {0}
def test_pubo_degree_reduction_lam(): pubo = PUBO({ ('x0', 'x1'): -1, ('x1', ): 1, ('x1', 'x2'): -1, ('x2', ): 1, ('x3', 'x2'): -1, ('x3', ): 1, ('x4', 'x3'): -1, ('x4', ): 1, })**2 # just make sure it runs pubo.to_qubo(lam=4) pubo.to_qubo(lam=lambda v: v) pubo.to_qubo(lam=Symbol('lam')) pubo.to_qubo(lam=lambda v: v * Symbol('lam')) pubo.to_quso(lam=4) pubo.to_quso(lam=lambda v: v) pubo.to_quso(lam=Symbol('lam')) pubo.to_quso(lam=lambda v: v * Symbol('lam'))
def test_pubo_reinitialize_dictionary(): d = PUBO({(0, 0): 1, ('1', 0): 2, (2, 0): 0, (0, '1'): 1}) assert d in ({(0, ): 1, ('1', 0): 3}, {(0, ): 1, (0, '1'): 3})