File: advmpz.rst

package info (click to toggle)
python-gmpy2 2.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,628 kB
  • ctags: 1,123
  • sloc: ansic: 21,036; python: 5,846; makefile: 163
file content (264 lines) | stat: -rw-r--r-- 8,337 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
Multiple-precision Integers (Advanced topics)
=============================================

The xmpz type
-------------

gmpy2 provides access to an experimental integer type called *xmpz*. The
*xmpz* type is a mutable integer type. In-place operations (+=, //=, etc.)
modify the orignal object and do not create a new object. Instances of
*xmpz* cannot be used as dictionary keys.

::

    >>> import gmpy2
    >>> from gmpy2 import xmpz
    >>> a = xmpz(123)
    >>> b = a
    >>> a += 1
    >>> a
    xmpz(124)
    >>> b
    xmpz(124)

The ability to change an *xmpz* object in-place allows for efficient and rapid
bit manipulation.

Individual bits can be set or cleared::

    >>> a[10]=1
    >>> a
    xmpz(1148)

Slice notation is supported. The bits referenced by a slice can be either 'read
from' or 'written to'. To clear a slice of bits, use a source value of 0. In
2s-complement format, 0 is represented by an arbitrary number of 0-bits. To set
a slice of bits, use a source value of ~0. The *tilde* operator inverts, or
complements the bits in an integer. (~0 is -1 so you can also use -1.) In
2s-complement format, -1 is represented by an arbitrary number of 1-bits.

If a value for *stop* is specified in a slice assignment and the actual
bit-length of the *xmpz* is less than *stop*, then the destination *xmpz* is
logically padded with 0-bits to length *stop*.

::

    >>> a=xmpz(0)
    >>> a[8:16] = ~0
    >>> bin(a)
    '0b1111111100000000'
    >>> a[4:12] = ~a[4:12]
    >>> bin(a)
    '0b1111000011110000'

Bits can be reversed::

    >>> bin(a)
    '0b10001111100'
    >>> a[::] = a[::-1]
    >>> bin(a)
    '0b111110001'

The *iter_bits()* method returns a generator that returns True or False for each
bit position. The methods *iter_clear()*, and *iter_set()* return generators
that return the bit positions that are 1 or 0. The methods support arguments
*start* and *stop* that define the beginning and ending bit positions that are
used. To mimic the behavior of slices. the bit positions checked include *start*
but the last position checked is *stop* - 1.

::

    >>> a=xmpz(117)
    >>> bin(a)
    '0b1110101'
    >>> list(a.iter_bits())
    [True, False, True, False, True, True, True]
    >>> list(a.iter_clear())
    [1, 3]
    >>> list(a.iter_set())
    [0, 2, 4, 5, 6]
    >>> list(a.iter_bits(stop=12))
    [True, False, True, False, True, True, True, False, False, False, False, False]

The following program uses the Sieve of Eratosthenes to generate a list of
prime numbers.

::

    from __future__ import print_function
    import time
    import gmpy2

    def sieve(limit=1000000):
        '''Returns a generator that yields the prime numbers up to limit.'''

	# Increment by 1 to account for the fact that slices  do not include
	# the last index value but we do want to include the last value for
	# calculating a list of primes.
	sieve_limit = gmpy2.isqrt(limit) + 1
	limit += 1

	# Mark bit positions 0 and 1 as not prime.
	bitmap = gmpy2.xmpz(3)

	# Process 2 separately. This allows us to use p+p for the step size
	# when sieving the remaining primes.
	bitmap[4 : limit : 2] = -1

	# Sieve the remaining primes.
	for p in bitmap.iter_clear(3, sieve_limit):
	    bitmap[p*p : limit : p+p] = -1

	return bitmap.iter_clear(2, limit)

    if __name__ == "__main__":
        start = time.time()
        result = list(sieve())
        print(time.time() - start)
        print(len(result))


Advanced Number Theory Functions
--------------------------------

The following functions are based on mpz_lucas.c and mpz_prp.c by David
Cleaver.

A good reference for probable prime testing is
http://www.pseudoprime.com/pseudo.html

**is_bpsw_prp(...)**
    is_bpsw_prp(n) will return True if *n* is a Baillie-Pomerance-Selfridge-Wagstaff
    probable prime. A BPSW probable prime passes the is_strong_prp() test with base
    2 and the is_selfridge_prp() test.

**is_euler_prp(...)**
    is_euler_prp(n,a) will return True if *n* is an Euler (also known as
    Solovay-Strassen) probable prime to the base *a*.

    | Assuming:
    |     gcd(n, a) == 1
    |     n is odd
    |
    | Then an Euler probable prime requires:
    |    a**((n-1)/2) == 1 (mod n)

**is_extra_strong_lucas_prp(...)**
    is_extra_strong_lucas_prp(n,p) will return True if *n* is an extra strong
    Lucas probable prime with parameters (p,1).

    | Assuming:
    |     n is odd
    |     D = p*p - 4, D != 0
    |     gcd(n, 2*D) == 1
    |     n = s*(2**r) + Jacobi(D,n), s odd
    |
    | Then an extra strong Lucas probable prime requires:
    |     lucasu(p,1,s) == 0 (mod n)
    |      or
    |     lucasv(p,1,s) == +/-2 (mod n)
    |      or
    |     lucasv(p,1,s*(2**t)) == 0 (mod n) for some t, 0 <= t < r

**is_fermat_prp(...)**
    is_fermat_prp(n,a) will return True if *n* is a Fermat probable prime to the
    base a.

    | Assuming:
    |     gcd(n,a) == 1
    |
    | Then a Fermat probable prime requires:
    |     a**(n-1) == 1 (mod n)

**is_fibonacci_prp(...)**
    is_fibonacci_prp(n,p,q) will return True if *n* is an Fibonacci
    probable prime with parameters (p,q).

    | Assuming:
    |     n is odd
    |     p > 0, q = +/-1
    |     p*p - 4*q != 0
    |
    | Then a Fibonacci probable prime requires:
    |     lucasv(p,q,n) == p (mod n).

**is_lucas_prp(...)**
    is_lucas_prp(n,p,q) will return True if *n* is a Lucas probable prime with
    parameters (p,q).

    | Assuming:
    |     n is odd
    |     D = p*p - 4*q, D != 0
    |     gcd(n, 2*q*D) == 1
    |
    | Then a Lucas probable prime requires:
    |     lucasu(p,q,n - Jacobi(D,n)) == 0 (mod n)

**is_selfridge_prp(...)**
    is_selfridge_prp(n) will return True if *n* is a Lucas probable prime with
    Selfidge parameters (p,q). The Selfridge parameters are chosen by finding
    the first element D in the sequence {5, -7, 9, -11, 13, ...} such that
    Jacobi(D,n) == -1. Let p=1 and q = (1-D)/4 and then perform a Lucas
    probable prime test.

**is_strong_bpsw_prp(...)**
    is_strong_bpsw_prp(n) will return True if *n* is a strong
    Baillie-Pomerance-Selfridge-Wagstaff probable prime. A strong BPSW
    probable prime passes the is_strong_prp() test with base 2 and the
    is_strongselfridge_prp() test.

**is_strong_lucas_prp(...)**
    is_strong_lucas_prp(n,p,q) will return True if *n* is a strong Lucas
    probable prime with parameters (p,q).

    | Assuming:
    |     n is odd
    |     D = p*p - 4*q, D != 0
    |     gcd(n, 2*q*D) == 1
    |     n = s*(2**r) + Jacobi(D,n), s odd
    |
    | Then a strong Lucas probable prime requires:
    |     lucasu(p,q,s) == 0 (mod n)
    |      or
    |     lucasv(p,q,s*(2**t)) == 0 (mod n) for some t, 0 <= t < r

**is_strong_prp(...)**
    is_strong_prp(n,a) will return True if *n* is an strong (also known as
    Miller-Rabin) probable prime to the base a.

    | Assuming:
    |     gcd(n,a) == 1
    |     n is odd
    |     n = s*(2**r) + 1, with s odd
    |
    | Then a strong probable prime requires one of the following is true:
    |     a**s == 1 (mod n)
    |      or
    |     a**(s*(2**t)) == -1 (mod n) for some t, 0 <= t < r.

**is_strong_selfridge_prp(...)**
    is_strong_selfridge_prp(n) will return True if *n* is a strong Lucas
    probable prime with Selfidge parameters (p,q). The Selfridge parameters are
    chosen by finding the first element D in the sequence
    {5, -7, 9, -11, 13, ...} such that Jacobi(D,n) == -1. Let p=1 and
    q = (1-D)/4 and then perform a strong Lucas probable prime test.

**lucasu(...)**
    lucasu(p,q,k) will return the k-th element of the Lucas U sequence defined
    by p,q. p*p - 4*q must not equal 0; k must be greater than or equal to 0.

**lucasu_mod(...)**
    lucasu_mod(p,q,k,n) will return the k-th element of the Lucas U sequence
    defined by p,q (mod n). p*p - 4*q must not equal 0; k must be greater than
    or equal to 0; n must be greater than 0.

**lucasv(...)**
    lucasv(p,q,k) will return the k-th element of the Lucas V sequence defined
    by parameters (p,q). p*p - 4*q must not equal 0; k must be greater than or
    equal to 0.

**lucasv_mod(...)**
    lucasv_mod(p,q,k,n) will return the k-th element of the Lucas V sequence
    defined by parameters (p,q) (mod n). p*p - 4*q must not equal 0; k must be
    greater than or equal to 0; n must be greater than 0.