def test_is_square(self): for k in [-2, -1, 2, 3, 5, 7, 11, 2545]: self.assertEqual(is_square(k), False) for (k, r) in [(9, 3), (16, 4), (289, 17), (130321, 361)]: self.assertEqual(is_square(k), r) self.assertEqual(is_square([(2, 4), (5, 2)]), 20) self.assertEqual(is_square([(2, 4), (5, 3)]), False) values = [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961 ] squares = [a for a in xrange(1000) if is_square(a)] self.assertEqual(squares, values)
def test_is_square(self): self.assertRaisesRegexp(ValueError, "is_square: Must have n >= 0.", is_square, -2) for k in [2, 3, 5, 7, 11]: self.assertEqual(is_square(k), False) for (k, r) in [(9, 3), (16, 4), (289, 17), (130321, 361)]: self.assertEqual(is_square(k), r) self.assertEqual(is_square([(2, 4), (5, 2)]), 20) self.assertEqual(is_square([(2, 4), (5, 3)]), False) values = [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961 ] squares = [a for a in xrange(1, 1000) if is_square(a)] self.assertEqual(squares, values)
def pell_fundamental_solution(D, n=1): """Returns the fundamental solution to the Pell equation x**2 - D*y**2 == n, where n in (-1, 1). Given D > 0 not a square, and n in (-1, 1), this method returns the fundamental solution to the Pell equation described above. The fundamental solution (x, y) is the one with least positive value of x, and correspondingly the least positive value of y. Input: * D: int (D > 0) * n: int (n in (-1, 1)). Returns: * (x, y): tuple Raises: * ValueError: If D <= 0, D is perfect square, n not in (-1, 1), or if no solutions exist. Examples: >>> pell_fundamental_solution(61) (1766319049, 226153980) >>> 1766319049**2 - 61*226153980**2 1 >>> pell_fundamental_solution(17, -1) (4, 1) >>> 4**2 - 17*1**2 -1 >>> pell_fundamental_solution(15, -1) Traceback (most recent call last): ... ValueError: pell_fundamental_solution: Solution nonexistent. >>> pell_fundamental_solution(15, -2) Traceback (most recent call last): ... ValueError: pell_fundamental_solution: Must have D > 0 not a perfect square and n in (-1, 1). Details: For D > 0 not a perfect square, the equation x**2 - D*y**2 == 1 always has solutions, while the equation x**2 - D*y**2 == -1 only has solutions when the continued fraction expansion of sqrt(D) has odd period length. See Corollary 5.7 of "Fundamental Number Theory with Applications" by Mollin for details. See also the article "Simple Continued Fraction Solutions for Diophantine Equations" by Mollin. """ if D <= 0 or is_square(D) or n not in (1, -1): raise ValueError("pell_fundamental_solution: Must have D > 0 not a perfect square and n in (-1, 1).") contfrac = QuadraticIrrational(D) # No solution for n == -1 if the period length is even. if n == -1 and contfrac.period_length % 2 == 0: raise ValueError("pell_fundamental_solution: Solution nonexistent.") # Otherwise, solutions always exist for D not a perfect square. for (x, y) in contfrac.convergents(): if x*x - D*y*y == n: return (x, y)