Skip to content

Commit 926417e

Browse files
committed
test: validate kernelCos against Julia implementation
1 parent aec0e88 commit 926417e

File tree

7 files changed

+134
-22
lines changed

7 files changed

+134
-22
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
julia 1.5
2+
JSON 0.21

lib/node_modules/@stdlib/math/base/special/kernel-cos/test/fixtures/julia/large_negative.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

lib/node_modules/@stdlib/math/base/special/kernel-cos/test/fixtures/julia/large_positive.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env julia
2+
#
3+
# @license Apache-2.0
4+
#
5+
# Copyright (c) 2018 The Stdlib Authors.
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
import JSON
20+
21+
"""
22+
gen( domain, name )
23+
24+
Generate fixture data and write to file.
25+
26+
# Arguments
27+
28+
* `domain`: domain
29+
* `name::AbstractString`: output filename
30+
31+
# Examples
32+
33+
``` julia
34+
julia> x = range( -1000.0, stop = 1000.0, length = 2001 );
35+
julia> gen( x, \"data.json\" );
36+
```
37+
"""
38+
function gen( domain, name )
39+
x = collect( domain );
40+
y = cos.( x );
41+
42+
# Store data to be written to file as a collection:
43+
data = Dict([
44+
("x", x),
45+
("expected", y)
46+
]);
47+
48+
# Based on the script directory, create an output filepath:
49+
filepath = joinpath( dir, name );
50+
51+
# Write the data to the output filepath as JSON:
52+
outfile = open( filepath, "w" );
53+
write( outfile, JSON.json(data) );
54+
write( outfile, "\n" );
55+
close( outfile );
56+
end
57+
58+
# Get the filename:
59+
file = @__FILE__;
60+
61+
# Extract the directory in which this file resides:
62+
dir = dirname( file );
63+
64+
# Values within the defined domain:
65+
x = range( -pi/4.0, stop = pi/4.0, length = 1000 )
66+
gen( x, "small_range.json" );
67+
68+
# Positive values outside the defined domain:
69+
x = range( 40.0*pi/4.0, stop = 200*pi/4.0, length = 1000 )
70+
gen( x, "large_positive.json" );
71+
72+
# Negative values outside the defined domain:
73+
x = range( -200*pi/4.0, stop = -40*pi/4.0, length = 1000 )
74+
gen( x, "large_negative.json" );

lib/node_modules/@stdlib/math/base/special/kernel-cos/test/fixtures/julia/small_range.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

lib/node_modules/@stdlib/math/base/special/kernel-cos/test/test.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,18 @@
2222

2323
var tape = require( 'tape' );
2424
var isnan = require( '@stdlib/math/base/assert/is-nan' );
25-
var linspace = require( '@stdlib/array/base/linspace' );
2625
var rempio2 = require( '@stdlib/math/base/special/rempio2' );
27-
var PI = require( '@stdlib/constants/float64/pi' );
2826
var cos = require( '@stdlib/math/base/special/cos' );
2927
var kernelCos = require( './../lib' );
3028

3129

30+
// FIXTURES //
31+
32+
var smallRange = require( './fixtures/julia/small_range.json' );
33+
var largePositive = require( './fixtures/julia/large_positive.json' );
34+
var largeNegative = require( './fixtures/julia/large_negative.json' );
35+
36+
3237
// TESTS //
3338

3439
tape( 'main export is a function', function test( t ) {
@@ -39,13 +44,13 @@ tape( 'main export is a function', function test( t ) {
3944

4045
tape( 'the function returns `NaN` if provided `NaN` for either parameter', function test( t ) {
4146
var v = kernelCos( NaN, 0.0 );
42-
t.equal( isnan( v ), true, 'returns NaN' );
47+
t.equal( isnan( v ), true, 'returns expected value' );
4348

4449
v = kernelCos( 4.0, NaN );
45-
t.equal( isnan( v ), true, 'returns NaN' );
50+
t.equal( isnan( v ), true, 'returns expected value' );
4651

4752
v = kernelCos( NaN, NaN );
48-
t.equal( isnan( v ), true, 'returns NaN' );
53+
t.equal( isnan( v ), true, 'returns expected value' );
4954
t.end();
5055
});
5156

@@ -55,7 +60,7 @@ tape( 'the function evaluates the cosine for input values on the interval `[-pi/
5560
var x;
5661
var i;
5762

58-
values = linspace( -PI/4.0, PI/4.0, 1000 );
63+
values = smallRange.x;
5964
for ( i = 0; i < values.length; i++ ) {
6065
x = values[ i ];
6166
out = kernelCos( x, 0.0 );
@@ -72,7 +77,7 @@ tape( 'the function can be used to compute the cosine for input values outside o
7277
var n;
7378
var i;
7479

75-
values = linspace( 40.0*PI/4.0, 200*PI/4.0, 1000 );
80+
values = largePositive.x;
7681
y = new Array( 2 );
7782
for ( i = 0; i < values.length; i++ ) {
7883
x = values[ i ];
@@ -101,7 +106,7 @@ tape( 'the function can be used to compute the cosine for input values outside o
101106
var n;
102107
var i;
103108

104-
values = linspace( -200.0*PI/4.0, -40.0*PI/4.0, 1000 );
109+
values = largeNegative.x;
105110
y = new Array( 2 );
106111
for ( i = 0; i < values.length; i++ ) {
107112
x = values[ i ];

lib/node_modules/@stdlib/math/base/special/kernel-cos/test/test.native.js

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@
2323
var resolve = require( 'path' ).resolve;
2424
var tape = require( 'tape' );
2525
var isnan = require( '@stdlib/math/base/assert/is-nan' );
26-
var linspace = require( '@stdlib/array/base/linspace' );
26+
var abs = require( '@stdlib/math/base/special/abs' );
27+
var EPS = require( '@stdlib/constants/float64/eps' );
2728
var rempio2 = require( '@stdlib/math/base/special/rempio2' );
28-
var PI = require( '@stdlib/constants/float64/pi' );
29-
var cos = require( '@stdlib/math/base/special/cos' );
3029
var tryRequire = require( '@stdlib/utils/try-require' );
3130

3231

@@ -38,6 +37,13 @@ var opts = {
3837
};
3938

4039

40+
// FIXTURES //
41+
42+
var smallRange = require( './fixtures/julia/small_range.json' );
43+
var largePositive = require( './fixtures/julia/large_positive.json' );
44+
var largeNegative = require( './fixtures/julia/large_negative.json' );
45+
46+
4147
// TESTS //
4248

4349
tape( 'main export is a function', opts, function test( t ) {
@@ -48,52 +54,64 @@ tape( 'main export is a function', opts, function test( t ) {
4854

4955
tape( 'the function returns `NaN` if provided `NaN` for either parameter', opts, function test( t ) {
5056
var v = kernelCos( NaN, 0.0 );
51-
t.equal( isnan( v ), true, 'returns NaN' );
57+
t.equal( isnan( v ), true, 'returns expected value' );
5258

5359
v = kernelCos( 4.0, NaN );
54-
t.equal( isnan( v ), true, 'returns NaN' );
60+
t.equal( isnan( v ), true, 'returns expected value' );
5561

5662
v = kernelCos( NaN, NaN );
57-
t.equal( isnan( v ), true, 'returns NaN' );
63+
t.equal( isnan( v ), true, 'returns expected value' );
5864
t.end();
5965
});
6066

6167
tape( 'the function evaluates the cosine for input values on the interval `[-pi/4, pi/4]`', opts, function test( t ) {
68+
var expected;
6269
var values;
6370
var out;
6471
var x;
6572
var i;
6673

67-
values = linspace( -PI/4.0, PI/4.0, 1000 );
74+
values = smallRange.x;
75+
expected = smallRange.expected;
6876
for ( i = 0; i < values.length; i++ ) {
6977
x = values[ i ];
7078
out = kernelCos( x, 0.0 );
71-
t.strictEqual( out, cos( x ), 'returns expected value' );
79+
t.strictEqual( out, expected[ i ], 'returns expected value' );
7280
}
7381
t.end();
7482
});
7583

7684
tape( 'the function can be used to compute the cosine for input values outside of `[-pi/4, pi/4]` after argument reduction via `rempio2` (positive)', opts, function test( t ) {
85+
var expected;
7786
var values;
87+
var delta;
88+
var tol;
7889
var out;
7990
var x;
8091
var y;
8192
var n;
8293
var i;
8394

84-
values = linspace( 40.0*PI/4.0, 200*PI/4.0, 1000 );
95+
values = largePositive.x;
96+
expected = largePositive.expected;
8597
y = new Array( 2 );
8698
for ( i = 0; i < values.length; i++ ) {
8799
x = values[ i ];
88100
n = rempio2( x, y );
89101
switch ( n & 3 ) {
90102
case 0:
91103
out = kernelCos( y[ 0 ], y[ 1 ] );
92-
t.strictEqual( out, cos( x ), 'returns expected value' );
104+
t.strictEqual( out, expected[ i ], 'returns expected value' );
93105
break;
94106
case 2:
95107
out = -kernelCos( y[ 0 ], y[ 1 ] );
96-
t.strictEqual( out, cos( x ), 'returns expected value' );
108+
if ( out === expected[ i ] ) {
109+
t.strictEqual( out, expected[ i ], 'returns expected value' );
110+
} else {
111+
delta = abs( out - expected[ i ] );
112+
tol = EPS * abs( expected[ i ] );
113+
t.ok( delta <= tol, 'within tolerance. x: '+x+'. out: '+out+'. E: '+expected[i]+'. tol: '+tol+'. Δ: '+delta+'.' );
114+
}
97115
break;
98116
default:
99117
break;
@@ -103,26 +121,36 @@ tape( 'the function can be used to compute the cosine for input values outside o
103121
});
104122

105123
tape( 'the function can be used to compute the cosine for input values outside of `[-pi/4, pi/4]` after argument reduction via `rempio2` (negative)', opts, function test( t ) {
124+
var expected;
106125
var values;
126+
var delta;
127+
var tol;
107128
var out;
108129
var x;
109130
var y;
110131
var n;
111132
var i;
112133

113-
values = linspace( -200.0*PI/4.0, -40.0*PI/4.0, 1000 );
134+
values = largeNegative.x;
135+
expected = largeNegative.expected;
114136
y = new Array( 2 );
115137
for ( i = 0; i < values.length; i++ ) {
116138
x = values[ i ];
117139
n = rempio2( x, y );
118140
switch ( n & 3 ) {
119141
case 0:
120142
out = kernelCos( y[ 0 ], y[ 1 ] );
121-
t.strictEqual( out, cos( x ), 'returns expected value' );
143+
t.strictEqual( out, expected[ i ], 'returns expected value' );
122144
break;
123145
case 2:
124146
out = -kernelCos( y[ 0 ], y[ 1 ] );
125-
t.strictEqual( out, cos( x ), 'returns expected value' );
147+
if ( out === expected[ i ] ) {
148+
t.strictEqual( out, expected[ i ], 'returns expected value' );
149+
} else {
150+
delta = abs( out - expected[ i ] );
151+
tol = EPS * abs( expected[ i ] );
152+
t.ok( delta <= tol, 'within tolerance. x: '+x+'. out: '+out+'. E: '+expected[i]+'. tol: '+tol+'. Δ: '+delta+'.' );
153+
}
126154
break;
127155
default:
128156
break;

0 commit comments

Comments
 (0)