Data update
This commit is contained in:
parent
796d366b97
commit
35bcdeebf8
504 changed files with 7045 additions and 610 deletions
|
|
@ -0,0 +1,100 @@
|
|||
BEGIN # Daniel Shanks's Square Form Factorization (SquFoF) - based on the Wren sample #
|
||||
|
||||
MODE INTEGER = LONG INT; # large enough INT type #
|
||||
PROC(LONG REAL)LONG REAL size sqrt = long sqrt; # sqrt for INTEGER values #
|
||||
|
||||
[]INTEGER multipliers = ( 1, 3, 5, 7, 11, 3 * 5, 3 * 7, 3 * 11
|
||||
, 5 * 7, 5 * 11, 7 * 11, 3 * 5 * 7, 3 * 5 * 11
|
||||
, 3 * 7 * 11, 5 * 7 * 11, 3 * 5 * 7 * 11
|
||||
);
|
||||
PROC gcd = ( INTEGER x, y )INTEGER: # iterative gcd #
|
||||
BEGIN
|
||||
INTEGER a := x, b := y;
|
||||
WHILE b /= 0 DO
|
||||
INTEGER next a = b;
|
||||
b := a MOD b;
|
||||
a := next a
|
||||
OD;
|
||||
ABS a
|
||||
END # gcd # ;
|
||||
|
||||
PROC squfof = ( INTEGER n )INTEGER:
|
||||
IF INTEGER s = ENTIER ( size sqrt( n ) + 0.5 );
|
||||
s * s = n
|
||||
THEN s
|
||||
ELSE INTEGER result := 0;
|
||||
FOR multiplier FROM LWB multipliers TO UPB multipliers WHILE result = 0 DO
|
||||
INTEGER d = n * multipliers[ multiplier ];
|
||||
INTEGER pp := ENTIER size sqrt( d );
|
||||
INTEGER p prev := pp;
|
||||
INTEGER po = p prev;
|
||||
INTEGER q prev := 1;
|
||||
INTEGER qq := d - ( po * po );
|
||||
INTEGER l = ENTIER size sqrt( s * 8 );
|
||||
INTEGER bb = 3 * l;
|
||||
INTEGER i := 2;
|
||||
INTEGER b := 0;
|
||||
INTEGER q := 0;
|
||||
INTEGER r := 0;
|
||||
BOOL again := TRUE;
|
||||
WHILE i < bb AND again DO
|
||||
b := ( po + pp ) OVER qq;
|
||||
pp := ( b * qq ) - pp;
|
||||
q := qq;
|
||||
qq := q prev + ( b * ( p prev - pp ) );
|
||||
r := ENTIER ( size sqrt( qq ) + 0.5 );
|
||||
IF i MOD 2 = 0 THEN again := r * r /= qq FI;
|
||||
IF again THEN
|
||||
q prev := q;
|
||||
p prev := pp;
|
||||
i +:= 1
|
||||
FI
|
||||
OD;
|
||||
IF i < bb THEN
|
||||
b := ( po - pp ) OVER r;
|
||||
p prev := pp := ( b * r ) + pp;
|
||||
q prev := r;
|
||||
qq := ( d - ( p prev * p prev ) ) OVER q prev;
|
||||
i := 0;
|
||||
WHILE
|
||||
b := ( po + pp ) OVER qq;
|
||||
p prev := pp;
|
||||
pp := ( b * qq ) - pp;
|
||||
q := qq;
|
||||
qq := q prev + ( b * ( p prev - pp ) );
|
||||
q prev := q;
|
||||
i +:= 1;
|
||||
pp /= p prev
|
||||
DO SKIP OD
|
||||
FI;
|
||||
r := gcd( n, q prev );
|
||||
IF r /= 1 AND r /=n THEN result := r FI
|
||||
OD;
|
||||
result
|
||||
FI # squfof # ;
|
||||
|
||||
[]INTEGER examples = ( 2501, 12851
|
||||
, 13289, 75301
|
||||
, 120787, 967009
|
||||
, 997417, 7091569
|
||||
, 13290059, 42854447
|
||||
, 223553581, 2027651281
|
||||
, 11111111111, 100895598169
|
||||
, 1002742628021, 60012462237239
|
||||
, 287129523414791, 9007199254740931
|
||||
, 11111111111111111, 314159265358979323
|
||||
, 384307168202281507, 419244183493398773
|
||||
, 658812288346769681, 922337203685477563
|
||||
, 1000000000000000127, 1152921505680588799
|
||||
, 1537228672809128917, 4611686018427387877
|
||||
);
|
||||
|
||||
print( ( "Integer Factor Quotient", newline ) );
|
||||
print( ( "----------------------------------------", newline ) );
|
||||
FOR example FROM LWB examples TO UPB examples DO
|
||||
INTEGER n = examples[ example ];
|
||||
INTEGER fact = squfof( n );
|
||||
STRING quot = IF fact = 0 THEN "fail" ELSE whole( n OVER fact, 0 ) FI;
|
||||
print( ( whole( n, -20 ), " ", whole( fact, -10 ), " ", quot, newline ) )
|
||||
OD
|
||||
END
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <random>
|
||||
|
||||
uint64_t test_value = 0;
|
||||
uint64_t sqrt_test_value = 0;
|
||||
|
||||
class BQF { // Binary quadratic form
|
||||
public:
|
||||
BQF(const uint64_t& a, const uint64_t& b, const uint64_t& c) : a(a), b(b), c(c) {
|
||||
q = ( sqrt_test_value + b ) / c;
|
||||
bb = q * c - b;
|
||||
}
|
||||
|
||||
BQF rho() {
|
||||
return BQF(c, bb, a + q * ( b - bb ));
|
||||
}
|
||||
|
||||
BQF rho_inverse() {
|
||||
return BQF(c, bb, ( test_value - bb * bb ) / c);
|
||||
}
|
||||
|
||||
uint64_t a, b, c;
|
||||
private:
|
||||
uint64_t q, bb;
|
||||
};
|
||||
|
||||
uint64_t squfof(const uint64_t& number) {
|
||||
const uint32_t sqrt = std::sqrt(number);
|
||||
if ( sqrt * sqrt == number ) {
|
||||
return sqrt;
|
||||
}
|
||||
|
||||
test_value = number;
|
||||
sqrt_test_value = std::sqrt(test_value);
|
||||
|
||||
// Principal form
|
||||
BQF form(0, sqrt_test_value, 1);
|
||||
form = form.rho_inverse();
|
||||
|
||||
// Search principal cycle
|
||||
for ( uint32_t i = 0; i < 4 * std::sqrt(2 * sqrt_test_value); i += 2 ) {
|
||||
// Even step
|
||||
form = form.rho();
|
||||
|
||||
uint64_t sqrt_c = std::sqrt(form.c);
|
||||
if ( sqrt_c * sqrt_c == form.c ) { // Square form found
|
||||
// Inverse square root
|
||||
BQF form_inverse(0, -form.b, sqrt_c);
|
||||
form_inverse = form_inverse.rho_inverse();
|
||||
|
||||
// Search ambiguous cycle
|
||||
uint64_t previous_b = 0;
|
||||
do {
|
||||
previous_b = form_inverse.b;
|
||||
form_inverse = form_inverse.rho();
|
||||
} while ( form_inverse.b != previous_b );
|
||||
|
||||
// Symmetry point
|
||||
const uint64_t g = std::gcd(number, form_inverse.a);
|
||||
if ( g != 1 ) {
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
// Odd step
|
||||
form = form.rho();
|
||||
}
|
||||
|
||||
if ( number % 2 == 0 ) {
|
||||
return 2;
|
||||
}
|
||||
return 0; // Failed to factorise, possibly a prime number
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::random_device random;
|
||||
std::mt19937 generator(random());
|
||||
const uint64_t lower_limit = 100'000'000'000'000'000;
|
||||
std::uniform_int_distribution<uint64_t> distribution(lower_limit, 10 * lower_limit);
|
||||
|
||||
for ( uint32_t i = 0; i < 20; ++i ) {
|
||||
uint64_t test = distribution(random);
|
||||
uint64_t factor = squfof(test);
|
||||
|
||||
if ( factor == 0 ) {
|
||||
std::cout << test << " - failed to factorise" << std::endl;
|
||||
} else {
|
||||
std::cout << test << " = " << factor << " * " << test / factor << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
multiplier[] = [ 1 3 5 7 11 3 * 5 3 * 7 3 * 11 5 * 7 5 * 11 7 * 11 3 * 5 * 7 3 * 5 * 11 3 * 7 * 11 5 * 7 * 11 3 * 5 * 7 * 11 ]
|
||||
func gcd a b .
|
||||
while b <> 0
|
||||
a = a mod b
|
||||
swap a b
|
||||
.
|
||||
return a
|
||||
.
|
||||
func squfof N .
|
||||
s = floor (sqrt N + 0.5)
|
||||
if s * s = N
|
||||
return s
|
||||
.
|
||||
for multiplier in multiplier[]
|
||||
if N > 9007199254740992 / multiplier
|
||||
print "Number " & N & " is too big"
|
||||
break 1
|
||||
.
|
||||
D = multiplier * N
|
||||
P = floor sqrt D
|
||||
Po = P
|
||||
Pprev = P
|
||||
Qprev = 1
|
||||
Q = D - Po * Po
|
||||
L = 2 * floor sqrt (2 * s)
|
||||
B = 3 * L
|
||||
for i = 2 to B - 1
|
||||
b = (Po + P) div Q
|
||||
P = b * Q - P
|
||||
q = Q
|
||||
Q = Qprev + b * (Pprev - P)
|
||||
r = floor (sqrt Q + 0.5)
|
||||
if i mod 2 = 0 and r * r = Q
|
||||
break 1
|
||||
.
|
||||
Qprev = q
|
||||
Pprev = P
|
||||
.
|
||||
if i < B
|
||||
b = (Po - P) div r
|
||||
P = b * r + P
|
||||
Pprev = P
|
||||
Qprev = r
|
||||
Q = (D - Pprev * Pprev) / Qprev
|
||||
i = 0
|
||||
repeat
|
||||
b = (Po + P) div Q
|
||||
Pprev = P
|
||||
P = b * Q - P
|
||||
q = Q
|
||||
Q = Qprev + b * (Pprev - P)
|
||||
Qprev = q
|
||||
i += 1
|
||||
until P = Pprev
|
||||
.
|
||||
r = gcd N Qprev
|
||||
if r <> 1 and r <> N
|
||||
return r
|
||||
.
|
||||
.
|
||||
.
|
||||
return 0
|
||||
.
|
||||
data[] = [ 2501 12851 13289 75301 120787 967009 997417 7091569 13290059 42854447 223553581 2027651281 11111111111 100895598169 1002742628021 60012462237239 287129523414791 9007199254740931 ]
|
||||
for example in data[]
|
||||
factor = squfof example
|
||||
if factor = 0
|
||||
print example & " was not factored."
|
||||
else
|
||||
quotient = example / factor
|
||||
print example & " has factors " & factor & " " & quotient
|
||||
.
|
||||
.
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public final class SquareFormFactorization {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
final long lowerLimit = 10_000_000_000_000_000L;
|
||||
final List<Long> tests = random.longs(20, lowerLimit, 10 * lowerLimit).boxed().toList();
|
||||
|
||||
for ( long test : tests ) {
|
||||
long factor = squfof(test);
|
||||
|
||||
if ( factor == 0 ) {
|
||||
System.out.println(test + " - failed to factorise");
|
||||
} else if ( factor == 1 ) {
|
||||
System.out.println(test + " is a prime number");
|
||||
} else {
|
||||
System.out.println(test + " = " + factor + " * " + test / factor);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private static long squfof(long number) {
|
||||
if ( BigInteger.valueOf(number).isProbablePrime(15) ) {
|
||||
return 1; // Prime number
|
||||
}
|
||||
|
||||
final int sqrt = (int) Math.sqrt(number);
|
||||
if ( sqrt * sqrt == number ) {
|
||||
return sqrt;
|
||||
}
|
||||
|
||||
testValue = number;
|
||||
sqrtTestValue = (long) Math.sqrt(testValue);
|
||||
|
||||
// Principal form
|
||||
BQF form = new BQF(0, sqrtTestValue, 1);
|
||||
form = form.rhoInverse();
|
||||
|
||||
// Search principal cycle
|
||||
for ( int i = 0; i < 4 * (long) Math.sqrt(2 * sqrtTestValue); i += 2 ) {
|
||||
// Even step
|
||||
form = form.rho();
|
||||
|
||||
long sqrtC = (long) Math.sqrt(form.c);
|
||||
if ( sqrtC * sqrtC == form.c ) { // Square form found
|
||||
// Inverse square root
|
||||
BQF formInverse = new BQF(0, -form.b, sqrtC);
|
||||
formInverse = formInverse.rhoInverse();
|
||||
|
||||
// Search ambiguous cycle
|
||||
long previousB = 0;
|
||||
do {
|
||||
previousB = formInverse.b;
|
||||
formInverse = formInverse.rho();
|
||||
} while ( formInverse.b != previousB );
|
||||
|
||||
// Symmetry point
|
||||
final long gcd = gcd(number, formInverse.a);
|
||||
if ( gcd != 1 ) {
|
||||
return gcd;
|
||||
}
|
||||
}
|
||||
|
||||
// Odd step
|
||||
form = form.rho();
|
||||
}
|
||||
|
||||
if ( number % 2 == 0 ) {
|
||||
return 2;
|
||||
}
|
||||
return 0; // Failed to factorise
|
||||
}
|
||||
|
||||
private static long gcd(long a, long b) {
|
||||
while ( b != 0 ) {
|
||||
long temp = a; a = b; b = temp % b;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
private static class BQF { // Binary quadratic form
|
||||
|
||||
public BQF(long aA, long aB, long aC) {
|
||||
a = aA; b = aB; c = aC;
|
||||
q = ( sqrtTestValue + b ) / c;
|
||||
bb = q * c - b;
|
||||
}
|
||||
|
||||
public BQF rho() {
|
||||
return new BQF(c, bb, a + q * ( b - bb ));
|
||||
}
|
||||
|
||||
public BQF rhoInverse() {
|
||||
return new BQF(c, bb, ( testValue - bb * bb ) / c);
|
||||
}
|
||||
|
||||
private long a, b, c;
|
||||
private long q, bb;
|
||||
|
||||
}
|
||||
|
||||
private static long testValue, sqrtTestValue;
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue