Release calc version 2.12.6.4

Fixed a man page warning about ./myfile where the leading dot
was mistook for an nroff macro.  Thanks goes to David Haller
<dnh at opensuse dot org> for providing the patch.

Improved gen_v1(h,n) in lucas.cal for cases where h is not a
multiple of 3. Optimized the search for v(1) when h is a
multiple of 3.

Fixed a Makefile problem, reported by Doug Hays <doughays6 at gmail
dot com>, where if a macOS user set BINDIR, LIBDIR, CALC_SHAREDIR
or INCDIR in the top section, their values will be overwritten by
the Darwin specific section.
This commit is contained in:
Landon Curt Noll
2018-01-16 15:27:13 -08:00
parent 1c20261b93
commit 8da0471f07
6 changed files with 286 additions and 100 deletions

13
CHANGES
View File

@@ -9,6 +9,19 @@ The following are the changes from calc version 2.12.6.1 to date:
Fixed an C code indenting issue that was reported by Thomas Walter Fixed an C code indenting issue that was reported by Thomas Walter
<th dot walter42 at gmx dot de> in zfunc.c. <th dot walter42 at gmx dot de> in zfunc.c.
Fixed a man page warning about ./myfile where the leading dot
was mistook for an nroff macro. Thanks goes to David Haller
<dnh at opensuse dot org> for providing the patch.
Improved gen_v1(h,n) in lucas.cal for cases where h is not a
multiple of 3. Optimized the search for v(1) when h is a
multiple of 3.
Fixed a Makefile problem, reported by Doug Hays <doughays6 at gmail
dot com>, where if a macOS user set BINDIR, LIBDIR, CALC_SHAREDIR
or INCDIR in the top section, their values will be overwritten by
the Darwin specific section.
The following are the changes from calc version 2.12.6.0 to 2.12.6.0: The following are the changes from calc version 2.12.6.0 to 2.12.6.0:

View File

@@ -23,7 +23,7 @@
# READLINE_LIB= -lreadline # READLINE_LIB= -lreadline
# READLINE_EXTRAS= -lhistory -lncurses # READLINE_EXTRAS= -lhistory -lncurses
# #
# Copyright (C) 1999-2017 Landon Curt Noll # Copyright (C) 1999-2018 Landon Curt Noll
# #
# Calc is open software; you can redistribute it and/or modify it under # Calc is open software; you can redistribute it and/or modify it under
# the terms of version 2.1 of the GNU Lesser General Public License # the terms of version 2.1 of the GNU Lesser General Public License
@@ -564,14 +564,30 @@ HAVE_UNUSED=
# #
# INCDIR= /dev/env/DJDIR/include # INCDIR= /dev/env/DJDIR/include
# #
# If in doubt, set: # If in doubt, for non-macOS hosts set:
# #
# INCDIR= /usr/include # INCDIR= /usr/include
# #
# However, if you are on macOS then set:
#
# INCDIR= /usr/local/include
#if 0 /* start of skip for non-Gnu makefiles */
ifeq ($(target),Darwin)
# default INCDIR for macOS
INCDIR= /usr/local/include
else
#endif /* end of skip for non-Gnu makefiles */
# default INCDIR for non-macOS
INCDIR= /usr/include
#INCDIR= /usr/local/include #INCDIR= /usr/local/include
#INCDIR= /dev/env/DJDIR/include #INCDIR= /dev/env/DJDIR/include
INCDIR= /usr/include
#if 0 /* start of skip for non-Gnu makefiles */
endif
#endif /* end of skip for non-Gnu makefiles */
# Where to install calc related things # Where to install calc related things
# #
@@ -602,23 +618,71 @@ INCDIR= /usr/include
# LIBDIR= /dev/env/DJDIR/lib # LIBDIR= /dev/env/DJDIR/lib
# CALC_SHAREDIR= /dev/env/DJDIR/share/calc # CALC_SHAREDIR= /dev/env/DJDIR/share/calc
# #
# If in doubt, set: # If in doubt, for non-macOS hosts set:
# #
# BINDIR= /usr/bin # BINDIR= /usr/bin
# LIBDIR= /usr/lib # LIBDIR= /usr/lib
# CALC_SHAREDIR= /usr/share/calc # CALC_SHAREDIR= /usr/share/calc
# #
# However, if you are on macOS then set:
#
# BINDIR= /usr/local/bin
# LIBDIR= /usr/local/lib
# CALC_SHAREDIR= /usr/local/share/calc
#
# NOTE: Starting with macOS El Capitan OS X 10.11, root by default
# could not mkdir under system locations, so macOS must now
# use the /usr/local tree.
#if 0 /* start of skip for non-Gnu makefiles */
ifeq ($(target),Darwin)
# default BINDIR for macOS
BINDIR= /usr/local/bin
else
#endif /* end of skip for non-Gnu makefiles */
# default BINDIR for non-macOS
BINDIR= /usr/bin
#BINDIR= /usr/local/bin #BINDIR= /usr/local/bin
#BINDIR= /dev/env/DJDIR/bin #BINDIR= /dev/env/DJDIR/bin
BINDIR= /usr/bin
#if 0 /* start of skip for non-Gnu makefiles */
endif
ifeq ($(target),Darwin)
# default LIBDIR for macOS
LIBDIR= /usr/local/lib
else
#endif /* end of skip for non-Gnu makefiles */
# default LIBDIR for non-macOS
LIBDIR= /usr/lib
#LIBDIR= /usr/local/lib #LIBDIR= /usr/local/lib
#LIBDIR= /dev/env/DJDIR/lib #LIBDIR= /dev/env/DJDIR/lib
LIBDIR= /usr/lib
#if 0 /* start of skip for non-Gnu makefiles */
endif
ifeq ($(target),Darwin)
# default CALC_SHAREDIR for macOS
CALC_SHAREDIR= /usr/local/share/calc
else
#endif /* end of skip for non-Gnu makefiles */
# default CALC_SHAREDIR for non-macOS
CALC_SHAREDIR= /usr/share/calc
#CALC_SHAREDIR= /usr/local/lib/calc #CALC_SHAREDIR= /usr/local/lib/calc
#CALC_SHAREDIR= /dev/env/DJDIR/share/calc #CALC_SHAREDIR= /dev/env/DJDIR/share/calc
CALC_SHAREDIR= /usr/share/calc
#if 0 /* start of skip for non-Gnu makefiles */
endif
#endif /* end of skip for non-Gnu makefiles */
# NOTE: Do not set CALC_INCDIR to /usr/include or /usr/local/include!!! # NOTE: Do not set CALC_INCDIR to /usr/include or /usr/local/include!!!
# Always be sure that the CALC_INCDIR path ends in /calc to avoid # Always be sure that the CALC_INCDIR path ends in /calc to avoid
@@ -990,7 +1054,7 @@ EXT=
# The default calc versions # The default calc versions
# #
VERSION= 2.12.6.3 VERSION= 2.12.6.4
# Names of shared libraries with versions # Names of shared libraries with versions
# #
@@ -1263,16 +1327,6 @@ LDCONFIG:=
# DARWIN_ARCH= -arch ppc # PPC binary # DARWIN_ARCH= -arch ppc # PPC binary
# DARWIN_ARCH= -arch x86_64 # native 64-bit binary # DARWIN_ARCH= -arch x86_64 # native 64-bit binary
DARWIN_ARCH= # native binary DARWIN_ARCH= # native binary
#
# Starting with El Capitan OS X 10.11, root by default could not
# mkdir under system locations, so we now use the /usr/local tree.
#
OPTDIR:= /usr/local
BINDIR:= /${OPTDIR}/bin
LIBDIR:= /${OPTDIR}/lib
CALC_SHAREDIR:= /${OPTDIR}/share
CALC_INCDIR:= /${OPTDIR}/include
SCRIPTDIR:= ${BINDIR}/cscript
endif endif
################## ##################

View File

@@ -28,6 +28,10 @@
* For a general tutorial on how to find a new largest known prime, see: * For a general tutorial on how to find a new largest known prime, see:
* *
* http://www.isthe.com/chongo/tech/math/prime/prime-tutorial.pdf * http://www.isthe.com/chongo/tech/math/prime/prime-tutorial.pdf
*
* Also see the reference code, available both C and go:
*
* https://github.com/arcetri/goprime
*/ */
/* /*
@@ -154,6 +158,12 @@
* *
* Finally, one should eliminate all values of 'h*2^n-1' where * Finally, one should eliminate all values of 'h*2^n-1' where
* 'h*2^n+1' is divisible by a small primes. * 'h*2^n+1' is divisible by a small primes.
*
* NOTE: Today, for world record sized h*2^n-1 primes, one might
* search for factors < 2^46 or more. By excluding h*2^n-1
* with prime factors < 2^46, where h*2^n-1 is a bit larger
* than the largest known prime, one may exclude about 96.5%
* of candidates that have "small" prime factors.
*/ */
pprod256 = 0; /* product of "primes up to 256" / "primes up to 46" */ pprod256 = 0; /* product of "primes up to 256" / "primes up to 46" */
@@ -805,84 +815,154 @@ rodseth_xhn(x, h, n)
* *
* The above distribution was found to hold fairly well over many values of * The above distribution was found to hold fairly well over many values of
* odd h that are also a multiple of 3 and for many values of n where h < 2^n. * odd h that are also a multiple of 3 and for many values of n where h < 2^n.
*
* For example for in a sample size of 1000000 numbers of the form h*2^n-1 * For example for in a sample size of 1000000 numbers of the form h*2^n-1
* where h is an odd multiple of 3, 12996351 <= h <= 13002351, * where h is an odd multiple of 3, 12996351 <= h <= 13002351,
* 4331116 <= n <= 4332116, these are the smallest v(1) values that were found: * 4331116 <= n <= 4332116, these are the smallest v(1) values that were found:
* *
* smallest percentage * smallest percentage
* v(1) used * v(1) used
* ------------------- * -------- ---------
* 3 40.0000% * 3 40.0000 %
* 5 25.6833% * 5 25.6833 %
* 9 11.6924% * 9 11.6924 %
* 11 10.4528% * 11 10.4528 %
* 15 4.8048% * 15 4.8048 %
* 17 2.3458% * 17 2.3458 %
* 21 1.6568% * 21 1.3734 %
* 29 1.2814% * 29 1.0527 %
* 27 0.6906% * 20 0.8595 %
* 35 0.4529% * 27 0.5758 %
* 39 0.3140% * 35 0.4420 %
* 41 0.1737% * 36 0.2433 %
* 31 0.1413% * 39 0.1779 %
* 45 0.1173% * 41 0.0885 %
* 51 0.0526% * 45 0.0571 %
* 55 0.0350% * 32 0.0337 %
* 49 0.0332% * 51 0.0289 %
* 59 0.0218% * 44 0.0205 %
* 69 0.0099% * 49 0.0176 %
* 65 0.0085% * 56 0.0137 %
* 71 0.0073% * 59 0.0108 %
* 57 0.0062% * 57 0.0053 %
* 85 0.0048% * 65 0.0047 %
* 81 0.0044% * 55 0.0045 %
* 95 0.0028% * 69 0.0031 %
* 99 0.0017% * 71 0.0024 %
* 77 0.0009% * 66 0.0011 %
* 53 0.0008% * 95 0.0008 %
* 67 0.0004% * 81 0.0008 %
* 105 0.0004% * 77 0.0006 %
* 111 0.0004% * 72 0.0005 %
* 125 0.0004% * 99 0.0004 %
* 87 0.0003% * 80 0.0003 %
* 101 0.0002% * 74 0.0003 %
* 83 0.0001% * 84 0.0002 %
* 109 0.0001% * 67 0.0002 %
* 121 0.0001% * 87 0.0001 %
* 129 0.0001% * 104 0.0001 %
* 129 0.0001 %
* *
* However, a case can be made for considering only odd values for v(1) candidates.
* When h * 2^n-1 is prime and h is an odd multiple of 3, a smallest v(1) that * When h * 2^n-1 is prime and h is an odd multiple of 3, a smallest v(1) that
* is even is extremely rate. Of the list of 127287 known primes of the form * is even is extremely rate. Of the list of 146553 known primes of the form
* h*2^n-1 when h was a multiple of 3, none has an smallest v(1) that was even. * h*2^n-1 when h is an odd a multiple of 3, none has an smallest v(1) that was even.
* *
* About 1 out of 1000000 cases when h is a multiple of 3 use v(1) > 127 as the * See:
* smallest value of v(1). *
* https://github.com/arcetri/verified-prime
*
* for that list of 146553 known primes of the form h*2^n-1.
*
* That same example for in a sample size of 1000000 numbers of the form h*2^n-1
* where h is an odd multiple of 3, 12996351 <= h <= 13002351,
* 4331116 <= n <= 4332116, these are the smallest odd v(1) values that were found:
*
* smallest percentage
* odd v(1) used
* -------- ---------
* 3 40.0000 %
* 5 25.6833 %
* 9 11.6924 %
* 11 10.4528 %
* 15 4.8048 %
* 17 2.3458 %
* 21 1.6568 %
* 29 1.6174 %
* 35 0.4529 %
* 27 0.3546 %
* 39 0.3470 %
* 41 0.2159 %
* 45 0.1173 %
* 31 0.0661 %
* 51 0.0619 %
* 55 0.0419 %
* 59 0.0250 %
* 49 0.0170 %
* 69 0.0110 %
* 65 0.0098 %
* 71 0.0078 %
* 85 0.0048 %
* 81 0.0044 %
* 95 0.0038 %
* 99 0.0021 %
* 125 0.0009 %
* 57 0.0007 %
* 111 0.0005 %
* 77 0.0003 %
* 165 0.0003 %
* 155 0.0002 %
* 129 0.0002 %
* 101 0.0002 %
* 53 0.0001 %
*
* Moreover when evaluating odd candidates for v(1), one may cache Jacobi symbol
* evaluations to reduce the number of Jacobi symbol evaluations to a minimum.
* For example, if one tests 5 and finds that the 2nd case fails:
*
* jacobi(5+2, h*2^n-1) != -1
*
* Then if one is later testing 9, the Jacobi symbol value for the first 1st case:
*
* jacobi(7-2, h*2^n-1)
*
* is already known.
*
* The hit rate in the cache improves (thus fewer Jacobi symbols need evaluating)
* if we sort the above "smallest odd v(1) values" in numerical order.
* Without Jacobi symbol value caching, it requires on average
* 4.851377 Jacobi symbol evaluations. With Jacobi symbol value caching
* cacheing, an averare of 4.348820 Jacobi symbol evaluations is needed.
* *
* Given this information, when odd h is a multiple of 3 we try, in order, * Given this information, when odd h is a multiple of 3 we try, in order,
* these sorted values of X: * these sorted odd values of X:
* *
* 3, 5, 9, 11, 15, 17, 21, 27, 29, 31, 35, 39, 41, 45, 49, 51, 53, 55, 57, 59, * 3, 5, 9, 11, 15, 17, 21, 29, 27, 35, 39, 41, 31, 45, 51, 55, 49, 59,
* 65, 67, 69, 71, 77, 81, 83, 85, 87, 95, 99, 101, 105, 109, 111, 121, 125 * 69, 65, 71, 57, 85, 81, 95, 99, 77, 53, 67, 125, 111, 105, 87, 129,
* 101, 83, 165, 155, 149, 141, 121, 109
* *
* And stop on the first value of X where: * And stop on the first value of X where:
* *
* jacobi(X-2, h*2^n-1) == 1 * jacobi(X-2, h*2^n-1) == 1
* jacobi(X+2, h*2^n-1) == -1 * jacobi(X+2, h*2^n-1) == -1
* *
* If no value in that list works, we start simple search starting with X = 129 * Less than 1 case out of 1000000 will not be satisifed by the above sorted list.
* If no value in that list works, we start simple search starting with X = 167
* and incrementing by 2 until a value of X is found. * and incrementing by 2 until a value of X is found.
* *
* The x_tbl[] matrix contains those common values of X to try in order. * The x_tbl[] matrix contains those values of X to try in order.
* If all x_tbl_len fail to satisfy Ref4 condition 1, then we begin a * If all x_tbl_len fail to satisfy Ref4 condition 1 (this happens less than
* linear search at next_x until we find a proper X value. * 1 in 1000000 cases), then we begin a linear search of odd values starting at
* next_x until we find a proper X value.
*/ */
x_tbl_len = 38; x_tbl_len = 42;
mat x_tbl[x_tbl_len]; mat x_tbl[x_tbl_len];
x_tbl = { x_tbl = {
3, 5, 9, 11, 15, 17, 21, 27, 29, 31, 35, 39, 41, 45, 49, 51, 53, 55, 57, 59, 3, 5, 9, 11, 15, 17, 21, 29, 27, 35, 39, 41, 31, 45, 51, 55, 49, 59,
65, 67, 69, 71, 77, 81, 83, 85, 87, 95, 99, 101, 105, 109, 111, 121, 125 69, 65, 71, 57, 85, 81, 95, 99, 77, 53, 67, 125, 111, 105, 87, 129,
101, 83, 165, 155, 149, 141, 121, 109
}; };
next_x = 129; next_x = 167; /* must be 2 more than the largest value in x_tbl[] */
/* /*
* gen_v1 - compute the v(1) for a given h*2^n-1 if we can * gen_v1 - compute the v(1) for a given h*2^n-1 if we can
@@ -940,12 +1020,22 @@ next_x = 129;
* *
* u(2) = v(h) (NOTE: some call this u(2)) * u(2) = v(h) (NOTE: some call this u(2))
* *
* so we simply return * so we can always return
* *
* v(1) = alpha^1 + alpha^(-1) * v(1) = alpha^1 + alpha^(-1)
* = (2+sqrt(3)) + (2-sqrt(3)) * = (2+sqrt(3)) + (2-sqrt(3))
* = 4 * = 4
* *
* In 40% of the cases when h is not a multiple of 3, 3 is a valid value
* for v(1). We can test if 3 is a valid value for v(1) in this case:
*
* if jacobi(1, h*2^n-1) == 1 and jacobi(5, h*2^n-1) == -1, then
* v(1) = 3
* else
* v(1) = 4
*
* HOTE: The above "if then else" works only of h is not a multiple of 3.
*
*** ***
* *
* Case 2: (h mod 3 == 0) * Case 2: (h mod 3 == 0)
@@ -1049,6 +1139,10 @@ gen_v1(h, n)
{ {
local x; /* potential v(1) to test */ local x; /* potential v(1) to test */
local i; /* x_tbl index */ local i; /* x_tbl index */
local v1m2; /* X-2 1st case */
local v1p2; /* X+2 2nd case */
local testval; /* h*2^n-1 - value we are testing if prime */
local mat cached_v1[next_x]; /* cached Jacobi symbol values or 0 */
/* /*
* check arg types * check arg types
@@ -1081,14 +1175,24 @@ gen_v1(h, n)
* check for Case 1: (h mod 3 != 0) * check for Case 1: (h mod 3 != 0)
*/ */
if (h % 3 != 0) { if (h % 3 != 0) {
/* v(1) is easy to compute */ if (rodseth_xhn(3, h, n) == 1) {
return 4; /* 40% of the time, 3 works when h mod 3 != 0 */
return 3;
} else {
/* otherwise 4 always works when h mod 3 != 0 */
return 4;
}
} }
/* /*
* What follow is Case 2: (h mod 3 == 0) * What follow is Case 2: (h mod 3 == 0)
*/ */
/*
* clear cache
*/
matfill(cached_v1, 0);
/* /*
* We will look for x that satisfies conditions in Ref4, condition 1: * We will look for x that satisfies conditions in Ref4, condition 1:
* *
@@ -1100,26 +1204,51 @@ gen_v1(h, n)
* to the next odd value, the now jacobi(X-2, h*2^n-1) * to the next odd value, the now jacobi(X-2, h*2^n-1)
* does not need to be re-evaluted. * does not need to be re-evaluted.
*/ */
testval = h*2^n-1;
for (i=0; i < x_tbl_len; ++i) { for (i=0; i < x_tbl_len; ++i) {
/* /*
* test Ref4 condition 1: * obtain the next test candidate
*/ */
x = x_tbl[i]; x = x_tbl[i];
if (rodseth_xhn(x, h, n) == 1) {
/* /*
* found a x that satisfies Ref4 condition 1 * Check x for condition 1 part 1
*/ *
ldebug("gen_v1", "h= " + str(h) + " n= " + str(n) + * jacobi(x-2, h*2^n-1) == 1
" v1= " + str(x) + " using tbl[ " + */
str(i) + " ]"); v1m2 = x-2;
return x; if (cached_v1[v1m2] == 0) {
cached_v1[v1m2] = jacobi(v1m2, testval);
} }
if (cached_v1[v1m2] != 1) {
continue;
}
/*
* Check x for condition 1 part 2
*
* jacobi(x+2, h*2^n-1) == -1
*/
v1p2 = x+2;
if (cached_v1[v1p2] == 0) {
cached_v1[v1p2] = jacobi(v1p2, testval);
}
if (cached_v1[v1p2] != -1) {
continue;
}
/*
* found a x that satisfies Ref4 condition 1
*/
ldebug("gen_v1", "h= " + str(h) + " n= " + str(n) +
" v1= " + str(x) + " using tbl[ " +
str(i) + " ]");
return x;
} }
/* /*
* We are in that rare case (about 1 in 835 000) where none of the * We are in that rare case (less than 1 in 1 000 000) where none of the
* common X values satisfy Ref4 condition 1. We start a linear search * common X values satisfy Ref4 condition 1. We start a linear search
* of odd vules at next_x from here on. * of odd vules at next_x from here on.
*/ */

View File

@@ -348,7 +348,7 @@ EXT=
# The default calc versions # The default calc versions
# #
VERSION= 2.12.6.3 VERSION= 2.12.6.4
# Names of shared libraries with versions # Names of shared libraries with versions
# #
@@ -628,16 +628,6 @@ LDCONFIG:=
# DARWIN_ARCH= -arch ppc # PPC binary # DARWIN_ARCH= -arch ppc # PPC binary
# DARWIN_ARCH= -arch x86_64 # native 64-bit binary # DARWIN_ARCH= -arch x86_64 # native 64-bit binary
DARWIN_ARCH= # native binary DARWIN_ARCH= # native binary
#
# Starting with El Capitan OS X 10.11, root by default could not
# mkdir under system locations, so we now use the /usr/local tree.
#
OPTDIR:= /usr/local
BINDIR:= /${OPTDIR}/bin
LIBDIR:= /${OPTDIR}/lib
CALC_SHAREDIR:= /${OPTDIR}/share
CALC_INCDIR:= /${OPTDIR}/include
SCRIPTDIR:= ${BINDIR}/cscript
endif endif
################## ##################

View File

@@ -348,7 +348,7 @@ EXT=
# The default calc versions # The default calc versions
# #
VERSION= 2.12.6.3 VERSION= 2.12.6.4
# Names of shared libraries with versions # Names of shared libraries with versions
# #

View File

@@ -45,7 +45,7 @@ static char *program;
#define MAJOR_VER 2 /* major library version */ #define MAJOR_VER 2 /* major library version */
#define MINOR_VER 12 /* minor library version */ #define MINOR_VER 12 /* minor library version */
#define MAJOR_PATCH 6 /* major software level under library version */ #define MAJOR_PATCH 6 /* major software level under library version */
#define MINOR_PATCH 3 /* minor software level or 0 if not patched */ #define MINOR_PATCH 4 /* minor software level or 0 if not patched */
/* /*