#ifdef MPQS_DEBUG_VERYVERBOSE
# ifndef MPQS_DEBUG_VERBOSE
# define MPQS_DEBUG_VERBOSE
# endif
#endif
#ifdef MPQS_DEBUG_VERBOSE
# ifndef MPQS_DEBUG
# define MPQS_DEBUG
# endif
# define PRINT_IF_VERBOSE(x) err_printf(x)
#else
# define PRINT_IF_VERBOSE(x)
#endif
#ifdef MPQS_DEBUG
# define MPQS_DEBUGLEVEL 1000
#else
# define MPQS_DEBUGLEVEL DEBUGLEVEL
#endif
#ifndef SEEK_SET
# define SEEK_SET 0
#endif
#ifdef __CYGWIN32__
# define WRITE "wb"
# define READ "rb"
#else
# define WRITE "w"
# define READ "r"
#endif
#define MPQS_STRING_LENGTH (4 * 1024UL)
#define MPQS_POSSIBLE_MULTIPLIERS 5
#define MPQS_MULTIPLIER_SEARCH_DEPTH 5
#define MPQS_LP_BOUND 12500000
#define MPQS_A_FUDGE 0.15
#define MPQS_CANDIDATE_ARRAY_SIZE 2000
#ifdef MPQS_USE_HISTOGRAMS
# define MPQS_MIN_SIZE_FB_FOR_HISTO 600
# define MPQS_MIN_CANDS_FOR_HISTO 4000
# define MPQS_MIN_FRELS_FOR_HISTO 110
# define MPQS_HISTO_FREL_QUANTILE 2.4
# define MPQS_HISTO_DROP_LIMIT 3.6
# define MPQS_HISTO_LPREL_BASEFLOW 1.4
#endif
#define MPQS_ADMIT_DEFEAT 1500
#ifdef LONG_IS_64BIT
typedef int mpqs_int32_t;
typedef unsigned int mpqs_uint32_t;
typedef ulong mpqs_uint64_t;
#else
typedef long mpqs_int32_t;
typedef ulong mpqs_uint32_t;
typedef struct {
ulong _w0;
ulong _w1;
} mpqs_uint64_t;
#endif
typedef union mpqs_invp {
ulong _ul;
mpqs_uint64_t _u64;
} mpqs_invp_t;
#define MPQS_FB_ENTRY_PAD 32
typedef union mpqs_FB_entry {
char __pad[MPQS_FB_ENTRY_PAD];
struct {
mpqs_int32_t __p;
float __flogp;
mpqs_invp_t __invp;
mpqs_int32_t __start1;
mpqs_int32_t __start2;
mpqs_uint32_t __sqrt_kN;
unsigned char __val;
unsigned char __flags;
} __entry;
} mpqs_FB_entry_t;
#define fbe_p __entry.__p
#define fbe_flogp __entry.__flogp
#define fbe_invp __entry.__invp
#define fbe_start1 __entry.__start1
#define fbe_start2 __entry.__start2
#define fbe_sqrt_kN __entry.__sqrt_kN
#define fbe_logval __entry.__val
#define fbe_flags __entry.__flags
#define MPQS_FBE_CLEAR 0x0
#define MPQS_FBE_DIVIDES_A 0x1ul
#define MPQS_MAX_OMEGA_K 2
typedef struct mpqs_multiplier {
mpqs_uint32_t k;
mpqs_uint32_t omega_k;
mpqs_uint32_t kp[MPQS_MAX_OMEGA_K];
} mpqs_multiplier_t;
static const mpqs_multiplier_t cand_multipliers[] = {
{ 1, 0, { 0, 0} },
{ 3, 1, { 3, 0} },
{ 5, 1, { 5, 0} },
{ 7, 1, { 7, 0} },
{ 11, 1, { 11, 0} },
{ 13, 1, { 13, 0} },
{ 15, 2, { 3, 5} },
{ 17, 1, { 17, 0} },
{ 19, 1, { 19, 0} },
{ 21, 2, { 3, 7} },
{ 23, 1, { 23, 0} },
{ 29, 1, { 29, 0} },
{ 31, 1, { 31, 0} },
{ 33, 2, { 3, 11} },
{ 35, 2, { 5, 7} },
{ 37, 1, { 37, 0} },
{ 39, 2, { 3, 13} },
{ 41, 1, { 41, 0} },
{ 43, 1, { 43, 0} },
{ 47, 1, { 47, 0} },
{ 51, 2, { 3, 17} },
{ 53, 1, { 53, 0} },
{ 55, 2, { 5, 11} },
{ 57, 2, { 3, 19} },
{ 59, 1, { 59, 0} },
{ 61, 1, { 61, 0} },
{ 65, 2, { 5, 13} },
{ 67, 1, { 67, 0} },
{ 69, 2, { 3, 23} },
{ 71, 1, { 71, 0} },
{ 73, 1, { 73, 0} },
{ 77, 2, { 7, 11} },
{ 79, 1, { 79, 0} },
{ 83, 1, { 83, 0} },
{ 85, 2, { 5, 17} },
{ 87, 2, { 3, 29} },
{ 89, 1, { 89, 0} },
{ 91, 2, { 7, 13} },
{ 93, 2, { 3, 31} },
{ 95, 2, { 5, 19} },
{ 97, 1, { 97, 0} }
};
typedef struct mqps_per_A_prime {
GEN _H;
mpqs_int32_t _i;
} mpqs_per_A_prime_t;
#define MPQS_H(i) (per_A_pr[i]._H)
#define MPQS_I(i) (per_A_pr[i]._i)
#define MPQS_AP(i) (FB[per_A_pr[i]._i].fbe_p)
#define MPQS_LP(i) (FB[per_A_pr[i]._i].fbe_flogp)
#define MPQS_SQRT(i) (FB[per_A_pr[i]._i].fbe_sqrt_kN)
#define MPQS_FLG(i) (FB[per_A_pr[i]._i].fbe_flags)
#define MPQS_MAX_OMEGA_A 17
typedef struct mpqs_inv_A_H {
mpqs_uint32_t _i[MPQS_MAX_OMEGA_A - 1];
} mpqs_inv_A_H_t;
#define MPQS_INV_A_H(i,j) (inv_A_H[j]._i[i])
typedef struct mpqs_handle {
unsigned char *sieve_array;
unsigned char *sieve_array_end;
mpqs_FB_entry_t *FB;
long *candidates;
char *relations;
long *relaprimes;
mpqs_inv_A_H_t *inv_A_H;
mpqs_per_A_prime_t *per_A_pr;
mpqs_int32_t M;
mpqs_int32_t size_of_FB;
mpqs_int32_t index0_FB;
mpqs_int32_t index1_FB;
mpqs_int32_t index2_FB;
unsigned char index2_moved;
unsigned char sieve_threshold;
#ifdef MPQS_USE_HISTOGRAMS
unsigned char do_histograms;
unsigned char done_histograms;
long *histo_full;
long *histo_lprl;
long *histo_drop;
#endif
GEN N;
GEN kN;
GEN A;
GEN B;
#ifdef MPQS_DEBUG
GEN C;
#endif
mpqs_int32_t omega_A;
mpqs_int32_t no_B;
double l2_target_A;
mpqs_uint32_t bin_index;
mpqs_uint32_t index_i;
mpqs_uint32_t index_j;
mpqs_int32_t target_no_rels;
mpqs_int32_t largest_FB_p;
mpqs_int32_t pmin_index1;
mpqs_int32_t lp_scale;
mpqs_int32_t first_sort_point;
mpqs_int32_t sort_pt_interval;
long lp_bound;
long digit_size_N;
long digit_size_kN;
const mpqs_multiplier_t *_k;
double tolerance;
double dkN;
double l2sqrtkN;
double l2M;
void *FB_chunk;
void *invAH_chunk;
} mpqs_handle_t;
typedef struct mpqs_parameterset {
float tolerance;
mpqs_int32_t lp_scale;
mpqs_int32_t M;
mpqs_int32_t size_of_FB;
mpqs_int32_t omega_A;
mpqs_int32_t pmin_index1;
mpqs_int32_t first_sort_point;
mpqs_int32_t sort_pt_interval;
} mpqs_parameterset_t;
static const mpqs_parameterset_t mpqs_parameters[] =
{
{ 0.8, 1, 900, 20, 3, 5, 70, 8},
{ 0.8, 1, 900, 21, 3, 5, 70, 8},
{ 0.8, 1, 920, 22, 3, 5, 70, 6},
{ 0.8, 1, 960, 24, 3, 5, 70, 6},
{ 0.8, 1, 1020, 26, 3, 5, 70, 6},
{ 0.8, 1, 1100, 29, 3, 5, 70, 6},
{ 0.8, 1, 1200, 32, 3, 5, 60, 8},
{ 0.8, 1, 1500, 35, 3, 5, 60, 8},
{ 0.8, 1, 1900, 40, 3, 5, 60, 8},
{ 0.8, 1, 2500, 60, 3, 5, 50, 10},
{ 0.8, 1, 3200, 80, 3, 5, 50, 10},
{ 0.8, 1, 4000, 100, 3, 5, 40, 10},
{ 0.8, 1, 4300, 100, 3, 5, 40, 10},
{ 0.8, 1, 4500, 120, 3, 5, 40, 10},
{ 0.8, 1, 4800, 140, 3, 5, 30, 10},
{ 0.8, 1, 5100, 160, 4, 7, 30, 10},
{ 0.8, 1, 5400, 180, 4, 7, 30, 10},
{ 0.9, 1, 5700, 200, 4, 7, 30, 10},
{ 1.12, 1, 6000, 220, 4, 7, 30, 10},
{ 1.17, 1, 6300, 240, 4, 11, 30, 10},
{ 1.22, 1, 6500, 260, 4, 11, 30, 10},
{ 1.30, 1, 6800, 325, 4, 11, 20, 10},
{ 1.33, 1, 7000, 355, 4, 13, 20, 10},
{ 1.36, 1, 7200, 375, 5, 13, 20, 10},
{ 1.40, 1, 7400, 400, 5, 13, 20, 10},
{ 1.43, 1, 7600, 425, 5, 17, 20, 10},
{ 1.48, 30, 7800, 550, 5, 17, 20, 10},
{ 1.53, 45, 8100, 650, 5, 17, 20, 10},
{ 1.60, 60, 9000, 750, 6, 19, 20, 10},
{ 1.66, 70, 10000, 850, 6, 19, 20, 10},
{ 1.69, 80, 11000, 950, 6, 23, 20, 10},
{ 1.69, 80, 12500, 1000, 6, 23, 20, 10},
{ 1.69, 80, 14000, 1150, 6, 23, 10, 10},
{ 1.69, 80, 15000, 1300, 6, 29, 10, 10},
{ 1.69, 80, 16000, 1500, 6, 29, 10, 10},
{ 1.69, 80, 17000, 1700, 7, 31, 10, 10},
{ 1.69, 80, 18000, 1900, 7, 31, 10, 10},
{ 1.69, 80, 20000, 2100, 7, 37, 10, 10},
{ 1.69, 80, 25000, 2300, 7, 37, 10, 10},
{ 1.69, 80, 27500, 2500, 7, 37, 10, 10},
{ 1.72, 80, 30000, 2700, 7, 41, 10, 10},
{ 1.75, 80, 35000, 2900, 7, 41, 10, 10},
{ 1.80, 80, 40000, 3000, 7, 43, 10, 10},
{ 1.85, 80, 50000, 3200, 7, 43, 10, 10},
{ 1.90, 80, 60000, 3500, 7, 47, 10, 10},
{ 1.95, 80, 70000, 3800, 7, 47, 10, 10},
{ 1.95, 80, 80000, 4100, 7, 53, 10, 10},
{ 1.95, 80, 90000, 4400, 7, 53, 10, 8},
{ 2.00, 80, 100000, 4700, 8, 53, 10, 8},
{ 2.05, 80, 110000, 5000, 8, 59, 10, 8},
{ 2.10, 80, 120000, 5400, 8, 59, 10, 8},
{ 2.15, 80, 130000, 5800, 8, 61, 10, 8},
{ 2.20, 80, 140000, 6100, 8, 61, 10, 8},
{ 2.25, 80, 150000, 6400, 8, 67, 10, 6},
{ 2.39, 80, 160000, 6700, 8, 67, 10, 6},
{ 2.30, 80, 165000, 7000, 8, 67, 10, 6},
{ 2.31, 80, 170000, 7300, 8, 71, 10, 6},
{ 2.32, 80, 175000, 7600, 8, 71, 10, 6},
{ 2.33, 80, 180000, 7900, 8, 73, 10, 6},
{ 2.34, 80, 185000, 8200, 8, 73, 10, 6},
{ 2.35, 80, 190000, 8600, 8, 79, 8, 6},
{ 2.36, 80, 195000, 8800, 8, 79, 8, 6},
{ 2.37, 80, 200000, 9000, 9, 79, 8, 6},
{ 2.38, 80, 205000, 9250, 9, 83, 5, 5},
{ 2.41, 80, 210000, 9500, 9, 83, 5, 5},
{ 2.46, 80, 220000, 9750, 9, 83, 5, 5},
{ 2.51, 80, 230000, 10000, 9, 89, 5, 5},
{ 2.56, 80, 240000, 10500, 9, 89, 5, 5},
{ 2.58, 80, 250000, 11200, 9, 89, 5, 5},
{ 2.60, 80, 260000, 12500, 9, 89, 5, 5},
{ 2.63, 80, 270000, 14000, 9, 97, 5, 4},
{ 2.65, 80, 280000, 15500, 9, 97, 5, 4},
{ 2.72, 80, 300000, 17000, 9, 97, 4, 4},
{ 2.77, 80, 320000, 18500, 9, 101, 4, 4},
{ 2.82, 80, 340000, 20000, 10, 101, 4, 4},
{ 2.84, 80, 360000, 21500, 10, 103, 4, 4},
{ 2.86, 80, 400000, 23000, 10, 103, 4, 3},
{ 2.88, 80, 460000, 24500, 10, 107, 4, 3},
{ 2.90, 80, 520000, 26000, 10, 107, 4, 3},
{ 2.91, 80, 580000, 27500, 10, 109, 4, 3},
{ 2.92, 80, 640000, 29000, 10, 109, 4, 3},
{ 2.93, 80, 700000, 30500, 10, 113, 2, 2},
{ 2.94, 80, 770000, 32200, 10, 113, 2, 2},
{ 3.6, 90, 2000000, 35000, 9, 113, 2, 2},
{ 3.7, 90, 2000000, 37000, 9, 113, 2, 2},
{ 3.7, 90, 2000000, 39500, 9, 127, 2, 2},
{ 3.7, 90, 2500000, 41500, 9, 127, 2, 2},
{ 3.8, 90, 2500000, 45000, 10, 127, 2, 2},
{ 3.8, 90, 2500000, 47500, 10, 131, 2, 2},
{ 3.7, 90, 3000000, 51000, 10, 131, 2, 2},
{ 3.8, 90, 3000000, 53000, 10, 133, 2, 2},
{ 3.8, 90, 3500000, 51000, 10, 133, 2, 2},
{ 3.8, 90, 3500000, 54000, 10, 139, 2, 2},
{ 3.8, 90, 3500000, 57000, 10, 139, 2, 2},
{ 3.9, 90, 4000000, 61000, 10, 139, 2, 2},
{ 3.9, 90, 4000000, 66000, 10, 149, 2, 2},
{ 3.9, 90, 4000000, 70000, 10, 149, 2, 2},
{ 3.9, 90, 4000000, 75000, 10, 151, 2, 2},
{ 3.9, 90, 4000000, 80000, 10, 151, 2, 2},
};
#define MPQS_MAX_DIGIT_SIZE_KN 107