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
<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:

View File

@@ -23,7 +23,7 @@
# READLINE_LIB= -lreadline
# 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
# the terms of version 2.1 of the GNU Lesser General Public License
@@ -564,14 +564,30 @@ HAVE_UNUSED=
#
# INCDIR= /dev/env/DJDIR/include
#
# If in doubt, set:
# If in doubt, for non-macOS hosts set:
#
# 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= /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
#
@@ -602,23 +618,71 @@ INCDIR= /usr/include
# LIBDIR= /dev/env/DJDIR/lib
# CALC_SHAREDIR= /dev/env/DJDIR/share/calc
#
# If in doubt, set:
# If in doubt, for non-macOS hosts set:
#
# BINDIR= /usr/bin
# LIBDIR= /usr/lib
# 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= /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= /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= /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!!!
# Always be sure that the CALC_INCDIR path ends in /calc to avoid
@@ -990,7 +1054,7 @@ EXT=
# The default calc versions
#
VERSION= 2.12.6.3
VERSION= 2.12.6.4
# Names of shared libraries with versions
#
@@ -1263,16 +1327,6 @@ LDCONFIG:=
# DARWIN_ARCH= -arch ppc # PPC binary
# DARWIN_ARCH= -arch x86_64 # native 64-bit 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
##################

View File

@@ -28,6 +28,10 @@
* 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
*
* 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
* '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" */
@@ -805,84 +815,154 @@ rodseth_xhn(x, h, n)
*
* 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.
*
* 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,
* 4331116 <= n <= 4332116, these are the smallest v(1) values that were found:
*
* smallest percentage
* 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.2814%
* 27 0.6906%
* 35 0.4529%
* 39 0.3140%
* 41 0.1737%
* 31 0.1413%
* 45 0.1173%
* 51 0.0526%
* 55 0.0350%
* 49 0.0332%
* 59 0.0218%
* 69 0.0099%
* 65 0.0085%
* 71 0.0073%
* 57 0.0062%
* 85 0.0048%
* 81 0.0044%
* 95 0.0028%
* 99 0.0017%
* 77 0.0009%
* 53 0.0008%
* 67 0.0004%
* 105 0.0004%
* 111 0.0004%
* 125 0.0004%
* 87 0.0003%
* 101 0.0002%
* 83 0.0001%
* 109 0.0001%
* 121 0.0001%
* 129 0.0001%
* smallest percentage
* v(1) used
* -------- ---------
* 3 40.0000 %
* 5 25.6833 %
* 9 11.6924 %
* 11 10.4528 %
* 15 4.8048 %
* 17 2.3458 %
* 21 1.3734 %
* 29 1.0527 %
* 20 0.8595 %
* 27 0.5758 %
* 35 0.4420 %
* 36 0.2433 %
* 39 0.1779 %
* 41 0.0885 %
* 45 0.0571 %
* 32 0.0337 %
* 51 0.0289 %
* 44 0.0205 %
* 49 0.0176 %
* 56 0.0137 %
* 59 0.0108 %
* 57 0.0053 %
* 65 0.0047 %
* 55 0.0045 %
* 69 0.0031 %
* 71 0.0024 %
* 66 0.0011 %
* 95 0.0008 %
* 81 0.0008 %
* 77 0.0006 %
* 72 0.0005 %
* 99 0.0004 %
* 80 0.0003 %
* 74 0.0003 %
* 84 0.0002 %
* 67 0.0002 %
* 87 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
* is even is extremely rate. Of the list of 127287 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.
* is even is extremely rate. Of the list of 146553 known primes of the form
* 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
* smallest value of v(1).
* See:
*
* 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,
* 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,
* 65, 67, 69, 71, 77, 81, 83, 85, 87, 95, 99, 101, 105, 109, 111, 121, 125
* 3, 5, 9, 11, 15, 17, 21, 29, 27, 35, 39, 41, 31, 45, 51, 55, 49, 59,
* 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:
*
* 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.
*
* The x_tbl[] matrix contains those common values of X to try in order.
* If all x_tbl_len fail to satisfy Ref4 condition 1, then we begin a
* linear search at next_x until we find a proper X value.
* The x_tbl[] matrix contains those values of X to try in order.
* If all x_tbl_len fail to satisfy Ref4 condition 1 (this happens less than
* 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];
x_tbl = {
3, 5, 9, 11, 15, 17, 21, 27, 29, 31, 35, 39, 41, 45, 49, 51, 53, 55, 57, 59,
65, 67, 69, 71, 77, 81, 83, 85, 87, 95, 99, 101, 105, 109, 111, 121, 125
3, 5, 9, 11, 15, 17, 21, 29, 27, 35, 39, 41, 31, 45, 51, 55, 49, 59,
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
@@ -940,12 +1020,22 @@ next_x = 129;
*
* 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)
* = (2+sqrt(3)) + (2-sqrt(3))
* = 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)
@@ -1049,6 +1139,10 @@ gen_v1(h, n)
{
local x; /* potential v(1) to test */
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
@@ -1081,14 +1175,24 @@ gen_v1(h, n)
* check for Case 1: (h mod 3 != 0)
*/
if (h % 3 != 0) {
/* v(1) is easy to compute */
return 4;
if (rodseth_xhn(3, h, n) == 1) {
/* 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)
*/
/*
* clear cache
*/
matfill(cached_v1, 0);
/*
* 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)
* does not need to be re-evaluted.
*/
testval = h*2^n-1;
for (i=0; i < x_tbl_len; ++i) {
/*
* test Ref4 condition 1:
* obtain the next test candidate
*/
x = x_tbl[i];
if (rodseth_xhn(x, h, n) == 1) {
/*
* 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;
/*
* Check x for condition 1 part 1
*
* jacobi(x-2, h*2^n-1) == 1
*/
v1m2 = x-2;
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
* of odd vules at next_x from here on.
*/

View File

@@ -348,7 +348,7 @@ EXT=
# The default calc versions
#
VERSION= 2.12.6.3
VERSION= 2.12.6.4
# Names of shared libraries with versions
#
@@ -628,16 +628,6 @@ LDCONFIG:=
# DARWIN_ARCH= -arch ppc # PPC binary
# DARWIN_ARCH= -arch x86_64 # native 64-bit 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
##################

View File

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

View File

@@ -45,7 +45,7 @@ static char *program;
#define MAJOR_VER 2 /* major library version */
#define MINOR_VER 12 /* minor 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 */
/*