ANN: GMPY binaries for Windows 2.5

mensanator at aol.com mensanator at aol.com
Sat Sep 2 16:57:37 EDT 2006


casevh at comcast.net wrote:
> > > Notes
> > > ====
> > > They have not been extensively tested.
> >
> > They don't work. At least the Pentium4 binary doesn't work,
> > same problem as before. Is the patch installed?
>
> I found the problem. Updated binaries should be available in a couple
> of hours. I'll add a note to the web page. I tested the patch but then
> overwrote the patched file with the unpatched file.
>
> I should quit doing this late at night....
>
> Thanks for testing.

That's a relief. I've downloaded the 1.04a version and re-ran
all the tests where I first noticed divm() errors. I can't even
remember why I wrote this program but the important thing
is that it uses divm() with non-coprime parameters which
provokes the divm() bug.

import gmpy
import random
import operator

def product(a,b):
    return a*b

def gcdlist(X):
    mingcd = 999999
    for i in xrange(1,len(X)):
        g = gmpy.gcd(X[i-1],X[i])
        if g<mingcd: mingcd = g
    return mingcd

X = [8,16,20,24,40,72,84,92]
g = gcdlist(X)
s = sum(X)

print '       X:',X
print '     gcd:',g

N = 0
while N<s:
    N = g * random.randint(s,3333)
print '       N:',N

if N>s:
    C = [1 for i in X]
    diff = N-s
    done = False
    i = -1
    XL = -len(X)
    while not done:
        while diff>=X[i]:
            C[i] += 1
            diff -= X[i]
        if diff==0:
            done = True
        else:
            i -= 1
            if i<XL:
                done = True
    NN = sum(map(operator.__mul__,X,C))
    print '       X:',X
    print '       C:',C
    print '      NN:',NN
    print '    diff:',diff
    print
    if diff>0:
        p = 0
        q = 1
        done = False
        while not done:
            gpq = gmpy.gcd(X[p],X[q])
            if diff % gpq == 0:
                done = True
            else:
                q += 1
                if q==len(X):
                    p += 1
                    q = p + 1
        print 'p: %d    q: %d' % (p,q)
        a = gmpy.divm(diff,X[p],X[q])
        b = (X[p]*a - diff)/X[q]
        print 'a: %d    b: %d    X[p]: %d    X[q]: %d' %
(a,b,X[p],X[q])
        if C[q]==b:
            print 'non-zero adjustment'
            print 'a: %d    b: %d' % (a + X[q],b + X[p])
            C[p] += a + X[q]
            C[q] -= b + X[p]
        else:
            C[p] += a
            C[q] -= b
        NN = sum(map(operator.__mul__,X,C))
        print '       X:',X
        print '       C:',C
        print '      NN:',NN
        print

##    This is what a successful output should look like
##
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 4492
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 1, 1, 1, 1, 1, 2, 45]
##          NN: 4488
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [24, 1, -8, 1, 1, 1, 2, 45]
##          NN: 4492
##
##    X is a list of integers selected so that the GCD of the entire
list is >2.
##    N is selected to be greater than sum(X) and divisible by GCD(X).
##    C is initialized to [1,1,1,1,1,1,1,1].
##    NN is the sum of each X element multiplied by its corresponding C
##    element. The values of C are then adjusted until the difference
##    between N and NN is 0.
##
##    If a difference of 0 is unobtainable (in the example diff=4 is
smaller
##    than the smallest element of X), then the program solves a linear
##    congruence by first finding a pair of X whose GCD divides diff
##    (8 and 20). For the solution a=3, b=1, we add three to C[0] and
##    subtract 1 from C[2] making
##           C: [1, 1, 1, 1, 1, 1, 2, 45]
##    into
##           C: [4, 1, 0, 1, 1, 1, 2, 45]
##
##    But I don't want any 0s in the list, only positive and negative
##    integers. Thus, in this example, a 0 adjustment is made:
##           C: [24, 1, -8, 1, 1, 1, 2, 45]


Here is the divm() bug in action. Note that when complete, NN=6286
which does not match N=6296.


##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 6296
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 1, 2, 1, 1, 65]
##          NN: 6292
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 0    X[p]: 8    X[q]: 20
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(5), 1, mpz(1), 1, 2, 1, 1, 65]
##          NN: 6286

Once the bug has corrupted gmpy, simple arithmetic no longer works:

##    >>> print gmpy.mpz(8)*gmpy.mpz(3)
##    6

Now, with the patch installed into version 1.04:

>>> import gmpy
>>> gmpy.version()
'1.04'
>>> gmpy.divm(4,8,20)
mpz(3)
>>> gmpy.divm(4,8,20)
mpz(3)

>>> gmpy.mpz(20)
mpz(20)
>>> gmpy.mpz(8)
mpz(8)
>>> gmpy.mpz(4)
mpz(4)

Good! Things are now back to normal.

Re-running the above program multiple times ensuring
that divm() gets called repeatedly with non-coprime
parameters:

## changing to gmpy 1.04
## divm() should be fixed now


##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 5420
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 1, 1, 1, 1, 1, 1, 56]
##          NN: 5416
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(24), 1, mpz(-8), 1, 1, 1, 1, 56]
##          NN: 5420
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 12328
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 1, 1, 1, 1, 131]
##          NN: 12324
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(25), 1, mpz(-8), 1, 1, 1, 1, 131]
##          NN: 12328
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 7448
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 1, 1, 1, 1, 78]
##          NN: 7448
##        diff: 0
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 3212
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 1, 1, 1, 1, 1, 1, 32]
##          NN: 3208
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(24), 1, mpz(-8), 1, 1, 1, 1, 32]
##          NN: 3212
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 8648
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 1, 1, 1, 1, 91]
##          NN: 8644
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(25), 1, mpz(-8), 1, 1, 1, 1, 91]
##          NN: 8648
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 8756
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 1, 1, 2, 1, 1, 1, 92]
##          NN: 8752
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(24), 1, mpz(-8), 2, 1, 1, 1, 92]
##          NN: 8756
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 6740
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 2, 1, 1, 1, 70]
##          NN: 6736
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(25), 1, mpz(-8), 2, 1, 1, 1, 70]
##          NN: 6740
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 6528
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 1, 1, 1, 1, 68]
##          NN: 6528
##        diff: 0
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 3004
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 1, 1, 1, 1, 2, 1, 29]
##          NN: 3004
##        diff: 0
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 6772
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 1, 1, 2, 2, 1, 1, 70]
##          NN: 6768
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(24), 1, mpz(-8), 2, 2, 1, 1, 70]
##          NN: 6772
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 11320
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 2, 1, 1, 1, 1, 1, 120]
##          NN: 11320
##        diff: 0
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 2248
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 1, 2, 1, 1, 21]
##          NN: 2244
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(25), 1, mpz(-8), 1, 2, 1, 1, 21]
##          NN: 2248
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 4604
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 2, 1, 1, 1, 1, 1, 47]
##          NN: 4604
##        diff: 0
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 5820
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 2, 1, 1, 1, 60]
##          NN: 5816
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(25), 1, mpz(-8), 2, 1, 1, 1, 60]
##          NN: 5820
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 4092
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 2, 1, 1, 2, 1, 1, 41]
##          NN: 4092
##        diff: 0
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 8048
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 2, 1, 1, 2, 1, 1, 84]
##          NN: 8048
##        diff: 0
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 1992
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 1, 1, 1, 1, 2, 1, 18]
##          NN: 1992
##        diff: 0
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 3740
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 1, 1, 1, 1, 2, 1, 37]
##          NN: 3740
##        diff: 0
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 3336
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 2, 1, 1, 1, 33]
##          NN: 3332
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(25), 1, mpz(-8), 2, 1, 1, 1, 33]
##          NN: 3336
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 12460
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [2, 1, 1, 1, 2, 1, 1, 132]
##          NN: 12456
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(25), 1, mpz(-8), 1, 2, 1, 1, 132]
##          NN: 12460
##
##    >>> ================================ RESTART
================================
##    >>>
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##         gcd: 4
##           N: 9540
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [1, 1, 1, 1, 1, 2, 1, 100]
##          NN: 9536
##        diff: 4
##
##    p: 0    q: 2
##    a: 3    b: 1    X[p]: 8    X[q]: 20
##    non-zero adjustment
##    a: 23    b: 9
##           X: [8, 16, 20, 24, 40, 72, 84, 92]
##           C: [mpz(24), 1, mpz(-8), 1, 1, 2, 1, 100]
##          NN: 9540

In every case, NN ended up equal to N, so divm() appears to
be working correctly now.


I also ran my Mersenne Hailstone test to check performance
(since the last time I ran it, I've added a GB of Ram to
my computer and re-coded my programs to be non-recursive).
In my Collatz research, in the place where I use divm()
the parameters are always co-prime, so I used gmpy 1.01
for months without discovering the bug.


##    Python 2.4a3
##    gmpy.version: 1.01
##
##    Brute force search: gclass(2**i-1,xyz)
##    Find 1st Generation k Type [1,2] Mersenne Hailstone
##
##                2**5-1  generation: 1
##               2**29-1  generation: 2
##              2**245-1  generation: 3
##             2**2189-1  generation: 4
##            2**19685-1  generation: 5
##           2**177149-1  generation: 6
##
##    27.97 seconds
##
##    Closed form: Type12MH(k,i)
##    Find ith, kth Generation Type [1,2] Mersenne Hailstone
##    using the closed form equation
##
##    2**(6*((i-1)*9**(k-1)+(9**(k-1)-1)/2+1)-1)-1
##
##                2**5-1  generation: 1
##               2**29-1  generation: 2
##              2**245-1  generation: 3
##             2**2189-1  generation: 4
##            2**19685-1  generation: 5
##           2**177149-1  generation: 6
##          2**1594325-1  generation: 7
##         2**14348909-1  generation: 8
##        2**129140165-1  generation: 9
##       2**1162261469-1  generation:10
##
##    1.359 seconds
##
##    Verify Type12MH Hailstones:
##    Find ith, kth Generation Type (xyz) Hailstone
##    using the non-recursive equation
##
##
(gmpy.divm(y**(k-1)-prev_gen[2],y-x,y**(k-1))/y**(k-2))*xyz[1]**(k-1)+prev_gen[3]
##
##    where i=((hailstone-geni(k,1,xyz))/(xyz[1]**k))+1
##
##                2**5-1  generation: 1
##               2**29-1  generation: 2
##              2**245-1  generation: 3
##             2**2189-1  generation: 4
##            2**19685-1  generation: 5
##           2**177149-1  generation: 6
##          2**1594325-1  generation: 7
##         2**14348909-1  generation: 8
##        2**129140165-1  generation: 9
##       2**1162261469-1  generation:10
##
##    4.516 seconds

##    Python 2.5c1
##
##    gmpy.version: 1.04
##
##    Brute force search: gclass(2**i-1,xyz)
##    Find 1st Generation k Type [1,2] Mersenne Hailstone
##
##                2**5-1  generation: 1
##               2**29-1  generation: 2
##              2**245-1  generation: 3
##             2**2189-1  generation: 4
##            2**19685-1  generation: 5
##           2**177149-1  generation: 6
##
##    21.64 seconds
##
##    Closed form: Type12MH(k,i)
##    Find ith, kth Generation Type [1,2] Mersenne Hailstone
##    using the closed form equation
##
##    2**(6*((i-1)*9**(k-1)+(9**(k-1)-1)/2+1)-1)-1
##
##                2**5-1  generation: 1
##               2**29-1  generation: 2
##              2**245-1  generation: 3
##             2**2189-1  generation: 4
##            2**19685-1  generation: 5
##           2**177149-1  generation: 6
##          2**1594325-1  generation: 7
##         2**14348909-1  generation: 8
##        2**129140165-1  generation: 9
##       2**1162261469-1  generation:10
##
##    1.375 seconds
##
##    Verify Type12MH Hailstones:
##    Find ith, kth Generation Type (xyz) Hailstone
##    using the non-recursive equation
##
##
(gmpy.divm(y**(k-1)-prev_gen[2],y-x,y**(k-1))/y**(k-2))*xyz[1]**(k-1)+prev_gen[3]
##
##    where i=((hailstone-geni(k,1,xyz))/(xyz[1]**k))+1
##
##                2**5-1  generation: 1
##               2**29-1  generation: 2
##              2**245-1  generation: 3
##             2**2189-1  generation: 4
##            2**19685-1  generation: 5
##           2**177149-1  generation: 6
##          2**1594325-1  generation: 7
##         2**14348909-1  generation: 8
##        2**129140165-1  generation: 9
##       2**1162261469-1  generation:10
##
##    4.25 seconds


Great! Everything seems to work perfectly.

I really, really, REALLY appreciate your making Windows binaries
of gmpy. Since all my Collatz research is now dependent on gmpy,
I can't upgrade Python until gmpy is upgraded. And with the
compiler woes I've been reading about, I was afraid gmpy might
not ever be upgraded (for Windows).


> 
> Case




More information about the Python-list mailing list