ratpoints-2.1.3/0000755000175000001440000000000011536145472013001 5ustar mstollusersratpoints-2.1.3/rptest.c0000644000175000001440000002147411536145472014476 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.3 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009, 2011 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * rptest.c * * * * Test program for ratpoints * * * * Michael Stoll, May 27, 2009 * * + fixed a small bug that could cause a segfault * * (pointed out by Giovanni Mascellani and Randall Rathbun) * * MS, Mar 10, 2011 * ***********************************************************************/ #include #include #include "ratpoints.h" #include "testdata.h" mpz_t c[RATPOINTS_MAX_DEGREE+1]; /* The coefficients of f */ ratpoints_interval domain[2*RATPOINTS_MAX_DEGREE]; /************************************************************************** * function that processes the points * **************************************************************************/ typedef struct {int print_between; int no_output; int one_point; int no_y;} data; int process(long a, long b, const mpz_t y, void *info0, int *quit) { data *info = (data *)info0; *quit = 0; if(info->no_output) return(1); if(info->print_between) { printf(","); } else { info->print_between = 1; } printf("[%ld,", a); mpz_out_str((FILE *)NULL, 10, y); printf(",%ld]", b); return(1); } int main(int argc, char *argv[]) { long total, n; ratpoints_args args; long degree = 6; long height = 16383; long sieve_primes1 = RATPOINTS_DEFAULT_SP1; long sieve_primes2 = RATPOINTS_DEFAULT_SP2; long num_primes = RATPOINTS_DEFAULT_NUM_PRIMES; long max_forbidden = RATPOINTS_DEFAULT_MAX_FORBIDDEN; long b_low = 1; long b_high = height; long sturm_iter = RATPOINTS_DEFAULT_STURM; long array_size = RATPOINTS_ARRAY_SIZE; int no_check = 0; int no_y = 0; int no_reverse = 0; int no_jacobi = 0; int no_output = 0; unsigned int flags = 0; data *info = malloc(sizeof(data)); /* initialize multi-precision integer variables */ for(n = 0; n <= degree; n++) { mpz_init(c[n]); } /************************************************************************** * get at the input * **************************************************************************/ /* recognize optional args */ { long i = 1; while(i < argc) { if(*(argv[i]) != '-') return(-6); switch(argv[i][1]) { case 'h': /* height bound */ if(argc == i) return(-6); i++; if(sscanf(argv[i], " %ld", &height) != 1) return(-6); i++; break; case 'p': /* max number of primes used */ if(argc == i) return(-6); i++; if(sscanf(argv[i], " %ld", &num_primes) != 1) return(-6); i++; break; case 'F': /* max number of "forbidden divisors of denominator" */ if(argc == i) return(-6); i++; if(sscanf(argv[i], " %ld", &max_forbidden) != 1) return(-6); i++; break; case 'n': /* number of primes used for first stage of sieving */ if(argc == i) return(-6); i++; if(sscanf(argv[i], " %ld", &sieve_primes1) != 1) return(-6); i++; break; case 'N': /* number of primes used for sieving altogether */ if(argc == i) return(-6); i++; if(sscanf(argv[i], " %ld", &sieve_primes2) != 1) return(-6); i++; break; case 'j': /* do not use Jacobi sum test */ no_jacobi = 1; i++; break; case 'J': /* do use Jacobi sum test */ no_jacobi = 0; i++; break; case 'k': /* keep: do not reverse polynomial */ no_reverse = 1; i++; break; case 'K': /* allow reversal of polynomial */ no_reverse = 1; i++; break; case 'x': /* no check */ no_check = 1; i++; break; case 'X': /* do check points */ no_check = 1; i++; break; case 'y': /* no y */ no_y = 1; i++; break; case 'Y': /* print complete points */ no_y = 1; i++; break; case 'z': /* no output */ no_output = 1; i++; break; case 'Z': /* do print points */ no_output = 1; i++; break; case 's': /* no Sturm sequence computation */ sturm_iter = -1; i++; break; case 'S': /* Sturm sequence */ i++; if(i <= argc && argv[i][0] != '-') { if(sscanf(argv[i], " %ld", &sturm_iter) != 1) return(-6); i++; } else sturm_iter = RATPOINTS_DEFAULT_STURM; break; case 'd': /* Bounds for denom */ switch(argv[i][2]) { case 'l': /* lower bound */ if(argc == i) return(-6); i++; if(sscanf(argv[i], " %ld", &b_low) != 1) return(-6); i++; break; case 'u': /* upper bound */ if(argc == i) return(-6); i++; if(sscanf(argv[i], " %ld", &b_high) != 1) return(-6); i++; break; default: return(-6); } break; default: return(-6); } } } /* initialize */ args.degree = degree; /* this information is needed for the initialization */ find_points_init(&args); if(no_check) { flags |= RATPOINTS_NO_CHECK; } if(no_y) { flags |= RATPOINTS_NO_Y; } if(no_reverse) { flags |= RATPOINTS_NO_REVERSE; } if(no_jacobi) { flags |= RATPOINTS_NO_JACOBI; } for(n = 0; n < NUM_TEST; n++) { /* set up polynomial */ long k; for(k = 0; k < 7; k++) { mpz_set_si(c[k], testdata[n][k]); } /* typedef struct {mpz_t *cof; long degree; long height; ratpoints_interval *domain; long num_inter; long b_low; long b_high; long sp1; long sp2; double ratio1; double ratio2; long array_size; long sturm; long num_primes; long max_forbidden; unsigned int flags; ...} ratpoints_args; */ args.cof = &c[0]; args.degree = degree; args.height = height; args.domain = &domain[0]; args.num_inter = 0; args.b_low = b_low; args.b_high = b_high; args.sp1 = sieve_primes1; args.sp2 = sieve_primes2; args.array_size = array_size; args.sturm = sturm_iter; args.num_primes = num_primes; args.max_forbidden = max_forbidden; args.flags = flags; /* typedef struct {int print_between; int no_output; int one_point; int no_y;} data; */ info->print_between = 0; info->no_output = no_output; info->no_y = 0; if(no_output == 0) { printf("{"); } total = find_points_work(&args, process, (void *)info); if(no_output == 0) { printf("}\n"); } /* fflush(NULL); */ } /* clean up */ find_points_clear(&args); free(info); for(n = 0; n <= degree; n++) { mpz_clear(c[n]); } return(0); } ratpoints-2.1.3/rp-private.h0000644000175000001440000001355011536145472015247 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.2 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * rp-private.h * * * * Header file with information local to the ratpoints code * * * * Michael Stoll, Apr 14, 2009 * ***********************************************************************/ #include #include #include #include #define LONG_LENGTH (8*sizeof(long)) /* number of bits in an unsigned long */ #define LONG_SHIFT ((LONG_LENGTH == 16) ? 4 : \ (LONG_LENGTH == 32) ? 5 : \ (LONG_LENGTH == 64) ? 6 : 0) #define LONG_MASK (~(-1L< #define AND(a,b) ((ratpoints_bit_array)__builtin_ia32_andps((__v4sf)(a), (__v4sf)(b))) #define EXT0(a) ((unsigned long)__builtin_ia32_vec_ext_v2di((__v2di)(a), 0)) #define EXT1(a) ((unsigned long)__builtin_ia32_vec_ext_v2di((__v2di)(a), 1)) #define TEST(a) (EXT0(a) || EXT1(a)) #define RBA(a,b) ((__v2di){(a), (b)}) /* Use SSE 128 bit registers for the bit arrays */ typedef __v2di ratpoints_bit_array; #define zero (RBA(0LL, 0LL)) #define RBA_LENGTH (128) /* number of bits in a ratpoints_bit_array */ #define RBA_SHIFT ((RBA_LENGTH == 128) ? 7 : 0) #define RBA_MASK (~(-1L<. * ***********************************************************************/ /*********************************************************************** * main.c * * * * Main program file for the ratpoints executable * * * * Michael Stoll, May 27, 2009 * ***********************************************************************/ #include #include #include #include "ratpoints.h" /************************************************************************** * define * **************************************************************************/ #define RATPOINTS_VERSION \ "This is ratpoints-2.1.3 Copyright (C) 2008,2009 by Michael Stoll.\n\n" \ "This program comes with ABSOLUTELY NO WARRANTY.\n" \ "This is free software, and you are welcome to redistribute it under the\n" \ "terms of the GNU General Public License version 2 or later.\n\n" \ "Please acknowledge use of this program in published work.\n\n" /************************************************************************** * global variables * **************************************************************************/ mpz_t c[RATPOINTS_MAX_DEGREE+1]; /* The coefficients of f */ mpz_t tmp, tmp2; int quiet; /* A flag saying whether to suppress messages */ int one_point; /* A flag saying if one point is enough */ int points_at_infty; /* A flag saying if we should look for points at infty */ int no_output; /* A flag that indicates that no points should be printed */ char *print_format; /* The printf format for printing points */ char *string_before; /* String to be printed before the points */ char *string_between;/* String to be printed between the points */ char *string_after; /* String to be printed after the points */ ratpoints_interval domain[2*RATPOINTS_MAX_DEGREE]; /* This contains the intervals representing the search region */ char *usage_str = "Usage: ratpoints 'a_0 a_1 ... a_n' max_height\n" " [-dl low_den] [-du up_den]\n" " [-f format] [-fs str] [-fm str] [-fe str] [-y] [-Y]\n" " [[-l low1] -u up1 ... -l lown [-u upn]]\n" " [-n num_primes1] [-N num_primes2] [-p max_primes]\n" " [-F max_forbidden] [-s] [-S [iter]]\n" " [-q] [-v] [-z] [-Z] [-1] [-i] [-I]\n" " [-k] [-K] [-j] [-J] [-x] [-X]\n\n"; /************************************************************************** * prototypes * **************************************************************************/ int read_input(long, char *argv[], ratpoints_args*); char *scan_mpz(char*, mpz_t); void print_poly(mpz_t*, long); void print_string(char*); void message(long n, long total, ratpoints_args *args); void error(long); /************************************************************************** * function that processes the points * **************************************************************************/ typedef struct {int print_between; int no_output; int one_point; int points_at_infty; int no_y; char *pf; char* string_before; char *string_between;} data; int process(long a, long b, const mpz_t y, void *info0, int *quit) { data *info = (data *)info0; char *fmt = info->pf; if(b == 0 && !(info->points_at_infty)) return(0); *quit = info->one_point; if(info->no_output) return(1); if(info->print_between) { print_string(info->string_between); } else { print_string(info->string_before); info->print_between = 1; } while(*fmt) { char c = *fmt++; switch(c) { case '%': c = *fmt++; switch(c) { case 0: putchar('%'); return(1); case 'x': printf("%ld", a); break; case 'y': if(info->no_y) { putchar('%'); putchar('y'); } else { mpz_out_str((FILE *)NULL, 10, y); } break; case 'z': printf("%ld", b); break; default: putchar('%'); putchar(c); break; } break; case '\\': c = *fmt++; switch(c) { case 0: putchar('\\'); return(1); case 't': printf("\t"); break; case 'n': printf("\n"); break; case '\\': putchar('\\'); break; case '%': putchar('%'); break; default: putchar('\\'); putchar(c); break; } break; default: putchar(c); break; } } fflush(stdout); return(1); } /************************************************************************** * main * **************************************************************************/ int main(int argc, char *argv[]) { long total; ratpoints_args args; { long n; /* initialise multi-precision integer variables */ for(n = 0; n <= RATPOINTS_MAX_DEGREE; n++) { mpz_init(c[n]); } } mpz_init(tmp); mpz_init(tmp2);; /* read input */ if(argc < 3) error(2); if(read_input(argc-1, &argv[0], &args)) { message(1, 0, &args); return(0); } if(!quiet) { message(0, 0, &args); message(5, args.degree, &args); if(!(args.flags & RATPOINTS_VERBOSE)) { message(6, args.height, &args); printf("\n"); } } args.array_size = RATPOINTS_ARRAY_SIZE; if(!quiet && args.num_inter > 0) message(3, 0, &args); /* typedef struct {int print_between; int no_output; int one_point; int points_at_infty; int no_y; char *pf; char* string_before; char *string_between;} data; */ { data *info = malloc(sizeof(data)); info->print_between = 0; info->no_output = no_output; info->pf = print_format; info->one_point = one_point; info->points_at_infty = points_at_infty; info->string_before = string_before; info->string_between = string_between; info->no_y = args.flags & (RATPOINTS_NO_CHECK | RATPOINTS_NO_Y); total = find_points(&args, process, (void *)info); free(info); } if(total < 0) { mpz_clear(tmp); mpz_clear(tmp2); if(total == RATPOINTS_NON_SQUAREFREE) error(8); error(9); } if(total == 0) print_string(string_before); print_string(string_after); if(!quiet) { if(!(args.flags & RATPOINTS_VERBOSE)) { printf("\n\n"); message(4, 0, &args); message(7, 0, &args); message(8, 0, &args); } message(2, total, &args); } mpz_clear(tmp); mpz_clear(tmp2); { long n; /* initialise multi-precision integer variables */ for(n = 0; n <= RATPOINTS_MAX_DEGREE; n++) { mpz_clear(c[n]); } } return(0); } /************************************************************************** * procedures * **************************************************************************/ /************************************************************************** * get at the input * **************************************************************************/ int read_input(long argc, char *argv[], ratpoints_args *args) { int l_seen = 0; /* flag for dealing with -l -u */ mpz_t fff; long num_inter = 0; /* Initialize args */ /* typedef struct {mpz_t *cof; long degree; long height; ratpoints_interval *domain; long num_inter; long b_low; long b_high; long sp1; long sp2; double ratio1; double ratio2; long array_size; long sturm; long num_primes; long max_forbidden; unsigned int flags; ...} ratpoints_args; */ args->cof = &c[0]; args->degree = 0; args->height = 0; args->domain = &domain[0]; args->num_inter = 0; /* No interval up to now */ args->b_low = 1; /* denominators go from 1 to h */ args->b_high = -1; args->sp1 = -1; /* gives default value */ args->sp2 = -1; /* gives default value */ args->array_size = RATPOINTS_ARRAY_SIZE; args->sturm = RATPOINTS_DEFAULT_STURM; args->num_primes = -1; /* gives default value */ args->max_forbidden = -1; /* gives default value */ args->flags = 0; /* do the check by default */ /* list y-coordinates by default */ /* allow reversal of polynomial */ /* use Jacobi symbol test */ mpz_init(fff); { char *s = argv[1]; long degree = 0; while((degree <= RATPOINTS_MAX_DEGREE) && (s = scan_mpz(s, c[degree]))) { degree++; } degree--; if(scan_mpz(s, fff)) error(3); if(degree == 0) error(5); args->degree = degree; } if(sscanf(argv[2], " %ld", &(args->height)) != 1 || args->height < 1) { error(4); } args->b_high = args->height; /* Set global variables to their default values */ no_output = 0; /* print points by default */ quiet = 0; /* don't be quiet */ one_point = 0; /* look for all points */ points_at_infty = 1; /* also find points at infinity */ print_format = NULL; string_before = NULL; string_between = NULL; string_after = NULL; /* recognise optional args */ { long i = 3; while(i <= argc) { if(*(argv[i]) != '-') error(6); switch(argv[i][1]) { case 'l': /* lower intevral endpoint */ if(argc == i) error(7); i++; if(l_seen) error(7); /* -l -l */ if(num_inter == RATPOINTS_MAX_DEGREE) error(7); if(sscanf(argv[i], " %lf", &domain[num_inter].low) != 1) error(7); if(num_inter > 0 && domain[num_inter-1].up >= domain[num_inter].low) error(7); i++; l_seen = 1; break; case 'u': /* upper interval endpoint */ if(argc == i) error(7); i++; if(!l_seen) { if(num_inter == 0) domain[0].low = -args->height; else error(7); /* -u -u */ } if(sscanf(argv[i], " %lf", &domain[num_inter].up) != 1) error(7); if(domain[num_inter].low > domain[num_inter].up) error(7); i++; l_seen = 0; num_inter++; break; case 'p': /* max number of primes used */ if(argc == i) error(6); i++; if(sscanf(argv[i], " %ld", &(args->num_primes)) != 1) error(6); i++; break; case 'F': /* max number of "forbidden divisors of denominator" */ if(argc == i) error(6); i++; if(sscanf(argv[i], " %ld", &(args->max_forbidden)) != 1) error(6); i++; break; case 'n': /* number of primes used for first stage of sieving */ if(argc == i) error(6); i++; if(sscanf(argv[i], " %ld", &(args->sp1)) != 1) error(6); i++; break; case 'N': /* number of primes used for sieving altogether */ if(argc == i) error(6); i++; if(sscanf(argv[i], " %ld", &(args->sp2)) != 1) error(6); i++; break; case 'f': /* printing format */ switch(argv[i][2]) { case 0: /* just -f */ if(argc == i) error(6); i++; { long l = strlen(argv[i]); print_format = malloc((l+1)*sizeof(char)); strcpy(print_format, argv[i]); } i++; break; case 's': /* starting string */ if(argc == i) error(6); i++; { long l = strlen(argv[i]); string_before = malloc((l+1)*sizeof(char)); strcpy(string_before, argv[i]); } i++; break; case 'm': /* in-between string */ if(argc == i) error(6); i++; { long l = strlen(argv[i]); string_between = malloc((l+1)*sizeof(char)); strcpy(string_between, argv[i]); } i++; break; case 'e': /* ending string */ if(argc == i) error(6); i++; { long l = strlen(argv[i]); string_after = malloc((l+1)*sizeof(char)); strcpy(string_after, argv[i]); } i++; break; default: error(6); } break; case 'q': /* quiet */ quiet = 1; i++; break; case 'v': /* verbose */ args->flags |= RATPOINTS_VERBOSE; i++; break; case 'j': /* do not use Jacobi symbol */ args->flags |= RATPOINTS_NO_JACOBI; i++; break; case 'J': /* do use Jacobi symbol */ args->flags &= ~RATPOINTS_NO_JACOBI; i++; break; case 'k': /* keep: do not reverse polynomial */ args->flags |= RATPOINTS_NO_REVERSE; i++; break; case 'K': /* allow reversal of polynomial */ args->flags &= ~RATPOINTS_NO_REVERSE; i++; break; case 'x': /* no check */ args->flags |= RATPOINTS_NO_CHECK; i++; break; case 'X': /* do check points */ args->flags &= ~RATPOINTS_NO_CHECK; i++; break; case 'y': /* print only x-coordinates */ args->flags |= RATPOINTS_NO_Y; i++; break; case 'Y': /* print all points */ args->flags |= RATPOINTS_NO_Y; i++; break; case 'z': /* no output */ no_output = 1; i++; break; case 'Z': /* output the points */ no_output = 0; i++; break; case '1': /* only one point */ one_point = 1; i++; break; case 'i': /* no points at infty */ points_at_infty = 0; i++; break; case 'I': /* print points at infty */ points_at_infty = 1; i++; break; case 's': /* don't use Sturm sequence computation */ args->sturm = -1; i++; break; case 'S': /* Sturm sequence */ args->sturm = RATPOINTS_DEFAULT_STURM; i++; if(i <= argc && argv[i][0] != '-') { if(sscanf(argv[i], " %ld", &(args->sturm)) != 1) error(6); i++; } break; case 'd': /* Bounds for denom */ switch(argv[i][2]) { case 'l': /* lower bound */ if(argc == i) error(6); i++; if(sscanf(argv[i], " %ld", &(args->b_low)) != 1) error(6); i++; break; case 'u': /* upper bound */ if(argc == i) error(6); i++; if(sscanf(argv[i], " %ld", &(args->b_high)) != 1) error(6); i++; break; default: error(6); } break; default: error(6); } } } if(l_seen) /* complete last interval */ { domain[num_inter].up = args->height; num_inter++; } args->num_inter = num_inter; if(!print_format) /* default print format */ { print_format = (args->flags & (RATPOINTS_NO_CHECK | RATPOINTS_NO_Y)) ? "(%x : %z)\n" : "(%x : %y : %z)\n"; } if(quiet) { args->flags &= ~RATPOINTS_VERBOSE; } mpz_clear(fff); return(0); } /* Read in a long long long integer. */ char *scan_mpz(char *s, mpz_t x) { long neg = 0; if(s == NULL || *s == 0) return NULL; while(*s == ' ') s++; if(*s == 0) return NULL; if(*s == '-') {neg = 1; s++;} else if(*s == '+') s++; mpz_set_si(tmp2, 0); while('0' <= *s && *s <= '9') { mpz_mul_ui(tmp2, tmp2, 10); mpz_add_ui(tmp2, tmp2, (long)(*s - '0')); s++; } if(neg) mpz_neg(tmp2, tmp2); mpz_set(x, tmp2); return s; } /************************************************************************** * output routines * **************************************************************************/ void print_poly(mpz_t *coeffs, long degree) { int flag = 0; int i; char *s; for(i = degree; i >= 0; i--) { mpz_set(tmp, coeffs[i]); if(mpz_cmp_si(tmp, 0) != 0) { if(mpz_cmp_si(tmp, 0) > 0) { printf(flag ? " + " : ""); } else { printf(flag ? " - " : "- "); mpz_neg(tmp, tmp); } flag = 1; switch(i) { case 0: s = mpz_get_str((char *) 0, 10, tmp); printf("%s", s); free(s); break; case 1: if(mpz_cmp_si(tmp, 1) == 0) { printf("x"); } else { s = mpz_get_str((char *) 0, 10, tmp); printf("%s x", s); free(s); } break; default: if(mpz_cmp_si(tmp, 1) == 0) { printf("x^%d", i); } else { s = mpz_get_str((char *) 0, 10, tmp); printf("%s x^%d", s, i); free(s); } break; } } } printf("\n"); fflush(stdout); } void print_string(char *str) { if(str) { while(*str) { char c = *str++; if(c == '\\') { c = *str++; switch(c) { case 0: putchar('\\'); return; case 't': printf("\t"); break; case 'n': printf("\n"); break; case '\\': putchar('\\'); break; case '%': putchar('%'); break; default: putchar('\\'); putchar(c); break; } } else putchar(c); } } } void message(long n, long total, ratpoints_args *args) { switch(n) { case 0: printf("\n%s\n", RATPOINTS_VERSION); break; case 1: printf("\n%s\n%s", RATPOINTS_VERSION, usage_str); break; case 2: if(args->flags & (RATPOINTS_NO_CHECK | RATPOINTS_NO_Y)) { printf("\n%ld rational point pairs found.\n\n", total); } else { printf("\n%ld rational points found.\n\n", total); } break; case 3: printf("Search region:\n "); { long i; for(i = 0; i < args->num_inter; i++) { if(i) printf(" U "); printf("[%f, %f]", args->domain[i].low, args->domain[i].up); } } printf("\n"); break; case 4: printf("%ld primes used for first stage of sieving,\n", args->sp1); printf("%ld primes used for both stages of sieving together.\n", args->sp2); break; case 5: printf("\nCurve equation is y^2 = "); print_poly(args->cof, args->degree); printf("\n"); break; case 6: printf("max. Height = %ld\n", args->height); break; case 7: if(args->flags & RATPOINTS_REVERSED) printf("Polynomial was reversed for better performance.\n"); if(args->flags & RATPOINTS_USE_SQUARES) { printf("(Reversed) polynomial is +-monic of odd degree:\n"); printf(" could restrict denominators to squares.\n"); } if(args->flags & RATPOINTS_USE_SQUARES1) { printf("(Reversed) polynomial has odd degree:\n"); printf(" could restrict denominators essentially to squares.\n"); } if(args->flags & RATPOINTS_NO_JACOBI) printf("Jacobi symbol test was not used.\n"); if(args->flags & RATPOINTS_NO_CHECK) { printf("Points were not checked exactly:\n"); printf(" some of the printed x-coordinates may not give points.\n"); } break; case 8: printf("Search intervals:\n"); { long i; for(i = 0; i < args->num_inter; i++) { printf("[%lf, %lf]", args->domain[i].low, args->domain[i].up); if(i < args->num_inter -1) printf(" U "); } printf("\n"); } break; } fflush(stdout); } void error(long errno) { switch(errno) { case 3: printf("\nToo many coefficients.\n\n"); break; case 4: printf("\nIncorrect height argument.\n\n"); break; case 5: printf("\nThe polynomial must have degree at least 1.\n\n"); break; case 6: printf("\nWrong syntax for optional arguments:\n\n"); case 2: printf("\n%s\n%s", RATPOINTS_VERSION, usage_str); break; case 7: printf("\nIncorrect interval arguments (not alternating, "); printf("too many, or not ordered).\n\n"); break; case 8: printf("\nPolynomial is not square-free.\n\n"); break; case 9: printf("\nBug no. 1 - please report!\n\n"); break; } fflush(stdout); exit(errno); } ratpoints-2.1.3/sift.c0000644000175000001440000002304011536145472014111 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.2 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * sift.c * * * * The sieving procedure for ratpoints * * * * Michael Stoll, Apr 14, 2009 * ***********************************************************************/ #include "rp-private.h" /************************************************************************** * check if m and n are relatively prime * **************************************************************************/ static inline int relprime(long m, long n) { /* n (the denominator) is always positive here */ if(m == 0) { return(n == 1); } if(m < 0) m = -m; if(!(m & 1)) { if(!(n & 1)) { return(0); } m >>= 1; while(!(m & 1)) { m >>= 1; } } while(!(n & 1)) { n >>= 1; } while(n != m) { if(n > m) { n -= m; n >>= 1; while(!(n & 1)) { n >>= 1; } } else { m -= n; m >>= 1; while(!(m & 1)) { m >>= 1; } } } return(m == 1); } /************************************************************************** * Try to avoid divisions * **************************************************************************/ static inline long mod(long a, long b) { long b1 = b << 4; /* b1 = 16*b */ if(a < -b1) { a %= b; if(a < 0) { a += b; } return(a); } if(a < 0) { a += b1; } else { if(a >= b1) { return(a % b); } } b1 >>= 1; /* b1 = 8*b */ if(a >= b1) { a -= b1; } b1 >>= 1; /* b1 = 4*b */ if(a >= b1) { a -= b1; } b1 >>= 1; /* b1 = 2*b */ if(a >= b1) { a -= b1; } if(a >= b) { a -= b; } return(a); } /************************************************************************** * The inner loop of the sieving procedure * **************************************************************************/ long _ratpoints_sift0(long b, long w_low, long w_high, ratpoints_args *args, bit_selection which_bits, ratpoints_bit_array *survivors, sieve_spec *sieves, int *quit, int process(long, long, const mpz_t, void*, int*), void *info) { long total = 0; long range = w_high - w_low; long sp1 = args->sp1; long sp2 = args->sp2; #ifdef DEBUG { long n, c = 0; printf("\nsift0(b = %ld) @ start [high numerators to the left]:\n", b); for(n = range - 1; n >= 0; n--, c++) { if((c & (0xff >> RBA_SHIFT)) == 0) { printf("\n"); } #ifdef USE_SSE printf("%*.*lx%*.*lx ", WIDTH, WIDTH, EXT1(survivors[n]), WIDTH, WIDTH, EXT0(survivors[n])); #else printf("%*.*lx ", WIDTH, WIDTH, survivors[n]); #endif } printf("\n"); fflush(NULL); } #endif /* now do the sieving (fast!) */ #ifdef DEBUG printf("\nsift0: sp1 = %ld, sp2 = %ld\n\n", sp1, sp2); fflush(NULL); #endif { long n; for(n = 0; n < sp1; n++) { ratpoints_bit_array *sieve_n = sieves[n].ptr; register long p = sieves[n].p; long r = mod(-w_low-sieves[n].offset, p); register ratpoints_bit_array *surv = survivors; if(w_high < w_low + r) { /* if we get here, r > 0, since w_high >= w_low always */ register ratpoints_bit_array *siv1 = &sieve_n[p-r]; register ratpoints_bit_array *siv0 = siv1 + range; while(siv1 != siv0) #ifdef USE_SSE { *surv = AND(*surv, *siv1++); surv++; } #else { *surv++ &= *siv1++; } #endif } else { register ratpoints_bit_array *siv1 = &sieve_n[p-r]; register ratpoints_bit_array *surv_end = &survivors[range - p]; { register long i; for(i = r; i; i--) #ifdef USE_SSE { *surv = AND(*surv, *siv1++); surv++; } #else { *surv++ &= *siv1++; } #endif } siv1 -= p; while(surv <= surv_end) { register long i; for(i = p; i; i--) #ifdef USE_SSE { *surv = AND(*surv, *siv1++); surv++; } #else { *surv++ &= *siv1++; } #endif siv1 -= p; } surv_end += p; while(surv < surv_end) #ifdef USE_SSE { *surv = AND(*surv, *siv1++); surv++; } #else { *surv++ &= *siv1++; } #endif } #ifdef DEBUG { long k, c = 0; printf("\nsift0 after prime p = %ld [high numerators to the left]:", p); for(k = range - 1; k >= 0; k--, c++) { if((c & (0xff >> RBA_SHIFT)) == 0) { printf("\n"); } #ifdef USE_SSE printf("%*.*lx%*.*lx ", WIDTH, WIDTH, EXT1(survivors[k]), WIDTH, WIDTH, EXT0(survivors[k])); #else printf("%*.*lx ", WIDTH, WIDTH, survivors[k]); #endif } printf("\n"); fflush(NULL); } #endif } /* for n */ } #ifdef DEBUG { long n, c = 0; printf("\nsift0(b = %ld) after phase 1 [high numerators to the left]:\n", b); for(n = range - 1; n >= 0; n--, c++) { if((c & (0xff >> RBA_SHIFT)) == 0) { printf("\n"); } #ifdef USE_SSE printf("%*.*lx%*.*lx ", WIDTH, WIDTH, EXT1(survivors[n]), WIDTH, WIDTH, EXT0(survivors[n])); #else printf("%*.*lx ", WIDTH, WIDTH, survivors[n]); #endif } printf("\n\n"); fflush(NULL); } #endif /* Second phase of the sieve: test each surviving bit array with more primes */ { ratpoints_bit_array *surv0 = &survivors[0]; long i; for(i = w_low; i < w_high; i++) { register ratpoints_bit_array nums = *surv0++; sieve_spec *ssp = &sieves[sp1]; register long n; #ifdef DEBUG #ifdef USE_SSE if(TEST(nums)) { printf("\nsurviving word %*.*lx%*.*lx @ i = %ld\n", WIDTH, WIDTH, EXT1(nums), WIDTH, WIDTH, EXT0(nums), i); #else if(nums) { printf("\nsurviving word %*.*lx @ i = %ld\n", WIDTH, WIDTH, nums, i); #endif fflush(NULL); } #endif #ifdef USE_SSE for(n = sp2-sp1; n && TEST(nums); n--) #else for(n = sp2-sp1; n && nums; n--) #endif { register long p = ssp->p; #ifdef USE_SSE nums = AND(nums, ssp->ptr[mod(i + ssp->offset, p)]); #else nums &= ssp->ptr[mod(i + ssp->offset, p)]; #endif #ifdef DEBUG #ifdef USE_SSE printf("after prime p = %ld: %*.*lx%*.*lx\n", p, WIDTH, WIDTH, EXT1(nums), WIDTH, WIDTH, EXT0(nums)); #else printf("after prime p = %ld: %*.*lx\n", p, WIDTH, WIDTH, nums); #endif fflush(NULL); #endif ssp++; } /* Check the survivors of the sieve if they really give points */ #ifdef USE_SSE if(TEST(nums)) #else if(nums) #endif { long a0, a, da, d; /* a will be the numerator corresponding to the selected bit */ #ifdef DEBUG long bit = 0; #endif if(which_bits == num_all) { d = 1; a0 = i << RBA_SHIFT; da = RBA_LENGTH/2; } else { d = 2; a0 = i << (RBA_SHIFT+1); da = RBA_LENGTH; if(which_bits == num_odd) { a0++; } } { #ifdef USE_SSE unsigned long nums0 = EXT0(nums); unsigned long nums1 = EXT1(nums); #else unsigned long nums0 = nums; #endif for(a = a0; nums0; a += d, nums0 >>= 1) { /* test one bit */ if((nums0 & 1) && relprime(a, b)) { #ifdef DEBUG printf("\nsurviving bit no. %ld --> a = %ld. Check point...\n", bit, a); fflush(NULL); #endif total += _ratpoints_check_point(a, b, args, quit, process, info); if(*quit) return(total); } #ifdef DEBUG bit++; #endif } #ifdef USE_SSE #ifdef DEBUG bit = 0; #endif for(a = a0 + da; nums1; a += d, nums1 >>= 1) { /* test one bit */ if((nums1 & 1) && relprime(a, b)) { #ifdef DEBUG printf("\nsurviving bit no. %ld --> a = %ld. Check point...\n", bit+64, a); fflush(NULL); #endif total += _ratpoints_check_point(a, b, args, quit, process, info); if(*quit) return(total); } #ifdef DEBUG bit++; #endif } #endif } } } } return(total); } ratpoints-2.1.3/testbase0000644000175000001440000004006511536145472014543 0ustar mstollusers{} {[0,2,1],[0,-2,1]} {[0,2,1],[0,-2,1],[-2,346,5],[-2,-346,5]} {[0,0,1]} {} {[0,0,1],[-1,0,1]} {[-3,6,2],[-3,-6,2]} {} {} {} {} {[3,31,2],[3,-31,2],[2,51,3],[2,-51,3]} {} {[0,0,1],[-1,2,1],[-1,-2,1]} {} {} {} {[1,0,1]} {[-1,1,1],[-1,-1,1],[1,20,2],[1,-20,2]} {[-1,3,1],[-1,-3,1]} {[0,2,1],[0,-2,1]} {[-2,7,1],[-2,-7,1],[0,1,1],[0,-1,1]} {[-1,2,1],[-1,-2,1]} {[1,11,2],[1,-11,2]} {} {[1,2,0],[1,-2,0],[1,1,1],[1,-1,1]} {} {} {[-3,38,1],[-3,-38,1],[-1,2,1],[-1,-2,1],[1,2,1],[1,-2,1],[7,602,1],[7,-602,1],[1,513,6],[1,-513,6]} {} {[0,2,1],[0,-2,1]} {[1,1,1],[1,-1,1]} {[1,2,0],[1,-2,0]} {[0,0,1],[-1,3,2],[-1,-3,2],[1,3,0],[1,-3,0]} {[-1,3,1],[-1,-3,1]} {} {} {[0,0,1],[-1,3,1],[-1,-3,1]} {[0,2,1],[0,-2,1]} {} {[0,1,1],[0,-1,1]} {} {[0,1,1],[0,-1,1]} {[1,2,1],[1,-2,1]} {[0,3,1],[0,-3,1],[1,23,2],[1,-23,2]} {} {} {[0,2,1],[0,-2,1]} {[-1,4,1],[-1,-4,1]} {[1,3,1],[1,-3,1]} {} {[1,4,1],[1,-4,1]} {[-1,2,1],[-1,-2,1],[-1,4,2],[-1,-4,2]} {[-1,1,1],[-1,-1,1],[1,3,0],[1,-3,0]} {[0,0,1]} {[1,3,0],[1,-3,0],[1,3,1],[1,-3,1]} {[-1,4,1],[-1,-4,1],[0,3,1],[0,-3,1],[2,107,3],[2,-107,3],[38,1939745,83],[38,-1939745,83]} {[1,1,0],[1,-1,0],[0,1,1],[0,-1,1],[1,3,2],[1,-3,2],[-13,6499,9],[-13,-6499,9],[-49,198463,12],[-49,-198463,12]} {[1,0,1]} {} {} {[1,1,0],[1,-1,0],[0,3,1],[0,-3,1]} {} {[1,3,0],[1,-3,0]} {[0,3,1],[0,-3,1]} {[0,0,1],[1,3,0],[1,-3,0]} {} {} {} {[1,3,1],[1,-3,1]} {[1,1,0],[1,-1,0],[1,0,1]} {} {} {[0,0,1]} {[0,3,1],[0,-3,1]} {} {[0,3,1],[0,-3,1]} {[-1,4,1],[-1,-4,1]} {} {} {} {} {[1,1,0],[1,-1,0]} {[-1,2,1],[-1,-2,1]} {[1,0,0]} {} {} {} {} {[1,3,0],[1,-3,0]} {} {[1,1,1],[1,-1,1]} {} {[-1,0,1]} {[0,3,1],[0,-3,1],[4,23,1],[4,-23,1]} {[0,1,1],[0,-1,1]} {[0,2,1],[0,-2,1]} {[-1,2,1],[-1,-2,1],[1,2,1],[1,-2,1]} {} {[2,3461,11],[2,-3461,11]} {[-1,1,1],[-1,-1,1]} {[0,1,1],[0,-1,1]} {} {} {} {[1,0,0]} {} {[-1,5,1],[-1,-5,1]} {[-1,1,1],[-1,-1,1]} {[-2,8,1],[-2,-8,1],[-1,1,1],[-1,-1,1],[2,16,1],[2,-16,1]} {[0,3,1],[0,-3,1]} {} {[1,144,4],[1,-144,4]} {[1,1,0],[1,-1,0]} {[3,82,2],[3,-82,2]} {[1,0,0]} {[2,4,1],[2,-4,1]} {[-1,2,1],[-1,-2,1]} {} {} {[0,0,1],[1,2,1],[1,-2,1],[-2,16,1],[-2,-16,1]} {[0,2,1],[0,-2,1],[3,23,1],[3,-23,1]} {} {} {[1,3,1],[1,-3,1]} {} {[-1,1,1],[-1,-1,1]} {} {} {} {} {[0,3,1],[0,-3,1]} {} {[0,1,1],[0,-1,1]} {} {} {[0,2,1],[0,-2,1]} {} {} {[-1,3,1],[-1,-3,1],[2,3,1],[2,-3,1],[3,6,2],[3,-6,2]} {[0,3,1],[0,-3,1],[1,6,1],[1,-6,1],[-4,419,7],[-4,-419,7]} {[1,2,1],[1,-2,1],[7,2996,10],[7,-2996,10]} {[1,0,0]} {[1,2,1],[1,-2,1]} {[0,2,1],[0,-2,1]} {} {[3,49,2],[3,-49,2]} {[-1,18,2],[-1,-18,2]} {} {} {[0,0,1]} {[0,3,1],[0,-3,1]} {} {[1,2,0],[1,-2,0],[0,2,1],[0,-2,1]} {[-1,1,1],[-1,-1,1]} {[-2,22,1],[-2,-22,1]} {[1,1,0],[1,-1,0]} {[0,1,1],[0,-1,1]} {[1,1,1],[1,-1,1]} {} {[1,3,0],[1,-3,0]} {} {} {} {} {[-1,1,1],[-1,-1,1],[0,3,1],[0,-3,1]} {} {[3,1,1],[3,-1,1]} {} {} {[1,4,1],[1,-4,1]} {[-1,1,1],[-1,-1,1]} {[1,0,0],[0,3,1],[0,-3,1],[1,0,1]} {} {} {[1,5,1],[1,-5,1]} {[10,3648,7],[10,-3648,7]} {[-20,21952,1],[-20,-21952,1],[0,2,1],[0,-2,1]} {[-1,2,1],[-1,-2,1]} {} {[1,1,1],[1,-1,1],[-27,1795891,89],[-27,-1795891,89]} {[-1,5,2],[-1,-5,2]} {[1,3,0],[1,-3,0]} {} {[1,2,0],[1,-2,0]} {} {} {} {[-1,9,2],[-1,-9,2]} {} {} {} {[1,3,1],[1,-3,1]} {[-1,1,2],[-1,-1,2],[1,1,0],[1,-1,0],[1,1,1],[1,-1,1]} {} {[-1,1,1],[-1,-1,1]} {} {} {[0,2,1],[0,-2,1]} {} {[1,1,0],[1,-1,0],[7,357,4],[7,-357,4]} {[0,1,1],[0,-1,1]} {} {} {[1,2,0],[1,-2,0]} {[1,3,1],[1,-3,1]} {} {[0,0,1]} {[-2,9,1],[-2,-9,1]} {[1,0,1]} {[-1,7,2],[-1,-7,2]} {[0,2,1],[0,-2,1]} {[0,1,1],[0,-1,1]} {[0,2,1],[0,-2,1],[2,12,3],[2,-12,3]} {} {} {[-2,3,1],[-2,-3,1],[-1,0,1],[0,1,1],[0,-1,1],[-6,133,5],[-6,-133,5]} {[1,1,0],[1,-1,0]} {[-1,75,4],[-1,-75,4],[1,1,0],[1,-1,0]} {} {[-1,3,1],[-1,-3,1]} {} {[1,2,0],[1,-2,0],[1,3,1],[1,-3,1]} {} {[1,3,0],[1,-3,0]} {} {} {[0,3,1],[0,-3,1],[2,21,1],[2,-21,1]} {} {} {[0,1,1],[0,-1,1],[1,5,2],[1,-5,2]} {} {[0,3,1],[0,-3,1]} {} {} {[0,2,1],[0,-2,1]} {[-1,1,1],[-1,-1,1],[1,101,4],[1,-101,4]} {[-1,2,1],[-1,-2,1],[1,13,2],[1,-13,2]} {[-3,58,1],[-3,-58,1]} {[1,4,1],[1,-4,1],[3,1408,8],[3,-1408,8]} {} {[0,1,1],[0,-1,1]} {[1,2,1],[1,-2,1]} {} {} {[1,1,0],[1,-1,0],[-2,9,1],[-2,-9,1]} {[1,4,1],[1,-4,1]} {[-1,3,1],[-1,-3,1]} {} {} {} {} {} {} {[-1,1,1],[-1,-1,1]} {[1,1,0],[1,-1,0]} {} {} {[0,1,1],[0,-1,1]} {} {[1,3,0],[1,-3,0]} {} {[0,0,1]} {[0,1,1],[0,-1,1]} {} {} {[1,0,0],[1,1,1],[1,-1,1]} {} {[1,1,0],[1,-1,0]} {} {} {} {[0,2,1],[0,-2,1]} {[1,1,0],[1,-1,0],[-4,114,1],[-4,-114,1]} {[0,3,1],[0,-3,1]} {[1,2,0],[1,-2,0]} {} {} {} {[1,1,0],[1,-1,0]} {} {[0,2,1],[0,-2,1]} {[-1,3,1],[-1,-3,1]} {} {} {[0,3,1],[0,-3,1]} {[20,25315,19],[20,-25315,19]} {} {[-1,1,1],[-1,-1,1]} {[1,2,0],[1,-2,0]} {[0,3,1],[0,-3,1],[3,291,5],[3,-291,5]} {[1,3,0],[1,-3,0]} {} {} {[1,0,0]} {} {} {[1,1,0],[1,-1,0]} {[1,3,0],[1,-3,0]} {} {} {[0,3,1],[0,-3,1]} {} {[-2,37,3],[-2,-37,3]} {[-1,2,1],[-1,-2,1],[1,2,1],[1,-2,1]} {[1,0,0]} {} {} {[1,1,0],[1,-1,0]} {[1,2,0],[1,-2,0],[0,3,1],[0,-3,1]} {} {[0,3,1],[0,-3,1]} {[1,3,0],[1,-3,0]} {} {} {} {[0,2,1],[0,-2,1],[1,0,1]} {} {[0,3,1],[0,-3,1],[-704,40680297,933],[-704,-40680297,933]} {[0,0,1]} {[-1,1,1],[-1,-1,1],[1,5,1],[1,-5,1]} {} {[36,131678,1],[36,-131678,1]} {[1,1,0],[1,-1,0],[0,2,1],[0,-2,1]} {} {} {[1,3,0],[1,-3,0]} {[-1,1,1],[-1,-1,1],[1,1,0],[1,-1,0],[1,11,2],[1,-11,2],[1,503,6],[1,-503,6],[2,13,1],[2,-13,1],[3,113,5],[3,-113,5]} {[0,0,1],[1,0,0]} {[1,3,1],[1,-3,1]} {} {[1,3,1],[1,-3,1]} {} {} {} {[1,1,0],[1,-1,0],[-3,10,1],[-3,-10,1],[0,2,1],[0,-2,1],[-1,46,3],[-1,-46,3]} {[1,2,0],[1,-2,0]} {[0,0,1],[1,3,0],[1,-3,0]} {} {[0,1,1],[0,-1,1],[-1,16,2],[-1,-16,2]} {[93,594431,28],[93,-594431,28]} {[1,0,0],[0,1,1],[0,-1,1]} {[-1,2,1],[-1,-2,1]} {} {[1,0,1]} {[1,2,0],[1,-2,0],[0,2,1],[0,-2,1]} {[0,0,1]} {} {[0,2,1],[0,-2,1],[1,5,1],[1,-5,1]} {} {[-1,0,1],[0,2,1],[0,-2,1],[1,0,1]} {[0,2,1],[0,-2,1],[1,0,1]} {} {} {} {[0,3,1],[0,-3,1]} {[0,2,1],[0,-2,1]} {[0,0,1],[-1,2,1],[-1,-2,1],[1,1,0],[1,-1,0],[1,11,2],[1,-11,2]} {} {} {} {} {} {} {[1,3,1],[1,-3,1]} {} {} {[0,0,1]} {} {[0,3,1],[0,-3,1]} {[-1,0,1],[-2,0,7]} {} {[1,2,0],[1,-2,0]} {} {[-1,0,1]} {} {} {[1,2,0],[1,-2,0]} {[0,0,1]} {} {[0,2,1],[0,-2,1]} {[1,0,0]} {} {[-2,92,3],[-2,-92,3]} {} {[1,0,1]} {[0,0,1]} {[1,0,0]} {[1,2,0],[1,-2,0]} {[-1,4,1],[-1,-4,1]} {} {[-4,190,1],[-4,-190,1]} {} {[-1,0,1]} {} {[-1,3,1],[-1,-3,1]} {} {[1,3,0],[1,-3,0]} {[-1,2,1],[-1,-2,1]} {[1,2,1],[1,-2,1]} {[1,0,0],[-5,159,3],[-5,-159,3]} {} {[-1,3,1],[-1,-3,1]} {[-2,11,1],[-2,-11,1]} {} {} {} {[1,1,0],[1,-1,0],[2,6,1],[2,-6,1]} {} {} {[-2,13,1],[-2,-13,1]} {} {[1,2,0],[1,-2,0]} {[1,1,0],[1,-1,0],[-5,95,4],[-5,-95,4]} {} {} {[-1,6,1],[-1,-6,1]} {[2,1,1],[2,-1,1]} {[1,2,0],[1,-2,0]} {[1,2,2],[1,-2,2]} {} {} {} {[1,1,1],[1,-1,1]} {} {} {[-1,2,1],[-1,-2,1],[0,1,1],[0,-1,1]} {} {[-2,9,1],[-2,-9,1],[0,3,1],[0,-3,1]} {[1,2,0],[1,-2,0]} {} {[1,5,1],[1,-5,1]} {[4,43,5],[4,-43,5]} {} {[1,0,1],[-3,42,4],[-3,-42,4]} {} {} {[1,1,0],[1,-1,0],[1,3,1],[1,-3,1]} {[1,0,1]} {[1,2,1],[1,-2,1]} {[5,1735,8],[5,-1735,8],[-11,7265,16],[-11,-7265,16]} {} {[0,3,1],[0,-3,1]} {[-2,9,1],[-2,-9,1]} {[1,2,1],[1,-2,1]} {[-1,2,1],[-1,-2,1]} {} {} {[0,3,1],[0,-3,1]} {} {} {} {[1,3,0],[1,-3,0]} {[-1,2,1],[-1,-2,1]} {[1,0,0]} {} {} {} {[-1,0,1]} {[1,1,0],[1,-1,0]} {} {[-1,3,1],[-1,-3,1]} {} {[1,1,0],[1,-1,0]} {[0,1,1],[0,-1,1]} {[2,11,1],[2,-11,1]} {[0,0,1],[1,10,2],[1,-10,2]} {[-1,460,6],[-1,-460,6]} {[-2,20,1],[-2,-20,1]} {[-1,3,1],[-1,-3,1],[-6,368,5],[-6,-368,5]} {[1,3,1],[1,-3,1]} {} {[1,0,0]} {[0,2,1],[0,-2,1]} {[-1,3,1],[-1,-3,1],[1,2,0],[1,-2,0],[11,2535,1],[11,-2535,1]} {} {[1,19,2],[1,-19,2]} {} {[-1,3,1],[-1,-3,1],[0,2,1],[0,-2,1]} {} {[1,1,0],[1,-1,0]} {} {} {[1,2,1],[1,-2,1],[-1,11,2],[-1,-11,2]} {[1,3,0],[1,-3,0]} {} {[1,3,0],[1,-3,0],[1,3,1],[1,-3,1]} {} {[1,0,0],[-2,4,1],[-2,-4,1]} {[-1,27,2],[-1,-27,2]} {} {[1,3,0],[1,-3,0]} {} {[0,0,1]} {[0,1,1],[0,-1,1]} {[1,2,0],[1,-2,0]} {[1,2,0],[1,-2,0],[-1,3,1],[-1,-3,1],[0,1,1],[0,-1,1],[3,74,2],[3,-74,2],[-8,1591,7],[-8,-1591,7]} {} {} {} {[-1,5,1],[-1,-5,1],[1,3,0],[1,-3,0]} {[-1,4,1],[-1,-4,1]} {[0,1,1],[0,-1,1]} {} {[2,76,3],[2,-76,3],[7,7780,15],[7,-7780,15]} {[0,1,1],[0,-1,1],[1,1,1],[1,-1,1],[3,10,2],[3,-10,2]} {[1,1,0],[1,-1,0],[0,1,1],[0,-1,1],[-4,95,3],[-4,-95,3]} {[1,1,1],[1,-1,1],[-1,55,3],[-1,-55,3],[2,64,3],[2,-64,3]} {[3,57,2],[3,-57,2]} {[2,14,1],[2,-14,1]} {[-1,4,1],[-1,-4,1]} {} {[1,0,0],[-3,5,1],[-3,-5,1]} {[1,1,0],[1,-1,0],[0,3,1],[0,-3,1]} {} {[0,3,1],[0,-3,1]} {[-1,5,1],[-1,-5,1],[1,1,1],[1,-1,1],[1,22,2],[1,-22,2]} {} {[1,2,0],[1,-2,0]} {[-1,0,1],[0,1,1],[0,-1,1]} {[-7,521,5],[-7,-521,5]} {} {} {[1,3,0],[1,-3,0]} {} {[-2,20,1],[-2,-20,1],[1,2,1],[1,-2,1],[22,31638,15],[22,-31638,15]} {} {} {[1,3,1],[1,-3,1]} {} {} {[-1,1,1],[-1,-1,1]} {} {} {} {} {} {[1,4,1],[1,-4,1],[1,23,2],[1,-23,2]} {} {} {[0,3,1],[0,-3,1],[-5,257,4],[-5,-257,4]} {} {[-1,3,1],[-1,-3,1]} {} {[-1,0,1],[0,3,1],[0,-3,1]} {[-1,0,1]} {[0,0,1]} {[0,3,1],[0,-3,1],[-5,348,6],[-5,-348,6]} {} {} {} {[-1,1,1],[-1,-1,1]} {} {} {} {} {[1,2,0],[1,-2,0],[0,3,1],[0,-3,1]} {[1,0,0]} {[0,3,1],[0,-3,1]} {} {[-1,7,2],[-1,-7,2],[1,1,0],[1,-1,0]} {[1,1,0],[1,-1,0]} {[1,3,0],[1,-3,0]} {[1,1,0],[1,-1,0]} {[1,2,0],[1,-2,0]} {[3,3,2],[3,-3,2]} {} {} {} {} {} {[1,0,0]} {} {[1,1,0],[1,-1,0],[0,3,1],[0,-3,1]} {} {[1,4,1],[1,-4,1]} {} {} {} {[1,0,1]} {[1,1,0],[1,-1,0]} {[0,1,1],[0,-1,1]} {} {[-1,4,1],[-1,-4,1]} {[0,1,1],[0,-1,1]} {[0,1,1],[0,-1,1]} {} {} {[1,2,0],[1,-2,0],[4,100,1],[4,-100,1]} {[1,3,0],[1,-3,0],[1,0,1],[-313,27928221051,2496],[-313,-27928221051,2496]} {} {[0,1,1],[0,-1,1]} {} {[1,1,0],[1,-1,0]} {} {} {} {[1,3,0],[1,-3,0],[0,2,1],[0,-2,1]} {} {[1,3,1],[1,-3,1]} {} {[1,0,0],[-1,0,1]} {} {[-1,4,1],[-1,-4,1]} {[0,3,1],[0,-3,1]} {[1,1,1],[1,-1,1]} {} {[-3,81,1],[-3,-81,1]} {[-47,3295394,104],[-47,-3295394,104]} {[0,2,1],[0,-2,1]} {[-1,5,1],[-1,-5,1]} {[1,1,1],[1,-1,1]} {[1,0,0],[-1,5,1],[-1,-5,1]} {[1,0,1]} {[1,3,0],[1,-3,0]} {[-1,53,4],[-1,-53,4],[1,3,0],[1,-3,0]} {} {[-2,16,1],[-2,-16,1],[-1,0,1],[0,2,1],[0,-2,1],[5,198,1],[5,-198,1],[1,27,2],[1,-27,2],[7,5094,11],[7,-5094,11]} {[1,2,0],[1,-2,0],[0,2,1],[0,-2,1],[3,20,4],[3,-20,4]} {} {[0,0,1]} {} {} {[1,1,0],[1,-1,0],[1,4,1],[1,-4,1]} {} {} {} {[1,1,0],[1,-1,0],[0,1,1],[0,-1,1],[-57,543145,112],[-57,-543145,112]} {[0,3,1],[0,-3,1]} {[0,3,1],[0,-3,1]} {} {[-1,2,1],[-1,-2,1],[1,0,1]} {} {} {[1,0,0]} {} {[0,3,1],[0,-3,1]} {[-1,3,1],[-1,-3,1],[0,3,1],[0,-3,1]} {[-1,3,1],[-1,-3,1]} {} {[1,0,0]} {[-4,170,1],[-4,-170,1],[0,2,1],[0,-2,1]} {[1,0,0],[-8,604,1],[-8,-604,1],[-2,22,1],[-2,-22,1],[-1,5,1],[-1,-5,1],[0,0,1],[1,1,1],[1,-1,1],[-1,381,9],[-1,-381,9],[1,4,2],[1,-4,2],[-9,3228,8],[-9,-3228,8],[-1,95,5],[-1,-95,5],[9,1200,10],[9,-1200,10]} {[0,1,1],[0,-1,1],[1,3,1],[1,-3,1]} {} {} {[1,1,1],[1,-1,1]} {[0,1,1],[0,-1,1]} {[0,1,1],[0,-1,1]} {[1,1,0],[1,-1,0]} {[1,0,1],[-4,123,5],[-4,-123,5]} {} {[1,1,0],[1,-1,0],[0,3,1],[0,-3,1]} {} {[0,2,1],[0,-2,1]} {} {} {[0,1,1],[0,-1,1]} {} {} {[0,0,1],[-1,2,1],[-1,-2,1],[1,8,2],[1,-8,2]} {[0,2,1],[0,-2,1],[1,2,1],[1,-2,1]} {[-1,5,1],[-1,-5,1],[0,3,1],[0,-3,1],[2,17,1],[2,-17,1]} {[-1,3,1],[-1,-3,1],[1,1,0],[1,-1,0]} {[-3,112,2],[-3,-112,2]} {} {} {} {[-1,2,1],[-1,-2,1]} {[1,0,0],[1,2,1],[1,-2,1]} {} {[1,1,0],[1,-1,0]} {[-1,1,1],[-1,-1,1],[-1,7,2],[-1,-7,2]} {} {} {[0,1,1],[0,-1,1]} {} {[-1,1,1],[-1,-1,1]} {} {} {} {[0,0,1]} {[0,3,1],[0,-3,1]} {} {} {[1,2,1],[1,-2,1]} {} {} {[0,0,1]} {[2,5,1],[2,-5,1],[3,50,1],[3,-50,1]} {[0,3,1],[0,-3,1]} {[-1,25,3],[-1,-25,3],[1,2,0],[1,-2,0]} {} {} {} {} {} {} {} {[-1,4,1],[-1,-4,1]} {} {[-1,4,1],[-1,-4,1]} {[0,2,1],[0,-2,1],[1,1,1],[1,-1,1],[63,338641,71],[63,-338641,71],[168,8223850,205],[168,-8223850,205]} {[1,2,1],[1,-2,1]} {[4,10,3],[4,-10,3]} {} {} {} {[0,1,1],[0,-1,1]} {[-1,2,1],[-1,-2,1]} {[0,2,1],[0,-2,1]} {[-1,5,1],[-1,-5,1],[1,2,0],[1,-2,0],[-2,24,1],[-2,-24,1]} {} {[-4,16,1],[-4,-16,1],[0,2,1],[0,-2,1],[1,187,5],[1,-187,5]} {} {[-1,3,1],[-1,-3,1]} {} {[-1,0,1],[0,2,1],[0,-2,1]} {[-1,2,1],[-1,-2,1]} {[1,3,0],[1,-3,0]} {[1,0,0]} {[-1,3,1],[-1,-3,1]} {} {[1,16,2],[1,-16,2],[-1,71,3],[-1,-71,3],[-5,820,6],[-5,-820,6],[71,117115,51],[71,-117115,51]} {} {[1,2,0],[1,-2,0],[1,0,1]} {} {} {} {} {} {[1,5,2],[1,-5,2],[5,209,8],[5,-209,8]} {} {} {[-1,1,1],[-1,-1,1],[1,1,1],[1,-1,1],[4,1,1],[4,-1,1]} {} {} {[0,1,1],[0,-1,1]} {[1,0,1]} {[1,2,0],[1,-2,0]} {[0,2,1],[0,-2,1],[1,0,1],[10,2328,1],[10,-2328,1],[-9,767,4],[-9,-767,4]} {} {[1,4,1],[1,-4,1]} {[-1,1,1],[-1,-1,1]} {[-2,10,1],[-2,-10,1],[1,2,1],[1,-2,1]} {[1,2,0],[1,-2,0]} {[3,67,1],[3,-67,1],[-1,4,2],[-1,-4,2]} {} {} {[-2,12,1],[-2,-12,1]} {[1,3,0],[1,-3,0]} {} {} {[0,1,1],[0,-1,1]} {} {} {} {} {[0,2,1],[0,-2,1]} {[5,2086,13],[5,-2086,13]} {[0,3,1],[0,-3,1]} {[1,2,0],[1,-2,0]} {} {[0,1,1],[0,-1,1]} {[-2,23,3],[-2,-23,3]} {} {} {[1,4,1],[1,-4,1]} {[-1,537,6],[-1,-537,6],[1,3,0],[1,-3,0],[41,636063,51],[41,-636063,51]} {} {} {[-1,1,1],[-1,-1,1],[1,3,0],[1,-3,0]} {} {} {} {[1,3,0],[1,-3,0],[0,3,1],[0,-3,1],[1,25,2],[1,-25,2],[-1,209,4],[-1,-209,4]} {[0,2,1],[0,-2,1]} {[2,10,1],[2,-10,1]} {[0,1,1],[0,-1,1],[3,241,5],[3,-241,5]} {} {[1,2,0],[1,-2,0]} {} {} {[0,0,1],[-3,102,2],[-3,-102,2],[12,34950,23],[12,-34950,23]} {} {[1,3,0],[1,-3,0],[1,2,1],[1,-2,1]} {[-1,3,1],[-1,-3,1]} {[0,2,1],[0,-2,1]} {} {} {} {[-1,3,1],[-1,-3,1],[0,1,1],[0,-1,1]} {} {} {[0,0,1],[1,0,2]} {[-2,6,1],[-2,-6,1],[-1,0,1]} {[0,3,1],[0,-3,1]} {[-1,1,1],[-1,-1,1]} {} {[-1,1,1],[-1,-1,1],[0,3,1],[0,-3,1]} {[-2,17,1],[-2,-17,1],[5,368,1],[5,-368,1]} {} {} {[0,1,1],[0,-1,1],[1,0,1]} {[-1,0,1]} {[1,3,0],[1,-3,0]} {[0,2,1],[0,-2,1],[3,2357,10],[3,-2357,10]} {} {} {} {[-1,0,1],[0,3,1],[0,-3,1]} {} {[1,3,0],[1,-3,0]} {} {} {} {} {} {} {} {[1,3,0],[1,-3,0],[1,3,1],[1,-3,1]} {} {[0,3,1],[0,-3,1]} {} {[1,2,0],[1,-2,0],[-1,6,1],[-1,-6,1],[0,3,1],[0,-3,1]} {[-1,70,3],[-1,-70,3]} {} {[1,1,1],[1,-1,1]} {} {[0,2,1],[0,-2,1]} {[-1,0,1],[1,3,0],[1,-3,0],[4,190,1],[4,-190,1]} {} {[-2,1,1],[-2,-1,1]} {[-3,27,2],[-3,-27,2],[-1,9,2],[-1,-9,2]} {[-1,4,1],[-1,-4,1]} {} {[0,2,1],[0,-2,1]} {} {} {[1,12,2],[1,-12,2],[-1,180,4],[-1,-180,4],[4,9039,17],[4,-9039,17]} {[1,3,0],[1,-3,0],[0,2,1],[0,-2,1],[-1,25,2],[-1,-25,2]} {} {[-1,4,1],[-1,-4,1]} {} {} {[-1,4,1],[-1,-4,1]} {[3,265,5],[3,-265,5]} {} {} {} {} {} {} {[-1,3,1],[-1,-3,1]} {} {[1,2,0],[1,-2,0],[1,3,1],[1,-3,1]} {[1,3,0],[1,-3,0]} {[1,11,2],[1,-11,2]} {} {} {[1,0,0]} {} {[1,2,0],[1,-2,0],[2,12,1],[2,-12,1]} {[0,2,1],[0,-2,1]} {} {[0,2,1],[0,-2,1]} {[1,3,0],[1,-3,0]} {} {} {} {} {[1,1,0],[1,-1,0]} {} {[1,2,1],[1,-2,1]} {[1,3,0],[1,-3,0],[13,6807,9],[13,-6807,9]} {} {[-1,1,1],[-1,-1,1]} {[0,2,1],[0,-2,1],[1,2,1],[1,-2,1],[4,154,1],[4,-154,1]} {[1,24,2],[1,-24,2]} {} {} {[1,0,0],[1,3,1],[1,-3,1]} {[-1,1,1],[-1,-1,1]} {} {[-3,80,2],[-3,-80,2]} {} {[1,0,1]} {[1,3,0],[1,-3,0]} {[-1,4,1],[-1,-4,1],[1,2,0],[1,-2,0]} {} {[0,3,1],[0,-3,1],[92,14946963,209],[92,-14946963,209]} {} {} {[1,0,0]} {[-2,27,1],[-2,-27,1]} {} {[0,1,1],[0,-1,1],[-1,12,2],[-1,-12,2],[3,56,2],[3,-56,2]} {[0,1,1],[0,-1,1]} {} {[0,3,1],[0,-3,1]} {[0,2,1],[0,-2,1]} {[1,0,1]} {} {} {[1,0,1]} {} {} {} {[-1,3,1],[-1,-3,1]} {[1,0,0],[-1,2,1],[-1,-2,1]} {} {} {[-1,1,1],[-1,-1,1]} {} {[1,1,0],[1,-1,0]} {} {[1,0,0],[-1,3,1],[-1,-3,1],[0,1,1],[0,-1,1]} {[-1,3,1],[-1,-3,1],[-1,23,2],[-1,-23,2],[14,4236,13],[14,-4236,13]} {[1,3,0],[1,-3,0]} {[0,3,1],[0,-3,1]} {} {[1,1,0],[1,-1,0]} {} {} {} {[-1,1,1],[-1,-1,1],[1,1,1],[1,-1,1]} {} {} {[0,2,1],[0,-2,1],[1,0,1],[7,1990,11],[7,-1990,11]} {[1,1,0],[1,-1,0]} {[0,0,1]} {[-1,14,2],[-1,-14,2],[1,2,0],[1,-2,0]} {} {} {[1,0,0],[1,1,1],[1,-1,1]} {[0,0,1]} {[1,0,0]} {} {} {} {} {[0,1,1],[0,-1,1]} {} {[0,2,1],[0,-2,1],[1,2,2],[1,-2,2]} {} {[1,1,1],[1,-1,1]} {} {[1,0,0],[-2,8,1],[-2,-8,1],[-1,4,1],[-1,-4,1],[0,2,1],[0,-2,1],[3,38,1],[3,-38,1],[6,200,1],[6,-200,1],[127,3151792,49],[127,-3151792,49],[1,16,2],[1,-16,2],[325,2360754224,1058],[325,-2360754224,1058]} {[3,81,4],[3,-81,4]} {} {} {[1,2,1],[1,-2,1]} {[1,0,0]} {[-1,4,1],[-1,-4,1]} {} {[1,0,0],[1,2,2],[1,-2,2]} {} {} {[1,3,0],[1,-3,0],[1,19,2],[1,-19,2]} {} {} {} {[1,0,0],[-3,39,1],[-3,-39,1],[-2,9,1],[-2,-9,1]} {} {[2,3,1],[2,-3,1]} {[1,1,1],[1,-1,1]} {} {} {} {[0,1,1],[0,-1,1],[-3,287,5],[-3,-287,5]} {} {[1,2,1],[1,-2,1]} {} {[1,0,0]} {} {[-1,3,1],[-1,-3,1],[1,1,1],[1,-1,1]} {[1,0,0]} {[0,2,1],[0,-2,1]} {[0,3,1],[0,-3,1],[1,1,1],[1,-1,1]} {[0,2,1],[0,-2,1]} {[-1,1,1],[-1,-1,1]} {} {[1,1,1],[1,-1,1],[-1,23,2],[-1,-23,2]} {[0,0,1],[-1,0,1],[3,0,2]} {} {[0,3,1],[0,-3,1]} {} {} {[1,3,0],[1,-3,0]} {} {[-1,3,1],[-1,-3,1]} {} {[1,3,1],[1,-3,1]} {} {[1,0,0],[1,1,1],[1,-1,1]} {[0,0,1]} {} {[0,2,1],[0,-2,1]} {} {[0,2,1],[0,-2,1]} ratpoints-2.1.3/init.c0000644000175000001440000002560311536145472014116 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.2 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * init.c * * * * Macro definitions for the sieve_init functions * * * * Michael Stoll, Apr 14, 2009 * ***********************************************************************/ #include "rp-private.h" #ifdef USE_SSE /* The following is for primes < LONG_LENGTH */ #define CODE_INIT_SIEVE1(prime) \ static ratpoints_bit_array *sieve_init_##prime(void *se1, long b1, void *args1) \ { \ ratpoints_sieve_entry *se = se1; \ ratpoints_args *args = args1; \ register int *isfs = se->is_f_square; \ register long b = b1; \ long lmp = LONG_LENGTH % (prime); \ long ldp = LONG_LENGTH / (prime); \ long p1 = (ldp + 1) * (prime); \ long diff_shift = p1 & LONG_MASK; \ long diff = LONG_LENGTH - diff_shift; \ register unsigned long help0;\ { register long a; \ register long d = se->inverses[b]; \ register long ab = 0; /* a/b mod p */ \ register unsigned long test = 1UL; \ register unsigned long he0 = 0UL; \ for(a = 0; a < (prime); a++) \ { if(isfs[ab]) { he0 |= test; } \ ab += d; \ if(ab >= (prime)) ab -= (prime); \ test <<= 1; \ } \ help0 = he0; \ } \ \ { register unsigned long help1; \ { /* repeat bit pattern floor(LONG_LENGTH/p) times */ \ register unsigned long pattern = help0; \ register long i; \ /* the p * (floor(LONG_LENGTH/p) + 1) - LONG_LENGTH \ = p - (LONG_LENGTH mod p) \ upper bits into help[b][1] : \ shift away the LONG_LENGTH mod p lower bits */ \ help1 = pattern >> lmp; \ for(i = (prime); i < LONG_LENGTH; i <<= 1) \ { help0 |= help0 << i; } \ /* \ for(i = ldp; i; i--) \ { pattern <<= (prime); help0 |= pattern; } \ */ \ } \ \ { /* fill the bit pattern from help0/help1 into sieve[b][]. \ sieve[b][a0] has the same semantics as help0/help1, \ but here, a0 runs from 0 to p-1 and all bits are filled. */ \ register long a; \ unsigned long *si = (unsigned long *)args->ba_next; \ \ args->ba_next += (prime)*sizeof(ratpoints_bit_array); \ /* copy the first chunk into sieve[b][] */ \ si[0] = help0; \ /* now keep repeating the bit pattern, \ rotating it in help0/help1 */ \ for(a = 1 ; a < (prime); a++) \ { register unsigned long temp = help0 >> diff; \ help0 = help1 | (help0 << diff_shift); \ si[a] = help0; \ help1 = temp; \ } \ /* copy into the next p long words */ \ for(a = 0; a < (prime); a++) \ { si[a+(prime)] = si[a]; } \ /* set sieve array */ \ se->sieve[b] = (ratpoints_bit_array *)si; \ return((ratpoints_bit_array *)si); \ } } \ } /* This is for p > LONG_LENGTH */ #define CODE_INIT_SIEVE2(prime) \ static ratpoints_bit_array *sieve_init_##prime(void *se1, long b1, void *args1) \ { \ ratpoints_sieve_entry *se = se1; \ ratpoints_args *args = args1; \ register long p = (prime); \ register int *isfs = se->is_f_square; \ register long b = b1; \ /* long ldp = 0; = LONG_LENGTH / p */ \ /* long p1 = p; = (ldp + 1) * p; */ \ long wp = p >> LONG_SHIFT; \ long diff_shift = p & LONG_MASK; \ long diff = LONG_LENGTH - diff_shift; \ unsigned long help[(p>>LONG_SHIFT) + 2]; \ \ /* initialize help */ \ { register unsigned long *he = &help[0]; \ register unsigned long *he1 = &he[(p>>LONG_SHIFT) + 2]; \ while(he1 != he) { he1--; *he1 = 0UL; } \ } \ { register unsigned long work = 0UL; \ register long a; \ register long ab = 0; /* a/b mod p */ \ register long d = se->inverses[b]; \ register long n = 0; \ register unsigned long test = 1UL; \ for(a = 0; a < p; ) \ { if(isfs[ab]) { work |= test; } \ ab += d; \ if(ab >= p) ab -= p; \ test <<= 1; \ a++; \ if((a & LONG_MASK) == 0) \ { help[n] = work; n++; work = 0UL; test = 1UL; } \ } \ help[n] = work; \ } \ \ { /* fill the bit pattern from help[] into sieve[b][]. \ sieve[b][a0] has the same semantics as help[b][a0], \ but here, a0 runs from 0 to p-1 and all bits are filled. */ \ register unsigned long *si = (unsigned long *)args->ba_next; \ register long a1; \ register long a; \ \ args->ba_next += p*sizeof(ratpoints_bit_array); \ /* copy the first chunk from help[] into sieve[num][b][] */ \ for(a = 0; a < wp; a++) si[a] = help[a]; \ /* now keep repeating the bit pattern, rotating it in help */ \ for(a1 = a ; a < p; a++) \ { register long t = (a1 == wp) ? 0 : a1+1; \ help[a1] |= help[t]<>= diff; \ } \ /* copy into the next p long words */ \ for(a = 0; a < p; a++) \ { si[a+p] = si[a]; } \ /* set sieve array */ \ se->sieve[b] = (ratpoints_bit_array *)si; \ return((ratpoints_bit_array *)si); \ } \ } #else /* The following is for primes < LONG_LENGTH */ #define CODE_INIT_SIEVE1(prime) \ static ratpoints_bit_array *sieve_init_##prime(void *se1, long b1, void *args1) \ { \ ratpoints_sieve_entry *se = se1; \ ratpoints_args *args = args1; \ register int *isfs = se->is_f_square; \ register long b = b1; \ long lmp = LONG_LENGTH % (prime); \ long ldp = LONG_LENGTH / (prime); \ long p1 = (ldp + 1) * (prime); \ long diff_shift = p1 & LONG_MASK; \ long diff = LONG_LENGTH - diff_shift; \ register unsigned long help0;\ { register long a; \ register long d = se->inverses[b]; \ register long ab = 0; /* a/b mod p */ \ register unsigned long test = 1UL; \ register unsigned long he0 = 0UL; \ for(a = 0; a < (prime); a++) \ { if(isfs[ab]) { he0 |= test; } \ ab += d; \ if(ab >= (prime)) ab -= (prime); \ test <<= 1; \ } \ help0 = he0; \ } \ \ { register unsigned long help1; \ { /* repeat bit pattern floor(LONG_LENGTH/p) times */ \ register unsigned long pattern = help0; \ register long i; \ /* the p * (floor(LONG_LENGTH/p) + 1) - LONG_LENGTH \ = p - (LONG_LENGTH mod p) \ upper bits into help[b][1] : \ shift away the LONG_LENGTH mod p lower bits */ \ help1 = pattern >> lmp; \ for(i = (prime); i < LONG_LENGTH; i <<= 1) \ { help0 |= help0 << i; } \ /* \ for(i = ldp; i; i--) \ { pattern <<= (prime); help0 |= pattern; } \ */ \ } \ \ { /* fill the bit pattern from help0/help1 into sieve[b][]. \ sieve[b][a0] has the same semantics as help0/help1, \ but here, a0 runs from 0 to p-1 and all bits are filled. */ \ register long a; \ unsigned long *si = (unsigned long *)args->ba_next; \ \ args->ba_next += (prime)*sizeof(ratpoints_bit_array); \ /* copy the first chunk into sieve[b][] */ \ si[0] = help0; \ /* now keep repeating the bit pattern, \ rotating it in help0/help1 */ \ for(a = 1 ; a < (prime); a++) \ { register unsigned long temp = help0 >> diff; \ help0 = help1 | (help0 << diff_shift); \ si[a] = help0; \ help1 = temp; \ } \ /* set sieve array */ \ se->sieve[b] = (ratpoints_bit_array *)si; \ return((ratpoints_bit_array *)si); \ } } \ } /* This is for p > LONG_LENGTH */ #define CODE_INIT_SIEVE2(prime) \ static ratpoints_bit_array *sieve_init_##prime(void *se1, long b1, void *args1) \ { \ ratpoints_sieve_entry *se = se1; \ ratpoints_args *args = args1; \ register long p = (prime); \ register int *isfs = se->is_f_square; \ register long b = b1; \ /* long ldp = 0; = LONG_LENGTH / p */ \ /* long p1 = p; = (ldp + 1) * p; */ \ long wp = p >> LONG_SHIFT; \ long diff_shift = p & LONG_MASK; \ long diff = LONG_LENGTH - diff_shift; \ unsigned long help[(p>>LONG_SHIFT) + 2]; \ \ /* initialize help */ \ { register unsigned long *he = &help[0]; \ register unsigned long *he1 = &he[(p>>LONG_SHIFT) + 2]; \ while(he1 != he) { he1--; *he1 = 0UL; } \ } \ { register unsigned long work = 0UL; \ register long a; \ register long ab = 0; /* a/b mod p */ \ register long d = se->inverses[b]; \ register long n = 0; \ register unsigned long test = 1UL; \ for(a = 0; a < p; ) \ { if(isfs[ab]) { work |= test; } \ ab += d; \ if(ab >= p) ab -= p; \ test <<= 1; \ a++; \ if((a & LONG_MASK) == 0) \ { help[n] = work; n++; work = 0UL; test = 1UL; } \ } \ help[n] = work; \ } \ \ { /* fill the bit pattern from help[] into sieve[b][]. \ sieve[b][a0] has the same semantics as help[b][a0], \ but here, a0 runs from 0 to p-1 and all bits are filled. */ \ register unsigned long *si = (unsigned long *)args->ba_next; \ register long a1; \ register long a; \ \ args->ba_next += p*sizeof(ratpoints_bit_array); \ /* copy the first chunk from help[] into sieve[num][b][] */ \ for(a = 0; a < wp; a++) si[a] = help[a]; \ /* now keep repeating the bit pattern, rotating it in help */ \ for(a1 = a ; a < p; a++) \ { register long t = (a1 == wp) ? 0 : a1+1; \ help[a1] |= help[t]<>= diff; \ } \ /* set sieve array */ \ se->sieve[b] = (ratpoints_bit_array *)si; \ return((ratpoints_bit_array *)si); \ } \ } #endif #include "init_sieve.h" ratpoints-2.1.3/sturm.c0000644000175000001440000002712411536145472014325 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.2 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * sturm.c * * * * Sturm sequence and positivity intervals * * * * Michael Stoll, Jan 9, 2008 * ***********************************************************************/ #include "ratpoints.h" /************************************************************************** * Arguments of _ratpoints_compute_sturm() : (from the args argument) * * * * + cofs - points to an array of mpz_t's holding the coefficients of * * the polynomial * * + degree - the degree of the polynomial * * + iter - the number of iteration steps in the refinement of the * * intervals * * + ivlist - points to an array of intervals giving the current search * * domain * * + num_iv - the number of intervals in ivlist, must be > 0 * * * * NOTE: ivlist must be able to store 1 + floor(degree/2) additional * * intervals. * * * * Return values : * * + >0 - normal operation, ivlist modified (intersection with positivity * * domain), return value is number of intervals * * + 0 - polynomial is everywhere negative, ivlist may be changed * * + -1 - polynomial is not squarefree, ivlist unchanged * **************************************************************************/ /* A helper function: evaluate the polynomial in cofs[] of given degree at num/2^denexp and return the sign. */ static long eval_sign(ratpoints_args *args, mpz_t *cofs, long degree, long num, long denexp) { long n, e, s; mpz_t *work = args->work; /* Horner scheme... */ mpz_set(work[0], cofs[degree]); for(n = degree-1, e = denexp; n >= 0; n--, e += denexp) { mpz_mul_si(work[0], work[0], num); mpz_mul_2exp(work[1], cofs[n], e); mpz_add(work[0], work[0], work[1]); } s = mpz_cmp_si(work[0], 0); return(s); } long _ratpoints_compute_sturm(ratpoints_args *args) { mpz_t *cofs = args->cof; long degree = args->degree; long iter = args->sturm; ratpoints_interval *ivlist = args->domain; long num_iv = args->num_inter; long n, m, k, new_num; mpz_t sturm[degree+1][degree+1]; /* Array to hold the polynomials */ long sturm_degs[degree+1]; /* The degrees of the polynomials */ mpz_t *work = args->work; long count1 = 0, count2 = 0; /* first initialize */ for(n = 0; n <= degree; n++) for(m = 0; m <= degree; m++) { mpz_init(sturm[n][m]); } /* copy polynomial f into first entry */ for(n = 0; n <= degree; n++) mpz_set(sturm[0][n], cofs[n]); sturm_degs[0] = degree; /* compute derivative in second entry */ for(n = 0; n < degree; n++) { mpz_set(work[2], cofs[n+1]); mpz_mul_si(sturm[1][n], work[2], n+1); } sturm_degs[1] = degree - 1; /* now do polynomial divisions ... */ for(k = 2; k <= degree; k++) { long d1 = sturm_degs[k-1], d2 = sturm_degs[k-2]; /* first copy sturm[k-2] into sturm[k] */ for(n = 0; n <= degree - (k-2); n++) mpz_set(sturm[k][n], sturm[k-2][n]); /* now build linear combination that reduces the degree */ while(d2 >= d1) { mpz_gcd(work[2], sturm[k-1][d1], sturm[k][d2]); mpz_fdiv_q(work[0], sturm[k-1][d1], work[2]); mpz_fdiv_q(work[1], sturm[k][d2], work[2]); if(mpz_cmp_si(work[0], 0) < 0) { mpz_neg(work[0], work[0]); mpz_neg(work[1], work[1]); } /* sturm[k] = work[0] * sturm[k] - work[1] * x^(d2-d1) * sturm[k-1] */ for(n = 0; n <= d1; n++) { mpz_mul(sturm[k][n+d2-d1], sturm[k][n+d2-d1], work[0]); mpz_submul(sturm[k][n+d2-d1], work[1], sturm[k-1][n]); } for(n = 0; n < d2-d1; n++) { mpz_mul(sturm[k][n], sturm[k][n], work[0]); } d2--; while(mpz_cmp_si(sturm[k][d2], 0) == 0 && d2 >= 0) d2--; if(d2 < 0) /* not squarefree */ { for(n = 0; n <= degree; n++) for(m = 0; m <= degree; m++) { mpz_clear(sturm[n][m]); } return(-1); } } /* change sign */ for(n = 0; n <= d2; n++) mpz_neg(sturm[k][n], sturm[k][n]); /* normalize */ mpz_set_ui(work[2], 0); for(n = 0; n <= d2; n++) { mpz_gcd(work[2], work[2], sturm[k][n]); if(mpz_cmp_ui(work[2], 1) == 0) break; } if(mpz_cmp_ui(work[2], 1) != 0) { for(n = 0; n <= d2; n++) mpz_fdiv_q(sturm[k][n], sturm[k][n], work[2]); } sturm_degs[k] = d2; if(d2 == 0) break; /* sturm[k] is constant */ } /* compute number of real zeros */ for(n = 0; n < k; n++) { long d1 = sturm_degs[n], d2 = sturm_degs[n+1]; int s1 = mpz_cmp_si(sturm[n][d1], 0), s2 = mpz_cmp_si(sturm[n+1][d2], 0); if(s1 != s2) count1++; if(d1 & 1) s1 = -s1; if(d2 & 1) s2 = -s2; if(s1 != s2) count2++; } if(count2 == count1 && mpz_cmp_si(cofs[0], 0) < 0) { /* no real roots, negative constant term ==> no points */ for(n = 0; n <= degree; n++) for(m = 0; m <= degree; m++) { mpz_clear(sturm[n][m]); } args->num_inter = 0; return(0); } /* Find list of intervals that may contain points */ /* recall: typedef struct {double low; double up;} ratpoints_interval; */ { ratpoints_interval ivlocal[1 + (degree>>1)]; ratpoints_interval *iptr = &ivlocal[0]; long max = (long)(((unsigned long)(-1))>>1); long min = -max; long num_intervals; long slcf = mpz_cmp_si(cofs[degree], 0); /* recursive helper function */ void iterate(long nl, long nr, long del, long der, long cleft, long cright, long sl, long sr, long depth) { /* nl/2^del, nr/2^der : interval left/right endpoints, cleft, cright: sign change counts at endpoints, sl, sr: signs at endpoints, depth: iteration depth */ if(cleft == cright && sl < 0) { return; } /* here we know the polynomial is negative on the interval */ if((cleft == cright && sl > 0) || depth >= iter) /* we have to add/extend an interval if we either know that the polynomial is positive on the interval (first condition) or the maximal iteration depth has been reached (second condition) */ { double l = ((double)nl)/((double)(1<low = l; iptr->up = u; iptr++; } else { if((iptr-1)->up == l) /* extend interval */ { (iptr-1)->up = u; } else /* new interval */ { iptr->low = l; iptr->up = u; iptr++; } } return; } /* now we must split the interval and evaluate the sturm sequence at the midpoint */ { long nm, dem, s0, s1, s2, s, cmid = 0, n; if(nl == min) { if(nr == max) { nm = 0; dem = 0; } else { nm = (nr == 0) ? -1 : 2*nr; dem = 0; } } else { if(nr == max) { nm = (nl == 0) ? 1 : 2*nl; dem = 0; } else /* "normal" case */ { if(del == der) /* then both are zero */ { if(((nl+nr) & 1) == 0) { nm = (nl+nr)>>1; dem = 0; } else { nm = nl+nr; dem = 1; } } else /* here one de* is greater */ { if(del > der) { nm = nl + (nr<<(del-der)); dem = del+1; } else { nm = (nl<<(der-del)) + nr; dem = der+1; } } } } s0 = eval_sign(args, sturm[0], sturm_degs[0], nm, dem); s1 = eval_sign(args, sturm[1], sturm_degs[1], nm, dem); if(s0*s1 == -1) { cmid++; } s = (s1 == 0) ? s0 : s1; for(n = 2; n <= k; n++) { s2 = eval_sign(args, sturm[n], sturm_degs[n], nm, dem); if(s2 == -s) { cmid++; s = s2; } else if(s2 != 0) { s = s2; } } /* now recurse */ iterate(nl, nm, del, dem, cleft, (s0==0) ? (cmid+1) : cmid, sl, (s0==0) ? -s1 : s0, depth+1); iterate(nm, nr, dem, der, cmid, cright, (s0==0) ? s1 : s0, sr, depth+1); } } /* end iterate() */ iterate(min, max, 0, 0, count2, count1, (degree & 1) ? -slcf : slcf, slcf, 0); num_intervals = iptr - &ivlocal[0]; /* intersect with given intervals */ { ratpoints_interval local_copy[num_iv]; long n, n1, n2; /* make a copy of the given list */ for(n = 0; n < num_iv; n++) local_copy[n] = ivlist[n]; n1 = 0; n2 = 0; n = 0; while(n1 < num_intervals && n2 < num_iv) { if(ivlocal[n1].low <= local_copy[n2].low) { if(ivlocal[n1].up < local_copy[n2].low) { n1++; } /* can forget this interval */ else { if(ivlocal[n1].up <= local_copy[n2].up) { /* note intersection */ ivlist[n].low = local_copy[n2].low; ivlist[n].up = ivlocal[n1].up; n++; n1++; } else { /* note intersection */ ivlist[n] = local_copy[n2]; n++; n2++; } } } else /* here, ivlocal[n1].low > local_copy[n2].low */ { if(local_copy[n2].up < ivlocal[n1].low) { n2++; } /* can forget this interval */ else { if(local_copy[n2].up <= ivlocal[n1].up) { /* note intersection */ ivlist[n].low = ivlocal[n1].low; ivlist[n].up = local_copy[n2].up; n++; n2++; } else { /* note intersection */ ivlist[n] = ivlocal[n1]; n++; n1++; } } } } args->num_inter = new_num = n; } } for(n = 0; n <= degree; n++) for(m = 0; m <= degree; m++) { mpz_clear(sturm[n][m]); } return(new_num); } ratpoints-2.1.3/ratpoints.h0000644000175000001440000001057311536145472015203 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.3 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * ratpoints.h * * * * Header file for the ratpoints program and library * * * * Michael Stoll, September 21, 2009 * ***********************************************************************/ #include #define RATPOINTS_MAX_DEGREE 100 /* max. degree of f(x) */ #define RATPOINTS_ARRAY_SIZE 256 /* Array size in longs */ #define RATPOINTS_DEFAULT_SP1 9 /* Default value for sp1 */ #define RATPOINTS_DEFAULT_SP2 16 /* Default value for sp2 */ #define RATPOINTS_DEFAULT_NUM_PRIMES 28 /* Default value for num_primes */ #define RATPOINTS_DEFAULT_STURM 10 /* Default value for sturm_iter */ #define RATPOINTS_DEFAULT_MAX_FORBIDDEN 30 /* Default value for max_forbidden */ typedef struct {double low; double up;} ratpoints_interval; typedef struct { mpz_t *cof; long degree; long height; ratpoints_interval *domain; long num_inter; long b_low; long b_high; long sp1; long sp2; long array_size; long sturm; long num_primes; long max_forbidden; unsigned int flags; /* from here: private data */ mpz_t *work; long work_length; void *se_buffer; void *se_next; void *ba_buffer; void *ba_next; int *int_buffer; int *int_next; void *sieve_list; void *den_info; void *divisors; void *forb_ba; void *forbidden; } ratpoints_args; /* Define the flag bits for the flags component: */ #define RATPOINTS_NO_CHECK (unsigned int)0x0001 #define RATPOINTS_NO_Y (unsigned int)0x0002 #define RATPOINTS_NO_REVERSE (unsigned int)0x0004 #define RATPOINTS_NO_JACOBI (unsigned int)0x0008 #define RATPOINTS_VERBOSE (unsigned int)0x0010 #define RATPOINTS_FLAGS_INPUT_MASK \ (RATPOINTS_NO_CHECK | RATPOINTS_NO_Y | RATPOINTS_NO_REVERSE | \ RATPOINTS_NO_JACOBI | RATPOINTS_VERBOSE) /* Flags bits for internal purposes */ #define RATPOINTS_REVERSED (unsigned int)0x0100 #define RATPOINTS_CHECK_DENOM (unsigned int)0x0200 #define RATPOINTS_USE_SQUARES (unsigned int)0x0400 #define RATPOINTS_USE_SQUARES1 (unsigned int)0x0800 #define RATPOINTS_COMPUTE_BC (unsigned int)0x2000 /* Return values of find_points() */ #define RATPOINTS_NON_SQUAREFREE (-1) #define RATPOINTS_BAD_ARGS (-2) #define RATPOINTS_WORK_LENGTH_TOO_SMALL (-3) long find_points(ratpoints_args*, int proc(long, long, const mpz_t, void*, int*), void*); void find_points_init(ratpoints_args*); long find_points_work(ratpoints_args*, int proc(long, long, const mpz_t, void*, int*), void*); void find_points_clear(ratpoints_args*); ratpoints-2.1.3/testdata.h0000644000175000001440000005662011536145472014774 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.2 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * testdata.h * * * * A list of 1000 genus 2 curves to serve as test data for ratpoints * * * * Michael Stoll, Jan 9, 2008 * ***********************************************************************/ #define NUM_TEST 1000 long testdata[NUM_TEST][7] = { {-10,-8,1,-2,0,-5,-4}, {4,-6,-4,-7,-8,5,-3}, {4,-8,2,-3,-1,0,-6}, {0,5,6,2,-7,4,-8}, {-5,10,-9,-6,7,-1,3}, {0,-8,-6,-9,-8,-6,-9}, {-6,5,7,-10,-1,1,-2}, {-2,9,-3,-3,-4,-2,-3}, {7,-7,-2,5,-1,8,7}, {-6,10,-6,9,-3,-7,-2}, {-3,-8,10,6,3,7,-7}, {-5,5,8,7,-2,2,-3}, {-8,5,9,-6,-2,-6,-1}, {0,6,0,-9,6,2,-3}, {2,1,-5,9,-9,1,-2}, {-5,8,-4,-5,10,-10,-5}, {-2,3,1,4,-5,7,3}, {-8,-8,4,8,7,3,-6}, {6,6,-5,-8,-5,-5,-2}, {6,-10,-6,-6,-7,-8,-8}, {4,10,-9,-1,6,10,3}, {1,2,7,3,-7,-9,-2}, {-7,-5,-2,0,-3,-9,2}, {3,1,-7,-3,4,7,3}, {-3,7,6,-3,-1,7,-8}, {-8,-3,0,-3,4,7,4}, {10,10,5,-7,0,3,-2}, {-7,-3,10,-4,-3,-7,3}, {7,-8,-2,7,-4,1,3}, {3,-3,-9,-10,5,-2,-1}, {4,9,-7,8,-3,1,10}, {-4,-9,-7,-3,9,7,8}, {-2,5,7,4,0,6,4}, {0,1,1,-1,4,4,9}, {8,4,-4,1,-3,-10,3}, {-10,-10,-3,9,7,0,-4}, {-7,-1,7,-9,9,-5,-7}, {0,5,1,-4,10,-2,-3}, {4,6,-6,1,-7,-8,-9}, {2,-7,-4,3,-2,-8,2}, {1,8,-8,-5,-2,9,-4}, {-6,9,-10,2,9,5,2}, {1,-4,-6,-9,-1,-3,-4}, {-2,4,3,1,-2,-10,10}, {9,5,-10,1,-10,-10,5}, {-1,6,-3,4,-6,-6,-2}, {3,4,-6,-6,-9,5,-1}, {4,-8,-2,6,6,3,8}, {2,0,3,0,10,4,5}, {-10,3,0,1,5,8,2}, {8,6,-2,5,-3,3,-9}, {10,-10,-3,-4,8,8,7}, {6,10,-4,-3,-9,-10,8}, {-5,-1,-3,-4,5,10,9}, {0,8,10,10,-8,8,-2}, {8,-4,-2,-10,-1,9,9}, {9,2,5,1,4,9,10}, {1,-2,6,-7,-4,-8,1}, {-6,8,-2,0,7,-5,-2}, {-4,-5,-7,8,-4,-4,-1}, {6,9,-9,3,-8,10,10}, {9,-5,5,2,2,1,1}, {-7,-2,1,8,2,-8,-1}, {5,-6,7,-7,6,-6,9}, {9,10,4,1,-1,7,-7}, {0,1,10,7,-9,-8,9}, {-10,9,5,-9,4,-3,6}, {-7,-6,5,9,-7,-10,-7}, {-8,-5,6,-7,-1,-4,-2}, {-4,7,6,0,3,1,-4}, {2,4,5,7,-10,-9,1}, {-3,9,-5,9,2,-8,2}, {7,2,10,-1,-4,-10,-2}, {0,-4,-9,-4,-4,-6,-10}, {9,1,-4,-4,4,7,6}, {-2,-1,6,8,4,-8,-10}, {9,-8,-5,9,2,-5,8}, {5,0,10,-10,2,5,-6}, {6,0,9,-7,-8,0,-2}, {6,3,-6,3,8,10,-9}, {-7,-2,-6,-1,10,-2,-5}, {-7,3,-5,9,1,-8,6}, {-5,7,-8,10,1,-9,1}, {6,-6,-7,0,6,3,-4}, {-2,-2,-10,-7,-5,-3,0}, {-6,-6,-3,-4,-9,-10,6}, {7,-6,0,10,-1,1,-8}, {10,9,-9,2,1,9,-3}, {-6,-4,-9,5,-10,10,8}, {-10,-8,-10,8,-1,-9,9}, {3,-3,-9,-4,-6,-8,-4}, {-2,8,9,-6,5,-7,-6}, {6,9,-9,3,7,10,-5}, {6,10,2,-5,0,-6,-9}, {9,-6,6,-9,-8,7,-1}, {1,0,-9,7,-10,-7,-10}, {4,-3,3,5,-4,-5,2}, {-9,-3,8,-6,2,9,3}, {10,-4,1,4,10,1,-5}, {5,10,0,-8,-9,6,3}, {-9,5,-4,-5,4,-4,6}, {1,-2,5,-5,-9,3,2}, {-8,-3,6,1,9,0,10}, {-3,-5,-3,-7,5,-4,-8}, {-7,8,7,1,-3,10,-4}, {8,0,8,9,9,-7,0}, {-5,-8,-3,10,-9,4,-8}, {3,-9,10,3,4,-9,-7}, {6,-8,-1,10,2,-5,-9}, {8,4,-6,-1,3,3,2}, {9,5,9,4,5,3,-9}, {-3,4,-5,9,-7,8,-7}, {3,9,-5,8,0,1,-4}, {-1,3,10,0,-3,2,1}, {7,-10,0,8,-10,3,10}, {7,-6,-4,2,0,-4,0}, {-8,4,-8,6,10,-9,2}, {-1,-10,-5,-2,1,9,6}, {-10,-4,2,9,4,7,-3}, {5,1,4,2,-7,4,-4}, {0,4,2,-10,-3,5,6}, {4,4,3,6,4,3,-1}, {-10,10,-10,8,-8,-6,-9}, {7,7,10,-9,-5,-1,-3}, {-7,10,4,-3,1,1,3}, {-10,5,-8,4,1,4,-4}, {-3,1,-1,8,10,4,8}, {2,10,3,-7,-1,-3,-6}, {-7,8,0,7,10,2,-6}, {-3,-4,-5,-2,1,-1,-5}, {-2,10,-4,8,-7,-4,-2}, {9,0,10,8,-4,4,-7}, {3,9,-5,0,1,4,7}, {1,10,4,9,1,-10,5}, {7,-6,-10,10,-8,2,-7}, {7,-3,7,10,-7,-6,6}, {4,4,2,4,10,-1,3}, {-4,-6,10,10,7,-5,-9}, {6,-8,1,-9,2,8,-7}, {3,-5,-6,-5,7,3,-2}, {9,8,-7,8,7,3,8}, {7,4,-4,6,4,-7,-6}, {-3,10,-1,1,4,-9,0}, {-3,5,-2,-6,9,-6,7}, {4,7,3,9,4,2,-7}, {-10,-3,1,10,5,-9,5}, {-5,5,-9,7,10,2,-3}, {7,1,0,6,-5,9,-6}, {-5,1,-7,-9,-1,9,-4}, {7,-6,-9,5,-2,-3,-6}, {0,6,9,-5,8,-5,10}, {9,10,-2,9,9,-3,5}, {-4,7,8,0,-6,-1,-1}, {4,5,7,-3,5,-9,4}, {-5,-7,8,5,-8,-5,-1}, {-10,5,-10,0,-2,2,10}, {7,7,5,-9,-10,2,1}, {1,-10,-8,1,3,4,-8}, {-8,4,10,1,-10,2,2}, {7,2,-4,-2,-10,-3,3}, {3,-5,-6,-2,-5,2,9}, {-3,-6,-9,-7,-3,3,-8}, {-6,-4,0,-1,9,-3,-8}, {-7,9,9,-7,4,0,-1}, {2,4,4,1,-9,10,-10}, {9,-1,-8,6,8,1,-2}, {10,-10,5,10,9,-10,-3}, {10,0,-10,-6,6,-7,2}, {10,0,-1,3,10,2,-3}, {-10,10,-2,7,5,-9,10}, {-2,-8,7,-6,6,9,10}, {6,5,2,-1,3,2,-4}, {9,5,-10,-6,-1,3,0}, {-2,-10,5,4,8,-6,-5}, {8,-4,-3,2,4,-5,-5}, {2,4,10,-4,8,-2,7}, {-4,10,8,9,1,-2,8}, {4,5,6,4,-8,9,8}, {-3,-6,4,1,6,2,-6}, {-8,8,-9,9,-7,-1,-3}, {7,-2,-9,10,1,4,-10}, {-1,-5,-5,-7,-9,4,-3}, {-3,8,2,0,-6,9,9}, {-4,5,0,-10,-4,-6,-8}, {-10,-6,-7,-6,-9,-2,4}, {-2,-5,-1,0,8,3,-10}, {-4,-3,6,9,-5,1,-8}, {2,0,6,8,-8,-2,-9}, {2,4,2,-7,-2,-4,-7}, {2,-7,-4,7,-2,9,7}, {3,-7,-3,0,1,1,-4}, {-4,-7,1,7,1,-4,-3}, {8,7,-4,-3,0,-2,3}, {-3,-7,1,8,3,-2,1}, {3,0,-7,2,-6,5,-7}, {-4,-2,-6,-3,-6,-2,10}, {5,10,1,10,10,-6,-4}, {-4,6,5,-10,2,6,-3}, {4,-5,2,3,-10,3,8}, {-5,4,-10,4,6,0,-2}, {-7,-3,-9,7,-3,2,1}, {1,-9,-9,2,8,8,7}, {-7,1,-7,-7,1,-6,-10}, {-9,1,-2,-5,3,5,-3}, {-3,-9,-3,9,6,-9,4}, {-2,9,-9,5,5,-7,8}, {5,-10,8,-8,-3,-8,-10}, {0,1,-7,7,6,3,-8}, {-1,-9,4,-8,-5,-6,-2}, {-6,5,1,8,-8,3,-3}, {6,8,-4,1,3,9,-1}, {4,-6,7,10,-9,-7,-8}, {1,7,-3,3,0,-10,-1}, {4,-6,-2,3,-1,7,-6}, {5,-8,-2,-4,-6,10,-5}, {10,-3,2,-1,-6,-8,-1}, {1,2,-5,-10,-7,-4,-1}, {7,-8,4,0,5,4,1}, {3,6,-2,2,6,-6,1}, {8,-4,6,1,-9,8,-8}, {-4,-6,8,5,-5,-4,5}, {-7,-3,8,-6,1,-6,-4}, {8,-4,-10,-3,10,4,4}, {-4,4,3,-7,1,-3,-8}, {6,-5,-4,-5,-7,-5,9}, {-10,6,-9,-8,2,2,2}, {-7,1,10,-9,10,-2,-4}, {9,0,-8,8,-3,10,2}, {3,-4,2,8,10,2,-1}, {2,8,-8,6,-6,7,8}, {1,5,-8,-4,-8,-7,7}, {-3,4,-5,-6,-10,-1,7}, {9,-6,-3,3,-6,-1,-1}, {-6,4,-10,6,-10,-4,-1}, {-4,-7,-4,4,-2,-8,7}, {4,8,-2,-2,-3,-7,-5}, {5,-10,0,2,-9,-4,-7}, {8,-7,-5,-6,0,7,-5}, {7,-9,4,10,-7,1,6}, {10,-8,1,8,0,-3,8}, {3,3,2,-2,-6,-2,-10}, {1,0,-8,5,6,-1,-8}, {-5,6,0,10,7,-4,-10}, {10,-5,2,5,6,8,7}, {7,2,7,-6,-8,-2,2}, {3,7,3,8,-3,-4,1}, {8,-2,9,0,-5,9,-3}, {6,0,5,-6,-9,-3,-2}, {-5,-8,-10,2,1,-2,-1}, {3,1,-9,5,-10,8,-8}, {6,-7,-4,-8,-2,-1,-4}, {-1,0,0,5,-2,-9,2}, {-7,10,-2,-2,-7,-7,-2}, {6,4,-3,-3,-1,-9,5}, {10,6,5,4,-1,-1,-4}, {-8,-4,-2,7,3,9,1}, {5,0,3,-6,0,10,-2}, {5,-10,7,7,5,2,5}, {1,3,4,-10,3,2,-8}, {-2,-1,4,-10,-10,-3,-7}, {-9,1,6,1,4,0,9}, {6,9,10,-4,2,6,10}, {0,2,-3,-1,-4,6,-1}, {1,-4,-7,-2,3,1,6}, {-1,-4,0,-2,-3,4,8}, {-8,4,-9,-4,-5,5,-6}, {-1,4,6,-9,6,-5,0}, {-6,-1,-3,5,-6,4,-7}, {6,-10,10,2,3,5,1}, {-10,-8,-1,7,-8,-2,5}, {3,-2,3,8,4,7,10}, {7,-4,8,5,-1,3,5}, {4,10,7,0,5,-3,5}, {-8,-3,-8,7,-3,-10,1}, {9,7,2,3,-7,-3,-3}, {-9,-7,-2,9,-2,-4,4}, {-4,-7,3,9,5,4,-5}, {3,3,4,10,-6,2,5}, {-9,2,9,0,-9,2,3}, {-6,-7,-1,-1,-7,-10,1}, {-6,8,9,-10,-3,-4,8}, {4,9,7,-4,4,1,10}, {6,6,4,-5,-2,-8,-6}, {-8,5,10,-2,1,1,3}, {-3,-2,2,-3,0,8,-4}, {9,2,6,8,9,8,-1}, {5,9,5,-10,10,3,-8}, {-4,1,-9,-4,-2,0,-9}, {10,7,4,3,-4,-7,-6}, {-5,9,-6,-9,-6,-6,4}, {9,0,-6,3,-9,-8,-6}, {-4,0,4,-5,8,-10,9}, {3,-7,5,5,9,-6,-10}, {-4,-5,2,9,5,-3,-10}, {5,6,0,2,-6,10,0}, {-7,-8,-1,10,-10,-3,-8}, {-9,6,2,-2,3,7,-9}, {-7,-3,-10,-6,-6,9,1}, {3,-10,9,2,10,7,9}, {-5,9,-9,9,-7,1,-5}, {6,-2,3,-3,3,-8,-8}, {9,-7,1,-9,-9,-6,-5}, {-3,-2,-5,1,0,0,-8}, {3,3,-6,-7,3,-8,-2}, {10,-9,-8,1,-4,8,6}, {-8,3,5,3,-4,-8,0}, {-3,3,-9,-7,5,-5,-8}, {8,10,-1,9,7,10,-3}, {-2,1,10,9,-2,-6,1}, {9,4,-6,9,-7,2,4}, {7,-8,-6,2,-6,2,-2}, {9,-9,0,8,4,0,-9}, {-4,-6,-3,6,9,9,9}, {-3,-6,-2,-7,6,0,10}, {5,-4,-7,0,-3,8,-8}, {7,1,5,-2,-7,-7,-7}, {4,-3,5,-6,7,-1,-6}, {6,-2,-4,4,-9,7,8}, {9,4,-3,8,1,7,3}, {0,-2,-8,-9,-2,4,10}, {-3,6,9,8,-3,-2,10}, {-8,-10,7,-8,6,6,-5}, {-8,-5,0,9,-9,-1,8}, {4,-1,10,1,5,-8,1}, {-4,5,4,0,-4,-9,-1}, {-9,8,-6,-8,2,-7,-6}, {-7,-8,8,9,5,6,9}, {7,-9,-3,2,-5,6,1}, {0,1,-1,0,-1,-5,0}, {3,-9,2,0,5,6,2}, {8,-7,-3,3,-8,-5,-4}, {10,8,-9,-7,3,2,2}, {10,5,3,-2,-6,9,-5}, {-10,7,5,-1,-6,3,-6}, {-10,-9,-1,-4,-10,-1,-1}, {4,7,10,-4,-1,3,1}, {-8,-7,0,-6,0,-6,4}, {0,2,-4,10,-7,2,9}, {8,-8,-1,9,5,-8,7}, {1,-10,-8,1,0,-5,-2}, {10,9,-10,6,8,9,-3}, {1,-3,-8,4,-7,-10,0}, {6,-7,-1,4,-1,-2,-5}, {8,6,-4,2,-2,-7,-6}, {10,-2,7,-10,-6,9,-8}, {4,2,9,6,-2,1,4}, {0,9,-4,-5,3,-4,-6}, {2,4,-4,-10,-9,-1,-1}, {4,6,10,2,2,-5,6}, {-9,3,-1,-9,-7,3,-10}, {4,9,-6,-5,3,-4,-1}, {4,9,-10,-7,-8,9,3}, {-2,8,0,8,5,5,-7}, {-7,9,1,-3,2,9,-8}, {-4,-1,-10,6,8,-6,-2}, {9,7,4,0,2,8,-4}, {4,9,-7,10,10,-10,-4}, {0,6,0,-8,-1,-2,1}, {-4,3,-5,1,-2,-9,-2}, {-7,-5,-8,-5,7,-5,8}, {8,1,-10,-8,-9,-10,6}, {-8,-3,-2,4,-5,2,-2}, {-5,-1,9,0,-6,-8,-5}, {-2,-7,-1,-3,7,-9,7}, {2,4,2,0,6,2,-7}, {7,-3,-1,7,-5,4,-2}, {-9,-8,-1,-2,10,-7,-4}, {0,-10,10,7,-8,-10,3}, {2,8,2,-4,4,0,-7}, {9,6,7,-8,10,-8,-10}, {-2,-9,-7,0,-2,-9,-7}, {-3,8,1,3,7,1,-2}, {-9,-2,-2,1,4,0,4}, {-9,4,-5,2,-9,7,2}, {-2,-9,5,2,-1,4,-5}, {2,2,-7,-10,5,-7,6}, {5,-7,2,-4,0,-1,-1}, {8,-1,2,10,10,-5,4}, {0,9,-2,-4,2,-5,-1}, {-9,4,-6,1,-7,-7,-3}, {4,-1,5,-4,3,-7,2}, {-3,9,-5,6,5,2,0}, {6,7,-4,9,-9,9,-4}, {8,-6,-5,-7,-3,2,7}, {-6,-8,1,2,8,5,-7}, {5,9,-7,2,-6,-8,5}, {0,-2,-7,-5,-9,-7,-7}, {-6,5,10,6,0,6,0}, {10,4,-6,0,-5,-8,4}, {-1,-3,-9,-7,1,-9,6}, {-3,-8,-4,-1,1,-7,5}, {-4,-6,7,10,7,6,10}, {8,7,-1,-8,-10,1,-9}, {3,7,1,8,1,-4,6}, {-7,1,-3,9,0,10,-7}, {-7,-6,8,-7,-6,2,3}, {3,0,4,-3,-5,-8,-2}, {6,1,2,-3,1,7,9}, {3,-6,5,9,-1,5,5}, {6,4,-3,6,0,-5,-4}, {-1,-4,1,-9,3,3,0}, {-2,-7,-8,-2,0,-2,-5}, {8,0,-3,1,-4,-3,6}, {-1,-7,-9,10,-4,-5,2}, {6,-4,-2,-1,-4,4,-2}, {3,-2,-7,-1,-9,2,-7}, {-9,-8,-8,-10,-7,6,-10}, {10,9,-4,1,5,-4,1}, {5,10,-9,-3,-3,-6,-10}, {10,6,-10,-7,3,8,-2}, {-7,10,5,6,-8,-1,5}, {-8,-8,-10,-6,6,-8,-8}, {-3,-8,9,-1,3,1,4}, {-10,-8,-9,8,-1,-10,1}, {3,-8,5,1,3,-10,-1}, {-8,5,1,9,-9,0,-3}, {8,-9,10,-10,-1,-10,-10}, {-1,5,-10,-4,-8,-10,8}, {-6,9,-8,10,-10,-3,4}, {3,-10,2,9,4,1,10}, {8,6,8,4,1,4,-9}, {3,-10,8,-5,-2,-10,8}, {10,-5,-3,7,-1,6,-2}, {6,-10,-4,-9,0,8,10}, {2,10,-6,6,10,10,-1}, {7,-8,4,-10,3,9,3}, {1,2,-3,-10,3,10,5}, {-5,-8,-6,9,-1,9,-6}, {9,-10,9,-6,8,3,-1}, {-7,1,-8,0,-10,-4,4}, {-10,1,0,3,4,3,10}, {10,-3,10,2,7,-4,3}, {-3,9,-6,-3,7,0,-6}, {-9,-3,0,1,4,1,-4}, {6,2,-4,6,0,-6,-4}, {7,-5,5,4,-9,6,-6}, {-10,-10,4,-2,7,-2,-7}, {8,-8,2,-6,10,2,1}, {5,-10,-2,1,-10,8,8}, {8,6,3,-9,-5,8,-7}, {5,2,8,8,0,6,-7}, {-4,3,-10,4,-3,4,-1}, {9,-3,-8,0,-8,-9,-6}, {-5,9,-6,-8,2,3,2}, {-1,10,-2,4,10,-9,-8}, {-5,-10,8,-7,-5,8,-3}, {-10,8,-4,8,4,-2,-7}, {-8,4,-1,-10,4,3,-4}, {9,-1,1,-9,9,4,-1}, {-7,-7,9,0,6,-3,-7}, {-2,-4,-8,3,9,9,-4}, {3,9,9,5,-9,8,7}, {-3,-4,-9,1,-2,4,9}, {-5,2,3,-6,-10,-9,3}, {-3,10,5,7,2,1,0}, {3,-10,9,-1,2,-2,-4}, {3,3,-6,-1,-6,3,-6}, {8,6,-9,7,-3,-4,2}, {-5,-1,4,-1,5,-1,-7}, {-8,8,0,-7,-8,-10,1}, {-1,0,10,2,8,-5,8}, {-2,-2,-8,-4,9,-8,-4}, {-10,-8,-1,8,2,0,2}, {-10,7,-4,3,-4,-6,1}, {1,2,-7,-3,-9,-7,2}, {-3,10,2,-6,-5,9,-1}, {0,4,-9,9,9,7,-6}, {5,2,-5,-3,-10,-9,10}, {-10,9,3,2,5,-5,3}, {-2,5,10,-10,5,3,-6}, {-9,1,0,5,8,10,-6}, {2,-6,-5,6,2,9,3}, {-4,9,-8,-2,0,-10,0}, {4,6,-9,-3,-2,-4,2}, {-8,-7,2,10,9,-5,4}, {-5,4,-5,6,6,2,-1}, {3,10,-3,-6,-10,-7,-1}, {8,6,-1,-1,9,1,-5}, {4,-8,-2,-9,-6,3,-1}, {8,-8,-7,-6,-10,3,-6}, {-1,6,7,-2,6,-10,1}, {5,1,6,-6,-5,-10,-8}, {-3,6,9,-3,-4,-9,-3}, {3,8,8,-10,-7,-1,3}, {10,0,-7,-4,7,-8,9}, {2,-9,2,-9,-8,10,8}, {-9,8,-3,5,1,-2,9}, {-7,4,-7,10,-2,5,-1}, {10,-1,-5,3,1,-1,0}, {10,3,5,-10,10,7,-1}, {2,-5,0,3,4,-7,-3}, {-5,-6,-9,7,-1,-9,9}, {8,6,-8,-10,3,1,8}, {0,1,-1,5,4,0,10}, {1,3,-1,-9,9,-6,-3}, {-7,0,1,8,7,8,4}, {1,8,0,-1,9,-2,4}, {-1,-8,-8,-3,-10,3,-10}, {7,0,-8,3,0,-6,-4}, {5,-3,-10,-10,8,-8,8}, {-4,-2,7,-7,0,-4,9}, {10,2,5,-2,-4,-7,-2}, {1,6,1,1,-1,-6,6}, {-1,-7,4,-1,-1,-6,-6}, {2,7,-1,1,-2,7,10}, {1,-6,2,-3,9,2,-4}, {1,10,6,-8,6,7,1}, {6,5,-3,-7,-6,8,-2}, {6,-1,-10,-4,5,3,3}, {10,1,4,-1,7,10,-4}, {7,2,-6,-9,6,-8,-6}, {-5,8,0,-3,7,5,-10}, {-2,0,0,8,-9,-4,0}, {9,-8,-6,1,6,10,1}, {-6,-7,3,-9,-9,6,-4}, {9,-2,-2,6,4,9,10}, {8,1,0,-4,-5,-9,10}, {-8,-2,6,9,0,6,6}, {10,10,4,1,9,-6,4}, {1,9,-1,2,10,9,10}, {2,-9,-6,-10,0,1,-1}, {-2,-1,-3,4,-5,6,-6}, {-3,7,9,5,8,9,-2}, {-5,5,8,10,8,7,9}, {-2,5,-10,3,4,10,-2}, {-10,-1,-6,10,6,-1,6}, {7,4,-1,-2,9,2,10}, {5,-8,-7,4,10,-8,-3}, {2,-2,6,4,5,-1,-5}, {8,2,-4,6,6,1,2}, {-9,2,-3,7,6,2,3}, {2,4,1,-2,-8,-10,-2}, {-6,-1,5,9,10,5,-1}, {-10,9,10,2,-7,-3,-8}, {2,-2,2,9,-2,0,-1}, {-6,-1,6,7,-8,0,-8}, {-4,-1,0,7,1,-4,-2}, {10,-6,2,2,10,-5,3}, {8,-10,-4,3,2,4,10}, {-9,3,1,-5,-10,-6,-5}, {9,-3,-2,-2,-8,-1,5}, {-5,3,-5,2,3,10,-2}, {5,-10,0,-7,1,8,-6}, {5,-6,-3,3,-7,0,7}, {9,4,1,1,-7,-8,-6}, {2,5,-5,-10,1,0,-3}, {0,8,9,-5,2,8,10}, {9,10,10,2,2,7,-6}, {-4,-2,-6,4,10,4,5}, {-8,-5,-8,4,8,-10,-6}, {-3,-4,7,-1,-10,7,6}, {-7,-5,-2,0,-6,-4,7}, {-7,5,2,-7,-5,1,-3}, {-6,0,8,-4,10,-4,-5}, {-10,-5,-8,-1,5,4,6}, {-7,-7,2,-5,8,0,2}, {9,-7,-7,2,-4,-1,4}, {10,-2,-7,-9,7,-5,0}, {9,-9,9,7,0,2,5}, {2,6,3,10,3,1,8}, {7,8,-8,0,-6,-4,1}, {-3,7,-10,4,5,4,1}, {-9,0,-7,-10,-8,8,9}, {3,-8,9,-5,2,-4,1}, {-10,-1,5,4,6,-5,4}, {-6,-2,-4,8,-1,-8,5}, {-7,-7,-7,-4,-7,-4,-8}, {-3,-10,0,7,-9,1,-4}, {-7,9,-8,3,8,8,-2}, {-2,-10,-5,7,-10,-10,-9}, {7,-2,9,1,3,4,6}, {10,-9,-10,-4,1,6,0}, {-4,10,1,9,-7,-4,-8}, {9,2,4,-8,-5,-5,1}, {-2,-3,-9,1,-6,-4,3}, {3,-3,-3,6,2,4,7}, {5,-3,-9,2,10,8,-6}, {-9,-4,2,0,-10,-8,-9}, {3,9,1,3,-8,-5,3}, {-2,-6,10,1,9,-4,-8}, {-10,3,-10,2,3,8,1}, {1,-3,-1,-4,0,-5,2}, {-7,5,10,8,2,-7,-3}, {-5,-6,9,-3,-10,-8,5}, {1,9,3,-4,-5,-2,-6}, {1,9,-1,-1,-10,-3,-3}, {10,4,3,7,-1,-2,-9}, {-4,-7,1,-3,5,6,8}, {8,10,-2,4,-6,-5,4}, {2,-10,-3,-9,5,6,9}, {-3,8,2,-1,-9,0,-2}, {1,-6,-8,-1,2,1,-2}, {-3,3,5,-4,10,-9,-10}, {-8,0,-2,5,-10,0,1}, {6,-5,-1,-6,0,0,-10}, {-10,0,3,1,0,7,6}, {7,-6,1,-6,9,3,2}, {4,-8,3,-3,-4,-10,9}, {-2,10,-8,-1,1,8,-5}, {-3,7,8,-1,-2,3,-3}, {-7,-6,-5,4,6,-4,3}, {2,9,-1,-1,3,-4,0}, {-5,-1,-10,0,-6,-3,-7}, {6,1,7,3,1,-9,-3}, {9,-7,0,-8,6,10,-3}, {-8,0,-3,-2,3,8,3}, {-9,-4,8,-2,0,7,-10}, {-6,7,-6,0,4,-8,6}, {6,-7,0,4,-2,5,-4}, {4,-5,5,-9,-7,8,3}, {8,-2,-9,-2,9,-5,8}, {5,1,10,10,-10,-6,-9}, {10,3,9,-4,1,-4,0}, {-4,-2,5,2,-7,9,-3}, {2,-5,3,8,8,2,9}, {-1,-4,10,-4,0,4,9}, {5,7,-3,-10,-3,-8,7}, {4,10,6,7,1,-3,3}, {4,-3,-8,9,-9,5,4}, {-8,1,-7,-9,4,-2,-9}, {0,5,-9,-8,0,1,-8}, {-5,-5,3,6,2,-10,-3}, {-4,-1,2,4,7,-4,-7}, {8,1,-5,9,1,1,1}, {-2,7,9,5,-1,-4,7}, {-8,6,8,-9,-7,-5,2}, {-10,9,2,-8,-10,5,-5}, {1,7,6,-2,9,-8,1}, {9,8,8,9,-1,-6,-3}, {9,-3,-1,6,7,-3,7}, {-8,0,-2,10,-2,-2,-5}, {-10,0,9,5,10,-7,-7}, {-8,-6,-6,-1,-9,-4,-7}, {-5,8,-6,-1,10,-3,2}, {3,-8,-6,10,10,-3,0}, {-8,6,4,0,-1,-8,-1}, {9,2,2,-5,8,-8,-1}, {9,-9,-6,8,-10,-10,5}, {-6,-3,-7,5,8,-10,6}, {-3,-8,-2,-9,1,-6,7}, {-3,-7,-1,2,1,7,0}, {4,4,-1,8,-9,-7,6}, {0,-2,4,0,9,-10,0}, {1,-1,5,-2,2,10,-6}, {2,5,2,5,-6,5,8}, {-6,-1,-3,6,0,2,10}, {-1,0,5,9,-4,-5,-3}, {1,-8,-4,-3,5,3,-4}, {1,9,-7,-9,-10,4,3}, {-5,6,-7,-10,7,-5,1}, {5,1,-4,-8,-3,10,-1}, {-10,8,4,-9,-2,3,-8}, {9,6,9,5,8,-6,1}, {5,-5,-7,-8,-10,0,-3}, {4,-9,-10,2,10,-6,-7}, {7,-3,2,-6,0,6,-4}, {5,5,1,2,10,7,-7}, {1,8,7,8,-3,-1,-9}, {-7,9,7,1,-10,7,8}, {-3,2,-6,3,3,-1,-7}, {0,-2,6,6,3,-9,-10}, {4,-5,7,-8,-6,9,3}, {9,-10,3,8,6,-2,3}, {-7,-6,10,1,-6,-6,1}, {10,2,-3,-10,2,-5,10}, {10,9,-7,-10,2,8,-6}, {-1,6,-5,1,-2,0,-5}, {-5,-4,3,3,0,-8,-2}, {-4,5,7,6,2,-7,3}, {-10,2,4,-4,6,6,0}, {2,6,0,3,1,-6,6}, {-3,1,-7,2,-9,4,1}, {5,7,-3,4,6,-5,-1}, {-9,4,9,-10,-7,10,6}, {-1,1,-9,-6,-4,-3,-5}, {1,-6,2,8,-3,-3,-8}, {2,-8,-8,-10,4,-9,-1}, {-10,-2,2,-5,5,2,-1}, {8,-1,-7,-1,-9,-4,7}, {-10,6,-7,-10,6,7,7}, {-1,-6,9,-10,-2,-4,-8}, {0,5,-9,-10,-7,-5,-7}, {9,2,1,-1,0,-4,-5}, {3,1,-4,-8,-3,-9,7}, {-10,-9,-1,7,-2,-1,-7}, {-10,7,2,2,8,2,-7}, {2,2,10,-5,-10,6,8}, {5,-9,-8,1,-10,-1,6}, {0,-5,-3,10,8,-9,-6}, {7,-3,2,-10,-8,-7,7}, {9,5,6,1,0,0,10}, {3,3,-8,7,2,6,4}, {2,10,-3,7,4,-4,-8}, {-4,6,7,4,0,8,7}, {-5,5,8,-7,-9,-2,-1}, {-3,-6,-8,-6,4,2,-1}, {5,-7,-5,5,8,-3,-10}, {6,-1,0,-8,10,7,10}, {6,10,3,-7,-8,-6,-2}, {-9,-10,4,6,3,-8,6}, {-1,8,-1,-2,-10,-6,-1}, {-2,2,6,-7,-5,-4,8}, {4,-8,5,2,1,-8,5}, {8,1,-8,-6,-4,6,7}, {8,1,9,3,8,-7,-5}, {-8,10,-6,-7,-6,-2,-5}, {-5,0,6,-3,5,10,-6}, {10,-7,3,-9,-7,-6,-5}, {1,-7,-1,4,3,-10,-4}, {7,5,2,7,9,-2,-4}, {4,-4,4,9,-5,-10,-9}, {2,-1,5,1,9,-5,4}, {-7,4,-5,-8,-10,6,6}, {4,-7,-10,6,-5,-6,-1}, {-4,-6,7,4,-8,8,-5}, {7,-2,-4,-4,-5,-7,-2}, {10,3,-6,3,10,6,-8}, {4,1,7,-4,-1,10,-3}, {8,0,6,-5,1,7,-9}, {-5,-2,8,7,4,1,9}, {-5,0,7,9,-3,5,0}, {-5,-4,1,-4,-3,-1,7}, {-7,5,8,3,-7,-1,-9}, {5,-4,4,-2,5,-1,-2}, {-7,-3,7,7,1,6,8}, {-1,-1,-10,7,-6,7,4}, {8,6,8,9,-8,-9,5}, {-8,0,8,0,-10,10,7}, {-10,2,-9,4,6,-9,-5}, {-3,-3,9,8,9,-3,-5}, {6,7,10,2,9,6,10}, {-1,5,-5,2,2,-4,-7}, {5,2,-3,-6,-4,1,7}, {5,6,10,-3,8,-5,2}, {-7,-6,2,-4,9,10,-3}, {-9,3,3,-3,-6,7,-3}, {8,8,-7,9,5,-2,-8}, {1,-3,-5,-2,-4,0,6}, {10,3,6,1,-10,-3,-7}, {2,-1,-10,7,-3,9,4}, {4,-2,-4,0,-8,5,5}, {-3,0,-3,-3,5,-1,3}, {5,6,3,7,10,-9,-6}, {-5,7,6,7,4,-3,7}, {-8,8,-9,4,6,1,2}, {-8,-7,-10,2,-5,-2,4}, {-2,0,10,4,2,-1,6}, {-10,-5,-4,-2,0,10,8}, {7,0,7,5,6,-2,-2}, {8,-2,5,-10,10,-10,-7}, {10,-2,-5,0,-10,3,9}, {2,3,10,2,-10,7,-8}, {8,-7,5,-9,1,1,-7}, {1,1,8,3,9,9,8}, {10,10,-8,7,-6,10,10}, {-2,-10,-5,-8,-8,6,-6}, {-5,-6,3,-8,-2,-5,-5}, {-1,-1,3,5,7,2,2}, {4,-5,-5,-6,3,5,7}, {-1,7,-2,-6,-4,-4,-10}, {9,10,2,-6,-3,-8,-7}, {3,0,8,9,0,-5,4}, {-9,4,-6,10,-7,6,10}, {1,-8,-10,-6,5,-1,-6}, {-1,-7,0,0,-6,8,-8}, {-7,-7,-6,9,-9,-9,6}, {8,-2,-2,6,10,6,7}, {-1,6,8,-9,8,7,-3}, {8,10,-4,9,1,6,9}, {3,8,-2,-7,-7,-1,-8}, {-6,9,-8,-4,-6,0,2}, {-2,-6,-9,7,5,1,9}, {-5,1,-7,-1,-10,8,7}, {-7,8,-1,1,-10,-2,-9}, {6,-5,3,-3,-2,-1,-4}, {9,-5,9,10,-1,-10,9}, {4,-1,5,3,-7,9,-8}, {8,-2,6,-5,3,-2,2}, {1,-1,5,4,3,7,-6}, {-10,-7,5,4,3,-2,-10}, {-4,8,-8,3,-5,-1,4}, {-7,-7,0,-2,-4,-7,5}, {3,3,7,-7,-10,-9,6}, {0,9,7,8,10,-9,6}, {-7,1,-9,1,-5,-4,-2}, {-1,10,-9,-5,-3,3,9}, {-3,2,6,-3,1,-7,-3}, {4,10,8,3,2,7,-1}, {3,-3,3,-10,-3,8,10}, {-3,7,8,-5,3,4,-4}, {-5,2,4,-4,-4,9,10}, {1,-1,1,-2,4,5,5}, {2,9,10,8,-4,-10,2}, {3,-9,2,-3,-7,-3,6}, {0,-2,4,-6,10,1,6}, {2,-3,5,7,0,8,5}, {9,7,4,5,-10,8,8}, {6,9,8,6,-8,-8,2}, {2,-8,3,6,7,10,-9}, {9,3,-4,-9,-10,2,2}, {-1,5,1,3,6,7,7}, {-10,6,-8,10,5,10,-7}, {-10,8,2,2,2,-1,2}, {1,7,10,-6,-1,-8,-3}, {2,-9,8,-4,-9,4,-10}, {7,4,-9,7,5,10,9}, {4,8,-8,-2,-7,-3,-9}, {-5,0,7,-1,-8,-9,7}, {-10,-7,-7,1,3,7,-5}, {-9,-5,0,-2,-8,2,-2}, {9,9,10,5,-6,1,2}, {6,10,-2,6,-6,-2,-1}, {-4,-5,4,-10,-3,0,9}, {-9,-5,-2,-2,7,-7,3}, {5,4,-7,7,-5,6,2}, {5,-6,-6,-4,-7,-5,-8}, {-10,-9,-10,-1,-6,-1,8}, {2,-10,2,-6,8,-9,-3}, {-8,5,5,-2,2,-7,10}, {-3,-3,6,3,-9,-8,3}, {2,-6,3,1,8,-8,9}, {-3,-7,2,0,-2,10,-8}, {9,-9,-2,-8,-4,5,-8}, {-5,-4,-10,-5,-1,7,10}, {9,-1,8,-8,4,-2,4}, {7,0,-2,3,6,2,-8}, {-9,7,6,0,3,7,-2}, {10,7,-8,-7,-10,1,8}, {-9,9,9,1,-7,9,6}, {4,8,-8,-9,2,-1,-1}, {-8,7,7,-2,-3,0,9}, {8,-3,-1,0,-9,5,6}, {5,-10,-8,-1,8,-2,-3}, {-3,-5,10,5,-5,-8,-3}, {10,1,-2,-3,8,-8,-10}, {3,9,-9,0,10,0,2}, {4,1,-5,-6,-9,-1,6}, {-8,4,1,10,1,-3,6}, {-7,5,8,-3,10,4,5}, {5,-9,10,-3,-3,-2,-8}, {4,-10,-2,-6,10,8,9}, {-8,5,9,-2,-4,-4,-3}, {7,-4,1,-9,-6,-6,-5}, {-9,10,-2,4,-4,-8,2}, {-4,7,1,-2,-4,-9,10}, {-10,-8,10,-7,3,5,3}, {7,6,-10,-5,-5,-7,-5}, {3,9,6,9,-6,-5,-3}, {2,-6,-4,3,-2,-2,6}, {-3,-6,4,8,3,0,5}, {-5,1,-8,-5,6,5,3}, {-7,-3,1,7,2,1,6}, {-8,0,8,-8,10,-6,-2}, {-4,-6,-10,5,10,-2,10}, {8,6,5,9,-2,-7,2}, {10,-6,7,-10,1,3,4}, {2,-6,-8,-2,2,1,9}, {8,-9,-3,-6,-4,6,-3}, {7,-2,-10,7,0,-3,-10}, {8,1,3,3,-4,2,-6}, {-1,-10,9,1,8,10,0}, {-6,9,-10,-9,-6,10,-5}, {-4,0,-5,3,-9,1,4}, {4,-3,-5,-6,0,8,5}, {10,5,-6,-9,6,-4,6}, {4,7,1,-1,0,-4,7}, {-8,-2,-1,-7,7,4,9}, {10,-7,-4,2,7,-9,7}, {-2,10,-6,-6,-3,1,5}, {7,-9,-9,5,-4,5,-5}, {-1,2,-5,-5,-8,-1,-3}, {-5,-9,4,4,6,-4,1}, {-5,-1,-2,5,2,-3,-1}, {-5,9,2,-2,7,-6,-1}, {-1,-10,-7,6,-9,9,9}, {-4,6,-1,-10,10,2,5}, {3,7,-4,5,3,-9,2}, {4,4,-7,4,0,-9,8}, {6,8,-6,-1,10,2,-4}, {-3,-6,-7,6,0,-10,8}, {-5,6,-10,10,-9,-3,-6}, {3,3,-7,2,2,6,0}, {2,-3,-7,-10,6,3,-10}, {-5,4,-3,-1,8,0,-6}, {10,-9,-2,-9,1,-3,2}, {7,8,0,-2,-3,0,5}, {-6,6,9,-4,1,0,-6}, {-3,2,5,-5,3,4,9}, {2,-5,-9,-7,0,-7,4}, {-9,1,-7,7,0,-1,-3}, {9,-8,-10,-8,-5,5,-10}, {-9,-5,-4,4,-10,6,-5}, {10,-4,-10,-2,-7,7,-2}, {3,-9,1,-9,-5,5,0}, {-9,3,8,1,9,-2,8}, {2,0,-10,2,-9,4,-9}, {1,-1,7,7,5,10,-8}, {1,0,5,-10,2,2,-1}, {-8,4,5,-5,2,-9,5}, {9,10,3,-7,8,7,7}, {4,-3,-10,2,6,-5,-8}, {-2,-4,7,-6,10,-2,-3}, {7,0,-1,5,-7,5,3}, {-8,3,5,8,5,-7,8}, {3,-5,-2,6,2,2,-6}, {-10,-7,4,-1,1,-8,-8}, {10,-4,9,6,10,-6,6}, {-10,-1,2,8,0,-3,-8}, {6,2,4,1,7,2,-3}, {7,-5,6,6,1,9,0}, {-10,6,8,-4,7,0,8}, {10,3,7,0,10,8,-10}, {2,-9,-6,-6,-6,-3,-7}, {-7,9,1,6,8,10,-7}, {-10,0,-8,-1,4,8,1}, {-2,5,-10,6,-7,3,3}, {1,-1,-4,3,7,-7,0}, {8,2,3,-2,6,-1,-9}, {5,0,0,-7,-1,-9,9}, {9,-7,-4,1,-9,-2,-10}, {-9,-10,9,-9,-9,4,-7}, {8,6,-3,2,-7,1,1}, {-10,-4,-6,-10,-5,-4,-8}, {-7,5,-7,10,-9,-9,7}, {-3,10,-8,-9,-9,4,8}, {-10,1,-6,5,7,-6,10}, {10,-6,5,-1,-8,3,-5}, {-3,2,-3,10,-4,10,-7}, {4,4,-9,-7,7,-2,3}, {10,2,-6,-1,8,10,1}, {0,2,9,-7,1,10,2}, {5,0,-8,-7,-10,8,4}, {10,7,-4,9,7,6,8}, {2,-3,-1,2,9,8,-5}, {10,-2,-2,-7,9,-7,0}, {0,5,-7,-5,0,-1,-3}, {3,1,6,0,-2,-5,0}, {5,-2,-10,7,4,5,5}, {-2,-10,4,7,10,-7,8}, {-7,-2,-1,-8,-3,0,7}, {-4,3,-10,1,1,1,10}, {1,4,-4,-7,0,1,-8}, {3,4,-2,10,-10,7,6}, {4,-5,-9,2,10,-1,-2}, {-7,6,-5,6,-8,-4,-6}, {-3,9,-1,-7,0,5,-2}, {-7,0,8,-2,-2,-6,-5}, {4,0,1,-7,8,4,0}, {-6,8,9,0,-4,-7,-3}, {-7,-1,-5,-6,7,1,7}, {-4,-9,-1,8,-10,0,3}, {7,-1,10,-7,2,-3,-4}, {-9,5,-5,-6,9,-1,0}, {10,4,5,-9,3,2,-5}, {5,-10,9,5,7,0,3}, {3,-3,0,-10,0,-6,0}, {-8,3,2,-5,-5,2,-1}, {-4,-10,-10,10,-4,4,3}, {6,1,-9,5,6,8,9}, {-8,2,3,5,7,7,5}, {-4,0,7,-3,6,-8,-5}, {6,9,8,7,9,0,-9}, {-9,9,-7,9,-7,-10,0}, {-1,7,6,-6,4,-6,6}, {-9,-9,-7,8,-6,9,-3}, {5,-7,-1,-8,3,6,3}, {-1,-2,-10,2,-10,10,3}, {-5,-6,3,2,6,5,-7}, {-8,1,8,-1,7,-2,3}, {1,-6,-4,-8,2,2,6}, {3,0,1,6,-1,-1,-2}, {-10,0,1,8,2,0,3}, {6,-5,-6,7,9,-9,-10}, {-10,-10,-10,-5,-5,6,0}, {8,-4,-8,1,-10,8,-3}, {7,-3,3,-6,1,5,-6}, {8,10,10,7,6,-3,0}, {4,-6,6,-3,6,0,7}, {9,-7,-3,10,-2,-2,-4}, {4,-1,-4,-8,-3,7,-7}, {-8,2,9,-4,0,-5,-7}, {-2,9,7,7,3,7,-5}, {8,5,10,-5,-8,-6,-3}, {0,6,-10,-5,-6,-7,10}, {-9,-2,3,-10,5,-9,-1}, {9,-4,-6,-10,10,7,8}, {-7,-4,-1,-1,4,7,-7}, {-9,-3,-5,-2,-7,-5,7}, {-6,8,4,-3,10,-7,9}, {-10,-2,4,1,8,-2,-3}, {3,-3,-7,-2,9,8,7}, {8,9,8,9,9,9,-1}, {-3,10,6,-4,3,1,-4}, {5,1,1,5,-10,-4,-2}, {-7,7,3,2,1,-5,0}, {0,-4,-10,-2,9,-3,-3}, {2,8,-7,-4,5,7,-9}, {4,-4,4,4,0,5,5}, {5,-2,2,-3,9,3,8}, {4,3,-8,3,-9,4,6} }; ratpoints-2.1.3/gpl-2.0.txt0000644000175000001440000004310311536145472014622 0ustar mstollusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ratpoints-2.1.3/find_points.c0000644000175000001440000017174611536145472015501 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.3 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * find_points.c * * * * Core program file for ratpoints * * * * Michael Stoll, September 21, 2009 * ***********************************************************************/ #include "rp-private.h" #include "primes.h" /* defines long prime[PRIMES1000]; */ #include "find_points.h" /* defines static const int squares[RATPOINTS_NUM_PRIMES+1][RATPOINTS_MAX_PRIME]; squares[n][x] = 1 if x is a square mod prime[n], 0 if not static const long offsets[RATPOINTS_NUM_PRIMES]; offset[n] = (2*LONG_LENGTH)^(-1) mod prime[n] static const long inverses[RATPOINTS_NUM_PRIMES][RATPOINTS_MAX_PRIME]; inverses[n][x] = x^(-1) mod prime[n] for x != 0 mod prime[n] ratpoints_bit_array sieves0[RATPOINTS_NUM_PRIMES][RATPOINTS_MAX_PRIME_EVEN] sieves0[n][x] has bit i set (0 <= x < prime[n]) <==> x*LONG_LENGTH + i is not divisible by prime[n] */ #define MAX_DIVISORS 512 /* Maximal length of array for squarefree divisors of leading coefficient */ extern ratpoints_init_fun sieve_init[RATPOINTS_NUM_PRIMES]; typedef struct { double r; ratpoints_sieve_entry *ssp; } entry; typedef struct { int p; int val; int slope; } use_squares1_info; typedef struct { long p; unsigned long *start; unsigned long *end; unsigned long *curr; } forbidden_entry; static const int squares16[16] = {1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0}; /* Says if a is a square mod 16, for a = 0..15 */ /************************************************************************** * Initialization and cleanup of ratpoints_args structure * **************************************************************************/ /* NOTE: args->degree must be set */ void find_points_init(ratpoints_args *args) { long work_len = 3 + (args->degree + 1); /* allocate space for work[] */ mpz_t *work = malloc(work_len*sizeof(mpz_t)); #ifdef DEBUG printf("\nfind_points: initialize..."); fflush(NULL); #endif /* and initialize the mpz_t's in it */ { long i; for(i = 0; i < work_len; i++) mpz_init(work[i]); } /* insert in args */ args->work = work; args->work_length = work_len; /* allocate space for se_buffer */ args->se_buffer = (ratpoints_sieve_entry*)malloc(RATPOINTS_NUM_PRIMES * sizeof(ratpoints_sieve_entry)); args->se_next = args->se_buffer; /* allocate space for ba_buffer */ { long need = 0; long n; for(n = 0; n < RATPOINTS_NUM_PRIMES; n++) { need += prime[n]*prime[n]; } args->ba_buffer = malloc(need*sizeof(ratpoints_bit_array)); args->ba_next = args->ba_buffer; } /* allocate space for int_buffer */ args->int_buffer = malloc(RATPOINTS_NUM_PRIMES*(RATPOINTS_MAX_PRIME+1)*sizeof(int)); args->int_next = args->int_buffer; /* allocate sieve_list */ args->sieve_list = malloc(RATPOINTS_NUM_PRIMES * sizeof(ratpoints_sieve_entry*)); args->den_info = malloc((PRIMES1000+2)*sizeof(use_squares1_info)); args->divisors = malloc((MAX_DIVISORS+1)*sizeof(long)); args->forb_ba = malloc((RATPOINTS_NUM_PRIMES + 1)*sizeof(forbidden_entry)); args->forbidden = malloc((RATPOINTS_NUM_PRIMES + 1)*sizeof(long)); #ifdef DEBUG printf("done.\n"); fflush(NULL); #endif return; } void find_points_clear(ratpoints_args *args) { #ifdef DEBUG printf("\nfind_points: clean up..."); fflush(NULL); #endif /* clear mpz_t's in work[] */ { long i; mpz_t *work = args->work; for(i = 0; i < args->work_length; i++) mpz_clear(work[i]); } /* free memory */ free(args->work); free(args->se_buffer); free(args->ba_buffer); free(args->int_buffer); free(args->sieve_list); free(args->den_info); free(args->divisors); free(args->forb_ba); free(args->forbidden); /* clear pointer in args */ args->work = NULL; args->work_length = 0; args->se_buffer = NULL; args->se_next = NULL; args->ba_buffer = NULL; args->ba_next = NULL; args->int_buffer = NULL; args->int_next = NULL; args->sieve_list = NULL; args->den_info = NULL; args->divisors = NULL; args->forb_ba = NULL; args->forbidden = NULL; #ifdef DEBUG printf("done.\n"); fflush(NULL); #endif return; } /************************************************************************** * Helper function: valuation of gmp-integer at a prime * **************************************************************************/ #define VERY_BIG 1000 static long valuation(const mpz_t n, long p, long *r, mpz_t vvv) { long v = 0; unsigned long rem; mpz_abs(vvv, n); if(mpz_cmp_ui(vvv, 0) == 0) { *r = 0; return(VERY_BIG); } rem = mpz_fdiv_q_ui(vvv, vvv, p); while(rem == 0) { v++; rem = mpz_fdiv_q_ui(vvv, vvv, p); } *r = rem; return(v); } static long valuation1(long n, long p) { long v = 0; unsigned long rem; unsigned long qn = abs(n); if(n == 0) { return(VERY_BIG); } rem = qn % p; while(rem == 0) { v++; qn = qn/p; rem = qn % p; } return(v); } /************************************************************************** * Try to avoid divisions * **************************************************************************/ static inline long mod(long a, long b) { long b1 = b << 4; /* b1 = 16*b */ if(a < -b1) { a %= b; if(a < 0) { a += b; } return(a); } if(a < 0) { a += b1; } else { if(a >= b1) { return(a % b); } } b1 >>= 1; /* b1 = 8*b */ if(a >= b1) { a -= b1; } b1 >>= 1; /* b1 = 4*b */ if(a >= b1) { a -= b1; } b1 >>= 1; /* b1 = 2*b */ if(a >= b1) { a -= b1; } if(a >= b) { a -= b; } return(a); } /************************************************************************** * Helper function: Jacobi symbol * **************************************************************************/ static inline int jacobi(long b, mpz_t tmp, const mpz_t lcf) { /* Jacobi symbol (leading coeff/b) */ long f; /* avoid divisions as far as possible! */ /* remove 2's from b */ while((b & 1) == 0) b >>= 1; f = mpz_fdiv_r_ui(tmp, lcf, (unsigned long)b); if(f == 0) return(1); while(1) { long s = 1; long n = f; long m = b; /* m is odd, n is positive and < m */ /* looking at (n/m) */ while(!(n & 1)) { if(m & 2) s = -s; /* change sign iff m = 3 or 5 mod 8 */ if(m & 4) s = -s; n >>= 1; } while(1) { /* switch roles */ if(n & m & 2) s = -s; /* change sign iff m, n = 3 mod 4 */ /* now we are looking at (m/n) */ while(m > n) { m -= n; do { if(n & 2) s = -s; /* change sign iff n = 3 or 5 mod 8 */ if(n & 4) s = -s; m >>= 1; } while(!(m & 1)); } if(m == n) { if(m == 1) return(s); /* otherwise, m is the gcd of f and b; remove it from b */ b /= m; if(f >= b) f %= b; if(f == 0) return(1); break; } /* here m < n */ /* switch roles */ if(n & m & 2) s = -s; /* change sign iff m, n = 3 mod 4 */ /* now we are looking at (n/m) */ while(n > m) { n -= m; do { if(m & 2) s = -s; /* change sign iff m = 3 or 5 mod 8 */ if(m & 4) s = -s; n >>= 1; } while(!(n & 1)); } if(m == n) { if(m == 1) return(s); /* otherwise, m is the gcd of f and b; remove it from b */ b /= m; if(f >= b) f %= b; if(f == 0) return(1); break; } } } } static inline int jacobi1(long b, const long lcf) { /* Jacobi symbol (leading coeff/b) */ long f; int neg = 0; /* avoid divisions as far as possible! */ /* remove 2's from b */ while((b & 1) == 0) b >>= 1; f = lcf; if(f < 0) { f = -f; neg = 1; } if(b < 1UL<<(LONG_LENGTH - 4)) f = mod(f, b); if(f == 0) return(1); while(1) { long s = (neg && (b & 2)) ? -1 : 1; long n = f; long m = b; /* m is odd, n is positive */ /* looking at (n/m) */ while(!(n & 1)) { if(m & 2) s = -s; /* change sign iff m = 3 or 5 mod 8 */ if(m & 4) s = -s; n >>= 1; } while(1) { /* switch roles */ if(n & m & 2) s = -s; /* change sign iff m, n = 3 mod 4 */ /* now we are looking at (m/n) */ while(m > n) { m -= n; do { if(n & 2) s = -s; /* change sign iff n = 3 or 5 mod 8 */ if(n & 4) s = -s; m >>= 1; } while(!(m & 1)); } if(m == n) { if(m == 1) return(s); /* otherwise, m is the gcd of f and b; remove it from b */ b /= m; /* if(f >= b) f %= b; */ if(f == 0) return(1); break; } /* here m < n */ /* switch roles */ if(n & m & 2) s = -s; /* change sign iff m, n = 3 mod 4 */ /* now we are looking at (n/m) */ while(n > m) { n -= m; do { if(m & 2) s = -s; /* change sign iff m = 3 or 5 mod 8 */ if(m & 4) s = -s; n >>= 1; } while(!(n & 1)); } if(m == n) { if(m == 1) return(s); /* otherwise, m is the gcd of f and b; remove it from b */ b /= m; /* if(f >= b) f %= b; */ if(f == 0) return(1); break; } } } } /************************************************************************ * Set up information on possible denominators * * when polynomial is of odd degree with leading coefficient != +-1 * ************************************************************************/ static void setup_us1(ratpoints_args *args) { mpz_t *work = args->work; /* abs. value of leading coeff. in work[0] */ long count = 0; unsigned long i, v; unsigned long rem; /* typedef struct { int p; int val; int slope; } use_squares1_info; */ use_squares1_info *den_info = (use_squares1_info *)args->den_info; long *divisors = (long *)args->divisors; /* find prime divisors of leading coefficient*/ /* first p = 2 */ #ifdef DEBUG printf("\nsetup_us1: find v_2(lcf)..."); fflush(NULL); #endif v = mpz_scan1(work[0], 0); /* find first 1-bit ==> 2-adic valuation */ #ifdef DEBUG printf(" = %ld\n", v); fflush(NULL); #endif if(v > 0) { /* prime divisor found; divide it off */ den_info[count].p = 2; mpz_fdiv_q_2exp(work[0], work[0], v); /* remove power of 2 */ den_info[count].val = v; count++; } for(i = 0; i < PRIMES1000 && mpz_cmp_si(work[0], 1); i++) { int p = prime[i]; if(mpz_cmp_si(work[0], p*p) < 0) { /* remaining part must be prime */ #ifdef DEBUG printf("\nsetup_us1: remaining factor"); fflush(NULL); #endif if(mpz_fits_slong_p(work[0])) { den_info[count].p = mpz_get_si(work[0]); den_info[count].val = 1; #ifdef DEBUG printf(" = %d ==> fits into a long\n", den_info[count].p); fflush(NULL); #endif count++; mpz_set_si(work[0], 1); /* divide it off */ } #ifdef DEBUG else { printf(" is too large\n"); fflush(NULL); } #endif break; } else { #ifdef DEBUG printf("\nsetup_us1: find v_%d(lcf)...", p); fflush(NULL); #endif v = 0; rem = mpz_fdiv_q_ui(work[1], work[0], p); if(rem == 0) { /* prime divisor found; divide it off */ den_info[count].p = p; while(rem == 0) { v++; mpz_set(work[0], work[1]); rem = mpz_fdiv_q_ui(work[1], work[0], p); } den_info[count].val = v; count++; } #ifdef DEBUG printf(" = %ld\n", v); fflush(NULL); #endif } } #ifdef DEBUG printf("\nsetup_us1: %ld entries in den_info\n", count); fflush(NULL); #endif den_info[count].p = 0; /* terminate array */ /* check if factorization is complete */ if(mpz_cmp_si(work[0], 1) == 0) { /* set up array of squarefree divisors */ long *div = &divisors[1]; divisors[0] = 1; for(i = 0; i < count; i++) { /* multiply all divisors known so far by next prime */ long *div0 = &divisors[0]; long *div1 = div; for( ; div0 != div1; div0++) { long t = *div0 * (long)den_info[i].p; if(t <= args->b_high) { *div++ = t; } if(div >= &divisors[MAX_DIVISORS]) { break; } } if(div >= &divisors[MAX_DIVISORS]) { break; } } if(div < &divisors[MAX_DIVISORS]) { *div = 0; /* terminate divisors array */ /* note that we can use the information */ args->flags |= RATPOINTS_USE_SQUARES1; /* set slopes in den_info */ #ifdef DEBUG printf("\nsetup_us1: compute slopes...\n"); fflush(NULL); #endif for(i = 0; i < count; i++) { /* compute min{n : (d-k)*n > v_p(f_d) - v_p(f_k), k = 0,...,d-1} */ int p = den_info[i].p; int v = den_info[i].val; int n = 1; int k; mpz_t *c = args->cof; long degree = args->degree; for(k = degree - 1; k >= 0; k--) { long dummy; int t = 1 + v - valuation(c[k], p, &dummy, work[0]); int m = CEIL(t, (degree - k)); if(m > n) { n = m; } } #ifdef DEBUG printf(" i = %ld (p = %d): slope = %d\n", i, p, n); fflush(NULL); #endif den_info[i].slope = n; } } else { #ifdef DEBUG printf("\nsetup_us1: too many divisors\n"); fflush(NULL); #endif } } else { #ifdef DEBUG printf("\nsetup_us1: no complete factorization\n"); fflush(NULL); #endif } return; } /************************************************************************ * Consider 2-adic information * ************************************************************************/ static bit_selection get_2adic_info(ratpoints_args *args, unsigned long *den_bits, ratpoints_bit_array *num_bits) { mpz_t *c = args->cof; long degree = args->degree; int is_f_square16[24]; long cmp[degree+1]; /* The coefficients of f reduced modulo 16 */ long npe = 0, npo = 0; bit_selection result; #ifdef DEBUG printf("\nget_2adic_info: start...\n"); fflush(NULL); #endif /* compute coefficients mod 16 */ { long n; for(n = 0; n <= degree; n++) { cmp[n] = mpz_get_si(c[n]) & 0xf; } } { long a; for(a = 0 ; a < 16; a++) { unsigned long s = cmp[degree]; long n; for(n = degree - 1 ; n >= 0 ; n--) { s *= a; s += cmp[n]; } s &= 0xf; if((is_f_square16[a] = squares16[s])) { if(a & 1) { npo++; } else { npe++; } } } } /* even denominators: is_f_square16[16+k] says if f((2k+1)/2) is a square, k = 0..3 is_f_square16[20+k] says if f((2k+1)/4) is a square, k = 0,1 is_f_square16[22] says if f(odd/8) is a square is_f_square16[23] says if f(odd/2^n), n >= 4, can be a square */ { long np1 = 0, np2 = 0, np3 = 0, np4 = 0; if(degree & 1) { long cf = 4*cmp[degree-1]; long a; if(degree >= 2) cf += 8*cmp[degree-2]; for(a = 0; a < 4; a++) { /* Compute 2 c[d] k^d + 4 c[d-1] k^(d-1) + 8 c[d-2] k^(d-2), k = 2a+1. Note that k^d = k mod 8, k^(d-1) = 1 mod 8. */ long k = 2*a+1; long s = (2*k*cmp[degree] + cf) & 0xf; if((is_f_square16[16+a] = squares16[s])) np1++; } if((is_f_square16[20] = squares16[(4*cmp[degree]) & 0xf])) np2++; if((is_f_square16[21] = squares16[(12*cmp[degree]) & 0xf])) np2++; if((is_f_square16[22] = squares16[(8*cmp[degree]) & 0xf])) np3++; is_f_square16[23] = 1; np4++; } else { long cf = (degree >= 2) ? 4*cmp[degree-2] : 0; long a; if(degree >= 3) cf += 8*cmp[degree-3]; for(a = 0; a < 4; a++) { /* compute c[d] k^d + 2 c[d-1] k^(d-1) + ... + 8 c[d-3] k^(d-3), k = 2a+1. Note that k^d = k^2 mod 16, k^(d-1) = k mod 8. */ long k = 2*a+1; long s = ((cmp[degree]*k + 2*cmp[degree-1])*k + cf) & 0xf; if((is_f_square16[16+a] = squares16[s])) np1++; } if((is_f_square16[20] = squares16[(cmp[degree]+4*cmp[degree-1]) & 0xf])) np2++; if((is_f_square16[21] = squares16[(cmp[degree]+12*cmp[degree-1]) & 0xf])) np2++; if((is_f_square16[22] = squares16[(cmp[degree]+8*cmp[degree-1]) & 0xf])) np3++; if((is_f_square16[23] = squares16[cmp[degree]])) np4++; } #ifdef DEBUG printf("\nis_f_square16 :\n["); { long a; for(a = 0; a < 23; a++) printf("%d,", is_f_square16[a]); printf("%d]\n", is_f_square16[23]); } fflush(NULL); #endif /* set den_bits */ { unsigned long db = 0; long i; if(npe + npo > 0) { db |= 0xaaaaUL; } /* odd denominators */ if(np1 > 0) { db |= 0x4444UL; } /* v_2(den) = 1 */ if(np2 > 0) { db |= 0x1010UL; } /* v_2(den) = 2 */ if(np3 > 0) { db |= 0x0100UL; } /* v_2(den) = 3 */ if(np4 > 0) { db |= 0x0001UL; } /* v_2(den) >= 4 */ if(db == 0) { *den_bits = 0UL; return(num_none); } for(i = 16; i < LONG_LENGTH; i <<= 1) { db |= db << i; } #ifdef DEBUG printf("\nden_bits :%*.*lx\n", WIDTH, WIDTH, db); fflush(NULL); #endif *den_bits = db; } /* determine result */ result = (npe == 0) ? ((npo == 0) ? num_none : num_odd) : ((npo == 0) ? num_even : num_all); } { /* set up num_bits[16] */ long b; /* odd denominators */ switch(result) { case num_all: for(b = 1; b < 16; b += 2) { unsigned long work = 0; unsigned long bit = 1; long i; long invb = b; /* inverse of b mod 16 */ if(b & 2) invb ^= 8; if(b & 4) invb ^= 8; for(i = 0; i < 16; i++) { if(is_f_square16[(invb*i) & 0xf]) { work |= bit; } bit <<= 1; } /* now repeat the 16 bits */ for(i = 16; i < LONG_LENGTH; i <<= 1) { work |= work << i; } #ifdef USE_SSE num_bits[b] = RBA(work, work); #else num_bits[b] = work; #endif } break; case num_odd: for(b = 1; b < 16; b += 2) { unsigned long work = 0; unsigned long bit = 1; long i; long invb = b; /* inverse of b mod 16 */ if(b & 2) invb ^= 8; if(b & 4) invb ^= 8; for(i = 1; i < 16; i += 2) { if(is_f_square16[(invb*i) & 0xf]) { work |= bit; } bit <<= 1; } /* now repeat the 8 bits */ for(i = 8; i < LONG_LENGTH; i <<= 1) { work |= work << i; } #ifdef USE_SSE num_bits[b] = RBA(work, work); #else num_bits[b] = work; #endif } break; case num_even: for(b = 1; b < 16; b += 2) { unsigned long work = 0; unsigned long bit = 1; long i; long invb = b; /* inverse of b mod 16 */ if(b & 2) invb ^= 8; if(b & 4) invb ^= 8; for(i = 0; i < 16; i += 2) { if(is_f_square16[(invb*i) & 0xf]) { work |= bit; } bit <<= 1; } /* now repeat the 8 bits */ for(i = 8; i < LONG_LENGTH; i <<= 1) { work |= work << i; } #ifdef USE_SSE num_bits[b] = RBA(work, work); #else num_bits[b] = work; #endif } break; case num_none: for(b = 1; b < 16; b += 2) { num_bits[b] = zero; } } /* v_2(den) = 1 : only odd numerators */ for(b = 1; b < 8; b += 2) { unsigned long work; unsigned long bit; long i; work = 0; bit = 1; for(i = 1; i < 16; i += 2) { if(is_f_square16[16 + (((b*i)>>1) & 0x3)]) { work |= bit; } bit <<= 1; } /* now repeat the 8 bits */ for(i = 8; i < LONG_LENGTH; i <<= 1) { work |= work << i; } #ifdef USE_SSE num_bits[2*b] = RBA(work, work); #else num_bits[2*b] = work; #endif } /* v_2(den) = 2 : only odd numerators */ for(b = 1; b < 4; b += 2) { unsigned long work = 0; unsigned long bit = 1; long i; work = 0; bit = 1; for(i = 1; i < 8; i += 2) { if(is_f_square16[20 + (((b*i)>>1) & 0x1)]) { work |= bit; } bit <<= 1; } /* now repeat the 4 bits */ for(i = 4; i < LONG_LENGTH; i <<= 1) { work |= work << i; } #ifdef USE_SSE num_bits[4*b] = RBA(work, work); #else num_bits[4*b] = work; #endif } /* v_2(den) = 3, >= 4 : only odd numerators */ #ifdef USE_SSE num_bits[8] = (is_f_square16[22]) ? RBA(~(0UL), ~(0UL)) : zero; num_bits[0] = (is_f_square16[23]) ? RBA(~(0UL), ~(0UL)) : zero; #else num_bits[8] = (is_f_square16[22]) ? ~(0UL) : zero; num_bits[0] = (is_f_square16[23]) ? ~(0UL) : zero; #endif } #ifdef DEBUG printf("\nget_2adic_info: done.\n"); fflush(NULL); #endif return(result); } /************************************************************************** * This is a comparison function needed for sorting in order to determine * * the `best' primes for sieving. * **************************************************************************/ static int compare_entries(const void *a, const void *b) { double diff = (((entry *)a)->r - ((entry *)b)->r); return (diff > 0) ? 1 : (diff < 0) ? -1 : 0; } /************************************************************************ * Collect the sieving information * ************************************************************************/ static long sieving_info(ratpoints_args *args, int use_c_long, long *c_long, ratpoints_sieve_entry **sieve_list) { mpz_t *c = args->cof; long degree = args->degree; long fba = 0; long fdc = 0; long pn; long pnp = 0; entry prec[RATPOINTS_NUM_PRIMES]; /* This array is used for sorting in order to determine the `best' sieving primes. */ forbidden_entry *forb_ba = (forbidden_entry *)args->forb_ba; long *forbidden = (long *)args->forbidden; /* initialize sieve in se_buffer */ for(pn = 0; pn < args->num_primes; pn++) { long coeffs_mod_p[degree+1]; /* The coefficients of f reduced modulo p */ long p = prime[pn]; long n, a, np; int *is_f_square = args->int_next; args->int_next += p + 1; /* need space for (p+1) int's */ #ifdef DEBUG printf("\nsieving_info: p = %ld\n", p); fflush(NULL); #endif /* compute coefficients mod p */ if(use_c_long) { for(n = 0; n <= degree; n++) { coeffs_mod_p[n] = mod(c_long[n], p); } } else { for(n = 0; n <= degree; n++) { coeffs_mod_p[n] = mpz_fdiv_r_ui(args->work[0], c[n], p); } } np = squares[pn][coeffs_mod_p[0]]; is_f_square[0] = np; for(a = 1 ; a < p; a++) { unsigned long s = coeffs_mod_p[degree]; if((degree+1)*RATPOINTS_MAX_BITS_IN_PRIME <= LONG_LENGTH) { for(n = degree - 1 ; n >= 0 ; n--) { s *= a; s += coeffs_mod_p[n]; } /* here, s < p^(degree+1) <= max. long */ s %= p; } else { for(n = degree - 1 ; n >= 0 ; n--) { s *= a; s += coeffs_mod_p[n]; if(s+1 >= (1UL)<<(LONG_LENGTH - RATPOINTS_MAX_BITS_IN_PRIME)) { s %= p; } } s %= p; } if((is_f_square[a] = squares[pn][s])) { np++; } } is_f_square[p] = (degree & 1) || squares[pn][coeffs_mod_p[degree]]; #ifdef DEBUG printf("\nis_f_square(p = %ld) : \n[", p); { long a; for(a = 0; a < p; a++) printf("%d,", is_f_square[a]); printf("%d]\n", is_f_square[p]); } fflush(NULL); #endif /* check if there are no solutions mod p */ if(np == 0 && !is_f_square[p]) { return(p); } /* Fill arrays with info for p */ if(np < p) { /* only when there is some information */ { double r = is_f_square[p] ? ((double)(np*(p-1) + p))/((double)(p*p)) : (double)np/(double)p; prec[pnp].r = r; } /* set up sieve_entry : typedef struct { ratpoints_init_fun init; long p; int *is_f_square; int *inverses; long offset; (ratpoints_bit_array *)sieve[RATPOINTS_MAX_PRIME]; } ratpoints_sieve_entry; */ { ratpoints_sieve_entry *se = (ratpoints_sieve_entry *)args->se_next; long i; args->se_next += sizeof(ratpoints_sieve_entry); /* one entry must be stored - note that se_next is of type void* */ se->init = sieve_init[pn]; se->p = p; se->is_f_square = is_f_square; se->inverses = &inverses[pn][0]; se->offset = offsets[pn]; se->sieve[0] = (ratpoints_bit_array *)&sieves0[pn][0]; for(i = 1; i < p; i++) { se->sieve[i] = NULL; } prec[pnp].ssp = se; } pnp++; } if((args->flags & RATPOINTS_CHECK_DENOM) && fba + fdc < args->max_forbidden && !is_f_square[p]) { /* record forbidden divisors of the denominator */ if(coeffs_mod_p[degree] == 0) { /* leading coeff. divisible by p */ long r; long v = valuation(c[degree], p, &r, args->work[0]); if((v & 1) || !squares[pn][r]) { /* Can only get something when valuation is odd or when valuation is even and lcf is not a p-adic square. Compute smallest n such that if v(den) >= n, the leading term determines the valuation. Then we must have v(den) < n. */ long n = 1; long k, pp; for(k = degree-1; k >= 0; k--) { if(coeffs_mod_p[k] == 0) { long dummy; long t = 1 + v - valuation(c[k], p, &dummy, args->work[0]); long m = CEIL(t, (degree-k)); if(m > n) { n = m; } } } if(n == 1) { forb_ba[fba].p = p; forb_ba[fba].start = &sieves0[pn][0]; forb_ba[fba].end = &sieves0[pn][p]; forb_ba[fba].curr = forb_ba[fba].start; fba++; pp = p; } else { for(pp = 1; n; n--) { pp *= p; } /* p^n */ forbidden[fdc] = pp; fdc++; } #ifdef DEBUG printf("\nexcluding denominators divisible by %ld\n", pp); fflush(NULL); #endif } } else /* leading coefficient is a non-square mod p */ { /* denominator divisible by p is excluded */ forb_ba[fba].p = p; forb_ba[fba].start = &sieves0[pn][0]; forb_ba[fba].end = &sieves0[pn][p]; forb_ba[fba].curr = forb_ba[fba].start; fba++; #ifdef DEBUG printf("\nexcluding denominators divisible by %ld\n", p); fflush(NULL); #endif } } } /* end for pn */ /* update sp2 and sp1 if necessary */ if(args->sp2 > pnp) { args->sp2 = pnp; } if(args->sp1 > args->sp2) { args->sp1 = args->sp2; } /* sort the array to get at the best primes */ qsort(prec, pnp, sizeof(entry), compare_entries); /* put the sorted entries into sieve_list */ { long n; for(n = 0; n < args->sp2; n++) { sieve_list[n] = prec[n].ssp; } } /* terminate array of forbidden divisors */ if(args->flags & RATPOINTS_CHECK_DENOM) { long n; for(n = args->num_primes; fba + fdc < args->max_forbidden && n < RATPOINTS_NUM_PRIMES; n++) { long p = prime[n]; if(p*p > args->b_high) break; if(mpz_kronecker_si(c[degree], p) == -1) { forb_ba[fba].p = p; forb_ba[fba].start = &sieves0[n][0]; forb_ba[fba].end = &sieves0[n][p]; forb_ba[fba].curr = forb_ba[fba].start; fba++; #ifdef DEBUG printf("\nexcluding denominators divisible by %ld\n", p); fflush(NULL); #endif } } forb_ba[fba].p = 0; /* terminating zero */ forbidden[fdc] = 0; /* terminating zero */ args->max_forbidden = fba + fdc; /* note actual number */ } if(fba + fdc == 0) { args->flags &= ~RATPOINTS_CHECK_DENOM; } #ifdef DEBUG printf("\nsieving_info: done.\n"); fflush(NULL); #endif return(0); } /************************************************************************** * The sieving procedure itself * **************************************************************************/ static long sift(long b, ratpoints_bit_array *survivors, ratpoints_args *args, bit_selection which_bits, ratpoints_bit_array bits16, ratpoints_sieve_entry **sieve_list, long *bp_list, int *quit, int process(long, long, const mpz_t, void*, int*), void *info) { long total = 0; /* typedef struct { long p; long offset; ratpoints_bit_array *ptr; } sieve_spec; */ sieve_spec ssp[args->sp2]; int do_setup = 1; #ifdef DEBUG printf("\nsift(b = %ld): start...\n", b); fflush(NULL); #endif if((b & 1) == 0) { which_bits = num_odd; } /* even denominator */ /* Note that b is new */ args->flags |= RATPOINTS_COMPUTE_BC; { long k; long height = args->height; for(k = 0; k < args->num_inter; k++) { long low, high; /* Determine relevant interval [low, high] of numerators. */ { ratpoints_interval inter = args->domain[k]; if(b*inter.low <= -height) { low = -height; } else { if(b*inter.low > height) { return(total); } low = ceil(b*inter.low); } if(b*inter.up >= height) { high = height; } else { if(b*inter.up < -height) { continue; } high = floor(b*inter.up); } } #ifdef DEBUG printf("\nsift: numerator interval [%ld, %ld]\n", low, high); fflush(NULL); #endif if(do_setup) { /* set up the sieve information */ long n; do_setup = 0; /* only do it once for every b */ #ifdef DEBUG printf("\nsift: set up sieve...\n"); fflush(NULL); #endif for(n = 0; n < args->sp2; n++) { ratpoints_sieve_entry *se = sieve_list[n]; long p = se->p; long bp = bp_list[n]; ratpoints_bit_array *sptr; if(which_bits != num_all) /* divide by 2 mod p */ { bp = (bp & 1) ? (bp+p) >> 1 : bp >> 1; } sptr = se->sieve[bp]; ssp[n].p = p; ssp[n].offset = (which_bits == num_odd) ? se->offset : 0; #ifdef DEBUG printf("\np = %ld, bp = %ld, offset = %ld\n", p, bp, ssp[n].offset); fflush(NULL); #endif /* copy if already initialized, else initialize */ ssp[n].ptr = sptr ? sptr : (*(se->init))(se, bp, args); #ifdef DEBUG if(!sptr) { long a, c = 0; printf("\nsieve(%ld, %ld) [high numerators to the left]:", p, bp); for(a = p-1; a >= 0; a--, c++) { if((c & (0xff >> RBA_SHIFT)) == 0) { printf("\n"); } #ifdef USE_SSE printf("%*.*lx%*.*lx ", WIDTH, WIDTH, EXT1(ssp[n].ptr[a]), WIDTH, WIDTH, EXT0(ssp[n].ptr[a])); #else printf("%*.*lx ", WIDTH, WIDTH, ssp[n].ptr[a]); #endif } printf("\n"); fflush(NULL); } #endif } } switch(which_bits) { case num_all: break; case num_none: break; case num_odd: low >>= 1; high--; high >>= 1; break; case num_even: low++; low >>= 1; high >>= 1; break; } /* now turn the bit interval into [low, high[ */ high++; if(low < high) { long w_low, w_high; long w_low0, w_high0; long range = args->array_size; /* Now the range of longwords (= bit_arrays) */ w_low = low >> RBA_SHIFT; /* FLOOR(low, RBA_LENGTH); */ w_high = (high + (long)(RBA_LENGTH-1)) >> RBA_SHIFT; /* CEIL(high, RBA_LENGTH); */ w_low0 = w_low; w_high0 = w_low0 + range; for( ; w_low0 < w_high; w_low0 = w_high0, w_high0 += range) { if(w_high0 > w_high) { w_high0 = w_high; range = w_high0 - w_low0; } /* initialise the bits */ { register long i; for(i = range; i; i--) { survivors[i-1] = bits16; } } /* boundary words */ if(w_low0 == w_low) { long sh = low - RBA_LENGTH * w_low; unsigned long *survl = (unsigned long *)survivors; #ifdef USE_SSE if(sh >= LONG_LENGTH) { survl[0] = 0UL; survl[1] &= (~0UL)<<(sh - LONG_LENGTH); } else { survl[0] &= ~(0UL)<= LONG_LENGTH) { survl[0] &= ~(0UL)>>(sh - LONG_LENGTH); survl[1] = 0UL; } else { survl[1] &= ~(0UL)>>sh; } #else survl[0] &= ~(0UL)>>sh; #endif } #ifdef DEBUG #ifdef USE_SSE printf("survivors[%ld] = %*.*lx%*.*lx\n", range-1, WIDTH, WIDTH, EXT1(survivors[range-1]), WIDTH, WIDTH, EXT0(survivors[range-1])); #else printf("survivors[%ld] = %*.*lx\n", range-1, WIDTH, WIDTH, survivors[range-1]); #endif fflush(NULL); #endif total += _ratpoints_sift0(b, w_low0, w_high0, args, which_bits, survivors, &ssp[0], quit, process, info); if(*quit) return(total); } } } } return(total); } /************************************************************************** * Find points by looping over the denominators and sieving numerators * **************************************************************************/ /* typedef struct {mpz_t *cof; long degree; long height; ratpoints_interval *domain; long num_inter; long b_low; long b_high; long sp1; long sp2; long array_size; long sturm; long num_primes; long max_forbidden; unsigned int flags; ** from here: private data ** mpz_t *work; long work_length; void *se_buffer; void *se_next; void *ba_buffer; void *ba_next; int *int_buffer; int *int_next; void *den_info; void *divisors; void *forb_ba; void *forbidden; } ratpoints_args; */ /* The first three entries of work[] are temporary mpz_t storage, the remaining ones constitue an array bc[] that will hold the coefficents of the polynomial, multiplied by powers of the denominator b */ long find_points_work(ratpoints_args *args, int process(long, long, const mpz_t, void*, int*), void *info) { long total = 0; /* total counts the points */ int quit = 0; mpz_t *c = args->cof; long degree = args->degree; long height = args->height; mpz_t *work = args->work; int point_at_infty = 0; /* indicates if there are points at infinity */ int lcfsq = mpz_perfect_square_p(c[degree]); forbidden_entry *forb_ba = (forbidden_entry *)args->forb_ba; long *forbidden = (long *)args->forbidden; /* The forbidden divisors, a zero-terminated array. Used when degree is even and leading coefficient is not a square */ use_squares1_info *den_info = (use_squares1_info *)args->den_info; long *divisors = (long *)args->divisors; /* These are used when degree is odd and leading coeff. is not +-1 */ long c_long[degree+1]; /* Stores the coefficients as longs if possible */ int use_c_long = 0; /* Flag that says if c_long[] is set */ ratpoints_sieve_entry **sieve_list = (ratpoints_sieve_entry **)args->sieve_list; bit_selection which_bits = num_all; unsigned long den_bits; ratpoints_bit_array num_bits[16]; args->flags &= RATPOINTS_FLAGS_INPUT_MASK; args->flags |= RATPOINTS_CHECK_DENOM; /* initialize memory management */ args->se_next = args->se_buffer; args->ba_next = args->ba_buffer; args->int_next = args->int_buffer; #ifdef DEBUG printf("\nfind_points_work: start...\n"); fflush(NULL); #endif if(c == NULL) return(RATPOINTS_BAD_ARGS); if(args->work_length < 3 + degree+1) return(RATPOINTS_WORK_LENGTH_TOO_SMALL); /* Eliminate leading zero coefficients */ { long old_degree = degree; while(degree > 0 && mpz_cmp_si(c[degree], 0) == 0) { degree--; } args->degree = degree; if((degree+1)>>1 < (old_degree+1)>>1) { /* Polynomial not squarefree as a binary form of even degree */ return(RATPOINTS_NON_SQUAREFREE); } } if(degree <= 0) return(RATPOINTS_BAD_ARGS); #ifdef DEBUG printf("\nfind_points_work: sanity checks...\n"); fflush(NULL); #endif /* Some sanity checks */ if(args->num_inter < 0) { args->num_inter = 0; } if(args->num_primes < 0) { args->num_primes = RATPOINTS_DEFAULT_NUM_PRIMES; } if(args->sp1 < 0) { args->sp1 = RATPOINTS_DEFAULT_SP1; } if(args->sp2 < 0) { args->sp2 = RATPOINTS_DEFAULT_SP2; } if(args->num_primes > RATPOINTS_NUM_PRIMES) { args->num_primes = RATPOINTS_NUM_PRIMES; } if(args->sp2 > args->num_primes) { args->sp2 = args->num_primes; } if(args->sp1 > args->sp2) { args->sp1 = args->sp2; } if(height < 1) { return(RATPOINTS_BAD_ARGS); } if(args->b_low < 1) { args->b_low = 1; } if(args->b_high < 1) { args->b_high = height; } if(args->b_high > height) { args->b_high = height; } if(args->max_forbidden < 0) { args->max_forbidden = RATPOINTS_DEFAULT_MAX_FORBIDDEN; } if(args->max_forbidden > RATPOINTS_NUM_PRIMES) { args->max_forbidden = RATPOINTS_NUM_PRIMES; } if(args->array_size <= 0) { args->array_size = RATPOINTS_ARRAY_SIZE; } { long s = 2*CEIL(height, LONG_LENGTH); if(args->array_size > s) { args->array_size = s; } } if(args->sturm > (long)(LONG_LENGTH - 2)) { args->sturm = (long)(LONG_LENGTH - 2); } /* Don't reverse if intervals are specified or limits for the denominator are given */ if(args->num_inter > 0 || args->b_low > 1 || args->b_high < height) { args->flags |= RATPOINTS_NO_REVERSE; } if(args->flags & RATPOINTS_VERBOSE) { printf("\nfind_points:\n"); printf(" degree: %ld\n", args->degree); printf(" coefficients:"); { long n; for(n = 0; n <= degree; n++) { printf(" "); mpz_out_str(NULL, 10, args->cof[n]); } } printf("\n"); printf(" height bound: %ld\n", args->height); printf(" denominators from %ld to %ld\n", args->b_low, args->b_high); printf(" number of primes to consider: %3ld\n", args->num_primes); printf(" number of primes for sieving: %3ld\n", args->sp2); printf(" number of primes for first stage: %3ld\n", args->sp1); printf(" maximal number of `forbidden divisors': %ld\n", args->max_forbidden); if(args->sturm >= 0) { printf(" iterations for isolations of connected components: %ld\n", args->sturm); } else { printf(" no isolation of connected components to be done\n"); } if(args->flags & RATPOINTS_NO_CHECK) { printf(" do not verify the points\n"); } if(args->flags & RATPOINTS_NO_REVERSE) { printf(" do not reverse the polynomial\n"); } if(args->flags & RATPOINTS_NO_JACOBI) { printf(" do not perform Jacobi symbol test\n"); } printf("\n"); } #ifdef DEBUG printf("\nfind_points_work: check whether to reverse polynomial\n"); fflush(NULL); #endif /* Check if reversal of polynomial might be better: * case 1: degree is even, but trailing coefficient is zero * case 2: degree is even, leading coefficient is a square, but trailing coefficient is not * case 3: degree is odd, leadinf coefficient is not +-1, trailing coefficient is zero, coeff. of x is +-1 */ if(!((args->flags) & RATPOINTS_NO_REVERSE)) { if(args->flags & RATPOINTS_VERBOSE) { printf("Check if polynomial should be reversed " "for better performance:\n"); } if((degree & 1) == 0) { if(mpz_cmp_si(c[0], 0) == 0) /* case 1 */ { long n; if(mpz_cmp_si(c[1], 0) == 0) { return(RATPOINTS_NON_SQUAREFREE); /* divisible by x^2 */ } args->flags |= RATPOINTS_REVERSED; for(n = 0; n < degree>>1; n++) { mpz_set(work[0], c[n]); mpz_set(c[n], c[degree-n]); mpz_set(c[degree-n], work[0]); } degree--; args->degree = degree; if(args->flags & RATPOINTS_VERBOSE) { printf(" even degree, zero constant term ==> reverse\n\n"); } } else { if(lcfsq && !mpz_perfect_square_p(c[0])) /* case 2 */ { long n; args->flags |= RATPOINTS_REVERSED; for(n = 0; n < degree>>1; n++) { mpz_set(work[0], c[n]); mpz_set(c[n], c[degree-n]); mpz_set(c[degree-n], work[0]); } lcfsq = 0; if(args->flags & RATPOINTS_VERBOSE) { printf(" even degree, leading coefficient is a square, " "constant term is not a square ==> reverse\n\n"); } } } } else /* now degree is odd */ { mpz_abs(work[0], c[degree]); mpz_abs(work[1], c[1]); if(mpz_cmp_si(work[0], 1) != 0 && mpz_cmp_si(c[0], 0) == 0 && mpz_cmp_si(work[1], 1) == 0) /* case 3*/ { long n; args->flags |= RATPOINTS_REVERSED; for(n = 1; n < degree>>1; n++) { mpz_set(work[0], c[n]); mpz_set(c[n], c[degree+1-n]); mpz_set(c[degree+1-n], work[0]); } if(args->flags & RATPOINTS_VERBOSE) { printf(" odd degree, leading coefficient not +/-1, zero " "constant term, coefficient of x is +/-1 ==> reverse\n\n"); } } } } if(args->flags & RATPOINTS_VERBOSE) { if(!(args->flags & RATPOINTS_REVERSED)) { printf(" criteria are not met ==> don't reverse\n\n"); } } #ifdef DEBUG if(args->flags & RATPOINTS_REVERSED) { printf("\nfind_points_work: polynomial reversed.\n"); fflush(NULL); } #endif /* Check is coefficients are small (i.e., fit into a long) */ { long i; int flag = 1; for(i = 0; i <= degree; i++) { if(mpz_fits_slong_p(c[i])) { c_long[i] = mpz_get_si(c[i]); } else { flag = 0; break; } } use_c_long = flag; } #ifdef DEBUG printf("\nfind_points_work: compute connected components\n"); fflush(NULL); #endif /* Deal with the intervals */ if(args->num_inter == 0) /* default interval (effectively ]-infty,infty[) if none is given */ { if(args->domain == NULL) return(RATPOINTS_BAD_ARGS); args->domain[0].low = -height; args->domain[0].up = height; args->num_inter = 1; } if(args->sturm >= 0) { long ret; if(args->flags & RATPOINTS_VERBOSE) { printf("Isolate the connected components:\n"); } ret = _ratpoints_compute_sturm(args); if(args->flags & RATPOINTS_VERBOSE) { if(ret < 0) { printf(" polynomial is not squarefree ==> stop\n\n"); } else if(ret == 0) { printf(" polynomial is always negative ==> no points\n\n"); } else { long n; printf(" can restrict to the following intervals:\n "); for(n = 0; n < args->num_inter; n++) { printf("[%lf, %lf] ", args->domain[n].low, args->domain[n].up); } printf("\n\n"); } } if(ret <= 0) /* not squarefree or no real points */ { if(ret == 0) return(0); return(RATPOINTS_NON_SQUAREFREE); } } /* Point(s) at infinity? */ if((degree & 1) || lcfsq) { args->flags &= ~RATPOINTS_CHECK_DENOM; point_at_infty = 1; if(args->flags & RATPOINTS_VERBOSE) { printf("There are points at infinity\n\n"); } } /* Can use only squares as denoms if degree is odd and poly is +-monic */ if(degree & 1) { mpz_set(work[1], c[degree]); mpz_abs(work[0], work[1]); if(mpz_cmp_si(work[0], 1) == 0) { args->flags |= RATPOINTS_USE_SQUARES; if(args->flags & RATPOINTS_VERBOSE) { printf("Degree is odd, leading coefficient is +/-1\n"); printf(" ==> can restrict to squares as denominators\n\n"); } } else /* set up information on divisors of leading coefficient */ { if(args->flags & RATPOINTS_VERBOSE) { printf("Degree is odd, leading coefficient is not +/-1\n"); printf(" ==> can restrict denominators\n" " to squares times certain " "divisors of the leading coefficient:\n"); } setup_us1(args); if(args->flags & RATPOINTS_VERBOSE) { if(args->flags & RATPOINTS_USE_SQUARES1) { long n; printf(" divisors:"); for(n = 0; divisors[n]; n++) { printf(" %ld", divisors[n]); } printf("\n\n"); } else { printf(" no complete factorization obtained, or too many divisors\n" " ==> cannot use this feature\n\n"); } } } } /* deal with f mod powers of 2 */ if(args->flags & RATPOINTS_VERBOSE) { printf("Obtain information from the polynomial mod 16:\n"); } which_bits = get_2adic_info(args, &den_bits, &num_bits[0]); /* which_bits says whether to consider even and/or odd numerators when the denominator is odd. Bit k in den_bits is 0 if b congruent to k mod LONG_LENGTH need not be considered as a denominator. Bit k in num_bits[b] is 0 is numerators congruent to k (which_bits = den_all) / 2k (which_bits = den_even) / 2k+1 (which_bits = den_odd) need not be considered for denominators congruent to b mod 16. */ #ifdef DEBUG { long i, c = 0; printf("\nusing %s numerators for odd denominators\n", (which_bits == num_none) ? "no" : (which_bits == num_even) ? "even" : (which_bits == num_odd) ? "odd" : "all"); printf("\nden_ bits : %*.*lx\n", WIDTH, WIDTH, den_bits); printf("\nnum_bits for b = 15, 14, ..., 0 mod 16 " "[high numerators to the left]:"); for(i = 15; i >= 0; i--, c++) { if((c & (0xff >> LONG_SHIFT)) == 0) { printf("\n"); } #ifdef USE_SSE printf(" %*.*lx", WIDTH, WIDTH, EXT0(num_bits[i])); #else printf(" %*.*lx", WIDTH, WIDTH, num_bits[i]); #endif } printf("\n\n"); fflush(NULL); } #else if(args->flags & RATPOINTS_VERBOSE) { printf(" use %s numerators for odd denominators\n\n", (which_bits == num_none) ? "no" : (which_bits == num_even) ? "even" : (which_bits == num_odd) ? "odd" : "all"); } #endif /* set up the sieve data structure */ if(args->flags & RATPOINTS_VERBOSE) { printf("Find the points mod p for the first %ld odd primes p:\n", args->num_primes); } { long ret = sieving_info(args, use_c_long, &c_long[0], sieve_list); if(ret) { #ifdef DEBUG printf("\nno points mod p = %ld ==> return(0)\n", ret); #else if(args->flags & RATPOINTS_VERBOSE) { printf(" no points mod p = %ld ==> no rational points\n\n", ret); } #endif return(0); } } #ifdef DEBUG { long n; printf("\n%ld primes for first stage:\n", args->sp1); for(n = 0; n < args->sp1; n++) { printf(" %ld", sieve_list[n]->p); } printf("\n\n%ld primes for second stage:\n", args->sp2 - args->sp1); for( ; n < args->sp2; n++) { printf(" %ld", sieve_list[n]->p); } printf("\n"); fflush(NULL); } #else if(args->flags & RATPOINTS_VERBOSE) { long n; printf(" use %ld primes for first stage:\n ", args->sp1); for(n = 0; n < args->sp1; n++) { printf(" %ld", sieve_list[n]->p); } printf("\n use %ld primes for second stage:\n ", args->sp2 - args->sp1); for( ; n < args->sp2; n++) { printf(" %ld", sieve_list[n]->p); } printf("\n\n"); } #endif /* deal with point(s) at infinity */ if(point_at_infty) { long a = 1, b = 0; #ifdef DEBUG printf("\nfind_points_work: points at infinity...\n"); fflush(NULL); #else if(args->flags & RATPOINTS_VERBOSE) { printf("Points at infinity:\n"); } #endif if(args->flags & RATPOINTS_REVERSED) { a = 0; b = 1; } if((args->flags) & RATPOINTS_NO_CHECK) { mpz_set_si(work[0], 0); total += process(a, b, work[0], info, &quit); } else { if(degree & 1) { mpz_set_si(work[0], 0); total += process(a, b, work[0], info, &quit); } else { mpz_sqrt(work[0], c[degree]); total += process(a, b, work[0], info, &quit); if(!quit && !((args->flags) & RATPOINTS_NO_Y)) { mpz_neg(work[0], work[0]); total += process(a, b, work[0], info, &quit); } } } if(quit) { return(total); } if(args->flags & RATPOINTS_VERBOSE) { printf("\n"); } } #ifdef DEBUG printf("\nfind_points_work: start sieving...\n"); fflush(NULL); #else if(args->flags & RATPOINTS_VERBOSE) { printf("Now start the sieving procedure...\n\n"); } #endif /* now do the sieving */ { ratpoints_bit_array *survivors; #ifdef DEBUG printf("\nfind_points_work: allocating space for survivors..."); fflush(NULL); #endif survivors = (ratpoints_bit_array *)malloc((args->array_size) *sizeof(ratpoints_bit_array)); #ifdef DEBUG printf(" done\n"); fflush(NULL); #endif if(args->flags & (RATPOINTS_USE_SQUARES | RATPOINTS_USE_SQUARES1)) { if(args->flags & RATPOINTS_USE_SQUARES) /* need only take squares as denoms */ { long b, bb; long bp_list[args->sp2]; long last_b = args->b_low; #ifdef DEBUG printf("\n using squares\n"); fflush(NULL); #endif { long n; for(n = 0; n < args->sp2; n++) { bp_list[n] = mod(args->b_low, sieve_list[n]->p); } } for(b = 1; bb = b*b, bb <= args->b_high; b++) { if(bb >= args->b_low) { ratpoints_bit_array bits = num_bits[bb & 0xf]; #ifdef USE_SSE if(TEST(bits)) #else if(bits) #endif { long n; long d = bb - last_b; /* fill bp_list */ for(n = 0; n < args->sp2; n++) { bp_list[n] = mod(bp_list[n] + d, sieve_list[n]->p); } last_b = bb; total += sift(bb, survivors, args, which_bits, bits, sieve_list, &bp_list[0], &quit, process, info); if(quit) { break; } } #ifdef DEBUG else { printf("\nb = %ld: excluded mod 16\n", b); fflush(NULL); } #endif } } } else /* args->flags & RATPOINTS_USE_SQUARES1 */ { long *div = &divisors[0]; long b, bb; long bp_list[args->sp2]; #ifdef DEBUG printf("\n using squares times divisors of leading coefficient\n"); fflush(NULL); #endif for( ; *div; div++) { long last_b = *div; #ifdef DEBUG printf("\n divisor = %ld\n", *div); fflush(NULL); #endif { long n; for(n = 0; n < args->sp2; n++) { bp_list[n] = mod(*div, sieve_list[n]->p); } } for(b = 1; bb = (*div)*b*b, bb <= args->b_high; b++) { if(bb >= args->b_low) { int flag = 1; ratpoints_bit_array bits = num_bits[bb & 0xf]; #ifdef USE_SSE if(EXT0(bits)) #else if(bits) #endif { long i; long n; long d = bb - last_b; /* fill bp_list */ for(n = 0; n < args->sp2; n++) { bp_list[n] = mod(bp_list[n] + d, sieve_list[n]->p); } last_b = bb; for(i = 0; den_info[i].p; i++) { int v = valuation1(bb, den_info[i].p); if((v >= den_info[i].slope) && ((v + (den_info[i].val)) & 1)) { flag = 0; break; } } if(flag) { total += sift(bb, survivors, args, which_bits, bits, sieve_list, &bp_list[0], &quit, process, info); if(quit) { break; } } } #ifdef DEBUG else { printf("\nb = %ld: excluded mod 16\n", b); fflush(NULL); } #endif } } if(quit) { break; } } } } else { if(args->flags & RATPOINTS_CHECK_DENOM) { long *forb; long b; long bp_list[args->sp2]; long last_b = args->b_low; unsigned long b_bits; #ifdef DEBUG printf("\n taking account of forbidden divisors of the denominator\n"); fflush(NULL); #endif { long n; for(n = 0; n < args->sp2; n++) { bp_list[n] = mod(args->b_low, sieve_list[n]->p); } } #ifdef DEBUG printf("\n bp_list initialized\n"); fflush(NULL); #endif { forbidden_entry *fba = &forb_ba[0]; long b_low = args->b_low; long w_low = (b_low-1) >> LONG_SHIFT; b_bits = den_bits; while(fba->p) { fba->curr = fba->start + mod(w_low, fba->p); b_bits &= *(fba->curr); fba++; } b_bits >>= (b_low-1) & LONG_MASK; } #ifdef DEBUG printf("\n initial b_bits = %*.*lx\n", WIDTH, WIDTH, b_bits); fflush(NULL); #endif for(b = args->b_low; b <= args->b_high; b++) { ratpoints_bit_array bits = num_bits[b & 0xf]; if((b & LONG_MASK) == 0) { /* next b_bits */ forbidden_entry *fba = &forb_ba[0]; b_bits = den_bits; while(fba->p) { fba->curr++; if(fba->curr == fba->end) { fba->curr = fba->start; } b_bits &= *(fba->curr); fba++; } } else { b_bits >>= 1; } #ifdef DEBUG printf("\n b_bits = %*.*lx\n", WIDTH, WIDTH, b_bits); fflush(NULL); #endif #ifdef USE_SSE if((b_bits & 1) && EXT0(bits)) #else if((b_bits & 1) && bits) #endif { /* check if denominator is excluded */ for(forb = &forbidden[0] ; *forb && (b % (*forb)); forb++) {}; #ifdef DEBUG if(*forb) { printf("\nb = %ld: excluded mod %ld\n", b, *forb); fflush(NULL); } #endif if(*forb == 0 && ((args->flags & RATPOINTS_NO_JACOBI) || (use_c_long ? jacobi1(b, c_long[degree]) : jacobi(b, work[0], c[degree])) == 1)) { long n; long d = b - last_b; /* fill bp_list */ for(n = 0; n < args->sp2; n++) { long bp = bp_list[n] + d; long p = sieve_list[n]->p; while(bp >= p) { bp -= p; } bp_list[n] = bp; } last_b = b; total += sift(b, survivors, args, which_bits, bits, sieve_list, &bp_list[0], &quit, process, info); if(quit) { break; } } #ifdef DEBUG else { if(*forb == 0) { printf("\nb = %ld: excluded by Jacobi symbol\n", b); fflush(NULL); } } #endif } } } /* if(args->flags & RATPOINTS_CHECK_DENOM) */ else { long b; long bp_list[args->sp2]; long last_b = args->b_low; { long n; for(n = 0; n < args->sp2; n++) { bp_list[n] = mod(args->b_low, sieve_list[n]->p); } } for(b = args->b_low; b <= args->b_high; b++) { ratpoints_bit_array bits = num_bits[b & 0xf]; #ifdef USE_SSE if(EXT0(bits)) #else if(bits) #endif { long n; long d = b - last_b; /* fill bp_list */ for(n = 0; n < args->sp2; n++) { long bp = bp_list[n] + d; long p = sieve_list[n]->p; while(bp >= p) { bp -= p; } bp_list[n] = bp; } last_b = b; total += sift(b, survivors, args, which_bits, bits, sieve_list, &bp_list[0], &quit, process, info); if(quit) { break; } } #ifdef DEBUG else { printf("\nb = %ld: excluded mod 16\n", b); fflush(NULL); } #endif } } } free(survivors); } #ifdef DEBUG printf("\nfind_points_work: done. total = %ld.\n", total); fflush(NULL); #endif return(total); } /************************************************************************** * The wrapper function, doing init, work, and clear * **************************************************************************/ long find_points(ratpoints_args *args, int process(long, long, const mpz_t, void*, int*), void *info) { long result; /* first initialize */ find_points_init(args); /* then do the work */ result = find_points_work(args, process, info); /* now clean up */ find_points_clear(args); /* and return the result */ return(result); } /************************************************************************** * Check a `survivor' of the sieve if it really gives a point. * * This function is called by _ratpoints_sift0(), see sift.c . * **************************************************************************/ long _ratpoints_check_point(long a, long b, ratpoints_args *args, int *quit, int process(long, long, const mpz_t, void*, int*), void *info) { mpz_t *c = args->cof; long degree = args->degree; int reverse = args->flags & RATPOINTS_REVERSED; long total = 0; mpz_t *work = args->work; mpz_t *bc = &work[3]; if(!((args->flags) & RATPOINTS_NO_CHECK)) { long k; /* Compute F(a, b), where F is the homogenized version of f of smallest possible even degree */ if(args->flags & RATPOINTS_COMPUTE_BC) { /* compute entries bc[k] = c[k] * b^(degree-k), k < degree */ #ifdef DEBUG printf("\ncheck_point: compute bc[] (b = %ld)\n", b); fflush(NULL); #endif mpz_set_si(work[0], 1); for(k = degree-1; k >= 0; k--) { mpz_mul_ui(work[0], work[0], b); mpz_mul(bc[k], c[k], work[0]); } args->flags &= ~RATPOINTS_COMPUTE_BC; } #ifdef DEBUG printf("check_point: computing f(a = %ld, b = %ld)\n", a, b); fflush(NULL); #endif mpz_set(work[2], c[degree]); for(k = degree-1; k >= 0; k--) { mpz_mul_si(work[2], work[2], a); mpz_add(work[2], work[2], bc[k]); } if(degree & 1) mpz_mul_ui(work[2], work[2], b); /* check if f(x,z) is a square; if so, process the point(s) */ if(mpz_cmp_si(work[2], 0) >= 0) { mpz_sqrtrem(work[0], work[1], work[2]); /* work[0] = isqrt(work[2]), work[1] = remainder */ if(mpz_cmp_si(work[1], 0) == 0) { #ifdef DEBUG printf("check_point: found point (a = %ld, b = %ld)\n", a, b); fflush(NULL); #endif if(reverse) { if(a >= 0) { total += process(b, a, work[0], info, quit); } else { total += process(-b, -a, work[0], info, quit); } } else total += process(a, b, work[0], info, quit); if(!*quit && mpz_cmp_si(work[0], 0) != 0 && !((args->flags) & RATPOINTS_NO_Y)) { mpz_neg(work[0], work[0]); if(reverse) { if(a >= 0) { total += process(b, a, work[0], info, quit); } else { total += process(-b, -a, work[0], info, quit); } } else { total += process(a, b, work[0], info, quit); } } } } } /* if(!no_check) */ else { mpz_set_si(work[0], 0); if(reverse) { if(a >= 0) { total += process(b, a, work[0], info, quit); } else { total += process(-b, -a, work[0], info, quit); } } else { total += process(a, b, work[0], info, quit); } } return(total); } ratpoints-2.1.3/gen_init_sieve_h.c0000644000175000001440000000472411536145472016452 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.2 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * gen_init_sieve_h.c * * * * This program writes the file init_sieve.h * * * * Michael Stoll, Jan 9, 2008 * ***********************************************************************/ #include "rp-private.h" #include "primes.h" ratpoints_bit_array work[RATPOINTS_MAX_PRIME]; int main(int argc, char *argv[]) { long n; for(n = 0; n < RATPOINTS_NUM_PRIMES; n++) { long p = prime[n]; if(p < LONG_LENGTH) { printf("CODE_INIT_SIEVE1(%ld)\n", p); } else { printf("CODE_INIT_SIEVE2(%ld)\n", p); } } printf("\n"); printf("ratpoints_init_fun sieve_init[RATPOINTS_NUM_PRIMES] = \n{"); for(n = 0; n < RATPOINTS_NUM_PRIMES; n++) { long p = prime[n]; { printf("&sieve_init_%ld", p); } if(n < RATPOINTS_NUM_PRIMES - 1) printf(",\n "); } printf("};\n\n"); return(0); } ratpoints-2.1.3/primes.h0000644000175000001440000000512411536145472014453 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.1 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * primes.h * * * * The odd prime numbers up to 1024 * * * * Michael Stoll, Jan 9, 2008 * ***********************************************************************/ #define PRIMES1000 171 static const long prime[PRIMES1000] = {3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103, 107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199, 211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313, 317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433, 439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563, 569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673, 677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811, 821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941, 947,953,967,971,977,983,991,997,1009,1013,1019,1021}; ratpoints-2.1.3/Makefile0000644000175000001440000001117111536145472014442 0ustar mstollusers# ratpoints-2.1.3 # - A program to find rational points on hyperelliptic curves # Copyright (C) 2008, 2009 Michael Stoll # # This program is free software: you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation, either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of version 2 of the GNU General # Public License along with this program. # If not, see . # # # Makefile # # Michael Stoll, September 21, 2009 PRIME_SIZE = 7 CC = gcc RM = rm -f INSTALL = cp INSTALL_DIR = /usr/local CCFLAGS1 = -Wall -O2 -fomit-frame-pointer -DRATPOINTS_MAX_BITS_IN_PRIME=${PRIME_SIZE} -DUSE_SSE # for gcc on Apple, may have to add '-fnested-functions' to CCFLAGS1 CCFLAGS2 = -lgmp -lgcc -lc -lm CCFLAGS3 = -L. -lratpoints CCFLAGS = DISTFILES = Makefile ratpoints.h rp-private.h primes.h \ gen_find_points_h.c gen_init_sieve_h.c \ sift.c init.c sturm.c find_points.c \ main.c rptest.c testdata.h testbase ratpoints-doc.pdf \ gpl-2.0.txt TEMPFILES = sift.o init.o sturm.o find_points.o \ sift.s init.s find_points.h init_sieve.h \ gen_find_points_h gen_init_sieve_h \ rptest.out sift-debug.o find_points-debug.o main.o TARGETFILES = ratpoints libratpoints.a rptest ratpoints-debug all: ratpoints libratpoints.a test: rptest testbase time ./rptest > rptest.out # diff -q testbase rptest.out cmp -s testbase rptest.out || echo "Test failed!" install-bin: ratpoints ${INSTALL} ratpoints ${INSTALL_DIR}/bin/ chmod 755 ${INSTALL_DIR}/bin/ratpoints install-lib: ratpoints.h libratpoints.a ${INSTALL} ratpoints.h ${INSTALL_DIR}/include/ chmod 644 ${INSTALL_DIR}/include/ratpoints.h ${INSTALL} libratpoints.a ${INSTALL_DIR}/lib/ chmod 644 ${INSTALL_DIR}/lib/libratpoints.a install: install-bin install-lib dist: ${DISTFILES} mkdir -p ratpoints-2.1.3 cp ${DISTFILES} ratpoints-2.1.3/ tar --create --file=ratpoints-2.1.3-`date --rfc-3339=date`.tar.gz \ --gzip --dereference ratpoints-2.1.3 rm -r ratpoints-2.1.3 clean: ${RM} ${TEMPFILES} distclean: clean ${RM} ${TARGETFILES} debug: ratpoints-debug libratpoints.a: sift.o init.o sturm.o find_points.o ar rs libratpoints.a sift.o init.o sturm.o find_points.o ratpoints: libratpoints.a main.c ratpoints.h ${CC} main.c -o ratpoints ${CCFLAGS1} ${CCFLAGS2} ${CCFLAGS3} ${CCFLAGS} main.o: main.c ratpoints.h ${CC} main.c -c -o main.o ${CCFLAGS1} -O3 ${CCFLAGS} ratpoints-debug: sift-debug.o init.o sturm.o find_points-debug.o main.o ${CC} sift-debug.o init.o sturm.o find_points-debug.o main.o \ -o ratpoints-debug ${CCFLAGS1} ${CCFLAGS2} ${CCFLAGS} sift.o: sift.c ratpoints.h rp-private.h ${CC} sift.c -c -o sift.o ${CCFLAGS1} -funroll-loops ${CCFLAGS} sift-debug.o: sift.c ratpoints.h rp-private.h ${CC} sift.c -c -o sift-debug.o ${CCFLAGS1} -funroll-loops -DDEBUG ${CCFLAGS} sift.s: sift.c ratpoints.h rp-private.h ${CC} sift.c -S -o sift.s ${CCFLAGS1} -funroll-loops ${CCFLAGS} sift.i: sift.c ratpoints.h rp-private.h ${CC} sift.c -E -o sift.i ${CCFLAGS1} -funroll-loops ${CCFLAGS} init.o: init.c ratpoints.h rp-private.h init_sieve.h ${CC} init.c -c -o init.o ${CCFLAGS1} -funroll-loops -O3 ${CCFLAGS} init.s: init.c ratpoints.h rp-private.h init_sieve.h ${CC} init.c -S -o init.s ${CCFLAGS1} -funroll-loops -O3 ${CCFLAGS} sturm.o: sturm.c ratpoints.h rp-private.h ${CC} sturm.c -c -o sturm.o ${CCFLAGS1} ${CCFLAGS} find_points.o: find_points.c ratpoints.h rp-private.h primes.h find_points.h ${CC} find_points.c -c -o find_points.o ${CCFLAGS1} ${CCFLAGS} find_points-debug.o: find_points.c ratpoints.h rp-private.h primes.h find_points.h ${CC} find_points.c -c -o find_points-debug.o ${CCFLAGS1} -DDEBUG ${CCFLAGS} rptest: libratpoints.a rptest.c ratpoints.h testdata.h ${CC} rptest.c -o rptest ${CCFLAGS1} ${CCFLAGS2} ${CCFLAGS3} ${CCFLAGS} gen_init_sieve_h: gen_init_sieve_h.c ratpoints.h rp-private.h primes.h ${CC} gen_init_sieve_h.c -o gen_init_sieve_h ${CCFLAGS1} ${CCFLAGS2} ${CCFLAGS} gen_find_points_h: gen_find_points_h.c ratpoints.h rp-private.h primes.h ${CC} gen_find_points_h.c -o gen_find_points_h ${CCFLAGS1} ${CCFLAGS2} ${CCFLAGS} init_sieve.h: gen_init_sieve_h ./gen_init_sieve_h > init_sieve.h find_points.h: gen_find_points_h ./gen_find_points_h > find_points.h ratpoints-2.1.3/ratpoints-doc.pdf0000644000175000001440000055742511536145472016304 0ustar mstollusers%PDF-1.4 % 5 0 obj << /S /GoTo /D (section.1) >> endobj 8 0 obj (1. Introduction) endobj 9 0 obj << /S /GoTo /D (section.2) >> endobj 12 0 obj (2. History and Acknowledgements) endobj 13 0 obj << /S /GoTo /D (section.3) >> endobj 16 0 obj (3. Availability) endobj 17 0 obj << /S /GoTo /D (section.4) >> endobj 20 0 obj (4. Installation) endobj 21 0 obj << /S /GoTo /D (subsection.4.1) >> endobj 24 0 obj (4.1. Extract the archive) endobj 25 0 obj << /S /GoTo /D (subsection.4.2) >> endobj 28 0 obj (4.2. Build the program and library) endobj 29 0 obj << /S /GoTo /D (subsection.4.3) >> endobj 32 0 obj (4.3. Run a test) endobj 33 0 obj << /S /GoTo /D (subsection.4.4) >> endobj 36 0 obj (4.4. Install) endobj 37 0 obj << /S /GoTo /D (subsection.4.5) >> endobj 40 0 obj (4.5. Debugging) endobj 41 0 obj << /S /GoTo /D (subsection.4.6) >> endobj 44 0 obj (4.6. Cleaning up) endobj 45 0 obj << /S /GoTo /D (subsection.4.7) >> endobj 48 0 obj (4.7. Requirements) endobj 49 0 obj << /S /GoTo /D (subsection.4.8) >> endobj 52 0 obj (4.8. List of files) endobj 53 0 obj << /S /GoTo /D (section.5) >> endobj 56 0 obj (5. How to use ratpoints) endobj 57 0 obj << /S /GoTo /D (subsection.5.1) >> endobj 60 0 obj (5.1. Basic operation) endobj 61 0 obj << /S /GoTo /D (subsection.5.2) >> endobj 64 0 obj (5.2. Early abort) endobj 65 0 obj << /S /GoTo /D (subsection.5.3) >> endobj 68 0 obj (5.3. Changing the output) endobj 69 0 obj << /S /GoTo /D (subsection.5.4) >> endobj 72 0 obj (5.4. Restricting the search domain) endobj 73 0 obj << /S /GoTo /D (subsection.5.5) >> endobj 76 0 obj (5.5. Setting the parameters for the sieve) endobj 77 0 obj << /S /GoTo /D (subsection.5.6) >> endobj 80 0 obj (5.6. Switching off optimizations) endobj 81 0 obj << /S /GoTo /D (subsection.5.7) >> endobj 84 0 obj (5.7. Switching off exact testing of points) endobj 85 0 obj << /S /GoTo /D (subsection.5.8) >> endobj 88 0 obj (5.8. Overriding previous options) endobj 89 0 obj << /S /GoTo /D (section.6) >> endobj 92 0 obj (6. How to use the library) endobj 93 0 obj << /S /GoTo /D (section.7) >> endobj 96 0 obj (7. Fine-tuning the parameters) endobj 97 0 obj << /S /GoTo /D (section.8) >> endobj 100 0 obj (8. Implementation) endobj 101 0 obj << /S /GoTo /D (subsection.8.1) >> endobj 104 0 obj (8.1. Overview) endobj 105 0 obj << /S /GoTo /D (subsection.8.2) >> endobj 108 0 obj (8.2. Sorting the primes) endobj 109 0 obj << /S /GoTo /D (subsection.8.3) >> endobj 112 0 obj (8.3. Using connected components) endobj 113 0 obj << /S /GoTo /D (subsection.8.4) >> endobj 116 0 obj (8.4. Using 2-adic information) endobj 117 0 obj << /S /GoTo /D (subsection.8.5) >> endobj 120 0 obj (8.5. Elimination of denominators) endobj 121 0 obj << /S /GoTo /D (subsection.8.6) >> endobj 124 0 obj (8.6. Reversing the polynomial) endobj 125 0 obj << /S /GoTo /D (subsection.8.7) >> endobj 128 0 obj (8.7. Some general remarks) endobj 129 0 obj << /S /GoTo /D (subsection.8.8) >> endobj 132 0 obj (8.8. Change log) endobj 133 0 obj << /S /GoTo /D (section*.1) >> endobj 136 0 obj (References) endobj 137 0 obj << /S /GoTo /D [138 0 R /Fit ] >> endobj 142 0 obj << /Length 2207 /Filter /FlateDecode >> stream xڍX[s۶~!g"^r|RqǗ4V:IfEA"TbAJtN_z[/n.7-/.?eJ oiRzq*Xk}y2"*Ȥ}|Q/D,?]$\ۇ>;on_ߗMˏ22:Ș%\y 4MIZ>Q%?d00#&ps&oׇflDL K1e岬:P6 }"A3T+ॾח-'ȄEB Ҙ߷UwsbĜֽi&߱` u. ݭҎ߷4~*i-k"ƻ@,eqD,JGy&y Əh%b e4lC;nm=*0I[%~'ئUA4vE&]Vp&b^T F9)uժ6<rɱ_e`!{x;EoMI͚&Wi!c[o}yTELHl[D T( j^ki&1 J1kȎ3y則sT3P=2E"51pD~yLuB-ulhf-EK\> [8&h -uW; cI*Q05#g7gr[]Zi-Ӛ&Oz,X%Cl=|¦O'2ceh>Fbn!hϥo, GDrVԳ̿uj~0y٘hKSJ܀%"yDgұ`ũ "TZiAAKj"og H@_u4Li}0z(jNH@_@h T@jTYa)!_jc4FS-!ʑbW}Ur٢Ԉ tɆ(=NUh$\m|vpncsR%J wT*3@n ho,PRْOS)  PLJg{2Gw1l PrKd1a).wu2HNBO{Ii/8܆L s72F 6.bC% 6Dt3egnMۻRcPQ6xȶ́f{Y:sy߹^^`(RW/#H? {>7"h"B[K*/SA5GtpU Mo endstream endobj 138 0 obj << /Type /Page /Contents 142 0 R /Resources 141 0 R /MediaBox [0 0 595.276 841.89] /Parent 152 0 R /Annots [ 139 0 R 140 0 R ] >> endobj 139 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [185.347 373.464 193.192 386.083] /Subtype /Link /A << /S /GoTo /D (section.8) >> >> endobj 140 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 0] /Rect [481.44 266.124 498.39 275.47] /Subtype /Link /A << /S /GoTo /D (cite.ratpoints) >> >> endobj 143 0 obj << /D [138 0 R /XYZ 89.964 738.753 null] >> endobj 144 0 obj << /D [138 0 R /XYZ 89.964 724.805 null] >> endobj 6 0 obj << /D [138 0 R /XYZ 89.964 609.483 null] >> endobj 10 0 obj << /D [138 0 R /XYZ 89.964 515.919 null] >> endobj 14 0 obj << /D [138 0 R /XYZ 89.964 310.946 null] >> endobj 141 0 obj << /Font << /F29 145 0 R /F30 146 0 R /F31 147 0 R /F32 148 0 R /F33 149 0 R /F34 150 0 R /F35 151 0 R >> /ProcSet [ /PDF /Text ] >> endobj 156 0 obj << /Length 1718 /Filter /FlateDecode >> stream xڭXY6~_J@̒uMMMfӵ$(2m%W!)(<726^XzF^J8rD,b^$Bo>_]ii/_^ fBE3Nq7(|w}vKnׯoίY_gY01?hK0f<$@149Fl N|Y2cUNg\(qO]nuBQ$J5yoh4܈ueDsj'Օ+U]=0"qG2L19hk0)0u;Qd #E 4+l.[@3`kH@lLLJ-! {`k}3 0~$$4/vC\ G'W7vn6֤IXjvTzp[7[vf ;UOO]})'aG8Q{sfV;Uve'MxzUR$6|}8BFۃn)Y `˼VrXݺA-ˍVkkN8sYځ+Nv"sv}jwZ@,hvrZ[[%ViBs)<~v1!p BFVv}Jq}p2[p C2$˳SyBDrNbP>| 6RwoDw^H on4qftP{)8rDmSV|yn%"dc $Сm N)vX\tNt]W;~d`oxoW^7F#~1wG`@q5A9|j`CS@萉GUnfr7@E#YFx64O yԋp&k CR M!AH{VS A{<$H+!Iˇ| \L <-1ΏҜM׮O|dOϛ9bGb~UH3]^ă6(tr5lu6ԹusPP8_bnxk,g/r,H90X@HXzWk{+vV= "!4I0ȍĀ2fbЎvb8 Ob lb irkHP[,.f&&j`ݾpb_Cԥ71Ug ռ?&gre1OT endstream endobj 155 0 obj << /Type /Page /Contents 156 0 R /Resources 154 0 R /MediaBox [0 0 595.276 841.89] /Parent 152 0 R >> endobj 157 0 obj << /D [155 0 R /XYZ 89.964 738.753 null] >> endobj 18 0 obj << /D [155 0 R /XYZ 89.964 724.805 null] >> endobj 22 0 obj << /D [155 0 R /XYZ 89.964 669.862 null] >> endobj 26 0 obj << /D [155 0 R /XYZ 89.964 575.422 null] >> endobj 30 0 obj << /D [155 0 R /XYZ 89.964 220.231 null] >> endobj 154 0 obj << /Font << /F35 151 0 R /F31 147 0 R /F32 148 0 R /F29 145 0 R /F33 149 0 R /F55 158 0 R /F56 159 0 R >> /ProcSet [ /PDF /Text ] >> endobj 163 0 obj << /Length 2134 /Filter /FlateDecode >> stream xڵXKs8WHUY0 Q[UYOVb:TMB26Ï (щw7(XQ7\)QRb$&J )IE)Tf3XofL7kl^vj v3cixՇ *¦8Iq2\g_5v {i}y5pcmOiJc /(<+/nbJKTm,7?H )%\ $hyLLݜsJ>| J=g f&t3 =/~ͥA Z@ ]Y面(ruddqIұ- ?"zexr\{efV'!8ūm^yFa& hO ZPL>% Ѓ.]Hٿ=d$! F/LK&esP'<Ǜxy64-ւ@|A4J"hS8"շj?$:ѮK,΢'܆wKZh7T]wگ3~(ֺj @?_8xց@t#V6R?fy[z>e:`^lF-n^H+~w\]7O`jc}U#W0SZm2PH9>`mg0Y TRg6gu?fx.Ͽ<$>@ D62Y8VtkUV4Y-k:Xkak nq:ԍnF#GyYt6.cpݽEB 6MWk z'eM"n}jHk_$}WWTQAC;v4/S9^&XH}k]?wCӏ\oۃ/:jY\owu F GY&9$7e H4l ٕ-Qnϥ`j5 |D4d+i*' B>Rv 2bԻ^f]d4t0չA SzqJC%Cypy9 *[`^"l̋f2h'ai70:n@ѹn7tz?:QkO,BP-FF2&U}lhB2kC5)^D,s.r7ƟT;6nj ip݃Q)Lk0̡zMDx6P׸y{Se` ߧ'{c%zKdu:/1*We<(8,+HG7?y$i:Lß㠀BMųr~(~PPW%"^=0GsN_Ųu[SZ.ۗMeos@9gS*֦o:<`M)7fz4niV|r?WPL҇~N;W w΍ չv}3\&\ 'trBbƼ:vFU_5m iCЈr/|g ܳNOߐq 0EPe-TIRvI4YG$kPuszGӿ,7qU&EfCY3XP /*_ fE q?@% endstream endobj 162 0 obj << /Type /Page /Contents 163 0 R /Resources 161 0 R /MediaBox [0 0 595.276 841.89] /Parent 152 0 R /Annots [ 160 0 R ] >> endobj 160 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 0] /Rect [214.547 282.965 238.651 292.429] /Subtype /Link /A << /S /GoTo /D (cite.gmp) >> >> endobj 164 0 obj << /D [162 0 R /XYZ 89.964 738.753 null] >> endobj 34 0 obj << /D [162 0 R /XYZ 89.964 724.805 null] >> endobj 38 0 obj << /D [162 0 R /XYZ 89.964 602.293 null] >> endobj 42 0 obj << /D [162 0 R /XYZ 89.964 473.928 null] >> endobj 46 0 obj << /D [162 0 R /XYZ 89.964 368.799 null] >> endobj 50 0 obj << /D [162 0 R /XYZ 89.964 274.918 null] >> endobj 161 0 obj << /Font << /F35 151 0 R /F31 147 0 R /F29 145 0 R /F33 149 0 R /F57 165 0 R >> /ProcSet [ /PDF /Text ] >> endobj 169 0 obj << /Length 3090 /Filter /FlateDecode >> stream xڭZ[۶~_81+^DI Z mIӤ'u4}\ Yr%9 Ώ?3fd_̛f7n-ˋ$Erb}byXz3zztb%zɣ߼^OKGoRgI^i跷KEo^}rZEjI3~S.892<_d9' -f>#C3)-CS}6v^ 1%7[QSvJm\75/iHʜHt sCe_ݡZ CBY{;0$HUnLݙai8tn9mvmg{! גT2aN,1*U:Y 4%6i;㾜1Un1eAt1,~_tH<2[fDx,%6>d6Yko-!{%Wg!Z֋|V "9-2]۽qX v,6 R T%zN%5'ijC"L/]ǓU<2ȼ<ɼb4h _" D0CL"pשoijT6{:ܹD9q SabCWq 9.cKͱ}"c:?O_C:YR=quA:({ϩ>9e P>RdMam)ڝ}i8  ڒ /j=>4rmv:L@7q@Z{SAN 5K<ϝݙi-u9 %xl .*`坛:? %nl닶/ܖ VI kisi, aa86s_qԕݧ~9NJ\uGˊwk ǥ騹_КMa4Bz=*9x]kBK}T;/#TwaEllr__@!\r} p BIşŋ-̳֙ŭ]_HsZ~Ϙ\8&Z__>SpUΌ돗/^^^ы@<в#{rLck˵ƃ0 AC v =SyS=ks;3d4egZgZAE>*ޕdaM;7m.h0(y&uRmGۦ~҃CTs8yieFwxL18 AjًLX-dUٷ\q*94m O:r|spѕ-$­=#ʴA’vCt!7XGg4;jғTj$Z),2+ǙeJ%ˢX\c(/:&<Ӑ1Da7ql4kfGwt .ifv]247] y> I$ I꟯itLѭt 1fW1\S>KтydKikM?fف4iʣWٳ\Y%ϰ'D8Kex"g5fHҁ5wFe> ~B:olx *3< V^Ge@_Ufk҃${ǛZYeݍ{ VDz }7-TE -`r-9fEtGWCQ M׃=JG"υ z'Nu)귮lFlψ"9D;T!6%y}4>V^}Nqy+ wx_NiN7$*D^gAG{} 4Ko"=lDk:ީ0d7YOHϒW g endstream endobj 168 0 obj << /Type /Page /Contents 169 0 R /Resources 167 0 R /MediaBox [0 0 595.276 841.89] /Parent 152 0 R >> endobj 170 0 obj << /D [168 0 R /XYZ 89.964 738.753 null] >> endobj 54 0 obj << /D [168 0 R /XYZ 89.964 688.475 null] >> endobj 58 0 obj << /D [168 0 R /XYZ 89.964 663.515 null] >> endobj 62 0 obj << /D [168 0 R /XYZ 89.964 332.598 null] >> endobj 66 0 obj << /D [168 0 R /XYZ 89.964 198.553 null] >> endobj 167 0 obj << /Font << /F35 151 0 R /F57 165 0 R /F33 149 0 R /F31 147 0 R /F32 148 0 R /F29 145 0 R /F55 158 0 R /F59 171 0 R /F56 159 0 R /F60 172 0 R /F61 173 0 R >> /ProcSet [ /PDF /Text ] >> endobj 176 0 obj << /Length 3006 /Filter /FlateDecode >> stream xڵZo8_a( b)iԽv{i8j˶Jvpptⴽ5b~J=JYf]GʹY꼧Ճ5|b?Tg' |=j2a05ع(*U}zMTnY( S[;*f? gIlg&P4c9>N͛U.q5;r1`!a~~"]a7![ڼ8y>u0`*rY*[=Z :q>X-y `w6#j0qˠrHDZ¿07@̪lfܧ`Y&<`dVM|#P7UKG]P 9y;qfO;dHq„ !H{|"K7&1mck@ y>LY[3t9]#6R.qNhѩ,c&Dh wqf=&Bg!v`$v08r- YAhmCu#s`Zǐf<߯l+P0 +G9Hbm FKz\|bt?NsPRh)#=t ' >A~:\G?B.bq:s4LP@pJO;e8e.O`8toXDBbQqg%MI1{6bY CJ 6LN)Q?6hp$>!L6D`6oz^V]ig4zlq Jdž^h/rYD4'J|ƚa. E*`4O6-R0ă͂xbPAA6DSbc[URAj˘PL+ sIF5V\doxΫم˰gJ4 Z |x6m ._oW4h#>`nS׸O(gS?rOhͬ%w0QSx֘j(Ǧī=u]`y=.zVpA<']TGv*7:FAo >*[2ltPyVD u| ?p&l_BǮ)nTMm 1*Du13Eg@ߙw` Q5sG3WgcFf^׶3 Mp3!T o!)NVym1-.@Tfl//z۟MB`<ިbS1~y?ubNܦH~3Î6;2eJz~o_]_umx)РP~1]_|fp ,`wr na2|j5zOooV`, h"Q_W]zZ1K~o^*c&Уxi,WU}.Su.vm$}Rt)oƢBUҶ*h9P-t(puѴOnI:8o(ftӢ"X_DE}U]k(l#5RLHAoq]SKNu>K9l(H=l67%/8+ endstream endobj 175 0 obj << /Type /Page /Contents 176 0 R /Resources 174 0 R /MediaBox [0 0 595.276 841.89] /Parent 152 0 R >> endobj 177 0 obj << /D [175 0 R /XYZ 89.964 738.753 null] >> endobj 70 0 obj << /D [175 0 R /XYZ 89.964 384.831 null] >> endobj 74 0 obj << /D [175 0 R /XYZ 89.964 156.602 null] >> endobj 174 0 obj << /Font << /F35 151 0 R /F31 147 0 R /F57 165 0 R /F33 149 0 R /F61 173 0 R /F55 158 0 R /F29 145 0 R /F59 171 0 R /F56 159 0 R >> /ProcSet [ /PDF /Text ] >> endobj 181 0 obj << /Length 3263 /Filter /FlateDecode >> stream xڭZ_sܶק[yCNSev*)/u2S'#eg[.HI_D`[`K]F?\7lR乊nv0*)Lff}߾~wyjeu|wRyf%Mn:zo~zH?]pjm\כ/R> EDBZYbMYR:}ݯY}5H ?Vķ5:zh/N[xcD]}pʁ&eǼ7-PV]%Ү^1E}\4 --9\D/) Y!h-@/Ң}"{Hvx"WhHf8#͎F$dXH icEIwA)$s)7~[ #-SE40zs"&(Yd(xS 7!s0`W$ afCu&/dwDjMe*tD/&5KMp$84^HU6zVS O񪤲pU8j;p>Y GVL*OL'f!Xx 'Xhf~AF:EQ-IY_\|.D k#d(hskm^[z$/g⟜%NTJ&2ϐ+緁s(ciǟ.߾R^'u.H(PS T +8Fs瀨hsL6,0溧Wk܌CR?L>% JHfSD&)L*pX dldgB|Tb@2t)SǁΊFsiS5ppz5H攏󰛝׍yb׌LN3-4#I3Ť:_ $9;,H( F!/y <u6 ƤzVÆ]EJ(&~p`%adyZꡄVO8`)9J^~"{ _"m}[_]`i3tlp^KzUʆM)BlM˄###cV "Cݔ@kn K꾄AQDŽCrǭ|h' $ ەC6xM$ĥvhq  `W}}k',`(t&7/NmL ÷IDۅ?8)M۬vi~,쳒@4zap#d0Ϗ3ֈQO/)gMJj#`ZXeN!WP7gb*] 1Ns PуFQ&_NYWb`UQĺ=0v . vüHlj^TZ>:DD.g!k{tƊ\sqCS:YB @qoq%DܕuY|shcaqv =':0]N@l0p&HRmj } yϊwCYk-aLb;<^C]3p0;I۟8TÒu=' _j>fW|He|Y@aiN5ฤDWlx c$4#4iGx dD5(ԙPBSHw$$^ɟCؚ:7"n/lCA8̳<X4aWmݤm0'AOΨ(|nJ ,Z^r;K,0j"yWL {ZzWNKzl]y4a/9VJJ܆e -d^_ KV^|o0/YSϜJ%(s_gPD%3D^mz P 3hH96L> I Up($V:xdqV*Izج既0( $\xā8wAH-x&rLXc{x)2(B&F9h$t '(!E5UG7'NIw0S̡kU>cW[z^'SXMm8ao[z,q]ˠ+=M zI&M^Uz!D=PMM, ̀ )GGRM{[ӸvOD(-kα?QΪ4>ш,CJ-; SKgӂP5۞ \̀񼗄 ^Mp}S~_f/`LxCwsɲ9ٞ+MߎԗB鼧MzY]Œa6n+"܆pAs;qUGl3KS(!1I5GM(zCrNC}C=0HŖB- 'c# H)SuC雍̟M t]رf]]H*7lhX{ȟitORdxDND CӒ=0a>1ts~7P.,1jW0KNP&K;Pzl20[*nvyO\rx Pe}U&0}?#GN!R={ߝ0ލ4}G٬oܝ#OHp]~EY ͋%C>Q8<8y5 f>T1ZЕ"8GM:-[?1YӏLಛjH v1)GLia)_|.d徳Dw뛋 endstream endobj 180 0 obj << /Type /Page /Contents 181 0 R /Resources 179 0 R /MediaBox [0 0 595.276 841.89] /Parent 152 0 R /Annots [ 178 0 R ] >> endobj 178 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [489.358 266.449 506.308 276.743] /Subtype /Link /A << /S /GoTo /D (subsection.5.5) >> >> endobj 182 0 obj << /D [180 0 R /XYZ 89.964 738.753 null] >> endobj 78 0 obj << /D [180 0 R /XYZ 89.964 344.773 null] >> endobj 82 0 obj << /D [180 0 R /XYZ 89.964 172.494 null] >> endobj 179 0 obj << /Font << /F35 151 0 R /F31 147 0 R /F55 158 0 R /F57 165 0 R /F33 149 0 R /F59 171 0 R /F29 145 0 R >> /ProcSet [ /PDF /Text ] >> endobj 185 0 obj << /Length 2475 /Filter /FlateDecode >> stream xڽ]sݿB{B.LΩOe<Il)RI;NXd:=}bf>}<}$gJųzƓϒHDFe>)rUp92Xy|*x?ip}CW8%b/i@?̅?\0_TA2yYoW3|). wl!"rd᦯ދW,T8ycmf쭹/ꮡYoj+  QEGaY#K^yfbxU'?NyDa<;mò)! !z|8 "7M/Y/u]zE> A]#RX.!xve$`t<) w9'afuo-[Rp7R~GaCzz}]1M!y::#ԣnh'^6 =ǝۇyEExE bQhUB-pxP.5<l @# t5)IHO]$ZoZk\-}a-Y91(Q *Q짟Y[zPwg)ѩ1:Y-x 8pæݪ!." Le-ˑ (17J*L0 dͩx8e7I~3 B ^_h7Xclۋ=ʨ}c}VeEu1Z nG{-'np'fO`4,.2qcfmx߹NM>foi,_n׵+TĻ)6Np;24^Ip J?'m~LpEZ>y,:>i%46a Zj y9)sOOzjT8OG׺K#11.& 8+&i åbP>u7"P@-p5qG*־ܩ"cA,Wؗm)hz.).!(9 0*>i!ۉ*dVr>H?ep g@DXT)aPd%`+;cʢ)=e˂4>mDP|U qн\CEb '}FjN-PjX ;땭6[6b7!bͦ t=ߠ} oD~'Ρ&[zgcLTjb|ou >5\AnY)J՜ӐiL4vT߰8M |] 9 ObEi;o&NUe=or*Pǧ^|l ( ¡z*ѱ S\!NYFllPZAB]VƻtS_RIH(B sDN.rB>TILeRG'EP5-Q6Yò Up \6E!#x] ^ƷO%rȘe7w 6T(t[Q|.8=p8ŮP0.` i@/9H^_!1Sofm 6H8[RĻ׆Kla3;S_!cRU^A?/`&rIGvOh endstream endobj 184 0 obj << /Type /Page /Contents 185 0 R /Resources 183 0 R /MediaBox [0 0 595.276 841.89] /Parent 187 0 R >> endobj 186 0 obj << /D [184 0 R /XYZ 89.964 738.753 null] >> endobj 86 0 obj << /D [184 0 R /XYZ 89.964 724.805 null] >> endobj 90 0 obj << /D [184 0 R /XYZ 89.964 628.433 null] >> endobj 183 0 obj << /Font << /F35 151 0 R /F31 147 0 R /F29 145 0 R /F33 149 0 R /F32 148 0 R >> /ProcSet [ /PDF /Text ] >> endobj 190 0 obj << /Length 3699 /Filter /FlateDecode >> stream x[s6_{:K4Mq7sv:DKJJRv﷋@Rbqf 8gG_?3Je"%e\Ǚ蛳g?}\\|΢g !Tb 2zGp[j<ٷo~?_\H=(i|#Sm6)sF7rU^òDzjے:jOKmO^'H$t~ LĥveQW+݌*϶~FaOT,s"( ,h)%^{a햊;(؂_Rm2Vp묚]Q!zݨ\AmꞘW n=q-I̲#fwAW<-t '(@a @PS6@\xC 9Q\/qJp*YΞ8> -3"2̑f:mfGjj2q½OE7h k88kc9jƽHn FAæQiHȧr8SG-TKyCMBsE%?Vie{ٴ^M!K.'2iI\ܶC` )if(Ib)$vѴ:tiNϔY!@8xV; Æ<(CWztUye@?bmٝJY:qҌg0:u ˷orA^^gk2⧤I2+fjXmo#!*[n[n`<ºӳ4e#]<聱Y`vĘ]`Z*,XF/ 0L%"z}rR+0f#U 3IT_w=c'ĹW!m:G0@3z?,$זf7fJ2*t:,O/DW^ؗe <OIcˇYx$J%q) OD ~sn:Z@1I^^0}^S@✋yuBZfC-ݤX#Do\1 Jk6L ̶=L ~ɽ[^2DKD\N]1p-"O؜wU je! ݻ9lI@$38_[5Fg@KBU aHL!oȺMBq3wQ/fK 38GOT!`yt 0.YlfBpIlæ-m̰ؒ,2uBi`Yd8Þsi Ü-0m}tLr0* }*Iz2i\ٜ@Gc*(zOK߶ܘH柘Y,mbgH|5S)@ɚϾ{'|vz;'3X41ȎɇKC ea%IJ;w&!;WՕ[a9̰ÁxT⏓Py먭ڍ_ipo-EC Ge's's*q=1LZh 9n /D>nyW*>JL4a8VQq "hØDKH}I|5Q?yq>J 2fwzs)e,g'l_IՊVdFħ2J@yߒ7_ݟ٧;)ʿɚzg&JC¶TNS߽bl W2HO˧)#MO .qbSC0m2FPBo=TjP+/2eg5q|IJ l,[_B=X>j)֟9͒"mL9.Y,M\?&&C?,v>3C$/xzU-M\f?JU. Ǚ=HZOpc2Ya6P:z0tXv%7,x׏(|tn~!1yC#k2}Fa>1IhS\C.ydJ4Znm=ـ¾:Q dX+ OeA͘MiE.D'(/O\C%+b-k:÷v 7*/]6AAk@+&sqҼZtZ`hƎ#ax% 1ݛ`>6dw==fyLMW EĖ/p?/GojU&*MI%h2ک"54nzf ;%>ɉOTU]eِ ތffV':C!opN$J-ed> endobj 191 0 obj << /D [189 0 R /XYZ 89.964 738.753 null] >> endobj 188 0 obj << /Font << /F35 151 0 R /F33 149 0 R /F31 147 0 R /F55 158 0 R /F61 173 0 R /F57 165 0 R /F62 192 0 R /F59 171 0 R >> /ProcSet [ /PDF /Text ] >> endobj 195 0 obj << /Length 1221 /Filter /FlateDecode >> stream xVn6}Wٍ( F͢SG H-,yu7 ;ȶʺEHΜ93sHDKdwzn9>c6 6\îc F绫u1{q9m}ә&1fcaL/[5u3SϘ^W3Ǟ * =hH-EeN*ز1q]fIR_JTzY _x'miO`F$(V"K=/$}6Ab%6muD1,~D&|mY-E_uZ,`xeC\ݨMdUU+Wyƺ"th* -`˳А@mOGPIևxX EHWjBU]d=Yy@瑘Tl+.U0%994: m IUg~P?$Y1!+5bΛhrY޼+h_M.fɏBL8NOQ9_,(\r)_N2Q/jS$.B@ck"_@1"xYo+m7] uq4Ts*H~~պp%^3ݐ y/' a?rQYw1SĺIM0׮O?TWe&+L&R3nIFkĎ-n~TaDHRk%Bb׋;ױA~Cͅ2ҊVaOoЯ4:E^T6Rh\o;aeawۄJe:}VbQ}k֨+_'>ɚ ~69oo@G葜z@Z㿍u}w5]^Mn\_pyLgGtlr}q[>hH]1Q綆 {dH endstream endobj 194 0 obj << /Type /Page /Contents 195 0 R /Resources 193 0 R /MediaBox [0 0 595.276 841.89] /Parent 187 0 R >> endobj 196 0 obj << /D [194 0 R /XYZ 89.964 738.753 null] >> endobj 193 0 obj << /Font << /F35 151 0 R /F33 149 0 R /F31 147 0 R >> /ProcSet [ /PDF /Text ] >> endobj 199 0 obj << /Length 844 /Filter /FlateDecode >> stream xڕVs@~)&NΐFtMaO6wZ1`oocPXPΕ9(=2!Pz&lQlS ^>LC_r,ѕS% ގl88اLs?cf$G7{'Ɏa"Pr9D.@#ۚb9 kLKXM`E*a.ɚjw5g?R`s-)(3lz5~7BiI Zh%ɺj,)u݈{" [z_r 7m# P6ě2۔m@Vŀ@q gfqloWpa2.Jr:L&*=:(<5J:2< իBnY#T DØf1Q8K =oTIz `e9s/1== t<^ң~Tq*  ?M NR&Uav!]5g2leZ @dd%XM>ϒC_ P"Jj8iʟ ZX[xYݙ^aNtCf^ʆޮۚB̂$DDc,6fk@d*YְpZ;Nk`^;[8~GhQ/ OT0uubn'pծ{ H[|㡶8=Ȕߓ61uc l&-P:2LǂbO3>ErJw1@2Pi ]AO\0^l3&$r7 }jy}op endstream endobj 198 0 obj << /Type /Page /Contents 199 0 R /Resources 197 0 R /MediaBox [0 0 595.276 841.89] /Parent 187 0 R >> endobj 200 0 obj << /D [198 0 R /XYZ 89.964 738.753 null] >> endobj 197 0 obj << /Font << /F35 151 0 R /F33 149 0 R >> /ProcSet [ /PDF /Text ] >> endobj 203 0 obj << /Length 2170 /Filter /FlateDecode >> stream xڥXܶ~>ZKBZ/}y Cx{B􊤽wq\6Tgb@:SR+/#؎Y\iR)u}ہg$Z޷ekOP4$/fyG]\yϔWK+v^a1R΢56)ZDl p Q6{m_7dD DT}e0aduWQBZweDtf׬avtW 7ﲑG} 2U,4< d)zA8Iz!D&q^ wU,UJ&z TI;0]rAMJAuM4Ak |g@+補>W) E3+>t[9YGBt:0;54"YxdfՃQ,(M$b{AP@(F ) kFj m},`#N"3C;e `QBI';N^ '']B lCY'`mDV#ȓ z b>w +.C;*D`DP+MW29y7 uXّy. u7Dw02mhH:J@&;MCO$"Nj:1N)V  񧒔`C42w {A[ȓMv0qIGUӻCO% nO֬E*EƴBF㿀I7H\Z_WwZH/kQO]@M.r%)54[jO5NεxqTcpٻL?wsspdJ*5ԋE-: <#c!U*% Qf90 'q8lfIAb47HC3N1|@3 6Bx Yއ@`lx7itpX#@Se97,_ʳGT[3S)'3!Tx:t8f-mUܥ?.b&A7RP40 |(dAI0PjɩV|pc#B`Yx{9Ӕ3MȺёh`p|-:) y>Z28LJ@T@ߕa=֬ LY? r!Ҝ5ꈉ <`BI{`¸=|qe$.[ G%8xT0lgZ{̃dPZ  \D ʄ+c_84x2HD;IyiCGmi^CΏM(}O OyL^Wnu@IGϙxNF/J@C8 1o*$RpαE0=AgR/n? 7 N J1]GJn3᛹S]r aQLr" Ϭ|G׫M'пPxu;sP0ȢѬX}_Sftz,Z8I@π[qm./ 1f(d;|j|I*?|Þvk*z`GvWhGP &6]oX'6"'׼ɝrj )#lVw&% endstream endobj 202 0 obj << /Type /Page /Contents 203 0 R /Resources 201 0 R /MediaBox [0 0 595.276 841.89] /Parent 187 0 R >> endobj 204 0 obj << /D [202 0 R /XYZ 89.964 738.753 null] >> endobj 94 0 obj << /D [202 0 R /XYZ 89.964 322.138 null] >> endobj 201 0 obj << /Font << /F35 151 0 R /F33 149 0 R /F31 147 0 R /F32 148 0 R /F59 171 0 R /F57 165 0 R /F55 158 0 R >> /ProcSet [ /PDF /Text ] >> endobj 208 0 obj << /Length 3546 /Filter /FlateDecode >> stream xڽZK6ϯ-T%@77k'Nm2Y[=$ GH%rBRO~v|Ȝ^DF?n(Y⛋/2 Y0*εXFvs˯͢KRD.XʢKG6t9^xRϿ_I$w  !-,V2sA4EwSU{>O<j~/Nj\*ZRɱx+-t-am9p:vs %b.GuCL-vhqԺGXȝHm`eX$X X ~51ĢE/7//K,e0\-6NjM[x".n"WśLY'Ib KͮkNԠ d]{I/0 NlYItxp lXM7<|i,{1i gj$a[<4*QNGԞ ~]C/HIhSo /=hWjr%^ uTW}(nڷeg{OJF_Ӥukd=gs'j5,N"(=~ꨟ5Zm*dTӛ0ۗL"ٮp Ʀ+ViDUݹ@2NM;i#+TŴ^ܴmi?0|Rnsc2^` ,R-%hen&c~l̇ :U23x\u5{x<褁WUd__6t,q!e˱i}9r9IDZa'}rlkHR説U_[GWmqec8\->Ł̀.I79VȢ6RwOQZm)*>o6Tx-V |:̼*rCM Wpez5=oNH#ءc ˻ L_ܫvէYBڴxIڶ:MpPK@R窔l>>趮uŻoL[HY0j`-{|_#t5oߗ̈{ ) i$$$'Cx$1g [E.Ch>*vx24XH;"DCA%$ýظ#yۚ^es:0{0IY(ꎋtW҉O"E `{}GpS8,Ϣ8D&mKW1-S߸ubCsp^cpG8aME!)ЋNQ$?2R%ͫc5R/A |"~=ck_05p*y =3HA{?L 4?OԠ-E\.j BZғoyeEPF8X چ0ik$[+WP3ymF3qnvEUQ p׊a%2jd3} 2=6P95~iXZs^K6e?,Afێda3v%ZfgҮ|{C*H߭:F}бCp1:6 ڡ8]q{oWѢ1᫲#x=Eu+օ/y%jGN\0|gBo8㕎TMm6/)yjT,t_zP+h>~BpUm|1i 9ӒXn}jɇ ,خk.vu4Cgy5Esp L>< ՠa233:G()tʡUH @8("% =+T?%ށ9hx'j)#ٙ  3Mrb>\}x qw1Dq_ءe')0泓L=u.#-D"hT_ݖ-ky&δ<J^E(Hz-Y}=KN7ƞL^*3M N ΟUTHSJf:j 7!}ɩu ~2P~a:O`AGx88)G ZD+=5KxsH2x+RpX^ mY N_trO(h-<n.sˆڮY>XowpV]X+8z?;nnx0cW>qU#*Y6}EXJrqDCrKS܇bӁ׃jO2V_*o o;8Qރ%=rSv[SR ">A8ޟ³GonxfHXj:Z[Ӳ WjDPPM>[ _>)Z;90'%  s¬;fO2j/\ sߍAnKsx(336TJ z2iH16t Z>5ՂI Yc'>72v9rSl8"߇93lW:MvWb2#"w.V)oϲ<+ƞ`66 Ak_ Bđ,axblu(16癏}DM(c0`)t+95p!T.kBt%$G&#ҽQ,B8< o mOAd/92tq* 䧶5*~{!<\*`[Aئ+hPUD q^#;ӟ b*gY, jU]%Yy;GN<kt5\oi+/%J-/g?DOWw>qC)1e=_bX=LrVCVp`?Pf/x" endstream endobj 207 0 obj << /Type /Page /Contents 208 0 R /Resources 206 0 R /MediaBox [0 0 595.276 841.89] /Parent 187 0 R >> endobj 209 0 obj << /D [207 0 R /XYZ 89.964 738.753 null] >> endobj 98 0 obj << /D [207 0 R /XYZ 89.964 642.907 null] >> endobj 102 0 obj << /D [207 0 R /XYZ 89.964 620.252 null] >> endobj 106 0 obj << /D [207 0 R /XYZ 89.964 255.722 null] >> endobj 110 0 obj << /D [207 0 R /XYZ 89.964 142.999 null] >> endobj 206 0 obj << /Font << /F35 151 0 R /F33 149 0 R /F31 147 0 R /F32 148 0 R /F29 145 0 R /F55 158 0 R /F57 165 0 R /F61 173 0 R >> /ProcSet [ /PDF /Text ] >> endobj 212 0 obj << /Length 3084 /Filter /FlateDecode >> stream xڕY[4~_ok3’l7U6  Ofw{I_&_:^?N7tn|aM|Qdv8[*~[ͫ7۲HږyrW?nH^lO^wϱ'7?zL֔ɫo_4vW\7ZrIʗnsmҴkwm'@.>CϣУp}y8%Cm,^mX:ȄS؅G^k]%MwalK.| 43XlwsJ+ԧ{욤ù;rix: g|"3֪@{'wOrM|+>p7uYX(G9x71 f+8% =K $S`ZwTáZfLoRuC;7U!4 s:!V"D/VubUQq _*S{+sYoLN9']E;i*2헃w?];yp`]a+t{_h"9*6M0BLbkxs@_͏Qpwеl-%r_ ֲ]Zv֥~@M]8]ߧ*B PvA1&KAJS0MQ$.SX. $2(0Y`@|_~+sZw>5DXfbVU(q$9}+7݄/P0`[$4nϱ6JSI8ڗYHOgrP@#.__ċ+!9 b(,K}c06 a&9"E=ndw-!Zw34,J IZWedSzJmw [ 7:2~9ݪ-e(:/v>F 819< 6x=2zr*F4>!شޘBj gk|9@cG|"1i,8gQhj;Y=t}#_]/NJ"Sy_-Ԅ0HDB=X5q0ML&]rNUj:-/Fc{R%/geXvW(*ueĚ{]=cFX_b& \ZH4eA5 1#9ULd˒z`"As?lX~6S2w *Sbģom%I׽8a3+1ݹ"ubRdLFq~:4Q#Ҝ;#lKsbXNVv[= +7?Y̔.?W6S0J?T a&hDx&dKWdA$اy>H"HÌɋ #]sW\Ds1q4"eAZ%{r!=d@2iήHI;B[3]K)x2lJzd3{цq-͈V#t4 d@#0Lk U_}rp & z)ܻpe}GO ̴\ū +Z2ԉL~=d06׃=0TJ . UX!Wn02R+7iqSbl~/8.͢*IK֍L(EFt/.ͤ`M@vS-Ì*ˤhD\ݵ#` E,gU,;<~C endstream endobj 211 0 obj << /Type /Page /Contents 212 0 R /Resources 210 0 R /MediaBox [0 0 595.276 841.89] /Parent 219 0 R /Annots [ 205 0 R ] >> endobj 205 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 0] /Rect [250.138 685.951 272.941 696.246] /Subtype /Link /A << /S /GoTo /D (cite.Cohen) >> >> endobj 213 0 obj << /D [211 0 R /XYZ 89.964 738.753 null] >> endobj 114 0 obj << /D [211 0 R /XYZ 89.964 617.021 null] >> endobj 118 0 obj << /D [211 0 R /XYZ 89.964 456.988 null] >> endobj 214 0 obj << /D [211 0 R /XYZ 89.964 380.641 null] >> endobj 215 0 obj << /D [211 0 R /XYZ 89.964 322.614 null] >> endobj 216 0 obj << /D [211 0 R /XYZ 89.964 225.069 null] >> endobj 210 0 obj << /Font << /F35 151 0 R /F31 147 0 R /F55 158 0 R /F62 192 0 R /F29 145 0 R /F32 148 0 R /F61 173 0 R /F57 165 0 R /F63 217 0 R /F56 159 0 R /F64 218 0 R /F60 172 0 R >> /ProcSet [ /PDF /Text ] >> endobj 223 0 obj << /Length 3121 /Filter /FlateDecode >> stream xڕZrܸ}W()sR+'rW[6[lJ˙fP|}ˌ- ӧ!EvqzQe%w*O2Uy\y_m/p~[YnUJ7?.$ ޯt|?컟neOVneQ>DE]( IaY:Kźar9W'ai؆f}2OXu٭.< ~TM{U-}YTETΛ:KeSmAo]7Jk EТ-V8s9Ⱦ%dlz |_hxZ8R͒5'Mkl?T=௸R 4޸S~%T>wj!*[l̙b{cv{\{Ǝ:3Nچt,ܶ)6mύ NWNpa益{h݁ IJ_4b?I+0N9U>Wx ;*1_8O}2p>򩦢0qY58tyI]aG Wp$Wmel9+7oeFQq>О%qf`-TA{!4INⳄR% 6Rr?\Gۆ(pu('1 Y Ow2Q8>I ?|e7aKʎ|r<HU0@YjGkyu@?W1TgHĘPrn6/(Pͮi}˿Om:ydSW]7~T >v1Cccȿ!gܶ;GhCoH{XPHGǒ 8VxD`3网[8py z몳n{6vmi#ZiѶѸXεz'*W㓟$xKp5@Hh\  !Rm6ZM Nφ;rВaM;n¸"uMӗ7Mavھᬃ9z1)dw`r@[:-uy\CzޤW2V!quF=Nu&zlD(RG)mumx~6 %vl^>ܳMIх)U. jƣq8WO#L~j&ZrBSE °[. 4 5`ٲMHdB6tv}ܐТm`]ց8+Og bT񊎖:kxK]Bvv;SΓbaMsc,XqA@x۳O?:w c-"%{0L%Ș#bgNC=LA8 Q"hQ+1dȿ٢a}rhG-`;N0x-'Hg{"xM^KҨ N݇;TO"NzSb̔ZO\/Xt,a}kpGyZ .:a,%khAAD|`J?NȅT02R(g]SKBb"~fkD9%3PXMCuͧnuorf,B-.Ma-o[@YD i-" xzXuK7ޛe'o n#g6 tNBܯ@۹ꀝR9Ny, H|Ƕ!? 2xq/i!N@;*^{nL=/ȹtZ2:|齨˧{]}"v}% [;( stXԘ?T絑SϷWA:^>wdb.X7"rֆi@_&T,ZN̞RfWhzFEg|x( MH1J2 5gT0 y b<|9HZ %ӵmt{ʟų孛_Ld 4}Hgs\AF$ZwKz@9hnlb@&Isyfl";YL͢зefy/Ԍy9dTP,ӈ,{5ŬǰѰ{xޣ?,M)؛8&cxQm׎gDǛs/D`l?;7C S^2#FY:sB=( v2 gZ)y#0{kv|8JĀR1żvݫ iu endstream endobj 222 0 obj << /Type /Page /Contents 223 0 R /Resources 221 0 R /MediaBox [0 0 595.276 841.89] /Parent 219 0 R >> endobj 224 0 obj << /D [222 0 R /XYZ 89.964 738.753 null] >> endobj 122 0 obj << /D [222 0 R /XYZ 89.964 724.805 null] >> endobj 126 0 obj << /D [222 0 R /XYZ 89.964 630.658 null] >> endobj 130 0 obj << /D [222 0 R /XYZ 89.964 431.202 null] >> endobj 221 0 obj << /Font << /F35 151 0 R /F31 147 0 R /F29 145 0 R /F55 158 0 R /F57 165 0 R /F60 172 0 R /F56 159 0 R /F59 171 0 R /F33 149 0 R /F32 148 0 R >> /ProcSet [ /PDF /Text ] >> endobj 227 0 obj << /Length 1108 /Filter /FlateDecode >> stream x}VMo8WHQzZu,I(IQ2c +KD7zhxdrșyqd"M>WREYFsG4W2*#ra6)cq)cNoo$M356 Ec)t7&x':Up/b`@ .BQ"$-8bYĉIka!qkA y#i~ YQe3bzĉ > VN}<"$\Segd:VKS>V*AտMdm =to&mӺ󻟱Jid[㥙*4x0i΍['|(y!snmVuRfkF6k27^' W Ʊs8SB.GrE}m+;},*`6 %x [doXTm?,I\K)%U|o~blw5 MޟOaVkrGG>Jz@sZk<۾nW{WaZ%'.y\ ayNV'χlՁʒĴr$Wu}I)'82%(=<%> endobj 228 0 obj << /D [226 0 R /XYZ 89.964 738.753 null] >> endobj 134 0 obj << /D [226 0 R /XYZ 89.964 634.079 null] >> endobj 220 0 obj << /D [226 0 R /XYZ 89.964 634.079 null] >> endobj 166 0 obj << /D [226 0 R /XYZ 89.964 610.169 null] >> endobj 153 0 obj << /D [226 0 R /XYZ 89.964 598.213 null] >> endobj 225 0 obj << /Font << /F35 151 0 R /F31 147 0 R /F33 149 0 R /F32 148 0 R /F30 146 0 R /F34 150 0 R /F68 229 0 R /F69 230 0 R >> /ProcSet [ /PDF /Text ] >> endobj 232 0 obj [525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525] endobj 234 0 obj [575 575 575 575 575 575 575 575] endobj 236 0 obj [365.7] endobj 238 0 obj [458.3 458.3] endobj 240 0 obj [611.1 777.8 722.2] endobj 242 0 obj [350 300 500 500 500 500 500 500 500 500 500 500 500 300 300 300 750 500 500 750 726.9 688.4 700 738.4 663.4 638.4 756.7 726.9 376.9 513.4 751.9 613.4 876.9 726.9 750 663.4 750 713.4 550 700 726.9 726.9 976.9 726.9 726.9 600 300 500 300 500 300 300 500 450 450 500 450 300 450 500 300 300 450 250 800 550 500 500 450 412.5 400 325 525 450 650 450 475 400 500 1000 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 613.4 800 750 676.9 650 726.9 700 750 700 750 0 0 700 600 550 575 862.5] endobj 243 0 obj [288.2 1062.5 708.3 708.3 944.5 944.5 0 0 590.3 590.3 708.3 531.3 767.4 767.4 826.4 826.4 649.3 849.5 694.7 562.6 821.7 560.8 758.3 631 904.2 585.5 720.1 807.4 730.7 1264.5 869.1 841.6 743.3 867.7 906.9 643.4 586.3 662.8 656.2 1054.6 756.4 705.8 763.6 708.3 708.3 708.3 708.3 708.3 649.3 649.3 472.2 472.2 472.2 472.2 531.3 531.3 413.2 413.2 295.1 531.3 531.3 649.3 531.3 295.1 885.4 795.8 885.4 443.6 708.3 708.3 826.4 826.4 472.2 472.2 472.2 649.3 826.4 826.4 826.4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 826.4] endobj 244 0 obj [531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 295.1 295.1 295.1 826.4 501.7 501.7 826.4 795.8 752.1 767.4 811.1 722.6 693.1 833.5 795.8 382.6 545.5 825.4 663.6 972.9 795.8 826.4 722.6 826.4 781.6 590.3 767.4 795.8 795.8 1091 795.8 795.8 649.3 295.1 531.3 295.1 531.3 295.1 295.1 531.3 590.3 472.2 590.3 472.2 324.7 531.3 590.3 295.1 324.7 560.8 295.1 885.4 590.3 531.3 590.3 560.8 414.1 419.1 413.2 590.3 560.8 767.4 560.8] endobj 245 0 obj [1000 500 500 1000 1000 1000 777.8 1000 1000 611.1 611.1 1000 1000 1000 777.8 275 1000 666.7 666.7 888.9 888.9 0 0 555.6 555.6 666.7 500 722.2 722.2 777.8 777.8 611.1 798.5 656.8 526.5 771.4 527.8 718.7 594.9 844.5 544.5 677.8 761.9 689.7 1200.9 820.5 796.1 695.6 816.7 847.5 605.6 544.6 625.8 612.8 987.8 713.3 668.3 724.7 666.7 666.7 666.7 666.7 666.7 611.1 611.1 444.4 444.4 444.4 444.4 500 500 388.9 388.9 277.8 500 500 611.1 500 277.8 833.3 750 833.3 416.7 666.7 666.7 777.8 777.8 444.4 444.4 444.4 611.1 777.8 777.8 777.8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 777.8 277.8 777.8 500 777.8 500 777.8 777.8 777.8 777.8 0 0 777.8 777.8 777.8 1000 500 500 777.8 777.8 777.8 777.8 777.8 777.8] endobj 247 0 obj [531.3 826.4 531.3 559.7 795.8 801.4 757.3 871.7 778.7 672.4 827.9 872.8 460.7 580.4 896 722.6 1020.4 843.3 806.2 673.6 835.7 800.2 646.2 618.6 718.8 618.8 1002.4 873.9 615.8 720 413.2 413.2 413.2 1062.5 1062.5 434 564.4 454.5 460.2 546.7 492.9 510.4 505.6 612.3 361.7 429.7 553.2 317.1 939.8 644.7 513.5 534.8 474.4 479.5 491.3] endobj 248 0 obj [272 761.6 489.6 761.6 489.6 516.9 734 743.9 700.5 813 724.8 633.8 772.4 811.3 431.9 541.2 833 666.2 947.3 784.1 748.3 631.1 775.5 745.3 602.2 573.9 665 570.8 924.4 812.6 568.1 670.2 380.8 380.8 380.8 979.2 979.2 410.9 514 416.3 421.4 508.8 453.8 482.6 468.9 563.7 334 405.1 509.3 291.7 856.5 584.5 470.7 491.4 434.1 441.3 461.2 353.6 557.3 473.4 699.9 556.4 477.4 454.9] endobj 249 0 obj [513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 285.5 285.5 285.5 799.4 485.3 485.3 799.4 770.7 727.9 742.3 785 699.4 670.8 806.5 770.7 371 528.1 799.2 642.3 942 770.7 799.4 699.4 799.4 756.5 571 742.3 770.7] endobj 250 0 obj [306.7 357.8 306.7 511.1 511.1 511.1 511.1 511.1 511.1 511.1 511.1 511.1 511.1 511.1 306.7 306.7 306.7 766.7 511.1 511.1 766.7 743.3 703.9 715.6 755 678.3 652.8 773.6 743.3 385.6 525 768.9 627.2 896.7 743.3 766.7 678.3 766.7 729.4 562.2 715.6 743.3 743.3 998.9 743.3 743.3 613.3 306.7 514.4 306.7 511.1 306.7 306.7 511.1 460 460 511.1 460 306.7 460 511.1 306.7 306.7 460 255.6 817.8 562.2 511.1 511.1 460 421.7 408.9 332.2 536.7 460 664.4 463.9 485.6] endobj 251 0 obj [514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6] endobj 253 0 obj [319.4 377.8 319.4 552.8 552.8 552.8 552.8 552.8 552.8 552.8 552.8 552.8 552.8 552.8 319.4 319.4 844.4 844.4 844.4 523.6 844.4 813.9 770.8 786.1 829.2 741.7 712.5 851.4 813.9 405.5 566.7 843 683.3 988.9 813.9 844.4 741.7 844.4 800 611.1 786.1 813.9 813.9 1105.5 813.9 813.9 669.4 319.4 552.8 319.4 552.8 319.4 319.4 613.3 580 591.1 624.4 557.8 535.6 641.1 613.3 302.2 424.4 635.6 513.3 746.7 613.3 635.6 557.8 635.6 602.2 457.8 591.1 613.3 613.3 835.6 613.3 613.3 502.2 552.8 1105.5 552.8 552.8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 683.3 902.8 844.4 755.5 727.8 813.9 786.1 844.4 786.1 844.4 0 0 786.1 552.8 552.8 319.4 319.4 523.6 302.2 424.4 552.8 552.8 552.8 552.8 552.8 813.9 494.4 915.5 735.6 824.4 635.6 975 1091.7 844.4 319.4 552.8] endobj 254 0 obj [272 489.6 816 489.6 816 761.6 272 380.8 380.8 489.6 761.6 272 326.4 272 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 272 272 272 761.6 462.4 462.4 761.6 734 693.4 707.2 747.8 666.2 639 768.3 734 353.2 503 761.2 611.8 897.2 734 761.6 666.2 761.6 720.6 544 707.2 734 734 1006 734 734 598.4 272 489.6 272 489.6 272 272 489.6 544 435.2 544 435.2 299.2 489.6 544 272 299.2 516.8 272 816 544 489.6 544 516.8 380.8 386.2 380.8 544 516.8 707.2 516.8 516.8 435.2 489.6 979.2 489.6 489.6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 611.8 816 761.6 679.6 652.8 734 707.2 761.6 707.2 761.6 0 0 707.2 571.2 544 544 816] endobj 255 0 obj [277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8 722.2 527.8 527.8] endobj 256 0 obj [375 312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.2 531.2 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.7 312.5 937.5 625 562.5 625 593.7 459.5 443.7 437.5 625 593.7 812.5 593.7 593.7 500 562.5 1125 562.5 562.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 675.9 937.5 875 787 750 879.6 812.5 875 812.5 875 0 0 812.5 656.2 625] endobj 257 0 obj << /Length1 780 /Length2 1738 /Length3 0 /Length 2282 /Filter /FlateDecode >> stream xڭRy<@cD@D ziLE@ 1J 'd8< `$fE_aF[*pEU;H f XD@SLkJU~ ˏ9rNWqd1<>L~ . [GiL.0{ "V`6,yդ- ymWث1ܰ"{q"h};y|7l/Lg1 74&@~(2Bp3@>E1h"Ko"WD*bH0,76/xS2AԡDqxCh&=a?-D #_D ߛ캔8NuI͋*٣gęMi冤ԃո'h៘ri(PZpd`9{|mjHܦq^Kvݥ>d; #5޿'8SӘco7аSH;n|VhX2 ݀ Y2&-Kq7œ]9fVWJ@ \.~jV3FoJϸo(2?`ӘfرqecUT@IFLȅ'76GR-Yg~*8P'Wtihat`IIVS+Q(Ez[v̳񈥢)17[ -:23u>tݍ4~jj09 i3EP N\/`pD"p^#;M;p*xI@\s ݾA}b\oMUrv_e Ku*CuDH}g֞Fkf$4斐pB\6~0+e0JŢ)zOpVvW)ԤnKF#t4Qie-μi#5j3HꞺܳ̿TJ*Wk6w/hJj6Fv=q^dm Gy<4=]8A eUG,)>Yq'Dh';}6Ӯm嫶K>Q3nhRtן}2)4B}ç CRӔ_褒4J&~)pLqg'|>/%dJm}"sͮ9H^u!e">lbBx?r}/(xR%j $zP/D,ZzN:`0/P͘ oKm~ڛ繻*7_yU-dZ V%O"\Ǿh>N|hi͡3VW@ùk[TG_ 7ߦ/4) Ū0T҂kƖofrcƄiU0eư0;vsia':l"EHD+!#`; aE(杚K5L/0;Y3tN;"/bq2:$32l9rՀ*.$%#T7 7N7lA/ zR?mv[>uS9}|[wqn>#DDq$19FBn67 }*l=~<jI' >V2R/s}q b (e])3<j+Ϟ7#d!"\0Βv6*UE6TGkk>m¨.)_;ɓR-;4ի$U#uR=v.7=N+dWnRֲnyOJv_Etc};<3^E8KE-v~:eNiG(h+ #NImo 8!S!$]ͮ阿^F]M{E`' `iOuޱd4~-yd6wQمaa.\xԩȽe 쉅 n'TYTԦ,ycOK#)$hf('6#R\Q,͊|Y qMU#ɶkoT>|q endstream endobj 258 0 obj << /Type /FontDescriptor /FontName /FOHVRK+CMBX10 /Flags 4 /FontBBox [-301 -250 1164 946] /Ascent 694 /CapHeight 686 /Descent -194 /ItalicAngle 0 /StemV 114 /XHeight 444 /CharSet (/eight/one/three) /FontFile 257 0 R >> endobj 259 0 obj << /Length1 1496 /Length2 8716 /Length3 0 /Length 9555 /Filter /FlateDecode >> stream xڭeTͶNwwww!8wݹ}N>?TZsUEI b`b.` ʋjX))Ʈ {1cWs^  @ `ec`GAV@"v Sc{8-@dbbnnƈ0L-AL8pp{͝]&i`f^3s D&9S\V7z;G7Wsgjۜv5[ښ=ry)\Mƶ.77o M*]ռ1w efdffOM@ 0vv6B 0q|X {3sO'1+x ?3?`g `C\&0!$XL$]C`=?֓C`=?SqXAT;IUC`ut2!Xf!^l'-&AZ`VAv]+/G+s"c mBo}kU?f9?^ gw BS?vr66pin!4l㯶W{^!?3y;[> lVKp<.f'_" ssOsSĥySPM?*`h!E-g:B?Aږ:Ѯi=VfG݅%x&pnU8 rJL{u7n!к̐Hvr4{}smL! Kb-꾵DquE7:p%ѐDND'1 sm#qh dt8+#y/wttU:^aZf{ 9RVA@O]BK3:jŢp`AzJA3B Oe)k"B<Vm* GOB@u< -w} "7RBAv tmX`~fp?S.3ҫ.>L3Y!l$Ap-z\תG[ }0}K܀JsA?mԙ#fGv)v[ <x"S xπ6{3o= inN,6Xq[.t9Ecm[{AQMN9|h:MWRَp:'b goKb8*kI70Y+I\ z[Ly5^ukU B:yi@Q]ٕ97|?o,N>tR͒@6)Z8M˼sd.Z v|C=|IeN0,knxX/KxLSL7'O4\l*2lԮOB)mV8PrwOmy嗾fز[2UF/aޮ;yoZl>55|w%O=?6>2Ԕ{UlW°k5HQG[}Dd*&z.X2ς*Ee, oE)gEΏ'Ojژq{{2 Z2EKYgo8޵e][Js !gyf,Qy[ԏGOҹ7ƒDn.}Y:8!dABun=ńU-JP8BVCT:_6A'Ϳ<fZ t;{3WJZ  Yg:4jᆲIt 7 Hl;P#VE4v)pB ŏ\IhlwJ/?O?O&Vv7~Tzʉ9e}7SUD78#t(RX̤{\h |c&u=F q@SChؽTX7$DX26?rWzǥLȝ 6rv!hbكD3R%Mn1ૌׄ6`a0.WGuQBνNg1/:eVp ݉E勤 EҺv3CthIfb~:] [9ݐoXa:Pg(5J_=dE]/_ğ7_'uQxȉ:㙛=u:^hyY}}C厎zrGO|urjgw/ ſ.,DbKLuSP3?6Af?Jds| yJ4!M_mD""_w",ٿj JMWl 䲣:` 7*@MB0AaUQsxI, aqr}Ue#!yP zRF_xk`*7s2e>) 21'{ "6p)#KT\g\ kez7,P&'MhVJ|4.~(T5, O-ԭ!7~ſePJ {*>¨ytlO+wP$$SJ6vHtdz"G;0ze AuRr >O)$X[t~ON*LE̴:8}Wd|erktb[->()UYJ+y~ 6b4:6Pf{h[(|'CRa GaaV'6,0R*GI36LÑSr+ Y(9V. b22֑~ІBG,0j d[epysvЯ_#TGK ()ًǦr %O~JU(u@WaPAl0W^PxLLU\NeV֜0mj?]f"y'VzQњ>+-kCGlYjtx'noJm-ƄVxqU&3>q ?:Q4LllcǐK9!2"cxE3,t{ImsrTFrqHzT#AE-6 x6OgMcDIVu GnA<z2.8$gCu_6 tONi. a[&᪖S~򾃠7$ncBi) 󲶮enD&3bJ 065~[4I~Tj&)d lqxiwNųH 2{m\"dgX&l;C$oda7&U+gFu&e3bN(dW.!4-{`/|Kg;\xVhA޶Sc\OXө1=<ݵg_vD6cSvEr풟 UO?!dN_rƈF .ǨsNW kHWi>Uq#j`긻fS^970?/j[LYI8^ޭ!uH5M@/eK7>nVBMn Bzaٽ֘4` #WQ9B]5O5K4_,ydžx]RɹXqЊu/.lX>U:bf {E T`⚴( R67i}LZY1Q'G;H}r13*a\tW۶&Jec|6Dg5P5nrOʏq9qJt'Gw)>fjS5v+$ МPFVGY꣦.znc H)_wŬ'>ufQ8 A`!s9<"RsȈ{$|⮥:nf=W{gPtϻCeᐞþa9\ uPsP|6lM mzp }fqc]oM:x㌡pOE'"Cϟb o.&Jj;e\/&M Тx#wTYP4O#6ʑ.=;/XamQ29ϑ'P#KZxtC-ˡf >KǥTv64[&3"M7R1 5NOXva,2ۤba@uۉ®ZC"w':vkw[wIHou`g@M2͵}M9/NŦ˰K#T.aNcٮ^+WxEݎX״vnJ= mn3O5 3ZġHܼcpA0QX\}lsH;{jŰwA Ti|4 ap}-{ZPV9uEKin ,n8PKB /(c-g'?acyɣ}9ЦRvD78/ =4*AksL̲ A[\rmƫ{pss)뇇8 ~QuF=Wۧ)XkWNI R.EvE2vk1Ff>3݈ }k|B!TwB'?| }RՑb-uA.J8F]$'*|6Jh=]iSz!jvrM t5UtHϲ j[ |](0ko@ CO\{(6Se.>EI6غ- r¶85ϡ<nˬL";_aΠ ƭ.jh?D:"pRRZ 75$ʚP w6c:eUu ?tw l2 |ӎhmpʭAԤv5-7g${A⒘gL%xVU ?[Fk ezf(h/g\|X7e\~o'$ȵ<%W| v'KW|2A+},)6քC1%0GСw[Qy5y*pxFR!)Q`x_:uXl55hW$z0sS4о+O4}OSUthZdœͳ+y?Jw&L@HwK~&ة2x-I|6z_3>@-'H'@m "8Kr6LNyA Lm>IS[WU%` i 5h3n%?fUpzD:DqcxYD28_s 2aV/M`Y ʈ` oK*>Dҵ!3GwT=G +4B.%~85qi;(v;CvYsO}mڕ yq2#A"G7 FQ2՟.FPٿ9oWOb;!:N?߬OkZmu-Q)y:2H{ IBM@oDCg80%<6On a _ݛOQ뱭P>M(t|ǝu`tIȮB8گ]q Z?wUȝ'+rs6,#1dl߀J k?Zn^ ~`a% eq ,ί.V1lօS=hUJV O]Lܔ"G/+x#eUW!kM8pjW?Ly`'FWDCKe\Ur\ƘDSp;&Re-(1ujA6bQ:('HDQd^> Q+"c&ʼnԚꈌ&'^Am- ICHξJT)TEDiR>O_Es3d5a`3x5ɡ!v+:׭Q )T&oߖnK%LC|fWXou_CT|"ExW> endobj 261 0 obj << /Length1 1410 /Length2 8013 /Length3 0 /Length 8839 /Filter /FlateDecode >> stream xڭeXh-%ww .ŭ-nE;ŵ@).EyϹi'fY{LSkhK`9;;( V֖r\Ү` w;;X$=l@AP@_W uqu0I3$],`,#@jevH::Y]= t rXm9QRt= p)OL dAP'GlΩrjM+bCgw+@ :w>v`g-$lٹyAvVk G7Nu_ zrrsհsrqO? 됫7  }&d9>#>`{0eN';l ֕5#pJ3opJ!prCN?TCN?OSCN ,CtCi`Y,/ rAnX.fWZ_SԬ<3 pk,/icl v+6f¬BX!F;?`K={N_u#;gث Lb0zp ay0UϿWa*>]_OK|\O+_?_g?lm{`7 }yj%>1,Pr$f7̒2E8E\tx*pߟ(Wq6I%9- a0fiZ@rXOWh6<;jTHO:Ml.cdhwޣ淩7E&YW/I{8ae "g=q1{[@:OHĞ,+eBTgp(ێN\P{;u>5>M` d\\`Zn4_ <ݮ̘02?Jሑ@GA_͈G˶̡IWA?_Q]htlU!ܜ&bz&aKFǜwq0Szػ_Jz[cBQ&*9@tdWyc0&W>uM[0ړ+k Blb4T|txTchə$^+2$Vj:_0^I{0yByf ސxF.2TayJ,ɒ b?FdP_.A#$ V9p|#Zm4x_S:<&N| }B[aé9}c[1@n+]N2V ӧYUc'z$ע0=(zKrauhx{h3[ޱ 0[Һ۫Ot_=h>~`zx~7?"jj2*d1MU3wjGmg:U9o1R"XXHwR- I'6}. |#vr 7 "s}i;wtS~m4š;7 Ҕ\.j~>cRZ|ܪ4>c)D{%#SoQ;/nnz֍Yqk'7{L?{֟]:7"@0&8`ef1CQEn=3.z!SW*>LpcjĤ~5=`BWXyb*dU 8zRHj 4wVհL- `GshLjZωR]E58WdP^":!_*К!OfXxNӹQ6YLi"h^ u~!~D6bPAՀE{frA8,"gΫ1l <5bƌ^(`Gs\51Uv}&21mh$(W=Nfi(kϝ~B)وµC7&b 8xW$2^ ؂C#{b24~\{Ut*ZP>'H-=Z UGC֊3b@+Rm./r"/c37 9cIB{wyb8c[#ZFKY4[=r/C6ҴDQ_*|'o[| E~b<׆˪ j=]4|.#gD^OTɜ?uɶ^䰹wy<:eJ6nfkȯ3#OKqEo;en{v8u4ѦV JAx\"]QwN[t^4 -UٮFjFߐCg9G׵MjhQؘS Un F1ˊD.(pZi&ا~=*Gfεl>6g^fwjmIZ7>U'{\LpU)I7mD[^l*tv9S(΢hjA_Qe{9BE(I} Mg9@_C'W70`}nد e_W}]=1q,^g(l*{^Cs)܋Ƃ%^/u®Lj~W%ԪeYgQT]{uxU:w~edSyQG ?1Hha#siRU[2JX۠5ݿ%w\+"(% 3RmT)5Y>#DMcM{ bB3\o}n zqSO83  ,U̟$:"Sqh5yI/hJYD7l~MPd}sGaj/FjۉܜQPs|Єy E8gĨ=y_h."\^'NUJ;0[b^ 6MOԔGfI d˱֭"l ]皅Tu3a -Ʊ +7bIvh^pr쐗$֬e]=O%b8 vqc /tF&u^dF>[7|R@=ʠfziBv9sܡn!ƌ]N*ko>-:VWگ՞|8\k*gtJ̖gJx)}Z1n``{>šrMn"œs /8x͢1pd]Bt;B![`$}h]jNC%@ciD }OO%#pbNRf{-ir/'>^QxH* %h&A+ -9}4}2fr^/YG/Ώg #o'++^½NjC4ŠqHs߄4vfr6}EutT)}^?s>aՙf7H/Iz>b[soĶ0WHAܨesq&OSgψj$53P4*ۭТ>{&J.\͛r=~^.YMETNifH_[cS'43~6v{@cBE!CT[I 4٢ ~F~Yкs⼉ߡȹ&-Ph4KudD ZH AGղu<+݌Iȵ$ѯlT4>l-&(< bq=T;h=ٙ&3s>ҙ*܍ C{BpbկN1?^H:{U~"] \cSЅdfOH}7)E9F`,p[ n/ST%ĴҖK~lHъ%f*UdhVm)iwڼ&[XE^q-Dh0'ߋ7~wSwqPvv#i [ߋ3 ah`V~;Zy" +BkAl+Ǔsw"ʸ4N[ߨ~kUWpU{9ư\Ă?WCm5"ZhK(} #2NgZas="Tx0c|l-0) m"kV>,KdždQ-B%eZh evc_s2O5!~dJqM7kf]W"}u۟mM? nR2(od;/^XY3I"KJ7[n\1LrGFvpȭ{^ߎh(-Qڠ[UTP .Wg;h5}Ү%Emg`hr!ѣ]=w2fS4'ōI";l|,t:Mn|Sq޹et|$Q&2ΫR4abBOHYnM0e Y"_TXUĜ%FMOePi㎆K,R}l'_ }:o^~8U-C~_xY{t¬4a4nknJTLioy&* R]_2Cر3yi b-φK}e5WόrV3ٻ~pm_+sFYuHHafF S2c5%Ì@=/^ ux|U%b4‡,]>i4& - ڑC #|;0 Ÿ xJQ]ܹ/4&?*[{V|O ߗpy7޿cű(XV>p*4SO(4skFO{5Ge鈜 YWJpE 'h=U~c/m:*7Z& dTX,7+$`;#Tvn=+Dq׀= 9]"jޒ,Q0}/^K;uvt']m XTC$纖,/uh+r:-T'̾y?M6!?GՅ_ft;KΞSxYeqH?e]w[2-]򮒖lJ'w uf$h'2O_ Iom^ؤzu>9l@9𔣓M|GJg;@\[޴.kXbDVqYi:BgAJدOÌLظY,g~ % DFlhԗuͺⷨg"iM>\97^DJ]Pߨ}QBfzFi(x w,ŵCrO ^\S!mZ巰8H7}35*6_l<$%ruV0@M6 ?jgVe<<ُ}͹:^gtl}M_B t &}#*h:_ve.Rʌ\/_>5:'{| YspnV0֫kH+1li]w*L srS 3_&:έ w Վ%Pq͠C öo8J@x[yՏɯ\VYb2q \z.[$[=!SA9+δ jRd/}@SB3gu֐LgC'؊w[;M|YOn4{|֥^_CIP[Q o3ߛ.aVZ#N!3p:<~V~}S91od3EwI߰/5,疋6Jc&sY#O:wȀqU5(bio~jAsNM>,ڔv7(U}~$f-D*phdr~4sHz;jR#M[?Fܴ-?~872! ǁZw)bn5S٤/2";H&6ˑ7Hh: :O؅ 6wU9Z@0QcnidǼн) 9_Ut.iI'Z<0BX{B [었˄?NQ 3l:@EoaLͼmD*tZa=\اh-n-jӱJ5b$ϲ4;oG1?ƌu)%R.ҥPn+&r \12 Dr|]2=@&[yIr# mJ~`i@f?Fޫ=NY lU94}8=D"x!^ 49ױzyDe&}@jKnw!OQVZks8/Gs A *ִ|p5|(!< "{0p${+SbI<ً'0s_OjWxށOwN +Q);!QVNJNRSwՊ@q()oOn>{;|:R輊'ڎU5?Ա|tf'r>,7ki%KݜZCJ2Ќ3q0H+W&xb f{.C<)pu'x!'Ϙ&(A^VBي BBɕ֋hk+{etCb9Wv('#}fF5k45&xIٹaF[ͶE-b GRRߴ'ߺ5;{ R#4c(*/}ʭr%`͛=? eS~E6Z+v{0!\dTenMYcPeGBېЊگy_Rv ӝ"Gw/KfjG?!ʶ\:>hLZmζT ϔx* Uzw !藛%W?N1|CYJ9l.hHG1͇#qEl RT$|fq󎔿786}yb #|~M,CRk`Utɗ1[laԓ8s/)0nHv?`G걮f:a9GjvE NNћ*4=DZ[80[R ;l2ga M QMi\#y72W®NJ@}2ME(9گ3Õ>td;(ŎER1q!yGrq=jo 񳬬|novKћGY endstream endobj 262 0 obj << /Type /FontDescriptor /FontName /VOFMIF+CMCSC10 /Flags 4 /FontBBox [14 -250 1077 750] /Ascent 514 /CapHeight 683 /Descent 0 /ItalicAngle 0 /StemV 72 /XHeight 431 /CharSet (/A/B/C/E/F/G/H/I/J/L/M/N/R/S/U/a/b/c/comma/d/dieresis/e/f/five/four/g/h/hyphen/i/k/l/m/n/nine/o/p/period/r/s/t/u/v/w/y/zero) /FontFile 261 0 R >> endobj 263 0 obj << /Length1 777 /Length2 1216 /Length3 0 /Length 1761 /Filter /FlateDecode >> stream xڭRkXSW A|T"xk; ~<,||�&B!?X C @ap8-Q8oCҨP,,MʼK+{ĨP X@pa0nj8K*rxyDP!EI1X,AS`l'Dh-$`@ }[z|CPle0%9Rk-8U]X}ZKXm[ɝkJt-)x=XFRibhr~$q'rQo n]zaoGIvwΏ _x}F^[p.y+TU{F‡=ƞvjN;#j>՗%ڮөлp%68V'=JqWobɝ}]|5k 4M.8 Z+:nsـ-6ڶ>9qi_5\{l'X{ܻ"cE5%f_4$ZNVюE{BІfox/_7"\fGlwW$v)&O &?!0qRdCM VDK?6k_7)#*ZU^+Тt>sB˕V3*Aj2 m>0=bgצQOS-?kIv{/ Ƨ[̎2Ǽσ ʿ[ b{E`1v 'fݕ3gt4"v܎(2gOn6{KHo^庆2˕+F9{FwnqTHջAPPcqi:_&+U>1+TNEs̍,T&) :=q?|PAúf1&[-j m-3/ε 攦TԽ5ِҴfH2)|Sʶ>Gn]</E6NVi&Ѹk(Hdm/aZ2o!T~Z$дbwERx$0ߐ0$NirM4iJ,Uwt ZsSf٤+VKOxGU*> endobj 265 0 obj << /Length1 1113 /Length2 6721 /Length3 0 /Length 7429 /Filter /FlateDecode >> stream xڭgн俆)­0-PPXhb o%(, apkup/?\EDEb@~_ }שĞuCo!a0 '6ݓ_hHDywwɃ#?PG,'G WAn^}s^99/ _-V..Pߏm`7 ZfVa59ߊ9]RÿJm/JLԎBÉaŏvUKmRq~Lݷ66n'rʈZeޟc>ь] EQFcNO8}bͼ0jTKox7p 4N;!n_s'H΂`N6zVQe}>D[zS^sCT~%,k[A'!߀y u)]^12q43m%%qeO<'/=/,) K2?:c'mC~A]Y}!X<Ъ5?uZ.4n(cen/7RH$/K77y nB >WG!-:V>{LyeQn8Kbn=lrYu˼,]W=YA`/ ɺCA&N z>#X"*(9hj9+h?5V_T#zkוvSz[gnixh5@%#Ymk:Phs4;F]L,`^k/Jr/s~ыoޱkavz =k[&/?_YP. / S(, æ~q+1Z~Ň>£4C|6@;::~!9:u e:qV; ' |ޝIuk`ϕh ~$1%jakNx9h)!c"!^9U"W 5sݪsDU ݎl$ x ]k.cd< :"E`x]UF鑘DДE~Sݯ7Q\Md=Nd򰱟H@w-9pqGJ*eqOxh||xfdQ\$g;愬AU`QE5g6*~Zc? _ 5$_ثwd v7gAٸ$QClK:!y— SO&Jȯ"> E͵4EQA}.9nӍ \йn|z A?ڐP|P`k:qȱ.W/˦x Okŗu !c+ZR%2KP&6r\ʞ `z˽R9v9շ5d'%ǟKމdHU/;2`F?;g>-OfiZoՑvC'gkqgKN*H- RbhfRmwԫV H!cݜ1Ӧ͒~U! ѻ)OKDW|έCWJ`<;ruGO&?,{hjQi}>A5;B[20dGJ(VmNQ{i3+U&.v "ﲿohc-םHennI }~~sM~:@V煎V-!M#R E PG?ԞkdH}Qߙ@x(Ungi5+g|F} Nx P_D7JWgll0!)f| =_ȺHN?8Wf~%e8ߺEMb2x+-^hΚmwL*ALz_&Ǻ^}qEIi[r/^ɦ9qsɱyM7:Fڅ=x?NZFԚ7 Ex`ERNȘE % ~q(أl$o?跐dq]@Fqyj:{UꗶPRt6z7::5ZjKwQ|qo?jti[Y~$SșF^@@w#чKQ&\8ɉ{B/,`ⴉ8 .=8K<&EYUf0^1 } ̈f=O*{gEB P=3ymĩe8 r*0Be[_ cH}:HzG>mw-Md]0 6 zO\1/Ts4 1mvpyeGlLSD;`aE>:DunKKXw%* }ŽELr!:=dNYhF\}71T:W!fND(:eǘ|Ϛvg˳^JC~:S3^T, ׹izme O:B28ym0&d#SxX<j57vd3K jO7hGX*yi/|ۺ 1ϐ NZqq~Ht4Gt{ի3UU(]^f(0i #(wpz<:ֻ@WU:`ڍLMsEB7fIkmo@`r=qJƹtςI{t2]O'@J.ʡ8XvnƳˋl6*t Wͱ Q3@@Xk< J. oPF^gJ7\z> tNՙG+pGLnk#u=b;<$>=͸Rd<\Y]Ջ 7 Lpbszh(hf 69Ԁh hmN[J${ŬvǏZf!R%$vngQZ5QSpQ(֧$W$bakH@ͣ5sHinݦNџʉT*CCW^|-y܃!=:nO2'R dB[D]b.~Qi}o7g oDG?%T*X7I"l̢bcSFp-m[44^ 9knN߅I{j9La6w_xݲ82l,̫u3J.mT_p_x:nAc"f%VRDY)aw*E~f̭~'{ls'6%R.ʽ;|12g@Qgowo 5S꺵z!Y<|R+ö}.S*C&gŠ (4Y"_j8~H[P2VZvD;A:=SOTrm12%oʈa+v\VTotUePBY N6s!9T\6LˑҴf{PDFt/?giM3bD5P5Ei>:>:ɦPP6ngDY;j]*itc^o.I=.Gr,CP[rVP*WT aA]kH.ĢIHc-7 $k̒N|s9#WX^Igߞ?(wd7d+61LC;O6F41AD`.1;^( <[C96Xb9ET% m^^<7r;%4Y*\ՅSk`*#Cxb”:ҥV<0ꛩ`|!G.QtKl싘煬ŷYF1d?$Jcjoݠ5BZmnM8}2^KpMkԘe8lF6,o7ZŜ9\EȬ˻)HͶe::͂sBoԼ(i˟xI\)bA I;8f+MN"үQ00kQ>od7o0 C!_TT;/F3OՎJ'< f1ޏ1BݤBM;>E{4I+@QS8y* Y城g ru㺐_=/-#F;HzOāSL5뵪~=fk"zmFN jR~UĴ c1QZȲ.c2s@L7]Xv^x-ahI,9/Jik!y@3+i4Q/2uڇ"~eZoը>`W ffN1١]{w堩ZH#6MG4 ! "6ad5kGg <')KXU85χO mFoÏ_D&r\FRMud jH|rWD2H]ψ<G?椆/fl).2eLB{>D -Wv,8Ex{]-rP ebKF(_S{k`L]Ŝ _V3 J`: Dc%;{Aj@geY F!fȣ\V{ͦBϯf2_ԬYقgCx.t◗a~Gz-8cIbz|@Oݓb5%e%iJ-`(#'@$Pl RvHDje endstream endobj 266 0 obj << /Type /FontDescriptor /FontName /NGXAXM+CMMI12 /Flags 4 /FontBBox [-30 -250 1026 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 65 /XHeight 431 /CharSet (/C/D/F/H/M/N/S/a/b/comma/d/f/greater/j/k/l/less/n/p/s/slash/u/x/y/z) /FontFile 265 0 R >> endobj 267 0 obj << /Length1 823 /Length2 2058 /Length3 0 /Length 2628 /Filter /FlateDecode >> stream xڭy,m)Mr$L R&h%Udl0q@,-QںpsBOq!4Ho9nj_&@0 qTQӇVw?H=2HbvTXO#U|BWCzuQhs)ky9܌vh@~4Gq2cnھ!d?O3y6f2>ZSNeY" ݬofϩ?Ž`E/w#N[61Y#111>s^;@7 d1m Ib *? zk Xn=-|i*JQG>T!o+>TT-WIV'%-L.'^WX:/IzN((f^[j`#0isnGةgKLF}H5/q GNWjb 9q{{x?Zn i9Ji*UC{A5] \mln01#LQKv-QPE~dZV6ggGڜ}Hu^b>۬>.9G7bfXb:))phrA=PS̩A8$G \4U]j')2ӝ_$F;bTF ۍd&\ BYm>4#4 hƼL ;lŏ\Kt6.7ѷ *ʵ>Rycί.YpJfȊoȌm^z0b10et!+zrU Tl# Myλ+fG!ɚ256 #x.ݛZ"y+}XBa5{t&$ IݖEc!̔@"ۚhVKp1JJJ SBXDlٶq[Wlrӭ%QU^d/[T~XuUׯeoMNSYEvD/1XƟ~_(Qo|R%`nQ7ӻ"f׏ڏ0F{܂c]d'Sk<2]S?&Q:3ajq7T|ӡƝyFDYK{D m9eۈŏQvg\,{?GW}@* H˼lw"3lѝ7k4o:676ӟ?= P ^ń궘cSOh\][T(l4?6r]={UCVDCe팫Οd{saȼ/ .~ueegDs+ʌS6^4ܞYե+XFp73n)jqV Ke"_2φTFo@QgKܟܓJ^Sdlb/]k8yU-s/B.%J8j\%yx]Oy@ [k f҉~ݜ3"ogee仍;-T*f1rg[äJ (J55|!t#}6N :;:ik}]\x(Ka9`juS{6)ۜ EJ-ENpF 7uS||xDz& u#|6g[Kn1 ( N"F gEkV'l:>\jy+ucAի;|tI E+-&!kqGn)וea/\rNjm)ކ)%֥`!dbE֮2V2$[hV2#dqÕN(cbXHG`eT΃_dĨC" GZ$b?Ixy( .VvX-yvx՜vSzPcɎjH ۟4Xt.ɸ7AǏ(5u 5yQTg&« $ endstream endobj 268 0 obj << /Type /FontDescriptor /FontName /VKKBCI+CMMI8 /Flags 4 /FontBBox [-24 -250 1110 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 78 /XHeight 431 /CharSet (/b/k/l/n/s/slash) /FontFile 267 0 R >> endobj 269 0 obj << /Length1 1407 /Length2 8668 /Length3 0 /Length 9490 /Filter /FlateDecode >> stream xڭuT[ӷq/Nq^܊K).!8/Z{݊+X9|i[ʺ3={VhԵ8$-9$ Vq@\\R .37DAa007@bce`f+H q9Tܬ!`3{lqH4Z ЄB\<  0X8bh cpw `[& &hXbUj;_jq9{8w.m* w*ۀ%!L6r6 u75h"`[PK_KI%?gOM߬͠ 뎋' ^,ϓՒuC-l|33/ 8Z@<O` # ׁ!P7 Mo?`9U~ `%A.P7rj&^P7TK&XSmbC,~y3:`,jXxy88.a%!3 Yx@,V ,ۚۛc:F،+-uq2w[ _nؙ:vN v[l ´m7rôy.szC\Y/ӇpuB!~! vwq8 FC 0Y(X$6)ld2+Usj}ϷNxάuo3ܓFvj:ǧPr >io6$=^;y4Y 5w^,S?\- rl#@Q !&5zB2ͳV[:bIBoE[ ZO>F~E6R,o1qErs_kb%Nפb8W տEkOh#v3/AŕZMo7=C&,^`b:smW`bxxl7fWt׌x< 9hu?O@-Nֱ>A?ʹkZ|1+"嶄2_%rаq+VH>K*^WTY n*j#qs=4 6ҡ| {Mܲp޶u=4;EFۣ+[%!P@qeٸ# Z :ڇیߋ7_1>aq; z\X^sFJqN7 53TZJSFۡ 9_!‹&(7EtgӖY jZw"K>9qgM5Y蛗׏"!n j߶23Ng\R2m^NrV}UJpw0PҌ^wm^jb*Ͷ蠐<~RŎY!7d#-QzjOyG~M [.Y2Ikn1Jn2IwTI.ceQe׷%?:=TTE;*̱lj[(ƺt`hz40FGS+髷CYkb_ 9Uu^]ZFHD4ׂR{o686"lnzZS ;FZejGD*/o|O[ó^}_.=_Tf{#[B\{Y"•}(}ֲ'GOپQx0+tp +dXJ^wr=:sY5rWz߯Bqb$[=_Lda=NTHfv: sY3үD[I.͇ގqD\Ix `"Nw*qJ>3W'+ ?>Y9 ʇ38,oNIJeGPS\T5L-AlBjԸFn!TEVDBzi+͓ |rAZ;rWSvG+B_EƔq3m'/cEQH^(`Ԩ0ςD;q=W;\]/u-"OB# M2qX0!eۺN$a>OV2hRcynxD7`(8~TzWr3s/o;zE "ɢvip꠨,Dl7 PQ@ɳ鉖GgV߄2Y)1qq($(. dU kTY,ZѶ39o4^C^p?l°|, PBIoj#dnIOvI;Dfظa:ʭZZ9fӜ|XJfq= :4Mzh_.HR߁ "Eo dvj1.nuE&xn QefyՅ8CP_sli$T}oWyVXBh] 21F,yٜFƺ-Z+6 MMcpqAZApH'b>YR$]oQ3%N~u [<$&:{\Ou.$}tɚ qyB|5UT C ~Q2sA79+;sW<旦+NyNcr7V9̚L)DljK*J{ }OeB@cro'/v8kzF?yjd9G{uB@;F+QAM{(]8dL_RJIhŻf_&xWP I[2AjUofT;SeO#8rt5$^^6̤V<3V"mAhjm}|>G9±V/oрM Vbu'g5f~$ pm-~UH ex-5R5M ^ VC2\2VXY*as}[*ۄΈ:UMi[[7tumՎls3Q[ht:LAo/:ոvχ)-+r7l|DϘ)6 Xhkwj=J1_mA{ξb q1Seeݷ~u$M i[=з<[`׆ a_2qb؎Bw|@HiXsMB14: 23u 0 L5+K9gX@Z)P[.g}Zhx&^W!#f8.>Ywl o~_~L872^(UtƬfۚ}H4241M,y;slxAKVj>+>^Aikp )R U.+8+[3Q_~GnL(FܫEt+D.}NEpI2A|3B_^yD_?Lk8^e`5X^*k~Gu<Q%Z~H?J?F|AWrNg6dKcoS؃b-^<ϫٶsJϱY*)U̵@cWTT!HcF:Y/yVJC):1Tt;o=$K dn> 跆@[yT5 4 cv"F%X3\JEji|H{//XM'pҞj΋VT*ܵ:XwjyKGaBC _S/+412޴cMCd7R\ aů@-Q,~[ޅ6ʔXd< nML"_Eym@l|*|)]Z9GG%V,h=`!ڛa7{ IL/ Q\:Hgڜ}Px!ݞ,ukn Jt;ʍ5`Q,F`剬8qhȅV?$^#+1􉐜7ջ4yMZ9,/|['~*n8 1@ ;wLKl!s M$qhӽ6ϡX7xHM‚$4RU`\ AL%UD)n;;I3(Ub ޻gv=}6|KWkwC/_g#&CP2=G($aƃ!#1`NT$YO>g5Wz!pMy >ݟih͞) %y=vL~F!cNR{2mkN{ё>xd [uCf%m/B|k?e== e,nncGgkϙ;0-A /[~.)lwLp-L`m31sxs3lI*LeE\'b/5EuAzJ{*01]- Ta.g\QK6fRL"H+Q*չTI@ĸw'glQOhIНiז) q@DOKM`ޒr+m+k1/ќs-|c^.:?Dikv2}Rg .mhpSe^ZKQYI\8^V( ,Kr2l ÊS맨ֻ50ɮ>-RFm38 W\kqP5 fNT'hD&[B\);]MdP-|רo:¶~cHK ejU}ͯH?۔y}d bW++uBxR* bruVf}3D/*GPQG!HVudS+Q`~#?|[`;yn҃ι簓mۧ#F>HpzHJT7An}cQnF|5n<n3?&可c@Y={DŴ%+ "O&Yh@B7Oh%5oKUb Dsjv-2sel &ʶ48GchMd3,q2~ E#*>?Ԛ$D1YWUː{!!Ltz]"ltHr8P*oC2 ѡJe5n'ɭoT7D`%F&$ADlńF00*yT^8)aa2|4pq;083O#pȼ>R'/$lL1dV&sv_ͯ?® 4ShWF'Q1|@DО.[h0zYI+I>e_*_AU3:|A95)W 㛲c@ZI#?GC,՟onU:5nT7rfwC^[*(fh96,Pe=Qj$qsXEгF FW>k5p슗mDkR1})[ab[=FPXPiO\l*5,khX}0(SH9Us X0g`UPF CUG@.3,( (c%O,ߑˈ;F0Im멙6Y.9ahSf .;f"uWa bi&'Hk %#&͉,K̿Aǚd;J KX♱G0T Yuz(2n!& 'b~9*$(Ǡ^$Xp3+4k5ZQeT8&;QQstnv oZUJHJcvĈGwB;o܌|ˑ[dxj 7Q(%dMB ^O`E3'Q%+. )MK(W5a!b~/Z[11_N"8D`RSu@flىj?9̓exRV>*hWWD;}IU RGގ`$0xKwaY+˳\H {U@eGsbpC5ݽ4Bn{f)́ꂣd`L|n jy'0w4#Jek/5v6 zh)7:tmNB|{蜳>#WaPԖۯFJoˮd( $C&-8[{b is$ I%^bR앭FU5`9G=/ʈI0}&΍|*9Qʇ9!~CnDE궟GV l8+h 8E˱|  `J`|AW*QS4m<93q]Z]u99%Cϡe<S#\ E`e4(y7!vIޤ Z/$6Enu >ELDEͫ7ɶ_cmU= $yc2E ĶMItCHZy%>>'N/͔{k3 %Y/ɹAu3+HF)Jx'dYn F-5f/"|0vkƳU=_يuO&yjʈ@6e-B*Q+.!+_f)?efq:\;H?>2ݵZcTNP!`}B$$Cz$3:"/ F_å=4SC2fE/,}@ee q_7,/ĺkc/ѻDܞ%lԆdH#|Z g9:$_RI>Zqhi˂|-gZҘ́g?"Ė/]XGmcdS1tg׺2prVTrØQdcAzIW.gGCn‘k5eeݢr \ peneĻ']1r_{~vے*Ř_ž cQ{AoՄ겻Oq~5"6*!"GM DjyGT<"퀴JÏF&Ο~ ]!EֻaD *yxlRcJxhiJ)w"-cحݓ@V8ޗ|DrR"1χ.+3s endstream endobj 270 0 obj << /Type /FontDescriptor /FontName /SZSJSK+CMR10 /Flags 4 /FontBBox [-251 -250 1009 969] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 69 /XHeight 431 /CharSet (/A/C/E/G/H/I/L/M/N/O/P/S/T/U/a/b/bracketleft/bracketright/c/colon/comma/d/e/five/g/h/i/k/l/m/n/nine/o/one/p/period/r/s/t/two/u/v/y/zero) /FontFile 269 0 R >> endobj 271 0 obj << /Length1 1980 /Length2 13025 /Length3 0 /Length 14102 /Filter /FlateDecode >> stream xڭUX]]$KpXw}{pww޻q]U52b9E:ACk}=7@XZDGF&ls0srfF;7 '7#@@)L@hgjgs0ZrY LA ?= hH045pM)Ho9AE(AER@%Z[Y Fp 2 - ?-,d,IOc=KS qqt vV;ߵI M-梅o P`gahe_%0|T}) x̒JD>R 7_(^S}.OCGOg!?.vk2碌֊z&gi \vf}4AgI*1XSCoz;Xrp`9 Jmik3JB܇I/`+G|wۣOsZVs &&z4DQmϕ S,M1)Vz-$qs#[ ^~9Ruř82jzk5F6U_%FisJ Y{X;UǤ$a&O=% 4kMƇ:ԏUa[r㯴Fgq' ce[_sY1/@&sJ;u21:4抆h ;Uo:T|gуɏ0.В8XC0%S\ r;ǵ|DҵrnrmIBƘc֟gZ)[<ӓ'uԟۍ۶ CN!\N"QjqB~zM^Hb&H BpȽ>Ϡ x|dm\t\(۟Bx@_Z}1vcIgj:nqF2md˃'l Nj:0M=.1ꋂ<[!/ 2fg~F%O 7xѬ]X#!Hr%׊M,)P?h%L),"m[z,w5t|Gi)ҷ6e`yiR^КFlZ,)tK!JՊhb,tK?.3Qpdo.K8FGI{urV`T;tbd(%6H3o3-,u](-|lJhuy5ǭP5\TQhA9~*dyTJʤ/ ~fl\]Β=Ky.\Tu"wܡ Eí%ۙsňb:dwEG>/04A7{@iz/G g>^hl j_B~~%}[ĚPt8AY.bw.4aW:*ݜ3 cTbq .h;ʯ4UJGo/mք ,e(mrұ2AkO..r2GD?J-(1#;=Z/~̰K)ky*6=u5/*`6v66IlN ;OfxCޯ k9h8C֊*܂NmOL~N)L 4lO k1;ϗ^8Q&VZd>sG=)jm|m/X`䐆de zu}LNUcӒ9%X;5\Lꊻ/SKA nd)tQj"'CΡHe}c_JHu[e5K 5HaP^fҺKjg~٫H*sBSߔ$Vj,+_80-_p;$ItLq|$Gw[<>b@@ E74c¡];Έ~11qMn?%.InMxCrIt hU!hMg"N*/C8IxxTI= @nۻb{7_Yu R;kʔJ$ !gWqBe-by,ە_{ӕ{d*"1Րd®СeGtO\S7d& _˵lht‘oL EАrT+~Ƽ:]ZZ fqq2$"9yxb0>n-tC&IN k3gWו~XEL R%q,wUe6,N&/wHa4:e>,-YʒIا7YIu@nX21,b KRk~p}!mh|4՞1ėtMad3PR1zVPIο SSᏺ|L1~ɸ=)Ŷo}EN =%Z:,| okAh,d=tpV"kٗ1m+Rm3pj]<&Nщ"#CS2RcI8ҏ [eC4_(~B{D|)ݻe< 6e<@=0ԟ]2]e[ ]{JPU\)}w_yD &cY(2K"[mc2VaSN~3^KM(yLnr?9}`eDS!Xk3eO::x/Kx$WO3Ь [x?k(ryb?hhLYһ,i$(iFyF9E>HDUB0جla}rcm5Kʲܗגhѵ̵ ]Y _Ќ/)c 1]_d&a5./-ɐRG>eլ`N%zţd+E>T;M{sNqu%k[ER?}J%)=x8>We gy G"a;uրJ =ޡ>p!P0@':ǾB?X3.A~"]zTIqq{6>B o$}æf1XŤ9>9U:nvc|ޯpˆ$S5"h/!bb0y9R7 A s]uYHΊ+V??v9wywk|Wv5 ~}]\+O,ۤѰ0Ұ C]s% ]k;oz 䀉 -W%=$Y &[>qeN>7/#!B-䉯*B5Xj“ϣW8&pCޢXg[T1x4;[[e8e nL0&* fdo-I)7rD& "[n&<Wz1U3ny(oMCUm_G t;4%-Kl1)s;)#7pJQVlxձڈ6 a禀Ƣr(@-1 o*n= rQE,TtÀjWRTq6ZbhpY1}?fN`sj, D#~vwT%;)jwkG_9Ǧw4RV:u٦ rh}SQOgZ#DD7F#VPREFKyE6L&rCWe۹;AڤSHh dwx!m;=Y6Č%B;ÏJ ƟdF?CƂ0fZr3jQA[5eN2:ѝQ,#}T;\rݜHXdsA"՜15]s_b*;xrdĸAs رh?Dgzޞ9Eڈv߀yj҂fRӜ/q<2Ow$a{K*j7%9,pٟX>U,66% &L&3U-jtezKV}3J I ޚبnԂC<:]H1h.4$d5پ@Z P$X~p>{c:4e= |BVaeXޞ1.Įd S*q/z%ܤ'N kbSpmG~XsW8 Q-F+ z7>qUp`udtߺXɦ:˜ pDJb9,WuUȊqOI0\jGTYږb2gG-ɴqySl*+,n'7f/,[ %sqkamW :_b|X)PqcHHPV'GomMԙP ^:Q:i ㆠ?m)ԓz"n DqFe]h0Ft"i^6K߹*)Hk3*'kй Qu*E{Һ_vs"[&8Y3ʗDP:2'ojJiWphmbkG0nVNDs6D5Qpb#lC K|=Zэai m¢% š|Dw "U_XZ,I{N@+AUn~n񚴹w#|u[ __ ?\6 Bk4S0x؟{"cJnۃ8i;lw [©M~`|Y^DG̗Hq[G171UzWlڀ@5 Ah}yNcY?2TLaKo+e1ڸ̒ZdIk B3 }\6lSK2bn+-'T_Kqfٙ֎̹kX,T;qk$}2wmi _~5f{2K>3ۉ}"^gK$ڈo+dcu. Y9~ <3`a-ӆ+YXno*Sqh$\52tm We&UQOQ5F*ycpߜidy^e=B~) >sMMnD2'[NNCэ}fJ'*ϋɣj[1`UA?By?awbwZiU)l$IՖ+fu]N#̧VˎP^6RQN;Aէ6ݢЧ>6>MO"lԛX/uu_ >]3Fo~W^m=/jmYmAm]Dj"h{;ϒOz8 .- WF5>s47.{ٔW_hv oZC."^TPhD>[b͜zO<Ģ Aנy;Íz0FTxyǝ¨:_X\%U˃=o6l0?nuN XQo;83$ tg]/*rn7|@қk)FWf$E6;9ϻ\*ʼG;\*X9zِۃ(2WD޷½(6:G29yW&*1E*LV7aYʼgDP#X DשhtkOv{BY&^T?{6Mλ#piEqV|̣W0aKVW̉SbPъ<\ +yj 9ie3IUNנ.LVWCw&Z'5zkddyBőSTmCjT#_=,P ځ) 2iyTúh9Lnκ4a#ʧQBjS[^#?:p5ﶱkk5s|˽`iP}-2+\Lzf%3HN4`zH<}jpBhl5Plt'+bN{@'\^hX`)hץƍ%FBO>G%kL[Tp_ނ|# Q7n/AR9M͊9(Sh=GK4J/B54 ="g5&z 4t;&g/ѻ8 \`>}ߛcO4Y7\J=zܿ|4 ~D(7*"]њ<|zX|]o,7Cg49}=,D˜,/ӡjn&gi:.ګ'We0~8G/[!:r]ѧ+nk$Gc!,HdoYkQ\P.(H!,,y(5%>@r{wܳ{iOO7טzzAv5|z*+6QU1yD˼3:-^$"nǏvòS[պR4]FĂqG̼{`2yDX q&jxkjrbp\'m%WEBv/^]2R憫KPOb*Q!,$y8r(O>-(Z/ՕL9eЗ*CÂKr v87X.1+Z) uT[h>zrz}z1!i!yUp7<@+G^o(w%>z*G J3_ 7VL}j?{)j|Ru L2VB>I"}>pŦQx\I~ɷDp`۶WwV*'QVooPCLQ3F cY#`$jq'D1~k26"Q,JX NubZkpp9H+)YaAqxբ(\im|>:t[\{ Ӷ(ȣzúXhYF=l삩c>:K "n , 1.oSRُAWmm `!/G8\HRvQIu߲'sqOKMX,V˒su!gZtoA )ۈ(YOJ1s%գu4prW+ 8_䌒cK7ՍྤK5޻d^4@ͱ]Iuo&ߑ(QWÏ_XPN]mDTʬӐ  9Ühq=Sz̶rj^ p#"|ee4ީo}̾ԓDB3WmQ[$xC4CI+XHlLRĭTVƌ l Å5XG}|ٸ.,.Os[0;7G)}_·GǺ蛧o>赥w$^y]Okʯ!`=Ji  S,&Vy_Tó^=;-b(\q#e2~d 1֩$ZKjoe;Zxq-MA]j1SJ S!"£xicbs֝b+u|lUxvz$ự\'6Z@,*dy|ltqhhpt'#f.+fZ-TT~s\C3~q+ؘ za.TNg㗰q_snmc[Ӡ{%DL |Rt۝-= $pZd/.2̤ zG4l#_&}3hc]ɗ %s:%V1ceRiRdp[M_9(kp ԛWNإ{aAyBH#m(1f!@ra,j4E; qTbk& 9+dPwxIՌE*(K,}2lȺUdWIb&ۘٗp=9xc `A уSAZfpt!p>Yd-7E)"`otN wg/5bh)#eJc>o84sY~H8gdwRv -M$Bu*~tWb3Eg=ĦH.2V9t}(n:k3q4 M!G;Bkdj/%r]36t>OkdUoM ڪ')[nEZʸ}?2UCvKF_DywMl03)Ȅ*ĶJm>ˬ2'A iE<lw꒎ݞ*Hӗsv} ႒_Z }%\(Z<H RkbN|pʖ" re ]F{=yQ*خ]䬒bzU䷩K )0/rQ^d`>n_=tf^=/ʬtls|hq`fUOk?-ɣ%<ݡU/Sw'. d|TCaRw!͔~Ж3_mѬȺ˰QrDY |lofѤ2i@11#C ϩPq~%o-#dOXv(1^"(MVҥ$!X=N2MKJ2dIfV*5R \xw؈(teרЙ*PIQzmAS͜ApLX7vO97ت+vsɃO6~ hIb3% ҞJ v k >\K<=S u@EN/f\yfE\ Mhol+bQ; )lcɄ'wpr˹x;! Z:1ɷHy&D~x?^!~ŝ8-%cO2kVd{hg<7|@}]gs t5yqlA!Ig)r R)ahT,$(# F\^] Ջ.s05"k{E ' r7#&W9P!Cܱ.1G?p6*4}&PHJ]jg=V8v?gS?AvG>% 9aw "k NL/Ś 6Txׁ7qwײN<ύ=(4uyi3օY2<+6z,q{ saTZ_Q5+y>=GArb6>h-kssSb4q|%wjlkScs7vb>4z0TR#u+E j5tСR2Yu,7AWd ĪZe69+=V$YlϠD` .nU+sp&g~~=0}d &bKXV yUnNǧ$MX0[6Q+o|sBڠx0j@!=u6ߟd-R8;O CWGU`&ګ7l*PZC>@U&j4Ǜ$e~IE4:a~6R=1bq~@!jAJBkpp#m Qժ\5k3D}cH)R>~qb7tkxld'ʼn;'YIÄNXO,qXwPeC=Bj)giiXFUAR;Ñ0"爛}aClt 'G{0A̩<k@^-CE`XyQ8VVէ!sIl-kWKɄPv AΧx&fO }& G3d:3uYh3ȁ+0h(2G̽fÙi^em eBdms{r i3&77}+ +ߗκJ?h endstream endobj 272 0 obj << /Type /FontDescriptor /FontName /JOAZDQ+CMR12 /Flags 4 /FontBBox [-34 -251 988 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 65 /XHeight 431 /CharSet (/A/B/C/D/E/F/G/H/I/J/L/M/N/O/P/R/S/T/U/W/Y/a/b/bracketleft/bracketright/c/colon/comma/d/e/eight/emdash/equal/exclam/f/ff/ffi/fi/five/fl/four/g/h/hyphen/i/j/k/l/m/n/nine/o/one/p/parenleft/parenright/percent/period/plus/q/quoteleft/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/v/w/x/y/z/zero) /FontFile 271 0 R >> endobj 273 0 obj << /Length1 895 /Length2 2727 /Length3 0 /Length 3328 /Filter /FlateDecode >> stream xڭRy<&D:"R9,3dN13c-v!a} Y-~Srto{yyWJ$8I"T79@8 $Pjh@?)P5Me M0hopB_H $oЗD`[<8 | 6 $A"' 0H 18Nȷ<8/<""#pR`DDq zqB,@FG_͍X 7{ƌEbA~$Q Da}eMI, ǡ !aAX"P`{m~|?ߴ1'f̆ \ !헧 qH< c A` U  `p(0y!8<0FBodlVC ^x?* ?!T * 1z PeI48@Ag 91JJ忄Hđ/cSc/ c "9_Z3k O,GO$3c]{]UsۜX1b\CuKIY9\Np1Ǐ9A~ _Վn,2[-Ks*s 'řZ\ȏ[r#rvёU6ipU ' WV3.N)Z),J &xvzbJYNRs>U@]vaE5i|a IكnVҏu/1fY?$$#>mơ^S5Ge.*nGx4@!8njt^0~j+Y~|&k*//Y"?yֿXG6BVQ}A{5gCh?Zi2or;w$`{k:L56gZ/2rt߉]> `X-d01MB0kKRV׮s>r:rfec38-o*)H}fP5Q!!z\ K2Еt:*h*>}MUNfiXKSl_!+1B9;Hp99UӭF\PͲERrK,I,٪vj2jaxweV|1]flm;YlzMuqRڈ'>{soUp_@~Ftꍹkmy/]|mNtQ c.t-JLȡ]c{f'By.4ʲa葉2F#* y7zp\`NM5>itڻja[9rkCbr{ȉ3~ dBE}y$䔩+rB'PăZ|ExuS x~j^/ zbM}9I]Պۥ?_?`Ոwe=rMk+gt\)p lIf|@硃 SMsH0-1) |Xˌ[SJºպcE$dTXPi_ *ODq\&ڠEP:M5k3zDb_\S !o*dz$~%D%fej۴Yϓ2s14ºMsQ`{;XٔzQ*1X毆 .@b qF)8'ˆR*#:{X(,l\=Ibv4CC;Nۉ%|ރi΋BׯW&/%ݸfOUh otiڡg񇍚5AxQrsEekZ)lӭ?ןk ~J=7Sz2vaCf^T,v51UE&1Oǧ+~KۥmՃ>=&N=s%}_<t{fų~ĥTq52]i]rc;7"O]P:lT*]7}We(dGMsܵ}Bh%*8гq#6>OwT<{[e RG/JƓJk׌$W'>Ã41B EGl34le\*eA3A|iZ]<,gr@>rTjh}>#|˜,[:BKp_>m6얌6Q5H݄Ki[\a ,M3Z> endobj 275 0 obj << /Length1 1113 /Length2 5270 /Length3 0 /Length 5975 /Filter /FlateDecode >> stream xڭeXj:!EJ;a$fb QnT$Fi iCCϳy~=|֚vf}>Y( DAOz; D(X@ @P}*$TD tvغ :\K@截t#!p7?@W+@ sA@ qXl<_zTH?f\0W(J$7%D8x0k< RCWrwpвt4=o (ɋ-`Wy3 do ?BHRy{wBS[ X{Q\mnϑ=- ޤ@e4]SXbNd)YĻ|@穤3K3NU ~Qkq&Lؘ%QJe@NO<)*WE+INcV/Sf)|zk)_clo$L{ q;{뗄6|FfgoUcībD׫HѷgԒ.J?ty`f|$!ŋ˔&5) P85EGp\lŨgQEe}Ϊlg=$ϿH ^c F>uf(ې&_2$6mvOhi5a"+dRWqmqi&JqO’uiy?lmg6i6(al 2XNYm:h>jV;ꆒńEqCdQ/Ҥ G E׫HyS7]3;.J``7F*2EɑtThmIHGg m Ci;C qZ2Dh<8TdNldY{Lg;+m6fxʈ:XcFi_F>m螝(pL Dc1e'`)vdЩ["VʕHb3%Rk8ղ6`H&N,~J݄ S}[] D:BZr,Y*jVׯNݐvǪtN'aދE5)[8MTRGƖ|;&b)ڤ@ #rSo+:VpkŦ4_ŲSDARvszh 0?U43^~%҂IZϛO1s){x-`AP ]Qf[ȦG524A?Ʃ":д#+9OB hU s5Fn^ȳ?;cͿE'"߮Mq-F'K5F$T.27|(YabF Y]n|?ȯmv8|;9cN+{'+,;TCqVy3݊ uUzK/} ʉKJmYSKݴsٶ}bQ1} (w7.R(řL:exכ;aޔAO;1o9ɁNV&l2i){ױa M&àw'ΰ,{ Pr&H: Nכ6ed%!'6RiهyKHt)3Hy0 yFߛ?۔RyX-I@f V)'Os o'Xt-U%ItUDp|v:ՌJ,$,}7c[R e HJD򘨨y@%[z6q0ץ5 Dn n=w9|zJf^AqKC@BD|b^o뭚X3ٖo΃rSRLrח(l kdUzK器SOF6$_ >&$CSp;<nGnHVcί%$${#RFx|+z7rD~آA'egMqұ6X `âgxKгg0b@2!&Ltf&{__sXjrNe.G|]bȚi$sIMEu_FJM:VDmuEdJs]K֭tEtI~,|o}Z'>m&Hvm֏j~}}O|.S6g?d=T2PAVkҽf]C9D|rZů)yph3Z?D[8(߬e"إv6Bx΀n bV:1I:P)͹eƬub/-?,j) P;/ciAs|`#Slj$+ѷ}NXRLb0S:} |_#`MڊDG%;nMcOj .&ZǛ+!KÓ#6C1%Ro͟%hD-hHChRD]/FkZb:[\^* TXyx+U6KIq!W|%K|깲O㒊p%)WDdzO5stDZt+H5xA]:Xo53$ N0&^X!VgUV9os8x)4/ESkts&B:we,JC%_>KRF+{}Mfjͫw.BR#2;M}n|vja5)ESHweC|э?fL׊KV3Q| 7{4x ,5}LS _=&ӲhD{oJbym( .[Ϗ,0S YL^ {CFV4r:TO1 ?5Rzq[ؔV.5Ϧ09b7cYG5ٮOIglI_q|i)ߌц~H4Hbs=)hYTQ.( Eb(78蘄SԶæ5rɺ̣D,ʸ!w͓K? ݖD1mHV\ԛ>2hs&W.we1?)z ȩt endstream endobj 276 0 obj << /Type /FontDescriptor /FontName /IPULTH+CMR9 /Flags 4 /FontBBox [-39 -250 1036 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 74 /XHeight 431 /CharSet (/A/C/D/E/F/G/H/I/M/N/O/P/R/S/T/U/eight/five/four/nine/one/seven/six/three/two/zero) /FontFile 275 0 R >> endobj 277 0 obj << /Length1 994 /Length2 1923 /Length3 0 /Length 2574 /Filter /FlateDecode >> stream xڭS{<Nm(O5D{)ҘyWsafAV*BDDb]W!(Ҷm{s9WFVG&4*SjG-l ddA<QLP jjb7 u-%:B8Jd!;;*ARpTt)p d lT0}@" D\ADE7Qh4 (@)4*A7ڒa%Q77&-[@d_ ӛ  S?7{Ԍ'CDE &/Hw OfyJ^ M!fN+uM Qv,O|eoد1%: Š0,L/ 3hDJTMӥ7 bjPqtkBQn -L:ZeD&^S}kV吘!V}8ԑ]q3K]?;,_'??;8Wt.]fV Hv7=~O{{'NEH>] D_툘\?ɇ3k }> 6;q~X}ee0 ӯpt_Lj}=l8,bF~^KDr˞1~ld]>=z-::f1Lٲk_C$dmhZOq;b/Ŵ.Y/Uf4{F-BWw;{OMWyScW)ΉoL[Pby<=߈FP H"FkGD?Q@f͖ܖm$o#= v-X6mtDCTWsq`q͠6!CIQ%|ǚ҄b%OK ̴~ 10aFCJK앆+~{d6f!K-+9kb)y3:Y*fFӮkoNRYGD[pf/N^ ܓ~(]H+LI>7[׾[E $$3 Z30501XTYP__T-y[CO =o`GkRt*f'׈l,~MC{)[ќ8(*hVĥwgknհV'[ʽj~wj_xAN@).:G$Cs"$1g3Lv7#.Ύb^7~75?D"]hꟌ\V_ga^4hzuT݋|!mW=3/N}0*{h|-Rj{vy>ZAi֭5%gSGwlw_?IQOJi@"BrcK+9"1L*c퉯grÖ'/;0YGMnDXěH z-+ė?Ul|?2ۓW:L6~+n4vMIHpt[H甭q΍"" DžcmOݲ3ji,!^k endstream endobj 278 0 obj << /Type /FontDescriptor /FontName /KIUHIX+CMSY10 /Flags 4 /FontBBox [-29 -960 1116 775] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 85 /XHeight 431 /CharSet (/arrowright/bullet/ceilingleft/ceilingright/element/greaterequal/infinity/lessequal/minus/periodcentered/plusminus/union) /FontFile 277 0 R >> endobj 279 0 obj << /Length1 745 /Length2 603 /Length3 0 /Length 1117 /Filter /FlateDecode >> stream xSU uLOJu+53Rp 4S03RUu.JM,sI,IR04Tp,MW04U002226RUp/,L(Qp)2WpM-LNSM,HZRQZZTeh\ǥrg^Z9D8&UZT tБ @'T*qJB7ܭ4'/1d<(0s3s* s JKR|SRЕB曚Y.Y옗khg`l ,vˬHM ,IPHK)N楠;z`{yjCb,WRY`P "0*ʬP6300*B+.׼̼t#S3ĢJ.QF Ն y) @(CV!- & E@0_Qkk Tihld`naV.(5Nae/5"5d떬Vֹ.U牵/oQ7;36t^bzɒW m;,}Q+zp^/lZ,bB~]xi<\6cN#iEgu*\g^ ߻-4IKI bw_#wy_o_Sak̋qg2<קgQ{QG^i=uc[;Z4UQL) MO)ޘyߺWu:/Zo&LVRV@jv endstream endobj 280 0 obj << /Type /FontDescriptor /FontName /JKSUUE+CMSY6 /Flags 4 /FontBBox [-4 -948 1329 786] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 93 /XHeight 431 /CharSet (/prime) /FontFile 279 0 R >> endobj 281 0 obj << /Length1 814 /Length2 853 /Length3 0 /Length 1401 /Filter /FlateDecode >> stream xڭ}4Ty#[s`f.PZw~̽fRM[TBҩi8*2N[K8I{lgy}~smaBG_1 rDc2lmH(0Q*S\7MI,%v~˵&7+$p"R@Hl+mD@$3@ P $ gp@AniR>%e@RAC;r9.U108}IRiHm'HI L B1$ֵp-1lDꋧH!pD\\gޤ)0a $"N!.BOoE ~rZéHGD| s\.Bo8U8J1<8\$Ejn,`T6NPt ' $.rӾWBi0).aRop$FWtrtG Ay#?FTI&~6zS M;znM+ٍN-ř;xF>BL- gP^R,Q}meU;ձ;헽}'uCۭ4֛ ĝn7X˲tӔw阙3xTڰ8q_*Çϥftl;Ӳ$gKjUV༴ 68y74Jc}̡ _u+^xs33>@Ns/MmcxmB#&wJE^UyW33Ћc_`\Vq]ޜ1,3_QV\ß䘢yF=Xe)qm]{j[9xXV_&0+qoymy={|J^}5&ߒv|h{l(н9јe=f0ocRQH3扩ݻ$y֝=}:Z} \.R/QL=u=uJ縣zƤcdAwAŪY}azIȹYRh>E^2e[XF?UzգIl+#Yf2d{&*#MkESһ9$o/duoտvW_ǺZ/R?XUsvzY'g-W̘#j.UޗVmc:š[/=~1$J՛M橽'8\11D-ǻw"mfe64j[Ds1u 劤MJuU{ٔJcW'ZZ~˰Ƣ , endstream endobj 282 0 obj << /Type /FontDescriptor /FontName /ZZLTBN+CMSY8 /Flags 4 /FontBBox [-30 -955 1185 779] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 89 /XHeight 431 /CharSet (/ceilingleft/ceilingright/minus/prime) /FontFile 281 0 R >> endobj 283 0 obj << /Length1 1081 /Length2 5577 /Length3 0 /Length 6261 /Filter /FlateDecode >> stream xڭeXTƑ.iAzTZ`NAEj`ADQDTZ:E)}X*?Aypc Of[X>!E3.> x1-nex?>}RdAE-C7[FJjՆ|5-MħX2jAo~!YeGwS5ȣ?[1l~BJѯ+$AciC= H)=0ryB:v`twJWGD]ՙ+VR_IL[|FtTU 1>|\1yhi(AY.WK ̠,uH[ą1.:GWa: U]:&IKU#pbhl@C۠S7KLO(9sjg- A^ICi WFf_Q%>[m3CV,:ɧOZ[hH]IK-^xxㅍNƊ("k*3]w$$X#͏agY|gXb1swz~)9.Pgl|4ou 8^lbl/nk[/M;ITzJCNj4:;L+BGBZ N?a}bkRwR5.D]>d?ʲ$CҊlud?11&Ya>縫FռxD]4 8|wl"t&D6,b֬>Y$ew>gɄ}2w?y^u&G.PZ/Jwq$s[.r9d_;81%uZ.d&oIiU191xyk$PӻMOs-bq6t KU4f۟{3 bzTz5(%,݈|MJDO! |J-?:|U RW>ĥt%܋n M-Z6ҰMUNTm>^Rz)ѽEg 3HS+VeB?Z̜T |ZX&4~bMaxd;&R>('MT7}{^0(z!ݣ>hucrꊞi+[Re{U6F _ Kl3ol.`Ԫwn7N3m> <\_1g0I9guxǔi}UUR~x9p^a]̸i(pf1*dIIM"w6Wq-"B2Ncb9䡓y&:oK$|0XipPKW}2*:2> XijV#mlÐ5sW>jmn2@gXd_Q$5cfQMm+U( _IWAdL"dr("ܧ$#FZL]+O'`-˸'fZ3V9Id54Ǟp΃Pjdf/FBN'^希,oJylai{cSQt|ald!bSN%9?(b*;$I/;y<{Iaƾ>_Hn,||I(+bߴ/{_C ﺅO,w_ZN'qpX⚦Φ?Гb+a`s7Fǝ=2d8R֭b^JkxT^evi<MUZL܅62ҡw)I>Yzrk'q/RGȀ+XPQو{ާܚ,O)բ{MRT[ւ m`G$Mw/u]Lg%\*R$L2y Lm% qqޡ<˅l>:'&R*Aaa+7UéU|NŁVgejɗةvD6 */.BtnO}xw~t_~8;7o?|V%Kip׏adKɯ!ydјf^pI}(Wc&bgۅViY5=j9,i\3UŠsoQuw}E' y<R<?bףve$fIuV4f4Q m?J3ݵ#3-j;zi;%N^䊕PO?]ԶjxݴX`@ANICY1^'I _[6I(z#>U,߉r!2@URV{[D|bMA>HJˉ)O"r*~l{=w{h)Ğ?\UZ<;׹4t ?s{kaUע積t̗Q]C*q̞( nMGVT$'أBPbT.e~1 MD|/6NTr-ڒ_U,w֊cl(MBap'zo={5j!`5 kz~Œ V+ܚ~A7h}M&S+y&gANLΥv|ȪkPD7Yc'㲘qnGFsGخR^b2A#0J`ϑVjە$(in2~:~bCzCV7bؙM}@s츀KT#'7Qf^3Y[ֹevk?^ƛl~(Hba04@WZE3E,=0aq6`Gkg`KjͨcJI44v-W"g ܋bq`//Os1=L͘ιj*#l\LdK>Ç6aL(֧u"}8-Wi(s0㹊Mwy'=V|FC 9Nܡs_poyGIXă2{\Ԛ)s^r]qq;*(Gt~̮n×CzYgx̠| {Svy4[޼7~! Dԭ^&e9xZ?gu }A۔5⋩WUeǁ;tάc 3/AWr6s͟$I@(/m3Hf)1Fb7St3&~:M曱7"K,,!E_`q4&f݅PRH9{&-UЅ0e;a*FDD&kj@l]8tb倯~^kT=j͗jqR MHE_=$ @oI8Լܶ@ĩJ^S+({$ş#PO\!W9$3E/ު1 ՞fIe˷QeJ|3^4~ 9'xn,EΘ{;^\+v߲Vg8wYV..ˠ1KBfV)r= \ػM.[}5]q(Gu+H|X;:F|6۰l (]G)8$Wتj^ bzuۇos##͎̔]*%RJ|x )e}s ~>~15OO@NH_4{S^#W0륯O嘼حWD)2/r7jDܖ徚Nbt5c3 `W5@ "sK/ -"Nx5 ev0*j0//r鵻re8p=ϓw;/> endobj 285 0 obj << /Length1 1109 /Length2 5510 /Length3 0 /Length 6204 /Filter /FlateDecode >> stream xڭgTS[@A &]Z5 T.HC!&UJ H( E;H*r̵^{B10M ')ꀤ qI >XĠ8" yHQRVQFxE8]䀪N0,F8 FM0$ )TEp\`X7TBG)$2A;`r C]ra]R@AŠQ@(́B> o!暮(}_ONH+0Nή8°%"]QH*@7%o+tDzHt\`04&0Nh3 (wo!a@kIqIIi!( JX,ؓBJJF "P7Gcp%@d|,_*+d_oJMJ $) J87#- ;F ]LͪK̼ݿU x߳??Γy6q/T[W-Y38^ٚbBKw䣨̛|zfY!Nku?b:0LT}\'2oEfsSM~-Ȉr|MѠ.mA-*!:~c֖6< 7Ir?Ee0E ZAxZ4cŶ}Oz+Yy ݳHX DܽbJ tL`fGu6)~$k3q\ 䙁RZW KF6Lf $Dk:3^  K\\kp k^o +214^VgM|+O3-_6XsՔ2XxA8JR)$=߳%y"mG^NLM\;t>Hdq;mxAR@5~)_'̢x'k0G`'Z׬Hэ=&Mn jjwBg@RR%.FRHn@^SdnvTb,n՘'B,hB׏c*|fxcl`͔%.,bQ֍۬q9̹<(hrMn}5,H.Xb)3^$j%uLG9I2_ˆe"{"훑#F%mZ2=/Jm  oqEc+B/[ukwǃF̩nH\0Wث~#2ԣ544ؼrSTA"mpYeV 4H`\L`:>٥صDz^[)ujY1ݔHyz/vTIv~׍DRMoy[΢6YNnDaìd6,WG# := dzWpG]Ce\UFkpxi;{i<B&%%UT߄H6r Xygq;#KI\f-׼F͉}fr΁{Lw+?JoͿHsM?_+Iqzq,3#X`E A@/SɠƶU}FѦ<'I3HgN,i)YO_qa' 3GOFo g͞Uj9h-kn_1kg;o݉4C%foGu?/͛$V>e24=7'l,x"0{{9M]JK~K;?3i] a1-OJ Q.|YHmb2Z3tifˉc͏r_agiM$/?r:Q\.t6 ,;ZJكSvYXߣ>VY 5ɻn|dV Oo)E˧deպ{S`ѸeӬ/l5}2P"$][tⲱ|oy)$/&:7PRwegf@oV}| 8vjƧb 3Zkܮ]vWzu H+A#-#}dl qmjŻx_06n1ixy-Pa" _Yw(j=DCN_F>fh*nL~g-N-SegB ߿Rs D+ cn$nmm;gSQTO.Hg3DgIn!KqZ~f|zPkZ})<@EW5pˮ ]U&`B7,ZXcRwZ\T*VVm[BnV#|.sC% -k7HqôjrK(:lqӈJf //HD6u,.qi4k`C.,7#;#Y#.ANvml{%7T AMUAف_r\;[R8bd<>а$F'\gg[=0_ӲMn馈1 [ߕKj*Ae - Ů ֏@4"3"vg`^7~b;2Ϛtc]5;8[W,?תlX_y !`2V:dѸjZ]ksTD}q1HuP1[A ׷-!8yq̞aԵѨE˷N7#Y3ݣ4Hv#t{#Us`Yq01i'l<"9Ehf>ǘ'1M0&";ڟ9IB-:e1㖥Y'(R-qUӻ0LHu1Qsak(W;{nhVq.=c4޾_{\wd cU*r>(:xQ)G(TJtάmK'Һ"Tӂ|CW/\;]28k>.9Sl]; /QN/ϯHp4&?Cqh)quomw eGkmu;5\|Gʟ-e'^U0z`U=MCT猴ެ~*YP/,+;AH9z8Ae\E딯ǜ e1P #NʟؖbR_.lv˸"rƮyV,`k0C3HÞG+%s+5K**d7p8Ac^^c=rذZWYGn(8Qm/Wxst=V! 8_Etc/DH'70P[2|H΢?HF4B5WBhIreb*DfMj-;֊LՁ r].n1VcU쥋}g1{ch (1bN5&Ԛ\y$tɈo=-O7b`#'̝Ekt<֜BonK~qwKrt+y!Uq&*qbHubn%i!!s桛Ɯ!NF0:DK=md.stFf]5)iN}!6)Q5K|dw3=mWLxk<|1R2 D 㺺F]F8`;z(UFFaIqhÜ*\eYnN2ࡪAo~ߍ0øe]TvU `g>&mkdsqC|3l/Q =G(JNVwkfףGdgPY+ sK2N:E>mQM4/>}Txegь)߀9zϼho&!WYȡprZJkԠV:_ufu&om8պ\~b@G,~薖p7UNe=!2@v p܇w;$Dh!CۜбBqrróu_FWCnsڌR@. ovyzk{vv(|v0P.^f=t۴7yyAXAh?Q<8NwҐ2^cI U+'eyDV ]ˏA"BGLшs*𜝐,{Krxށ|ӏ@_~Ն2ܷd9^5Ug)8/E/ 5M};.-+lyƊuN1)]ӕʴbn)t,>jCK(kHZ;{ p;Dsjۦ/oE KriB?_1+QrֺWdpOtD_ ?خs԰gnTp97FD[$q[MJ#B>RI)g]pоC= *2'{ttE|&;=\j<\QȺ#ótzs.cC@˽!݊{:-HdGMCtoR]E}0z'ष3%QHOJ(ti6-'6)ULӤ d|Τsfcg/9t,RXYI]=sֱ-Q֔?,?R{>w}>/!v ;jbw*& fBєeF1#U> endobj 287 0 obj << /Length1 1190 /Length2 6003 /Length3 0 /Length 6738 /Filter /FlateDecode >> stream xڭeXkIDEb莡A%`!PR$FJAZ[:{a~k:u\`k J  +"B@]`J DȻ !`("P;{C"13Z =ar@!$@ w@jXC0<=ٺ{7 M8 @0Ė_ ֿUA60;'@?! օ"l0vHϐ/. C ]QofxPoz@t!j qCavAQ! &/!70?>@`'FZ&q!?0~?$*&87Im!t !?v ?(,&=O9t :h7ο=z?΢: wZMu<m>#-E^.@kxh^Q-~} .޾^A! . x7e[(z!o ̤wկ^(~-Tծlk$ tzߧ$xw{*nIV)>uSkL;OwE0uF%uvdr(lܝch5ܚ"*fdZ&ĨGVZ8lދ$1g~8C^-#/dWxY 6w"2kRxϛ)]G0*7Z&Ffg.jEb_/[s >U{z8;5Hݱ? (R'ʦAMޱ~&E1L_ERJ K-|WN8Vj%6S`Ly;; ]לU֟T-/8DBmco-gp1nB/YUK (?.~nhl-0V\<s#R[C\^3#I3Mh KM_mqM8:W+s0olmJapnƯ3e뎨7}? Y@C%ő-X9OJ6)+{#2({7fDgg}([I'drM}&T{Xds=1FLyY/S[ҲQ}-)M`E9^CCKT+F3޻>ش|[0= ++OJWW?^xUߵm|Rq.0q+01]U[hc)Q]M(x ~d[s"'ƽޣts~i^MJ,`  W_b%$|qdYRl ,![IMRcS_u;nP͒z.(UrwcLN :u:a{:ߵPRFS썜Uǯ2..;H דgĉ fOQC^W67=bxr!8~\ɥfenA(_Ov$EU9C 5u_?bW<)|kN{5칓~$$- -}%#39loGwQڦ(X> TZP*磲TIٟUF/23L6tTS[Og} LEt{etX?7dIڈ]僇]v̰A.1av}q/S 2 k]aEo# ;f-^˰_yMaXe'tU4E9^[馺b$r]Y< Y!ͻPdivvzE~tkmyTq/?T:[%`$ 4R]p94e|uʝتf)OcdUkP*Xġ6JK]8nx鎠tZ,(UnHOL|'2ed=&hyY\V{ƳbWETSSKȢr#|;_>+ DMicq28)iZv.p"BZH6v?ެFەr~;Q|&{Cx6<̘PV Ϥ:$6-uqK•y]TG/RAS?lo#Z? Ȇ86Fqs{;HCe>N?m}(p%b. H0juIUeߧ~HY8El/ߴQbb~#et27j0rZg{BVT/iv3u,vޅ0ow8&MYe-M)J!l]majK jkQj7XEWJ&q2LL6#",ǜ鮝0euF}ٚ!q;G?+S[ϛډH?wǖ}>\aLݜ* V|_Ԁʞ_^a.uaTCk~vekJjWvڧW$ŠonJ>XFEiCJ1̭8Xg=KΰB8 (HK?%o."t;qOYӆ4tP^y,O^Iȭj,h]ӽ"bu55(Dsofՙx"|][-gwky L"7bþH?iX ̨k0Ű˳"_[敕pۍ;ˬ}1 0(Q}؏V"UUqMkXwdg`3=9kjΈ4#oJOjU#,{|3.cZMkD4C$T"I#8p]vi)N}iK˽rN}rӈ-QF9KmY g͍Z(o߂߈H-y-sVb?nuSl3aFMWmnTeQ)YcI, ^ Ƹԑya@5|ĽLxws%ьGzGx=ʩ(]&1%~<],ƚumyH(TłT*GlId-v.V&Y;7 :23eTPT~-\%5"jy+1d.R̷B*X@+s9t#~xcoEINTB[5XNr QB2&f Gu5QS*sK;PYgPE͊T@2醾gρԩ:GxߴE;L^ $2J|$"Ɯq p+l;~|<N=|i׸|}Wz[HIՅf0LvMu- (˟}C4F#UonsovF7rOTq-1PR xx*&y۹~U&l▄l׽&Qb@^@#Q-BkU H+)ƺ ۣs0,_Xp9zvQٜmǏ)~[Ed*ryܹEP*s*k`(\J_{{zk3ڍbs$`֜+4_܃Ni^aVbTuR[)kk'~?b=U +h)= Y%W%}㠾CwU<[*O$1@Z"Qv{d&@P5IDvKn9wڴa!~uLznAh+RYd6SPT *f%kPKVO\,ܫ~5- /-!-LV֞ !}mS5PAf27q{Cn{Hp.~zØM(аm<Vq.V ދ ~%~s-7I̪pon{k0sα^'/ྨU_ e Tۀت8kDユ5µߐE@ 澳3Mza?7T-k i FxKAJv,r/Z?'wꟉߢ=r. `sD i; 6o̵&sܻ͜+&Df0\.%mExXi+ǤPzuk_;P1,& i{9U_ܡ}x -gN<+IpoIgkNgwRm{!_>P&M/ƽimx?(g?%Jб$ 7?5y_Uj&n&ׯZ9}2+ StVg>ib/=F-P$sEfec&! _K_oĂi)Z+}uݧ $axrݟK/l^='X;yN@\9*#۶I R)hdkT.yU;TJ/Գ6Lט$ËkEjXR| rM'+B]T,IO|~7ksW,jx8!s37^@v>@vcR 'L0+.1q ٻgK$D$!q{t LފN0el>ɰΫӁkUCS_ yu#‹VAjm"v-T8bOs+w/Mn!!o`D%q ʉRgAObwT%&/{Kוֹe4:,."_3}>UM6{]ni܅^l~xHjiulAdύ|g'~i VLs@Uɼ/aq3{8kV-ݒf!e;Xe89snj/I>L3yhqF&?%*O/"dF~ kOtˤݺZ}x0u`ۅWdEzT03$>;13(o/b~rf] Os:zL{ Gc4%)LwI٦xnO})3󈼌mjRpbov%;+nSF;r|:xRD乁Np];9zL48DZmQ_QvRgD)nzǠjVIAu]K"ۊhd g$H$|;|MΉbۏP+D-% PŸƝ7 jʒn1a%mݦɡ#V?H(QqP:=To<ſfYլEG~bX0&Ov'OzAqE=@EcX*E`Rڊ[~vv! (8.&J?ݲ;<7\+DK|Ptׂ*i穜#ew)g>2!LhIpޙFbcT-c7_ką8[BkwSP'\N?e([\ǮUE0gPݏz ۀI+9Q%GHs $n4b d37ndXTo7y$i"]wSc"{2җ> endobj 289 0 obj << /Length1 2126 /Length2 13470 /Length3 0 /Length 14622 /Filter /FlateDecode >> stream xڭUXKҶ 'w% Npwg̻X3Y]U}UU@J$H+`dk`,jkDH QRbd01 9;;s98Φ&#' +' ,)@ @!D;@P dfl aoP547vrXYfhblD027tHo-;8E(")@F6V#cXzY[^@%VVWu}ks+xZ9;;dllUd̝wUIPo_fcۿ+h(SgZ7qRr;_b @to DaGHOF ( `b @/AzbK~PHP~PEZ>(~P(P~PM@-qvIxT<掖Jw4 `VF&`qV&N0/$6[;? i7Z/`bmQ/#F@6Zw!RM>B"[g՚~$u{K,nۙh3Y3 6Y #c+fN6ݥPm?4ScX20͍?3P=Õ_6sB`Q#bD{g['c#9c-#Ĭ Gck><c*$oB3ؖ'30`\mq{:oKGC[v8a P?>'`R pW pR<}1mQnƆ \)>"SeTMuf;@Fk՞"C:{)^|MwOhUNq߳#~8Alk=eY-MT/Ϻ8ɓV:MҭRߝƮ&nTKL )վ4%d)1|m2"zʶ:7MѸ;h;-&Sna_R"aOMW?\Δ)רz3˼BB:i:YZM$ftЖ^,f"NOLzQ5j?=)'ZaKE6o2nգ1yJЦHzFi,cLaU3 !XFa,XWbg,v?)ϣCQ 3`rHbxe~'$%g@6ZlI ga%R1]e+ -5t cmVQ}:ׁi:)yӫ)>U 5hfT.3hx C6RF$Ms6[ۭ5릤SMA/׹{IĕޯqlSEn_薂ts]כ%S1O.^q[K5VQR6iA.-oڡ¬xn{gצnB%-{c@%g薜6~Ch!*87 FD,^A9%|P.C{Y亴w"\yɨ"ySp8 p;JyWnw:jLٞiR0Xc.9b09Y$F[-Q\`47a~OqL}mķ-!Sҟy5rpWV ;.3/}u?EpDz:+I2JhOg4rzns;(pʖwk)SubYG1@Ƒ1kjjEM=A߶C/u,*9u2NMPŰx23,^Ok3aF).U3⨜f}qll-NVs./IZ*bgAWԾyum$uzBQKegCPD Q7c8j+g(Df_^/qk文iJL[%!S/GZCj݆W/61k1^mnL5!נ^.:|Zf1?!9o_Wx2J*g(66F INLgRG{ 2]&&[7UeĪ(EtV YFRvL"OF#MQ&_ռ-YQu2uKKsl)eMn l8w,.J&^] )FK}.i!|u7%;Z6 %ͣzgEeu.Pݗu B\aI NkɼgG3I$DJƅ/{[xtܖ@*SrI<4+:{/عvnojs{ԙ9 w|M<`I2Bq٦(UBa+`7E$jDѵB贖TVhN$PCJfቛn*  pSnIUcW W)len>EZ`t|v *V5׹ QK PWsԞ⭦_yw\0; V D  =8 sDaqIʎߚu{`A*d#+mGnղOgՀ%dAl+.Cלt Z;hz_Ƒ` jJ9oʦ-U`i\9Ly_]ط6<& z5B$ 49xm>GfqQaf>Q.v.M5OP:ƣ0A8@P{Beӯ]BV3 ֻ4}Z6ϋFln$`-77Ap WZ΅ D aSR|,0v]dǬMqR5zN+ 7u^utI{s%⢼^[-syVÀOj7wH~_۳˘ޣ X>S!dCSG\8PATy;MbRf ,8& $(esKe>RXH^sE$3/y=h:'E4~EqyJ}ov'cL/D{{+$Z>9rPBY4I b${S^քS^$^zJm ;a"4l;Izkh8mVwϡl2 Kg$; 8< - shB|kB#gLם}4vM{~"+jmJ K$ };\RP 2+Xm,*g?Gu`sdѡh)l 16Tvljo8^thUN}i*zT 8_RP_EmcD}%&n?`4ς)YZ h:qeJ_F昝7B,X왡w" QTrD佱}פװ)qNEhC Lr +ɐsy ў{fvfK+A۵TW$ӡc]=DUa#,b}{^Ǵ˟#3˝+/6@:H%ax\9͆6ʤA}˼AVlq]W= QA`Y #0 %vuӍڶIv qQTݮ7FSWۏ, e$ERl!.'E̎eZ1Fh9.D &c@r+c%>Z_xs,3RNT͗V yu1Bs?~ wfKw3i`@L˩€-#SjT I{ϐ$"s++|T`oL}?O* HMHAЧu 7#Qok;*;zGQ6rSgA?)81zzS"mb9{3?}~6(\p؏2ZqvaƊLXX4o/\F %`́* Zέj84V1}\yo8ؼ5n|Q._H>_%N1$ME͝pOmQpIg桓ևnYjWE=(&\^vȯ2$MPR{84f@aię.4e/ [q)>,b.c'ԅ!ùvx53 %cc'foK) ##]5uf Q)Z5OJw۲XINJY"u: "=ʑ~e >l 6]͐q)WGShy*JVӛ,Lh3ٷ-XFDWY5)` _ #,&^9/[:&޸Oq'_9>% v6W4)G-/C뙮9S}vYle_26n-Tv ğީ-}׳4 IЀܟTsE ]aՔ;?]("k~xJju@7mj1m1kK~H6; G}L!ܬM_ 8߉ 3D::<<~"\>4ozIpUo-19Qq蝩KIxъʈ{2i{\H N?7j;kD~I厱hL泚Cc7=}WOT0vz=2_ "(*2qm>X9;O,tn]݃`92oZũ(k-[=ک3&^:n'~w 򔜫ms#Q2i`Ёʼp֐ `\Llo,uJ+DI/S'{ O*+xZ[d56kYn)nkoQ]l@h1q+za/5*IQjBǜL!-{?|Z 9Ql.0wߺ,2S6Eh" Ϧ7R`7WA·l,͝H?wk!oa:+yn%O&5%@r2e7pbܔ&,yAjU@~SĖ\xCgO̢]Me{k_p>gwrE=AC (L*<ޘndo JwF#ÚWks]gު7T_Z >&ꋤf+thOP7~+k)a)It\(o<ƙ8Õzr{#]`vyw$}ă2iK;mE-[RʑF .2} fMjfa)wIY;tz[x3̮%%v6{[!o%']yy^W>m$he1boR;>"Y틇&2J2!*z0FЀF!Hnz[xHf%>Xk]H9OOzosDB;~q +hB)w+ G8ӻ%7 _=6 >S+ ;WXޟUו=̠Kج֋?ER%MF܌vGyr8fj=Z֋p0CW}]}SK g vv\IϊyF̐Z'^BoHR]6ƟqJh" Š oW=vӏ]# SxD22O~zFeMd{W'[ZȀP㤥iKWm'IOc6clMNQJB#yY*!= M Gi8mrlɵ[(٭~6  wDt1& Z"59dzY=b|x4&ʯxAة4d <ʟPb vLwfh`ɬq!z=pbO }cD9vPNuf5ŏq"(}ٲnwŌ.-ȑ ͎CxTf[ ؤR0&WO[| xMiCAyӾe{"lX'o y˛0G6SKb`YJx '?c.him c8Xw2W5~ؗDX(D]g穆)||EJgd5veuݕFF!|~G3jea7o%] G}ɷDž\]ܥwv`4DRE{7q$#H0-[cFGi@dighhOWE$'Vp8Lٺ=*UegZPMc^5B#P<D܂%cƺc[u1@L_ M8 T /X}eZUt=N>FC.14"YNvօMK4Rpǂ츟COXLxS_Q g9 WSm~vKu7, fܲY *2%AX~#H>ODwxy.ɞEGni[BK+t x< P.exHËʷ(VkxhJ龽B!Lѭro bW 쎗[酪N@,ᕴEF+KJc|/ RtQ>єrY_?8GGD%` H1jfhOz~Hp9A̞u|&թ)b8$ CJ;zI{8s$+E6C<ŧE% yliWp {DߜKEzpwWwbӚ_[R5ĦZWv&D`_(qCßi'<%EҿXqٝZ4w}f_Cwza?\6 (AItT~r#!UG{8لWtgrA 7YN/[)S#޽fpj`l5 ;JJ9^S=Zg*WXju-Ņ@UW aG[B%pW`ś;F׆@Eͫ$^7 Eڪ %v/7='4Aю/' rpyGi>uJ5M:2iF6BtiLgFn + XA.lt=dh |C[hdÑsHtTd^=[@3Ag}j,6iVfҕKט|Ļ:K W'$݊p@03Ly@:GtLXGn{F9/q +SIJ|e%ζAelv|wzY\27+M\ Ƹʕ2.*%˖ok1(޳( PMH7Pb$x'0.kHБb`{n< LO[eBcH)AN;Ȩlj7)0W^g0h6swJig"!? -%Lz,"$5> ԓܜxVm@*.y憸q9摬( J#QXچ3<БUy2Zy>0"YJFF*C Vhq'l/8*6(VIb)"Cg3[%Ig-8g- 8"uV9>L]tTZglĝc څ[oIC&[=TX?mIBvJj%Δ#׋pAd-)3?~#[W, Rl!GdR,TZ4ힶX<GVglA+sY x8u}=ꈖ~ 7% e. ( 74r\pe\b۰b8l}Kwx4=P Fp$:m+; KVt/+K!~tYUQ|7#zdB+`K=勘^ .™Lf18=`MHa.Ƞ(1r.#`GO+ˠ _d!hpz)}~}Y[*Kaޣ@NR 鉜}yM8r;i&SIO`ж2~fG~>*uʲ2@>t~BЮ4t Κɾd(nO^vjخ1]"9Ǝ˩%{ _ ?% <bںz3& n*Bf1,[gy%}%> FWSs@zza\CxTG1p>94EZcFUk^ٍm{/cXUZ}V{tف9OCbaܨABq+W"& N?i+#ٖћZ3«E@WC`3`3IR/;"5+0Ty'v`AW* ]0iwo ZB2Lzj(.>Iq1ܕT۸9,&QHn|iAIZLCT奄 VY6tJir0zqF6^6dFKZ۝⫿DSsw KZ;TmƂ- of.Î܂qwuGV15a. #Aa@8 .] j^\WB>(ix'!0)F^gp[iOŒ.!>k8 Ud->xX&ld0c7a~zMpQp1ZtwYJ*Bn B4;+|-k쐐{n9R;<6ɐ }ߺ֔V 5 bӥ9OldECA )O{6(<% rW阧QK-T.[0ϗφWU1/~Qjyv졆CqYZ"QL_(,?v[BoK0x'KW 'B#sóSj%+mF>2U, ܷ-vPХ ᔉٮUd&Js_{q1&weX>GxBIbT_5*Nɵ|<[xӑ5K#≗=ԋ/fڐkإ{RӏջQIJ_@MT2yNxP"==Q0WZzqܙxJq -5fF{]DCka0!(T+{45 ww y=q$QTR*'NM>,:enkf-gY'bggYp4AtҘ>ڊ4o0rͤnWu=N23XXj趲Rj+@Aee'@/, pUVrNxI``DN}3 z-H>xKӽ*W`k[K@t$x8〕FS!oEԝ )MD87{ЩmgxH6Svo+Ms$]ޝLK<5Pm#\,ط!.\9Xݑ%Tb!.!탿 Ki|χ]B.|-m0`9rl!k7:1,=W>_GS endstream endobj 290 0 obj << /Type /FontDescriptor /FontName /TEGVZU+CMTT12 /Flags 4 /FontBBox [-1 -234 524 695] /Ascent 611 /CapHeight 611 /Descent -222 /ItalicAngle 0 /StemV 65 /XHeight 431 /CharSet (/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/ampersand/asterisk/at/b/backslash/braceleft/braceright/bracketleft/bracketright/c/colon/comma/d/e/eight/equal/f/four/g/greater/h/hyphen/i/j/k/l/less/m/n/numbersign/o/one/p/parenleft/parenright/percent/period/plus/q/quotedbl/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero) /FontFile 289 0 R >> endobj 291 0 obj << /Length1 829 /Length2 1785 /Length3 0 /Length 2350 /Filter /FlateDecode >> stream xڭR{ ~:8?A]l_uaeSGSr>vwP)זfgӒ):z=$!T\9lb4<H(9ڗe8 Ve\H|NjZ1rF,V^}^Dtߏڴ6X4]O'opr}SH711ǥ3% 2sYY)#[WK"\q+_hKD40o/f&SzvH" y{#1WqG3[gJ&VbA7;92Km;QѺֹ1E>F{.zz!Fhh~XY(JZOVj3+{B)?B3SoT-ONO15^^V&ʦS$[ppb~ϩa{}w~rDs47~s`f6>#ꅊfw[2=^ՃX L b^!ʅH`Rb66({n!W Y} mq~WE?Phy!c,ûI,b ƓnW}qeU~Y{'[ΔECjGtPz=]yv'v+5R0uH>kּט$I'wWMSWYVa9"j}X@F?\?[ȪePmO?U:A7" ;J=oXÖ\pa̲+hl;!>q>g LI眓b|Ît 5֭\gɶZ+~-]m\KI.u3zz#"5W}6uN?OUq_r| endstream endobj 292 0 obj << /Type /FontDescriptor /FontName /FSYGFR+MSBM10 /Flags 4 /FontBBox [-55 -420 2343 920] /Ascent 464 /CapHeight 689 /Descent 0 /ItalicAngle 0 /StemV 40 /XHeight 463 /CharSet (/P/Q/R) /FontFile 291 0 R >> endobj 237 0 obj << /Type /Encoding /Differences [161/parenleftbig/parenrightbig] >> endobj 241 0 obj << /Type /Encoding /Differences [44/comma/hyphen/period 65/A 68/D/E 79/O 97/a/b/c/d/e/f/g/h/i 108/l/m/n/o/p/q/r/s/t/u/v/w 121/y 177/ffi] >> endobj 246 0 obj << /Type /Encoding /Differences [59/comma/less/slash/greater 67/C/D 70/F 72/H 77/M/N 83/S 97/a/b 100/d 102/f 106/j/k/l 110/n 112/p 115/s 117/u 120/x/y/z] >> endobj 235 0 obj << /Type /Encoding /Differences [33/arrowright 48/prime/infinity/element 91/union 100/ceilingleft/ceilingright 161/minus/periodcentered 167/plusminus 178/bullet 183/lessequal/greaterequal] >> endobj 233 0 obj << /Type /Encoding /Differences [33/exclam 37/percent 39/quoteright/parenleft/parenright 43/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon 61/equal 65/A/B/C/D/E/F/G/H/I/J 76/L/M/N/O/P 82/R/S/T/U/V/W 89/Y 91/bracketleft 93/bracketright 96/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z 124/emdash 174/ff/fi/fl/ffi] >> endobj 252 0 obj << /Type /Encoding /Differences [44/comma/hyphen/period 48/zero 52/four/five 57/nine 65/A/B/C 69/E/F/G/H/I/J 76/L/M/N 82/R/S 85/U 97/a/b/c/d/e/f/g/h/i 107/k/l/m/n/o/p 114/r/s/t/u/v/w 121/y 196/dieresis] >> endobj 231 0 obj << /Type /Encoding /Differences [34/quotedbl/numbersign 37/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four 54/six/seven/eight 58/colon/semicolon/less/equal/greater 64/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright 95/underscore 97/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft 125/braceright] >> endobj 239 0 obj << /Type /Encoding /Differences [80/P/Q/R] >> endobj 229 0 obj << /Type /Font /Subtype /Type1 /BaseFont /FOHVRK+CMBX10 /FontDescriptor 258 0 R /FirstChar 49 /LastChar 56 /Widths 234 0 R /Encoding 233 0 R >> endobj 145 0 obj << /Type /Font /Subtype /Type1 /BaseFont /IITPQF+CMBX12 /FontDescriptor 260 0 R /FirstChar 45 /LastChar 175 /Widths 256 0 R /Encoding 233 0 R >> endobj 148 0 obj << /Type /Font /Subtype /Type1 /BaseFont /VOFMIF+CMCSC10 /FontDescriptor 262 0 R /FirstChar 44 /LastChar 196 /Widths 253 0 R /Encoding 252 0 R >> endobj 217 0 obj << /Type /Font /Subtype /Type1 /BaseFont /DXJXEP+CMEX10 /FontDescriptor 264 0 R /FirstChar 161 /LastChar 162 /Widths 238 0 R /Encoding 237 0 R >> endobj 158 0 obj << /Type /Font /Subtype /Type1 /BaseFont /NGXAXM+CMMI12 /FontDescriptor 266 0 R /FirstChar 59 /LastChar 122 /Widths 248 0 R /Encoding 246 0 R >> endobj 159 0 obj << /Type /Font /Subtype /Type1 /BaseFont /VKKBCI+CMMI8 /FontDescriptor 268 0 R /FirstChar 61 /LastChar 115 /Widths 247 0 R /Encoding 246 0 R >> endobj 146 0 obj << /Type /Font /Subtype /Type1 /BaseFont /SZSJSK+CMR10 /FontDescriptor 270 0 R /FirstChar 44 /LastChar 121 /Widths 255 0 R /Encoding 233 0 R >> endobj 147 0 obj << /Type /Font /Subtype /Type1 /BaseFont /JOAZDQ+CMR12 /FontDescriptor 272 0 R /FirstChar 33 /LastChar 177 /Widths 254 0 R /Encoding 233 0 R >> endobj 171 0 obj << /Type /Font /Subtype /Type1 /BaseFont /VZVQXP+CMR8 /FontDescriptor 274 0 R /FirstChar 48 /LastChar 120 /Widths 244 0 R /Encoding 233 0 R >> endobj 151 0 obj << /Type /Font /Subtype /Type1 /BaseFont /IPULTH+CMR9 /FontDescriptor 276 0 R /FirstChar 48 /LastChar 85 /Widths 249 0 R /Encoding 233 0 R >> endobj 165 0 obj << /Type /Font /Subtype /Type1 /BaseFont /KIUHIX+CMSY10 /FontDescriptor 278 0 R /FirstChar 33 /LastChar 184 /Widths 245 0 R /Encoding 235 0 R >> endobj 218 0 obj << /Type /Font /Subtype /Type1 /BaseFont /JKSUUE+CMSY6 /FontDescriptor 280 0 R /FirstChar 48 /LastChar 48 /Widths 236 0 R /Encoding 235 0 R >> endobj 172 0 obj << /Type /Font /Subtype /Type1 /BaseFont /ZZLTBN+CMSY8 /FontDescriptor 282 0 R /FirstChar 48 /LastChar 161 /Widths 243 0 R /Encoding 235 0 R >> endobj 150 0 obj << /Type /Font /Subtype /Type1 /BaseFont /ODQSAJ+CMTI10 /FontDescriptor 284 0 R /FirstChar 44 /LastChar 121 /Widths 250 0 R /Encoding 241 0 R >> endobj 173 0 obj << /Type /Font /Subtype /Type1 /BaseFont /EWMELE+CMTI12 /FontDescriptor 286 0 R /FirstChar 45 /LastChar 177 /Widths 242 0 R /Encoding 241 0 R >> endobj 230 0 obj << /Type /Font /Subtype /Type1 /BaseFont /LSVXRU+CMTT10 /FontDescriptor 288 0 R /FirstChar 45 /LastChar 122 /Widths 232 0 R /Encoding 231 0 R >> endobj 149 0 obj << /Type /Font /Subtype /Type1 /BaseFont /TEGVZU+CMTT12 /FontDescriptor 290 0 R /FirstChar 34 /LastChar 125 /Widths 251 0 R /Encoding 231 0 R >> endobj 192 0 obj << /Type /Font /Subtype /Type1 /BaseFont /FSYGFR+MSBM10 /FontDescriptor 292 0 R /FirstChar 80 /LastChar 82 /Widths 240 0 R /Encoding 239 0 R >> endobj 152 0 obj << /Type /Pages /Count 6 /Parent 293 0 R /Kids [138 0 R 155 0 R 162 0 R 168 0 R 175 0 R 180 0 R] >> endobj 187 0 obj << /Type /Pages /Count 6 /Parent 293 0 R /Kids [184 0 R 189 0 R 194 0 R 198 0 R 202 0 R 207 0 R] >> endobj 219 0 obj << /Type /Pages /Count 3 /Parent 293 0 R /Kids [211 0 R 222 0 R 226 0 R] >> endobj 293 0 obj << /Type /Pages /Count 15 /Kids [152 0 R 187 0 R 219 0 R] >> endobj 294 0 obj << /Type /Outlines /First 7 0 R /Last 135 0 R /Count 9 >> endobj 135 0 obj << /Title 136 0 R /A 133 0 R /Parent 294 0 R /Prev 99 0 R >> endobj 131 0 obj << /Title 132 0 R /A 129 0 R /Parent 99 0 R /Prev 127 0 R >> endobj 127 0 obj << /Title 128 0 R /A 125 0 R /Parent 99 0 R /Prev 123 0 R /Next 131 0 R >> endobj 123 0 obj << /Title 124 0 R /A 121 0 R /Parent 99 0 R /Prev 119 0 R /Next 127 0 R >> endobj 119 0 obj << /Title 120 0 R /A 117 0 R /Parent 99 0 R /Prev 115 0 R /Next 123 0 R >> endobj 115 0 obj << /Title 116 0 R /A 113 0 R /Parent 99 0 R /Prev 111 0 R /Next 119 0 R >> endobj 111 0 obj << /Title 112 0 R /A 109 0 R /Parent 99 0 R /Prev 107 0 R /Next 115 0 R >> endobj 107 0 obj << /Title 108 0 R /A 105 0 R /Parent 99 0 R /Prev 103 0 R /Next 111 0 R >> endobj 103 0 obj << /Title 104 0 R /A 101 0 R /Parent 99 0 R /Next 107 0 R >> endobj 99 0 obj << /Title 100 0 R /A 97 0 R /Parent 294 0 R /Prev 95 0 R /Next 135 0 R /First 103 0 R /Last 131 0 R /Count -8 >> endobj 95 0 obj << /Title 96 0 R /A 93 0 R /Parent 294 0 R /Prev 91 0 R /Next 99 0 R >> endobj 91 0 obj << /Title 92 0 R /A 89 0 R /Parent 294 0 R /Prev 55 0 R /Next 95 0 R >> endobj 87 0 obj << /Title 88 0 R /A 85 0 R /Parent 55 0 R /Prev 83 0 R >> endobj 83 0 obj << /Title 84 0 R /A 81 0 R /Parent 55 0 R /Prev 79 0 R /Next 87 0 R >> endobj 79 0 obj << /Title 80 0 R /A 77 0 R /Parent 55 0 R /Prev 75 0 R /Next 83 0 R >> endobj 75 0 obj << /Title 76 0 R /A 73 0 R /Parent 55 0 R /Prev 71 0 R /Next 79 0 R >> endobj 71 0 obj << /Title 72 0 R /A 69 0 R /Parent 55 0 R /Prev 67 0 R /Next 75 0 R >> endobj 67 0 obj << /Title 68 0 R /A 65 0 R /Parent 55 0 R /Prev 63 0 R /Next 71 0 R >> endobj 63 0 obj << /Title 64 0 R /A 61 0 R /Parent 55 0 R /Prev 59 0 R /Next 67 0 R >> endobj 59 0 obj << /Title 60 0 R /A 57 0 R /Parent 55 0 R /Next 63 0 R >> endobj 55 0 obj << /Title 56 0 R /A 53 0 R /Parent 294 0 R /Prev 19 0 R /Next 91 0 R /First 59 0 R /Last 87 0 R /Count -8 >> endobj 51 0 obj << /Title 52 0 R /A 49 0 R /Parent 19 0 R /Prev 47 0 R >> endobj 47 0 obj << /Title 48 0 R /A 45 0 R /Parent 19 0 R /Prev 43 0 R /Next 51 0 R >> endobj 43 0 obj << /Title 44 0 R /A 41 0 R /Parent 19 0 R /Prev 39 0 R /Next 47 0 R >> endobj 39 0 obj << /Title 40 0 R /A 37 0 R /Parent 19 0 R /Prev 35 0 R /Next 43 0 R >> endobj 35 0 obj << /Title 36 0 R /A 33 0 R /Parent 19 0 R /Prev 31 0 R /Next 39 0 R >> endobj 31 0 obj << /Title 32 0 R /A 29 0 R /Parent 19 0 R /Prev 27 0 R /Next 35 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 19 0 R /Prev 23 0 R /Next 31 0 R >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 19 0 R /Next 27 0 R >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 294 0 R /Prev 15 0 R /Next 55 0 R /First 23 0 R /Last 51 0 R /Count -8 >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 294 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 294 0 R /Prev 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 294 0 R /Next 11 0 R >> endobj 295 0 obj << /Names [(Doc-Start) 144 0 R (cite.Cohen) 220 0 R (cite.gmp) 166 0 R (cite.ratpoints) 153 0 R (page.1) 143 0 R (page.10) 200 0 R] /Limits [(Doc-Start) (page.10)] >> endobj 296 0 obj << /Names [(page.11) 204 0 R (page.12) 209 0 R (page.13) 213 0 R (page.14) 224 0 R (page.15) 228 0 R (page.2) 157 0 R] /Limits [(page.11) (page.2)] >> endobj 297 0 obj << /Names [(page.3) 164 0 R (page.4) 170 0 R (page.5) 177 0 R (page.6) 182 0 R (page.7) 186 0 R (page.8) 191 0 R] /Limits [(page.3) (page.8)] >> endobj 298 0 obj << /Names [(page.9) 196 0 R (section*.1) 134 0 R (section.1) 6 0 R (section.2) 10 0 R (section.3) 14 0 R (section.4) 18 0 R] /Limits [(page.9) (section.4)] >> endobj 299 0 obj << /Names [(section.5) 54 0 R (section.6) 90 0 R (section.7) 94 0 R (section.8) 98 0 R (subsection.4.1) 22 0 R (subsection.4.2) 26 0 R] /Limits [(section.5) (subsection.4.2)] >> endobj 300 0 obj << /Names [(subsection.4.3) 30 0 R (subsection.4.4) 34 0 R (subsection.4.5) 38 0 R (subsection.4.6) 42 0 R (subsection.4.7) 46 0 R (subsection.4.8) 50 0 R] /Limits [(subsection.4.3) (subsection.4.8)] >> endobj 301 0 obj << /Names [(subsection.5.1) 58 0 R (subsection.5.2) 62 0 R (subsection.5.3) 66 0 R (subsection.5.4) 70 0 R (subsection.5.5) 74 0 R (subsection.5.6) 78 0 R] /Limits [(subsection.5.1) (subsection.5.6)] >> endobj 302 0 obj << /Names [(subsection.5.7) 82 0 R (subsection.5.8) 86 0 R (subsection.8.1) 102 0 R (subsection.8.2) 106 0 R (subsection.8.3) 110 0 R (subsection.8.4) 114 0 R] /Limits [(subsection.5.7) (subsection.8.4)] >> endobj 303 0 obj << /Names [(subsection.8.5) 118 0 R (subsection.8.6) 122 0 R (subsection.8.7) 126 0 R (subsection.8.8) 130 0 R (subsubsection.8.5.1) 214 0 R (subsubsection.8.5.2) 215 0 R] /Limits [(subsection.8.5) (subsubsection.8.5.2)] >> endobj 304 0 obj << /Names [(subsubsection.8.5.3) 216 0 R] /Limits [(subsubsection.8.5.3) (subsubsection.8.5.3)] >> endobj 305 0 obj << /Kids [295 0 R 296 0 R 297 0 R 298 0 R 299 0 R 300 0 R] /Limits [(Doc-Start) (subsection.4.8)] >> endobj 306 0 obj << /Kids [301 0 R 302 0 R 303 0 R 304 0 R] /Limits [(subsection.5.1) (subsubsection.8.5.3)] >> endobj 307 0 obj << /Kids [305 0 R 306 0 R] /Limits [(Doc-Start) (subsubsection.8.5.3)] >> endobj 308 0 obj << /Dests 307 0 R >> endobj 309 0 obj << /Type /Catalog /Pages 293 0 R /Outlines 294 0 R /Names 308 0 R /PageMode/UseOutlines /OpenAction 137 0 R >> endobj 310 0 obj << /Author(Michael Stoll)/Title(Documentation for ratpoints)/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.3)/Keywords() /CreationDate (D:20110310120511+01'00') /ModDate (D:20110310120511+01'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX using libpoppler, Version 3.141592-1.40.3-2.2 (Web2C 7.5.6) kpathsea version 3.5.6) >> endobj xref 0 311 0000000001 65535 f 0000000002 00000 f 0000000003 00000 f 0000000004 00000 f 0000000000 00000 f 0000000015 00000 n 0000005980 00000 n 0000178963 00000 n 0000000060 00000 n 0000000093 00000 n 0000006039 00000 n 0000178877 00000 n 0000000138 00000 n 0000000188 00000 n 0000006099 00000 n 0000178789 00000 n 0000000234 00000 n 0000000268 00000 n 0000008288 00000 n 0000178664 00000 n 0000000314 00000 n 0000000348 00000 n 0000008348 00000 n 0000178590 00000 n 0000000399 00000 n 0000000442 00000 n 0000008408 00000 n 0000178503 00000 n 0000000493 00000 n 0000000546 00000 n 0000008468 00000 n 0000178416 00000 n 0000000597 00000 n 0000000631 00000 n 0000011244 00000 n 0000178329 00000 n 0000000682 00000 n 0000000713 00000 n 0000011304 00000 n 0000178242 00000 n 0000000764 00000 n 0000000797 00000 n 0000011364 00000 n 0000178155 00000 n 0000000848 00000 n 0000000883 00000 n 0000011424 00000 n 0000178068 00000 n 0000000934 00000 n 0000000970 00000 n 0000011484 00000 n 0000177994 00000 n 0000001021 00000 n 0000001058 00000 n 0000015019 00000 n 0000177869 00000 n 0000001104 00000 n 0000001146 00000 n 0000015079 00000 n 0000177795 00000 n 0000001197 00000 n 0000001236 00000 n 0000015139 00000 n 0000177708 00000 n 0000001287 00000 n 0000001322 00000 n 0000015199 00000 n 0000177621 00000 n 0000001373 00000 n 0000001416 00000 n 0000018728 00000 n 0000177534 00000 n 0000001467 00000 n 0000001520 00000 n 0000018788 00000 n 0000177447 00000 n 0000001571 00000 n 0000001631 00000 n 0000022725 00000 n 0000177360 00000 n 0000001682 00000 n 0000001733 00000 n 0000022785 00000 n 0000177273 00000 n 0000001784 00000 n 0000001845 00000 n 0000025731 00000 n 0000177199 00000 n 0000001896 00000 n 0000001947 00000 n 0000025791 00000 n 0000177111 00000 n 0000001993 00000 n 0000002037 00000 n 0000035299 00000 n 0000177023 00000 n 0000002083 00000 n 0000002131 00000 n 0000039316 00000 n 0000176894 00000 n 0000002177 00000 n 0000002214 00000 n 0000039376 00000 n 0000176816 00000 n 0000002266 00000 n 0000002299 00000 n 0000039437 00000 n 0000176724 00000 n 0000002351 00000 n 0000002394 00000 n 0000039498 00000 n 0000176632 00000 n 0000002446 00000 n 0000002497 00000 n 0000043240 00000 n 0000176540 00000 n 0000002549 00000 n 0000002598 00000 n 0000043301 00000 n 0000176448 00000 n 0000002650 00000 n 0000002702 00000 n 0000047142 00000 n 0000176356 00000 n 0000002754 00000 n 0000002803 00000 n 0000047203 00000 n 0000176264 00000 n 0000002855 00000 n 0000002900 00000 n 0000047264 00000 n 0000176186 00000 n 0000002952 00000 n 0000002987 00000 n 0000048883 00000 n 0000176108 00000 n 0000003035 00000 n 0000003065 00000 n 0000005405 00000 n 0000005552 00000 n 0000005704 00000 n 0000006159 00000 n 0000003117 00000 n 0000005858 00000 n 0000005919 00000 n 0000172884 00000 n 0000173695 00000 n 0000173856 00000 n 0000173046 00000 n 0000175305 00000 n 0000174819 00000 n 0000174177 00000 n 0000175628 00000 n 0000049066 00000 n 0000008528 00000 n 0000008108 00000 n 0000006309 00000 n 0000008227 00000 n 0000173372 00000 n 0000173534 00000 n 0000011032 00000 n 0000011544 00000 n 0000010893 00000 n 0000008678 00000 n 0000011183 00000 n 0000174336 00000 n 0000049005 00000 n 0000015259 00000 n 0000014839 00000 n 0000011668 00000 n 0000014958 00000 n 0000174017 00000 n 0000174658 00000 n 0000174981 00000 n 0000018848 00000 n 0000018548 00000 n 0000015461 00000 n 0000018667 00000 n 0000022507 00000 n 0000022845 00000 n 0000022368 00000 n 0000019024 00000 n 0000022664 00000 n 0000025851 00000 n 0000025551 00000 n 0000022995 00000 n 0000025670 00000 n 0000175745 00000 n 0000029935 00000 n 0000029755 00000 n 0000025975 00000 n 0000029874 00000 n 0000175467 00000 n 0000031580 00000 n 0000031400 00000 n 0000030098 00000 n 0000031519 00000 n 0000032783 00000 n 0000032603 00000 n 0000031678 00000 n 0000032722 00000 n 0000035359 00000 n 0000035119 00000 n 0000032868 00000 n 0000035238 00000 n 0000043026 00000 n 0000039559 00000 n 0000039136 00000 n 0000035509 00000 n 0000039255 00000 n 0000043545 00000 n 0000042887 00000 n 0000039722 00000 n 0000043179 00000 n 0000043362 00000 n 0000043423 00000 n 0000043484 00000 n 0000173209 00000 n 0000174498 00000 n 0000175862 00000 n 0000048944 00000 n 0000047325 00000 n 0000046962 00000 n 0000043760 00000 n 0000047081 00000 n 0000049127 00000 n 0000048703 00000 n 0000047514 00000 n 0000048822 00000 n 0000172723 00000 n 0000175143 00000 n 0000172222 00000 n 0000049290 00000 n 0000171600 00000 n 0000049621 00000 n 0000171391 00000 n 0000049672 00000 n 0000170975 00000 n 0000049697 00000 n 0000172660 00000 n 0000049728 00000 n 0000171060 00000 n 0000049765 00000 n 0000050295 00000 n 0000050855 00000 n 0000051311 00000 n 0000171217 00000 n 0000052052 00000 n 0000052399 00000 n 0000052788 00000 n 0000053027 00000 n 0000053496 00000 n 0000171999 00000 n 0000054067 00000 n 0000054855 00000 n 0000055525 00000 n 0000055965 00000 n 0000056583 00000 n 0000058984 00000 n 0000059220 00000 n 0000068895 00000 n 0000069241 00000 n 0000078200 00000 n 0000078538 00000 n 0000080418 00000 n 0000080661 00000 n 0000088210 00000 n 0000088497 00000 n 0000091244 00000 n 0000091479 00000 n 0000101089 00000 n 0000101442 00000 n 0000115665 00000 n 0000116180 00000 n 0000119627 00000 n 0000119883 00000 n 0000125978 00000 n 0000126276 00000 n 0000128969 00000 n 0000129309 00000 n 0000130544 00000 n 0000130768 00000 n 0000132287 00000 n 0000132543 00000 n 0000138924 00000 n 0000139200 00000 n 0000145524 00000 n 0000145806 00000 n 0000152664 00000 n 0000152967 00000 n 0000167710 00000 n 0000168285 00000 n 0000170754 00000 n 0000175955 00000 n 0000176033 00000 n 0000179035 00000 n 0000179219 00000 n 0000179387 00000 n 0000179549 00000 n 0000179725 00000 n 0000179920 00000 n 0000180140 00000 n 0000180360 00000 n 0000180584 00000 n 0000180825 00000 n 0000180941 00000 n 0000181059 00000 n 0000181171 00000 n 0000181262 00000 n 0000181300 00000 n 0000181428 00000 n trailer << /Size 311 /Root 309 0 R /Info 310 0 R /ID [<9CD1AD829CAD9E5B20738D9292708A79> <9CD1AD829CAD9E5B20738D9292708A79>] >> startxref 181799 %%EOF ratpoints-2.1.3/gen_find_points_h.c0000644000175000001440000001006111536145472016617 0ustar mstollusers/*********************************************************************** * ratpoints-2.1.2 * * - A program to find rational points on hyperelliptic curves * * Copyright (C) 2008, 2009 Michael Stoll * * * * This program is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation, either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of version 2 of the GNU General * * Public License along with this program. * * If not, see . * ***********************************************************************/ /*********************************************************************** * gen_find_points_h.c * * * * This program writes the file find_points.h * * * * Michael Stoll, Mar 8, 2009 * ***********************************************************************/ #include "rp-private.h" #include "primes.h" long inv_mod_p(long p, long b) { /* invert b mod p */ /* doesn't have to be fast... -- actually this will be faster in our range than the usual XGCD. */ long i = 1, n = b; while(1) { if(n%p == 1) return(i); i++; n += b; } } int main(int argc, char *argv[]) { long n; { int work[RATPOINTS_MAX_PRIME]; printf("static const int " "squares[RATPOINTS_NUM_PRIMES+1][RATPOINTS_MAX_PRIME] =\n{\n"); for(n = 0; n < RATPOINTS_NUM_PRIMES; n++) { long p = prime[n]; long i; work[0] = 1; for(i = 1; i < p; i++) work[i] = 0; /* record non-zero squares mod p, p odd */ for(i = 1; i < p; i += 2) work[(i*i) % p] = 1; printf("{"); for(i = 0; i < p; i++) { printf("%d", work[i]); if(i < p-1) printf(","); } printf((n < RATPOINTS_NUM_PRIMES - 1) ? "},\n " : "}\n};\n"); } } printf("static const long offsets[RATPOINTS_NUM_PRIMES] =\n{"); for(n = 0; n < RATPOINTS_NUM_PRIMES; n++) { long p = prime[n]; { printf("%ld", inv_mod_p(p, (2*RBA_LENGTH)%p)); } printf((n < RATPOINTS_NUM_PRIMES - 1) ? "," : "};\n\n"); } printf("static const long " "inverses[RATPOINTS_NUM_PRIMES][RATPOINTS_MAX_PRIME] =\n{"); for(n = 0; n < RATPOINTS_NUM_PRIMES; n++) { long p = prime[n]; long i; printf("{0"); for(i = 1; i < p; i++) { printf(",%ld", inv_mod_p(p, i)); } printf((n < RATPOINTS_NUM_PRIMES - 1) ? "},\n " : "}\n};\n"); } { unsigned long work[RATPOINTS_MAX_PRIME]; printf("unsigned long " "sieves0[RATPOINTS_NUM_PRIMES][2*RATPOINTS_MAX_PRIME_EVEN] =\n{\n"); for(n = 0; n < RATPOINTS_NUM_PRIMES; n++) { long p = prime[n]; long i; for(i = 0; i < p; i++) work[i] = ~0UL; for(i = 0; i < LONG_LENGTH; i++) { work[(p*i)>>LONG_SHIFT] &= ~(1UL<<((p*i) & LONG_MASK)); } printf("{"); for(i = 0; i < p; i++) { printf("0x%*.*lx, ", 16, 16, work[i]); } for(i = 0; i < p; i++) { printf("0x%*.*lx", 16, 16, work[i]); if(i < p-1) printf(", "); } printf((n < RATPOINTS_NUM_PRIMES - 1) ? "},\n" : "}\n"); } printf("};\n\n"); } return(0); }