2

Update 11/24: I asked this question as a 'side venture'. The start was my work on an algorithm that used the back substitution method for solving linear congruence equations; see this. I just posted a Python program to stackoveflow, explaining how it might be useful in some applications.

Update 11/23: After thinking about Daniel Fischer's comments this question can be closed. Without a doubt the idea here could not possibly speed up any state of the art computing algorithms that calculate the gcd of large numbers. What I was calling a turbo method actually performed the same number of residue calculations, but the subtraction $b - a$ seemed so 'light' I thought of it as executing with fewer computing cycles. Here we employ the 'turbo' method on a simple example:

Compute: $\text{gcd}(30,32)$. Since $2*30 \gt 32$, the problem is reduced to $\text{gcd}(32-30,30) = \text{gcd}(2,30)$ and since $2 \mid 30$ the gcd is $2$.

Update 11/22: Anybody who knows how to convert the Python code to pseudocode is welcome to edit this question to include it (see comment).


I created a Python program to compute the GCD of two numbers $(a,b)$ with $0 \lt a \lt b$.

The program counts how many modulus operations are used in the standard method and how many are used with my 'turbo' version.

Question:

Is the count of modulus operations for the turbo version always less than or equal to the count for the standard method?

Python program

def gcd(A,B):
#           # Standard method
    a = A
    b = B
    cnt = 0
    while a:
        a,b = b%a,a
        cnt = cnt + 1
    print('Standard:', 'answer =', b, 'modulus operations:', cnt)
#           # Turbo method
    a = A
    b = B
    cnt = 0
    while True:
        t = 2*a
        if t > b:
            a = b - a
        a,b = b%a,a
        cnt = cnt + 1        
        if a == 0:
            break
    print('TurboChg:', 'answer =', b, 'modulus operations:', cnt)
    return

test_data = [
(32,82),
(24,56),
(36,60),
(227,2011),
(25,29),
(25527,53667),
(7,21),
]

for da_pair in test_data: print() print('***', 'WORKING ON', da_pair)
a, b = da_pair gcd(a,b)

OUTPUT

*** WORKING ON (32, 82)
Standard: answer = 2 modulus operations: 5
TurboChg: answer = 2 modulus operations: 4

*** WORKING ON (24, 56) Standard: answer = 8 modulus operations: 2 TurboChg: answer = 8 modulus operations: 2

*** WORKING ON (36, 60) Standard: answer = 12 modulus operations: 3 TurboChg: answer = 12 modulus operations: 2

*** WORKING ON (227, 2011) Standard: answer = 1 modulus operations: 6 TurboChg: answer = 1 modulus operations: 4

*** WORKING ON (25, 29) Standard: answer = 1 modulus operations: 3 TurboChg: answer = 1 modulus operations: 2

*** WORKING ON (25527, 53667) Standard: answer = 201 modulus operations: 5 TurboChg: answer = 201 modulus operations: 4

*** WORKING ON (7, 21) Standard: answer = 7 modulus operations: 1 TurboChg: answer = 7 modulus operations: 1

CopyPasteIt
  • 11,366
  • 1
    I am a retired programmer who doesn't know python. In order to attack your query, I need to convert your code to pseudocode. I wasn't able to do that. Perhaps someone else can. If you don't get a response from anyone else, and you want my help, then I request that you do two things: (1) Edit your query to completely remove all of the computer code, and instead insert pseudocode in its place. (2) When done, address a comment to @user2661923 flagging me. – user2661923 Nov 22 '20 at 21:04
  • 1
    I'm not big on code, but I wonder whether what you are doing is the "binary gcd algorithm" as presented at https://en.wikipedia.org/wiki/Binary_GCD_algorithm – Gerry Myerson Nov 22 '20 at 22:51
  • 1
    I'm not sure how Python's remainder operator behaves with negative inputs. Your latest change may have introduced a bug in case $A > B > 0$, and for $A = B$ or $A = 0$ you'll have a division by zero. For $0 < A < B$ however, your variant always uses at most as many remainder oprations as the standard method. When $a \leqslant b/2$, both loop bodies do the same (to the $(a,b)$ pair, yours does a bit of additional work with no effect then). When $b/2 < a < b$, let $q = \bigl\lfloor \frac{b}{b-a}$, so $b = q(b-a) + s$, $0 \leqslant s < b-a$. – Daniel Fischer Nov 22 '20 at 23:08
  • 1
    Then $s = qa - (q-1)b$, and the next loop iteration is entered with the pair $(s, b-a)$ in your method. In the standard method, the next loop iteration is entered with the pair $(b-a,a)$, and since $a = (q-1)(b-a) + s$ (same $s$ as before), the iteration after that is entered with the pair $(s, b-a)$, so it takes two iterations to reach the same state as yours reached in one. But unless you're working with numbers where the remainder operation takes massively more time than multiplying with $2$ and testing, there won't be a significant speed-up. – Daniel Fischer Nov 22 '20 at 23:08
  • 1
    @user2661923 The code can be copied/pasted into, say, this online python run and to figure out the code just add all the print statements you want! Note: Python is indent sensitive. – CopyPasteIt Nov 22 '20 at 23:24
  • @DanielFischer I tested your statement and it looks like, indeed, the $a = b -a$ 'pivot' saves (just) one step. (+1) – CopyPasteIt Nov 22 '20 at 23:54
  • 1
    @CopyPasteIt You missed the point of my previous comment. mathSE reviewers do not ordinarily even look at any computer code. As an experienced user, you should know that. As a courtesy, I did skim your code; but from my point of view, that's the end of my looking at your computer code. If you can resolve the problem with the help of others, good. If not, then before I even look at your query again, I need the actual python code gone. – user2661923 Nov 23 '20 at 00:29
  • @DanielFischer I feel a bit silly now - see question updates. – CopyPasteIt Nov 23 '20 at 17:11
  • @CopyPasteIt if your experimental results is positive, I suggest going for larger ranges of $a$ and $b$ and see if it (TurboChrg) stands every temptation to go greater than the other. – Spectre Nov 23 '20 at 17:26
  • I mean, 'experimental results are'... not 'is'.. sorry for the bad grammar... – Spectre Nov 23 '20 at 17:43
  • @GerryMyerson I've recognized that to compute Bézout's coefficients a computer algorithm should use exact integer division. Of interest: In 1993 Tudor Jebelean wrote two papers $\quad$ A Generalization of the Binary GCD Algorithm $\quad$ An Algorithm for Exact Division – CopyPasteIt Nov 25 '20 at 08:43

0 Answers0