|
| 1 | +/** |
| 2 | +* @license Apache-2.0 |
| 3 | +* |
| 4 | +* Copyright (c) 2025 The Stdlib Authors. |
| 5 | +* |
| 6 | +* Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 | +* you may not use this file except in compliance with the License. |
| 8 | +* You may obtain a copy of the License at |
| 9 | +* |
| 10 | +* http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | +* |
| 12 | +* Unless required by applicable law or agreed to in writing, software |
| 13 | +* distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | +* See the License for the specific language governing permissions and |
| 16 | +* limitations under the License. |
| 17 | +*/ |
| 18 | + |
1 | 19 | 'use strict'; |
2 | 20 |
|
| 21 | +// MODULES // |
| 22 | + |
3 | 23 | var resolve = require( 'path' ).resolve; |
4 | 24 | var tape = require( 'tape' ); |
5 | 25 | var tryRequire = require( '@stdlib/utils/try-require' ); |
6 | 26 | var isnan = require( '@stdlib/math/base/assert/is-nan' ); |
7 | 27 | var abs = require( '@stdlib/math/base/special/abs' ); |
| 28 | +var EPS = require( '@stdlib/constants/float64/eps' ); |
| 29 | + |
| 30 | + |
| 31 | +// FIXTURES // |
| 32 | + |
| 33 | +var data = require( './fixtures/julia/data.json' ); |
| 34 | + |
| 35 | + |
| 36 | +// VARIABLES // |
8 | 37 |
|
9 | 38 | var entropy = tryRequire( resolve( __dirname, './../lib/native.js' ) ); |
10 | 39 | var opts = { |
11 | 40 | 'skip': ( entropy instanceof Error ) |
12 | 41 | }; |
13 | 42 |
|
| 43 | + |
| 44 | +// TESTS // |
| 45 | + |
14 | 46 | tape( 'main export is a function', opts, function test( t ) { |
15 | 47 | t.ok( true, __filename ); |
16 | 48 | t.strictEqual( typeof entropy, 'function', 'main export is a function' ); |
17 | 49 | t.end(); |
18 | 50 | }); |
19 | 51 |
|
| 52 | +tape( 'if provided `NaN` for any parameter, the function returns `NaN`', opts, function test( t ) { |
| 53 | + var v = entropy( NaN, 10, 5 ); |
| 54 | + t.equal( isnan( v ), true, 'returns NaN' ); |
| 55 | + |
| 56 | + v = entropy( 20, NaN, 5 ); |
| 57 | + t.equal( isnan( v ), true, 'returns NaN' ); |
| 58 | + |
| 59 | + v = entropy( 20, 10, NaN ); |
| 60 | + t.equal( isnan( v ), true, 'returns NaN' ); |
| 61 | + |
| 62 | + t.end(); |
| 63 | +}); |
| 64 | + |
20 | 65 | tape( 'if provided an `N` which is not a nonnegative integer, the function returns `NaN`', opts, function test( t ) { |
21 | 66 | var v = entropy( -2, 4, 2 ); |
22 | 67 | t.strictEqual( isnan( v ), true, 'returns NaN' ); |
23 | 68 | t.end(); |
24 | 69 | }); |
25 | 70 |
|
26 | | -tape( 'the function returns the entropy', opts, function test( t ) { |
| 71 | +tape( 'the function matches expected results generated by Julia', opts, function test( t ) { |
27 | 72 | var expected; |
28 | 73 | var delta; |
29 | 74 | var tol; |
30 | 75 | var v; |
| 76 | + var N; |
| 77 | + var K; |
| 78 | + var n; |
| 79 | + var i; |
31 | 80 |
|
32 | | - // Case 1: N=2, K=1, n=1 (50/50 chance) |
33 | | - v = entropy( 2, 1, 1 ); |
34 | | - expected = 0.69314718056; |
35 | | - delta = abs( v - expected ); |
36 | | - tol = 1.0e-9; |
37 | | - t.ok( delta < tol, 'within tolerance. v: ' + v + '. expected: ' + expected ); |
| 81 | + for ( i = 0; i < data.expected.length; i++ ) { |
| 82 | + N = data.N[ i ]; |
| 83 | + K = data.K[ i ]; |
| 84 | + n = data.n[ i ]; |
| 85 | + expected = data.expected[ i ]; |
38 | 86 |
|
39 | | - // Case 2: N=16, K=11, n=4 |
40 | | - v = entropy( 16, 11, 4 ); |
41 | | - expected = 1.2156868611027067; // Corrected Value |
42 | | - delta = abs( v - expected ); |
43 | | - tol = 1.0e-9; |
44 | | - t.ok( delta < tol, 'within tolerance. v: ' + v + '. expected: ' + expected ); |
| 87 | + v = entropy( N, K, n ); |
| 88 | + |
| 89 | + delta = abs( v - expected ); |
| 90 | + tol = 50.0 * EPS; |
45 | 91 |
|
| 92 | + t.ok( delta <= tol, 'within tolerance. N: ' + N + '. K: ' + K + '. n: ' + n + '. v: ' + v + '. expected: ' + expected ); |
| 93 | + } |
46 | 94 | t.end(); |
47 | 95 | }); |
0 commit comments