Files
calc/lib/test3500.cal
2017-05-21 15:38:25 -07:00

287 lines
5.8 KiB
Plaintext

/*
* Copyright (c) 1996 Ernest Bowen and Landon Curt Noll
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and chongo@toad.com
*
* This library is used by the 3500 series of the regress.cal test suite.
*/
/*
* Stringent tests of the functions frem, fcnt, gcdrem.
*
* testf(n) gives n tests of frem(x,y) and fcnt(x,y) with randomly
* integers x and y generated so that x = f * y^k where f, y and
* k are randomly generated.
*
* testg(n) gives n tests of gcdrem(x,y) with x and y generated as for
* testf(n).
*
* testh(n,N) gives n tests of g = gcdrem(x,y) where x and y are products of
* powers of small primes some of which are common to both x and y.
* This test uses f = abs(x) and iteratively f = frem(f,p) where
* p varies over the prime divisors of y; the final value for f
* should equal g. For both x and y the primes are raised to the
* power rand(N); N defaults to 10.
*
* If verbose is > 1, the numbers x, y and values for some of the
* functions will be displayed. Numbers used in testf()
* and testg() occasionally have thousands of digits.
*
*/
global defaultverbose = 1; /* default verbose value */
global err;
define testfrem(x,y,verbose)
{
local f, n;
if (isnull(verbose)) verbose = defaultverbose;
f = frem(x,y);
n = fcnt(x,y);
if (verbose > 1)
printf("frem = %d, fcnt = %d\n\n", f, n);
if (abs(x) != f * abs(y)^n)
return 1;
if (!ismult(x,y) || abs(y) <= 1) {
if (f != abs(x))
return 2;
if (n != 0)
return 3;
return 0;
}
if (x == 0) {
if (f != 0 || n != 0)
return 4;
return 0;
}
if (f < 0 || !isint(f) || n <= 0)
return 5;
if (ismult(f, y))
return 6;
if (!ismult(x, y^n))
return 7;
if (ismult(x, y^(n+1)))
return 8;
return 0;
}
define testgcdrem(x,y,verbose)
{
local d, q;
if (isnull(verbose)) verbose = defaultverbose;
d = gcdrem(x,y);
if (verbose > 1)
printf("gcdrem = %d\n\n", d);
if (y == 0) {
if (d != 1)
return 1;
return 0;
}
if (x == 0) {
if (d != 0)
return 2;
return 0;
}
if (d <= 0)
return 3;
q = x/d;
if (!isint(q))
return 4;
if (!isrel(d, y))
return 5;
if (!isrel(d, q))
return 6;
return 0;
}
define testf(str,n,verbose)
{
local m, x, y, i, k, y1, f1, f, fail;
if (isnull(verbose))
verbose = defaultverbose;
if (verbose > 0) {
print str:":",:;
}
m = 0;
for (i = 0; i < n; i++) {
y1 = rand(2^rand(1,6));
y = rand(-(2^y1), 1 + 2^y1);
f1 = rand(2^rand(1,11));
f = rand(-(2^f1), 1+2^f1);
k = rand(1,1+2^10);
x = f * y^k;
if (verbose > 1) {
printf("x = %d\n", x);
printf("y = %d\n", y);
}
fail = testfrem(x,y,verbose);
if (fail != 0) {
printf("*** Failure %d on loop %d\n", fail, i);
if (verbose > 1) {
printf(" x = %d\n", x);
printf(" y = %d\n", y);
}
m++;
}
}
if (verbose > 0) {
if (m) {
printf("*** %d error(s)\n", m);
} else {
printf("no errors\n");
}
}
return m;
}
define testg(str,n,verbose)
{
local m, x, y, i, k, y1, f1, f, fail;
if (isnull(verbose))
verbose = defaultverbose;
if (verbose > 0) {
print str:":",:;
}
m = 0;
for (i = 0; i < n; i++) {
y1 = rand(2^rand(1,6));
y = rand(-(2^y1), 1 + 2^y1);
f1 = rand(2^rand(1,11));
f = rand(-(2^f1), 1+2^f1);
k = rand(1,1+2^10);
x = f * y^k;
if (verbose > 1) {
printf("x = %d\n", x);
printf("y = %d\n", y);
}
fail = testgcdrem(x,y,verbose);
if (fail != 0) {
printf("*** Failure %d on loop %d\n", fail, i);
if (verbose > 1) {
printf(" x = %d\n", x);
printf(" y = %d\n", y);
}
m++;
}
}
if (verbose > 0) {
if (m) {
printf("*** %d error(s)\n", m);
} else {
printf("no errors\n");
}
}
return m;
}
define testh(str,n,N,verbose)
{
local m, i, x, y, f, g;
if (isnull(verbose))
verbose = defaultverbose;
if (verbose > 0) {
print str:":",:;
}
m = 0;
if (isnull(N))
N = 61;
for (i = 0; i < n; i ++) {
x = 2^rand(N)*3^rand(N) * 7^rand(N) * 11^rand(N) * 101^rand(N);
y = 2^rand(N) * 3^rand(N) * 5^rand(N) * 11^rand(N) * 53^rand(N);
if (rand(2)) x = -x;
if (rand(2)) y = -y;
if (verbose > 1) {
printf("x = %d\n", x);
printf("y = %d\n", y);
}
f = abs(x);
g = gcdrem(x,y);
if (ismult(y,2)) f = frem(f,2);
if (ismult(y,3)) f = frem(f,3);
if (ismult(y,5)) f = frem(f,5);
if (ismult(y,11)) f = frem(f,11);
if (ismult(y,53)) f = frem(f,53);
if (f != g) {
printf("*** Failure on loop %d\n", i);
if (verbose > 1) {
printf(" x = %d\n", x);
printf(" y = %d\n", y);
printf(" f = %d\n", f);
printf(" g = %d\n", g);
}
m++;
}
}
if (verbose > 0) {
if (m) {
printf("*** %d error(s)\n", m);
} else {
printf("no errors\n");
}
}
return m;
}
/*
* test3500 - perform all of the above tests a bunch of times
*/
define test3500(verbose, tnum, n, N)
{
/* set test parameters */
if (isnull(verbose)) {
verbose = defaultverbose;
}
if (isnull(tnum)) {
tnum = 3501; /* default test number */
}
if (isnull(n)) {
n = 200;
}
if (isnull(N)) {
N = 61;
}
/*
* test a lot of stuff
*/
srand(3500e3500);
err += testf(strcat(str(tnum++), ": frem/fcnt"), n, verbose);
err += testg(strcat(str(tnum++), ": gcdrem"), n, verbose);
err += testh(strcat(str(tnum++),": gcdrem #2"), n, N, verbose);
if (verbose > 1) {
if (err) {
print "***", err, "error(s) found in testall";
} else {
print "no errors in testall";
}
}
return tnum;
}
global lib_debug;
if (lib_debug >= 0) {
print "global defaultverbose defined";
print "global err defined";
print "testfrem(x, y, verbose) defined";
print "testgcdrem(x, y, verbose) defined";
print "testf(str, n, verbose) defined";
print "testg(str, n, verbose) defined";
print "testh(str, n, N, verbose) defined";
print "test3500(verbose, n, N) defined";
}