def test_diophantine_overflow(): # Smoke test integer overflow detection max_intp = np.iinfo(np.intp).max max_int64 = np.iinfo(np.int64).max if max_int64 <= max_intp: # Check that the algorithm works internally in 128-bit; # solving this problem requires large intermediate numbers A = (max_int64//2, max_int64//2 - 10) U = (max_int64//2, max_int64//2 - 10) b = 2*(max_int64//2) - 10 assert_equal(solve_diophantine(A, U, b), (1, 1))
def test_diophantine_overflow(): # Smoke test integer overflow detection max_intp = np.iinfo(np.intp).max max_int64 = np.iinfo(np.int64).max if max_int64 <= max_intp: # Check that the algorithm works internally in 128-bit; # solving this problem requires large intermediate numbers A = (max_int64 // 2, max_int64 // 2 - 10) U = (max_int64 // 2, max_int64 // 2 - 10) b = 2 * (max_int64 // 2) - 10 assert_equal(solve_diophantine(A, U, b), (1, 1))
def check(A, U, exists=None): X = solve_diophantine(A, U, 0, require_ub_nontrivial=1) if exists is None: exists = (X is not None) if X is not None: assert_(sum(a*x for a, x in zip(A, X)) == sum(a*u//2 for a, u in zip(A, U))) assert_(all(0 <= x <= u for x, u in zip(X, U))) assert_(any(x != u//2 for x, u in zip(X, U))) if exists: assert_(X is not None, repr(X)) else: assert_(X is None, repr(X))
def test_diophantine_fuzz(): # Fuzz test the diophantine solver rng = np.random.RandomState(1234) max_int = np.iinfo(np.intp).max for ndim in range(10): feasible_count = 0 infeasible_count = 0 min_count = 500//(ndim + 1) numbers = [] while min(feasible_count, infeasible_count) < min_count: # Ensure big and small integer problems A_max = 1 + rng.randint(0, 11, dtype=np.intp)**6 U_max = rng.randint(0, 11, dtype=np.intp)**6 A_max = min(max_int, A_max) U_max = min(max_int-1, U_max) A = tuple(rng.randint(1, A_max+1, dtype=np.intp) for j in range(ndim)) U = tuple(rng.randint(0, U_max+2, dtype=np.intp) for j in range(ndim)) b_ub = min(max_int-2, sum(a*ub for a, ub in zip(A, U))) b = rng.randint(-1, b_ub+2, dtype=np.intp) if ndim == 0 and feasible_count < min_count: b = 0 X = solve_diophantine(A, U, b) if X is None: # Check the simplified decision problem agrees X_simplified = solve_diophantine(A, U, b, simplify=1) assert_(X_simplified is None, (A, U, b, X_simplified)) # Check no solution exists (provided the problem is # small enough so that brute force checking doesn't # take too long) try: ranges = tuple(xrange(0, a*ub+1, a) for a, ub in zip(A, U)) except OverflowError: # xrange on 32-bit Python 2 may overflow continue size = 1 for r in ranges: size *= len(r) if size < 100000: assert_(not any(sum(w) == b for w in itertools.product(*ranges))) infeasible_count += 1 else: # Check the simplified decision problem agrees X_simplified = solve_diophantine(A, U, b, simplify=1) assert_(X_simplified is not None, (A, U, b, X_simplified)) # Check validity assert_(sum(a*x for a, x in zip(A, X)) == b) assert_(all(0 <= x <= ub for x, ub in zip(X, U))) feasible_count += 1
def test_diophantine_fuzz(): # Fuzz test the diophantine solver rng = np.random.RandomState(1234) max_int = np.iinfo(np.intp).max for ndim in range(10): feasible_count = 0 infeasible_count = 0 min_count = 500 // (ndim + 1) numbers = [] while min(feasible_count, infeasible_count) < min_count: # Ensure big and small integer problems A_max = 1 + rng.randint(0, 11)**6 U_max = rng.randint(0, 11)**6 A_max = min(max_int, A_max) U_max = min(max_int - 1, U_max) A = tuple(rng.randint(1, A_max + 1) for j in range(ndim)) U = tuple(rng.randint(0, U_max + 2) for j in range(ndim)) b_ub = min(max_int - 2, sum(a * ub for a, ub in zip(A, U))) b = rng.randint(-1, b_ub + 2) if ndim == 0 and feasible_count < min_count: b = 0 X = solve_diophantine(A, U, b) if X is None: # Check the simplified decision problem agrees X_simplified = solve_diophantine(A, U, b, simplify=1) assert_(X_simplified is None, (A, U, b, X_simplified)) # Check no solution exists (provided the problem is # small enough so that brute force checking doesn't # take too long) try: ranges = tuple( xrange(0, a * ub + 1, a) for a, ub in zip(A, U)) except OverflowError: # xrange on 32-bit Python 2 may overflow continue size = 1 for r in ranges: size *= len(r) if size < 100000: assert_(not any( sum(w) == b for w in itertools.product(*ranges))) infeasible_count += 1 else: # Check the simplified decision problem agrees X_simplified = solve_diophantine(A, U, b, simplify=1) assert_(X_simplified is not None, (A, U, b, X_simplified)) # Check validity assert_(sum(a * x for a, x in zip(A, X)) == b) assert_(all(0 <= x <= ub for x, ub in zip(X, U))) feasible_count += 1