A small kernel of code for playing with Galois fields of arbitrary characteristic
Revision | 568df9626320c0377072e54da585e0668db67328 (tree) |
---|---|
Time | 2021-03-15 14:37:21 |
Author | Eric Hopper <hopper@omni...> |
Commiter | Eric Hopper |
A random assortment of stuff I've been playing with.
@@ -0,0 +1,60 @@ | ||
1 | +def gen_randomized_fib(r): | |
2 | + oldest = 1 | |
3 | + older = 1 | |
4 | + bitpool = 0 | |
5 | + bitpoolbits = 0 | |
6 | + while True: | |
7 | + if bitpoolbits <= 0: | |
8 | + bitpool = r.getrandbits(64) | |
9 | + bitpoolbits = 64 | |
10 | + yield oldest | |
11 | + if (bitpool & 1) == 0: | |
12 | + oldest, older = older, older + oldest | |
13 | + else: | |
14 | + oldest, older = older, older - oldest | |
15 | + bitpool >>= 1 | |
16 | + --bitpoolbits | |
17 | + | |
18 | +def inewt(b, n): | |
19 | + newest = b >> (b.bit_length() - (b.bit_length() // n)) | |
20 | + est = 0 | |
21 | + while newest != est: | |
22 | + prevest = est | |
23 | + est = newest | |
24 | + newest = ((n - 1) * est + b // (est ** (n - 1))) // n | |
25 | + if prevest == newest: | |
26 | + return min(est, newest) | |
27 | + return newest | |
28 | + | |
29 | +def factors(n): | |
30 | + factors = [] | |
31 | + while n & 1 == 0: | |
32 | + factors.append(2) | |
33 | + n = n >> 1 | |
34 | + test = 3 | |
35 | + testsq = 9 | |
36 | + while testsq <= n: | |
37 | + if (n % test) == 0: | |
38 | + factors.append(test) | |
39 | + n = n // test | |
40 | + else: | |
41 | + testsq += 4 * test + 4 | |
42 | + test += 2 | |
43 | + factors.append(n) | |
44 | + return factors | |
45 | + | |
46 | +import math | |
47 | + | |
48 | +def nth_root_big(b, n): | |
49 | + if b.bit_length() <= 1023: | |
50 | + return math.pow(b, 1/n) | |
51 | + d, m = divmod(b.bit_length(), 1023) | |
52 | + chop_factor = d + (0 if m == 0 else 1) | |
53 | + if n < chop_factor: | |
54 | + raise OverflowError(f"The {n} root of {b} is out of the range of a floating point.") | |
55 | + flist = factors(n) | |
56 | + flist.reverse() | |
57 | + runprod = 1 | |
58 | + while (len(flist) > 0) and (runprod < chop_factor): | |
59 | + runprod *= flist.pop() | |
60 | + return math.pow(inewt(b, runprod), 1 / (n // runprod)) |