Skip to content

Added Chakravala method to solve pell's equation #6848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [Newton Forward Interpolation](arithmetic_analysis/newton_forward_interpolation.py)
* [Newton Method](arithmetic_analysis/newton_method.py)
* [Newton Raphson](arithmetic_analysis/newton_raphson.py)
* [Newton Raphson New](arithmetic_analysis/newton_raphson_new.py)
* [Secant Method](arithmetic_analysis/secant_method.py)

## Audio Filters
Expand Down Expand Up @@ -107,6 +108,7 @@
* [Lempel Ziv](compression/lempel_ziv.py)
* [Lempel Ziv Decompress](compression/lempel_ziv_decompress.py)
* [Peak Signal To Noise Ratio](compression/peak_signal_to_noise_ratio.py)
* [Run Length Encoding](compression/run_length_encoding.py)

## Computer Vision
* [Cnn Classification](computer_vision/cnn_classification.py)
Expand Down Expand Up @@ -474,6 +476,7 @@
* [Binomial Distribution](maths/binomial_distribution.py)
* [Bisection](maths/bisection.py)
* [Ceil](maths/ceil.py)
* [Chakravala](maths/chakravala.py)
* [Check Polygon](maths/check_polygon.py)
* [Chudnovsky Algorithm](maths/chudnovsky_algorithm.py)
* [Collatz Sequence](maths/collatz_sequence.py)
Expand Down Expand Up @@ -621,6 +624,7 @@
* [Linear Congruential Generator](other/linear_congruential_generator.py)
* [Lru Cache](other/lru_cache.py)
* [Magicdiamondpattern](other/magicdiamondpattern.py)
* [Maximum Subarray](other/maximum_subarray.py)
* [Nested Brackets](other/nested_brackets.py)
* [Password Generator](other/password_generator.py)
* [Scoring Algorithm](other/scoring_algorithm.py)
Expand Down Expand Up @@ -1053,6 +1057,7 @@
* [Fetch Bbc News](web_programming/fetch_bbc_news.py)
* [Fetch Github Info](web_programming/fetch_github_info.py)
* [Fetch Jobs](web_programming/fetch_jobs.py)
* [Fetch Quotes](web_programming/fetch_quotes.py)
* [Fetch Well Rx Price](web_programming/fetch_well_rx_price.py)
* [Get Imdb Top 250 Movies Csv](web_programming/get_imdb_top_250_movies_csv.py)
* [Get Imdbtop](web_programming/get_imdbtop.py)
Expand Down
120 changes: 120 additions & 0 deletions maths/chakravala.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""
Implementing Chakravala method using python

https://en.wikipedia.org/wiki/Chakravala_method
https://kappadath-gopal.blogspot.com/2013/04/ancient-medieval-indian-mathematics.html

The chakravala method is a cyclic algorithm to solve indeterminate quadratic equations,
including Pell's equation.

"""

import math


def is_perfect_square(num: int) -> bool:
"""
Check if a number is perfect square number or not
:param num: the number to be checked
:return: True if number is square number, otherwise False

>>> is_perfect_square(9)
True
>>> is_perfect_square(16)
True
>>> is_perfect_square(1)
True
>>> is_perfect_square(0)
True
>>> is_perfect_square(10)
False
"""

sr = int(math.sqrt(num))
return sr * sr == num


def chakravala_method(num: int) -> (tuple[int, int] | tuple):
"""
This method takes in the value of N in the equation

x^2 = N*y^2 + 1
:param num: the number N equals to
:return: empty tuple if N is perfect square else tuple(x,y)

>>> chakravala_method(1)
()
>>> chakravala_method(2)
(3, 2)
>>> chakravala_method(4)
()
>>> chakravala_method(5)
(9, 4)
>>> chakravala_method(7)
(8, 3)

"""

if is_perfect_square(num):
return ()

# Takes b = 1 and finds a and k accordingly, refer to algorithm link
# variable naming is used as same as algorithm, (a,b,k,m) except N = num

b = 1

min_diff = num
a = 0
while True:
diff = abs(num - (a + 1) ** 2)
if min_diff > diff:
min_diff = diff
a += 1
continue
break

k = a**2 - num

while True:

kabs = abs(k)

if k == 1:
return (a, b)

if k == -1 or kabs == 2 or (kabs == 4 and (a % 2 == 0 or b % 2 == 0)):
return (abs((a**2 + num * b**2) // k), abs(2 * a * b // k))

min_diff = num
n = 1 # loop variable
n2 = n # stores the correct value of n
while True:
if kabs * n <= a:
n += 1
continue
if (kabs * n - a) % b == 0:
m = (kabs * n - a) // b
else:
n += 1
continue

diff = abs(m**2 - num)
if min_diff > diff:
min_diff = diff
n2 = n
n += 1
continue
break
m = (kabs * n2 - a) // b

a, b = abs((a * m + num * b) // k), abs((a + b * m) // k)
k = (m**2 - num) // k


if __name__ == "__main__":

import doctest

doctest.testmod()

print("X and Y for the equation X^2 - 13Y^2 = 1 is: ", chakravala_method(13))