mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
Converted all ASCII tabs to ASCII spaces using a 8 character tab stop, for all files, except for all Makefiles (plus rpm.mk). The `git diff -w` reports no changes.
1434 lines
42 KiB
Plaintext
1434 lines
42 KiB
Plaintext
/*
|
|
* test9500.trigeq - test of trigonometric identities for test 95dd
|
|
*
|
|
* We test over a wide variety of real (NUMBER) and complex (COMPLEX)
|
|
* values, that various trigonometric identities hold for all calc
|
|
* builtin trigonometric functions.
|
|
*
|
|
* We assume that the value produced by sin() (trigonometric sine)
|
|
* and cos() (trigonometric cosine) are correct. We can reasonably
|
|
* assume this because of the calc regression test suite:
|
|
*
|
|
* (such as test 34dd and in particular cal/test3400.trig.cal and
|
|
* such as test 89dd and in particular cal/test8900.special.cal)
|
|
*
|
|
* will test such those function beforehand.
|
|
*
|
|
* We use various trigonometric identity to verify the non-inverse
|
|
* trigonometric functions other than sin() and cos().
|
|
*
|
|
* we verify that it is true within the error tolerance of the eps
|
|
* (epsilon) argument.
|
|
*
|
|
* Copyright (C) 2023 Landon Curt Noll
|
|
*
|
|
* Primary author: Landon Curt Noll
|
|
*
|
|
* Calc is open software; you can redistribute it and/or modify it under
|
|
* the terms of the version 2.1 of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* Calc 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 Lesser General
|
|
* Public License for more details.
|
|
*
|
|
* A copy of version 2.1 of the GNU Lesser General Public License is
|
|
* distributed with calc under the filename COPYING-LGPL. You should have
|
|
* received a copy with calc; if not, write to Free Software Foundation, Inc.
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Under source code control: 2023/09/10 14:33:06
|
|
* File existed as early as: 2023
|
|
*
|
|
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
|
*/
|
|
|
|
|
|
/*
|
|
* base_tval - base set of test values
|
|
*
|
|
* Our 16 base test values must be > 0 and <= 1.
|
|
* We use these fractions because, when multiplied
|
|
* by pi() will give values that are commonly used.
|
|
*
|
|
* NOTE: There is no reason to sort these values other than ascetics. :-)
|
|
*/
|
|
static base_tval = list(
|
|
1/12, /* ~ 0.08333333333333333333 */
|
|
1/8, /* 0.12500000000000000000 */
|
|
1/6, /* ~ 0.16666666666666666667 */
|
|
1/5, /* 0.20000000000000000000 */
|
|
1/4, /* 0.25000000000000000000 */
|
|
1/3, /* ~ 0.33333333333333333333 */
|
|
3/8, /* 0.37500000000000000000 */
|
|
5/12, /* ~ 0.41666666666666666667 */
|
|
1/2, /* 0.50000000000000000000 */
|
|
2/3, /* ~ 0.66666666666666666667 */
|
|
3/4, /* 0.75000000000000000000 */
|
|
4/5, /* 0.80000000000000000000 */
|
|
5/6, /* ~ 0.83333333333333333333 */
|
|
7/8, /* 0.87500000000000000000 */
|
|
11/12, /* ~ 0.91666666666666666667 */
|
|
1 /* 1.00000000000000000000 */
|
|
);
|
|
|
|
|
|
/*
|
|
* tval - full test list
|
|
*
|
|
* This long list is formed via the form_tval() function from the base_tval list.
|
|
*
|
|
* When the form_tval() function forms the full test test values
|
|
* we will have 1025 values of various real and complex
|
|
* values that also include random values added or subtracted.
|
|
*
|
|
* See the form_tval() function for details.
|
|
*/
|
|
tval = list();
|
|
|
|
|
|
/*
|
|
* Lists that hold precomputed trigonometric functions on the tval full test list
|
|
*
|
|
* The precompute_trig() function will fill out these lists.
|
|
* They will be the same size as size as the full test list.
|
|
*/
|
|
sin_tval = list(); /* trigonometric sine of each test test value */
|
|
cos_tval = list(); /* trigonometric cosine of each test test value */
|
|
|
|
|
|
/*
|
|
* seed_rand - seed the subtractive 100 shuffle pseudo-random number generator
|
|
*
|
|
* We want to seed the subtractive 100 shuffle pseudo-random number generator
|
|
* with a constant so that the result of this test set will be deterministic.
|
|
*
|
|
* We seed the subtractive 100 shuffle pseudo-random number generator with
|
|
* a 128-bit seed value. The 128-bit seed value was produced when a
|
|
* Blum-Blum-Shub pseudo-random number generator was seeded with the
|
|
* following 160-bit SHA1 hash of 3 calls to seed():
|
|
*
|
|
* sha1(sha1(seed(), seed()<<64, seed()<<128)) == 0x732fda50b1bf6e34b604b7c75b993e5c37a4ad97
|
|
*
|
|
* This produced the following 160-bit value that was used to seed
|
|
* the Blum-Blum-Shub pseudo-random number:
|
|
*
|
|
* srandom(0x732fda50b1bf6e34b604b7c75b993e5c37a4ad97)
|
|
*
|
|
* The seeded Blum-Blum-Shub pseudo-random number generator was then
|
|
* used to generate a 128-bit value:
|
|
*
|
|
* randombit(128) == 0x37301cf47204f7fababc2f32e39ab338
|
|
*
|
|
* We seed the subtractive 100 shuffle pseudo-random number generator
|
|
* with the above mentioned 128-bit value:
|
|
*
|
|
* srand(0x37301cf47204f7fababc2f32e39ab338)
|
|
*/
|
|
define seed_rand()
|
|
{
|
|
return srand(0x37301cf47204f7fababc2f32e39ab338);
|
|
}
|
|
|
|
|
|
/*
|
|
* epsilon_bits - number of bits in epsilon()
|
|
*/
|
|
static epsilon_bits = highbit(1/epsilon()) + 1;
|
|
|
|
|
|
/*
|
|
* epsilon_norm - norm of a epsilon()
|
|
*/
|
|
static epsilon_norm = norm(epsilon());
|
|
|
|
|
|
/*
|
|
* random_rational_value - compute a random rational value > 0 and < 1
|
|
*
|
|
* We compute a pseudo-random value in the range (0,1) with a prevision of epsilon().
|
|
*
|
|
* We compute two distinct non-zero pseudo-random integers (i.e., > 0), a and b,
|
|
* that are epsilon_bits (see above) long and produced by the seeded
|
|
* subtractive 100 shuffle pseudo-random number generator (see seed_rand()).
|
|
*
|
|
* Return the smaller of a,b divided by the larger of a,b.
|
|
*/
|
|
define random_rational_value()
|
|
{
|
|
local a; /* epsilon_bits pseudo-random integer > 0 */
|
|
local b; /* epsilon_bits pseudo-random integer > 0 */
|
|
|
|
/*
|
|
* compute 1st non-zero pseudo-random epsilon_bits integer
|
|
*/
|
|
do {
|
|
a = randbit(epsilon_bits);
|
|
} while (a == 0);
|
|
|
|
/*
|
|
* compute 2nd non-zero pseudo-random epsilon_bits integer also != a
|
|
*/
|
|
do {
|
|
b = randbit(epsilon_bits);
|
|
} while (b == 0 || a == b);
|
|
|
|
/*
|
|
* return the min(a,b) / max(a,b): a value > 0 and < 1
|
|
*/
|
|
return min(a,b) / max(a,b);
|
|
}
|
|
|
|
|
|
/*
|
|
* form_tval - form a full list of test values
|
|
*
|
|
* Given an initial list of 16 values, we form 1025 test values.
|
|
*
|
|
* From the test set starts with 16 values from the base_tval[] list:
|
|
*
|
|
* tval = base_tval;
|
|
*
|
|
* We form a list of 32 values by appending all of the above with:
|
|
*
|
|
* tval[i] + 1
|
|
*
|
|
* We form a list of 64 values by appending all of the above with:
|
|
*
|
|
* -tval[i]
|
|
*
|
|
* We form a list of 128 values by appending all of the above with:
|
|
*
|
|
* For values >= 0: tval[i] + random_rational_value
|
|
* For values < 0: tval[i] - random_rational_value
|
|
*
|
|
* We form a list of 256 values by appending all of the above with:
|
|
*
|
|
* tval[i] * pi()
|
|
*
|
|
* We form a list of 512 values by appending all of the above with:
|
|
*
|
|
* tval[i] * 1i
|
|
*
|
|
* We for a list of 1024 values by appending new complex values where the
|
|
* real part is a randomly selected real value (from the first 256 list values), and the
|
|
* imaginary part is a randomly selected complex value (from the last 256 list values).
|
|
*
|
|
* Finally we append 0 to the list to form the full 1025 value list.
|
|
*/
|
|
define form_tval()
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local real_cnt; /* number of real values in tval[] array */
|
|
local imag_cnt; /* number of imaginary values in tval[] array */
|
|
local i;
|
|
|
|
/*
|
|
* seed the subtractive 100 shuffle pseudo-random number generator
|
|
*/
|
|
seed_rand();
|
|
|
|
/*
|
|
* load base_tval[] array into tval[] array
|
|
*/
|
|
tval = base_tval;
|
|
|
|
/*
|
|
* expand all tval with tval+1
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
append(tval, tval[i] + 1);
|
|
}
|
|
|
|
/*
|
|
* expand all tval with -tval
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
append(tval, -tval[i]);
|
|
}
|
|
|
|
/*
|
|
* expand all tval with tval +/- random_rational_value
|
|
*
|
|
* For values we add random_rational_value if > 0
|
|
* or we subtract crandom_rational_value if < 0.
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* use the sign to determine if we add or subtract */
|
|
if (tval[i] >= 0) {
|
|
append(tval, tval[i] + random_rational_value());
|
|
} else {
|
|
append(tval, tval[i] - random_rational_value());
|
|
}
|
|
}
|
|
|
|
/*
|
|
* expand all tval with tval * pi()
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
append(tval, tval[i] * pi());
|
|
}
|
|
|
|
/*
|
|
* expand all tval with tval * 1i
|
|
*/
|
|
tval_len = size(tval);
|
|
/* tval[0] thru tval[real_cnt-1] are real values */
|
|
real_cnt = tval_len;
|
|
for (i=0; i < tval_len; ++i) {
|
|
append(tval, tval[i] * 1i);
|
|
}
|
|
|
|
/*
|
|
* expand tval with randomly selected real value
|
|
* plus randomly selected complex value.
|
|
*/
|
|
tval_len = size(tval);
|
|
/* tval[real_cnt] thru tval[real_cnt+imag_cnt-1] are complex values */
|
|
imag_cnt = tval_len - real_cnt;
|
|
for (i=0; i < tval_len; ++i) {
|
|
append(tval, tval[rand(0,real_cnt)] + tval[real_cnt + rand(0,imag_cnt)]);
|
|
}
|
|
|
|
/*
|
|
* last, append our final 0 value
|
|
*/
|
|
append(tval, 0);
|
|
}
|
|
|
|
|
|
/*
|
|
* compute - form precomputed trigonometric value lists
|
|
*/
|
|
define precompute_trig()
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local i;
|
|
|
|
/*
|
|
* firewall - be sure tval list is setup
|
|
*/
|
|
if (size(tval) <= 0) {
|
|
form_tval();
|
|
}
|
|
tval_len = size(tval);
|
|
if (tval_len <= 0) {
|
|
quit "FATAL: tval_len is empty";
|
|
}
|
|
|
|
/*
|
|
* compute trigonometric sine of the tval full test list
|
|
*/
|
|
for (i=0; i < tval_len; ++i) {
|
|
append(sin_tval, sin(tval[i]));
|
|
}
|
|
if (size(tval) != size(sin_tval)) {
|
|
print "****: size(tval):", size(tval), "!= size(sin_tval)", size(sin_tval);
|
|
quit "FATAL: sin_tval not same size as tval_len";
|
|
}
|
|
|
|
/*
|
|
* compute trigonometric cosine of the tval full test list
|
|
*/
|
|
for (i=0; i < tval_len; ++i) {
|
|
append(cos_tval, cos(tval[i]));
|
|
}
|
|
if (size(tval) != size(cos_tval)) {
|
|
print "****: size(tval):", size(tval), "!= size(cos_tval)", size(cos_tval);
|
|
quit "FATAL: cos_tval not same size as tval_len";
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* compare - compare the trigonometric identity and the trigonometric function value
|
|
*
|
|
* given:
|
|
* ident_val computed trig value trigonometric identity
|
|
* trig_val computed value from the trigonometric function
|
|
* name trig function name
|
|
* index test index value
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* 0 ==> trigonometric identity and the trigonometric function value match
|
|
* 1 ==> trigonometric identity and the trigonometric function value do NOT match
|
|
*/
|
|
define compare(ident_val, trig_val, name, index, testnum)
|
|
{
|
|
local abs_diff; /* absolute difference between ident_val and trig_val */
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (!isnum(trig_val)) {
|
|
printf("**** trig test %d-%d failed: %s(tval[%d]): ",
|
|
testnum, index, name, index);
|
|
printf("%d returned a non-numeric value\n", trig_val);
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* compute absolute difference
|
|
*/
|
|
abs_diff = abs(ident_val - trig_val);
|
|
|
|
/*
|
|
* determine if ident_val within epsilon of trig_val
|
|
*/
|
|
if (near(norm(abs_diff), epsilon_norm) > 0) {
|
|
printf("**** trig test %d-%d failed: %s(tval[%d]): ",
|
|
testnum, index, name, index);
|
|
printf("%d is not near trig identity value: %d\n",
|
|
trig_val, ident_val);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* not_near_zero - determine if a value is within epsilon() of 0
|
|
*
|
|
* given:
|
|
* value real or complex value
|
|
*
|
|
* returns:
|
|
* 1 ==> value is farther from 0 than epsilon (not near zero)
|
|
* 0 ==> value is within epsilon of 0 (near zero)
|
|
*/
|
|
define not_near_zero(value)
|
|
{
|
|
if (near(norm(value), epsilon_norm) > 0) {
|
|
/* value is farther from 0 than epsilon */
|
|
return 1;
|
|
}
|
|
|
|
/* value is within epsilon of 0 */
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_tan - verify trigonometric tangent
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* tan(x) = sin(x) / cos(x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_tan(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0 || size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
error_count = 0;
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when cos(x) within epsilon of 0 */
|
|
if (not_near_zero(cos_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = sin_tval[i] / cos_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = tan(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "tan", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': tan test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_cot - verify trigonometric cotangent
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* cot(x) = cos(x) / sin(x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_cot(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0 || size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when sin(x) within epsilon of 0 */
|
|
if (not_near_zero(sin_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = cos_tval[i] / sin_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = cot(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "cot", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': cot test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_sec - verify trigonometric secant
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* sec(x) = 1 / cos(x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_sec(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when cos(x) within epsilon of 0 */
|
|
if (not_near_zero(cos_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = 1 / cos_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = sec(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "sec", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': sec test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_csc - verify trigonometric cosecant
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* csc(x) = 1 / sin(x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_csc(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when sin(x) within epsilon of 0 */
|
|
if (not_near_zero(sin_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = 1 / sin_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = csc(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "csc", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': csc test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_versin - verify versed trigonometric sine
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* versin(x) = 1 - cos(x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_versin(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when cos(x) within epsilon of 0 */
|
|
if (not_near_zero(cos_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = 1 - cos_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = versin(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "versin", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': versin test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_coversin - verify coversed trigonometric sine
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* coversin(x) = 1 - sin(x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_coversin(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when sin(x) within epsilon of 0 */
|
|
if (not_near_zero(sin_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = 1 - sin_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = coversin(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "coversin", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': coversin test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_vercos - verify versed trigonometric cosine
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* vercos(x) = 1 + cos(x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_vercos(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when cos(x) within epsilon of 0 */
|
|
if (not_near_zero(cos_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = 1 + cos_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = vercos(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "vercos", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': vercos test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_covercos - verify coversed trigonometric cosine
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* covercos(x) = 1 + sin(x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_covercos(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when sin(x) within epsilon of 0 */
|
|
if (not_near_zero(sin_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = 1 + sin_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = covercos(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "covercos", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': covercos test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_haversin - verify half versed trigonometric sine
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* haversin(x) = versin(x) / 2 = (1 - cos(x)) / 2
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_haversin(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when cos(x) within epsilon of 0 */
|
|
if (not_near_zero(cos_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = (1 - cos_tval[i]) / 2;
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = haversin(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "haversin", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': haversin test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_hacoversin - verify half versed trigonometric cosine
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* hacoversin(x) = coversin(x) / 2 = (1 - sin(x)) / 2
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_hacoversin(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when cos(x) within epsilon of 0 */
|
|
if (not_near_zero(sin_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = (1 - sin_tval[i]) / 2;
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = hacoversin(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "hacoversin", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': hacoversin test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_havercos - verify half versed trigonometric cosine
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* havercos(x) = vercos(x) / 2 = (1 + cos(x)) / 2
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_havercos(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when cos(x) within epsilon of 0 */
|
|
if (not_near_zero(cos_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = (1 + cos_tval[i]) / 2;
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = havercos(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "havercos", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': havercos test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_hacovercos - verify half coversed trigonometric cosine
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* hacovercos(x) = covercos(x) / 2 = (1 + sin(x)) / 2
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_hacovercos(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when sin(x) within epsilon of 0 */
|
|
if (not_near_zero(sin_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = (1 + sin_tval[i]) / 2;
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = hacovercos(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "hacovercos", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': hacovercos test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_exsec - exterior trigonometric secant
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* exsec(x) = sec(x) - 1 = (1 / cos(x)) - 1
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_exsec(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when cos(x) within epsilon of 0 */
|
|
if (not_near_zero(cos_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = (1 / cos_tval[i]) - 1;
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = exsec(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "exsec", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': exsec test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_excsc - verify trigonometric cosecant
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* excsc(x) = csc(x) - 1 = (1 / sin(x)) - 1
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_excsc(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* skip test when sin(x) within epsilon of 0 */
|
|
if (not_near_zero(sin_tval[i])) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = (1 / sin_tval[i]) - 1;
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = excsc(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "excsc", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': excsc test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_crd - verify trigonometric chord of a unit circle
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* crd(x) = 2 * sin(x / 2)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_crd(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* NOTE: We actually check the identity: crd(x*2) = 2 * sin(x) */
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = 2 * sin_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = crd(tval[i] * 2);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "crd", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': crd test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_cas - verify cosine plus sine
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* cas(x) = cos(x) + sin(x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_cas(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
if (size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = cos_tval[i] + sin_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = cas(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "cas", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': cas test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|
|
|
|
|
|
/*
|
|
* verify_cis - verify Euler's formula
|
|
*
|
|
* We use the following trigonometric identity:
|
|
*
|
|
* cis(x) = cos(x) + i*sin(x)
|
|
* cis(x) = exp(1i * x)
|
|
*
|
|
* given:
|
|
* testnum regression test number being performed
|
|
*
|
|
* returns:
|
|
* number of tests that failed
|
|
*/
|
|
define verify_cis(testnum)
|
|
{
|
|
local tval_len; /* current length of the tval[] array */
|
|
local ident_val; /* computed trig value trigonometric identity */
|
|
local trig_val; /* computed value from the trigonometric function */
|
|
local error_count; /* number of compare errors detected */
|
|
local i;
|
|
|
|
/*
|
|
* firewall
|
|
*/
|
|
if (size(sin_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
if (size(cos_tval) <= 0) {
|
|
precompute_trig();
|
|
}
|
|
|
|
/*
|
|
* for each test value, verify the trigonometric identity within epsilon
|
|
*/
|
|
tval_len = size(tval);
|
|
for (i=0; i < tval_len; ++i) {
|
|
|
|
/* compute trigonometric identity */
|
|
ident_val = cos_tval[i] + 1i*sin_tval[i];
|
|
|
|
/* compute trigonometric function */
|
|
trig_val = cis(tval[i]);
|
|
|
|
/* compare trigonometric identity with trigonometric function value */
|
|
if (compare(ident_val, trig_val, "cis", i, testnum)) {
|
|
++error_count;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* report test results
|
|
*/
|
|
if (error_count != 0) {
|
|
print '**** test', testnum : ': cis test failure count:', error_count;
|
|
}
|
|
return error_count;
|
|
}
|