Skip to content

Commit c9ec417

Browse files
chore: update test to use ULP-based testing & move hyp2f1NegCEqualBC to its own file
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent cc3d8a1 commit c9ec417

3 files changed

Lines changed: 84 additions & 46 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 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+
*
19+
* ## Notice
20+
*
21+
* The original C code and copyright notice are from the [Cephes Mathematical Library]{@link https://www.netlib.org/cephes/}. The implementation has been modified for JavaScript.
22+
*
23+
* ```text
24+
* (C) Copyright Stephen L. Moshier 1984, 1987, 1992, 2000.
25+
*
26+
* Use, modification and distribution are subject to the
27+
* Cephes Mathematical Library License. (See accompanying file
28+
* LICENSE or copy at https://smath.com/en-US/view/CephesMathLibrary/license)
29+
* ```
30+
*/
31+
32+
'use strict';
33+
34+
// MODULES //
35+
36+
var abs = require( '@stdlib/math/base/special/abs' );
37+
var max = require( '@stdlib/math/base/special/max' );
38+
39+
40+
// MAIN //
41+
42+
/**
43+
* Evaluates 2F1(a, b; b; x) when `b = c` is a negative integer using AMS55 #15.4.2.
44+
*
45+
* @private
46+
* @param {number} a - first parameter
47+
* @param {number} b - second parameter (equals c, a non-positive integer)
48+
* @param {number} x - argument
49+
* @returns {number} function value, or NaN if precision is insufficient
50+
*/
51+
function hyp2f1NegCEqualBC( a, b, x ) {
52+
var collectorMax;
53+
var collector;
54+
var sum;
55+
var k;
56+
57+
collectorMax = 1.0;
58+
collector = 1.0;
59+
sum = 1.0;
60+
61+
if ( !( abs( b ) < 1.0e5 ) ) {
62+
return NaN;
63+
}
64+
65+
for ( k = 1; k <= -b; k++ ) {
66+
collector *= ( a + k - 1.0 ) * x / k;
67+
collectorMax = max( abs( collector ), collectorMax );
68+
sum += collector;
69+
}
70+
71+
if ( 1.0e-16 * ( 1.0 + ( collectorMax / abs( sum ) ) ) > 1.0e-7 ) {
72+
return NaN;
73+
}
74+
75+
return sum;
76+
}
77+
78+
79+
// EXPORTS //
80+
81+
module.exports = hyp2f1NegCEqualBC;

lib/node_modules/@stdlib/math/base/special/hyp2f1/lib/main.js

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ var round = require( '@stdlib/math/base/special/round' );
3939
var gamma = require( '@stdlib/math/base/special/gamma' );
4040
var pow = require( '@stdlib/math/base/special/pow' );
4141
var abs = require( '@stdlib/math/base/special/abs' );
42-
var max = require( '@stdlib/math/base/special/max' );
4342
var isNonPositiveInteger = require( './isnonpositiveinteger.js' );
43+
var hyp2f1NegCEqualBC = require( './hyp2f1negcequalbc.js' );
4444
var isInteger = require( './isinteger.js' );
4545
var hys2f1 = require( './hys2f1.js' );
4646
var hyt2f1 = require( './hyt2f1.js' );
@@ -52,41 +52,6 @@ var config = require( './config.json' );
5252
var ETHRESH = config.ETHRESH;
5353

5454

55-
// FUNCTIONS //
56-
57-
/**
58-
* Evaluates 2F1(a, b; b; x) when `b = c` is a negative integer using AMS55 #15.4.2.
59-
*
60-
* @private
61-
* @param {number} a - first parameter
62-
* @param {number} b - second parameter (equals c, a non-positive integer)
63-
* @param {number} x - argument
64-
* @returns {number} function value, or NaN if precision is insufficient
65-
*/
66-
function hyp2f1NegCEqualBC( a, b, x ) {
67-
var collectorMax;
68-
var collector;
69-
var sum;
70-
var k;
71-
72-
if ( !( abs( b ) < 1.0e5 ) ) {
73-
return NaN;
74-
}
75-
collectorMax = 1.0;
76-
collector = 1.0;
77-
sum = 1.0;
78-
for ( k = 1; k <= -b; k++ ) {
79-
collector *= ( a + k - 1.0 ) * x / k;
80-
collectorMax = max( abs( collector ), collectorMax );
81-
sum += collector;
82-
}
83-
if ( 1.0e-16 * ( 1.0 + ( collectorMax / abs( sum ) ) ) > 1.0e-7 ) {
84-
return NaN;
85-
}
86-
return sum;
87-
}
88-
89-
9055
// MAIN //
9156

9257
/**

lib/node_modules/@stdlib/math/base/special/hyp2f1/test/test.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,17 +257,13 @@ tape( 'the function correctly evaluates the hypergeometric function', function t
257257

258258
for ( i = 0; i < x.length; i++ ) {
259259
v = hyp2f1( a[ i ], b[ i ], c[ i ], x[ i ] );
260-
delta = abs( v - expected[ i ] );
261-
tol = 8.0 * EPS * abs( expected[ i ] );
262-
t.ok( delta <= tol, 'within tolerance. a: ' + a[ i ] + ' b: ' + b[ i ] + ' c: ' + c[ i ] + ' x: ' + x[ i ] + '. Value: ' + v + '. Expected: ' + expected[ i ] + '. Delta: ' + delta + '. Tolerance: ' + tol + '.' );
260+
t.strictEqual( isAlmostSameValue( v, expected[ i ], 12 ), true, 'returns expected value.' );
263261
}
264262
t.end();
265263
});
266264

267265
tape( 'the function correctly evaluates the hypergeometric function', function test( t ) {
268266
var expected;
269-
var delta;
270-
var tol;
271267
var a;
272268
var b;
273269
var c;
@@ -283,17 +279,13 @@ tape( 'the function correctly evaluates the hypergeometric function', function t
283279

284280
for ( i = 0; i < x.length; i++ ) {
285281
v = hyp2f1( a[ i ], b[ i ], c[ i ], x[ i ] );
286-
delta = abs( v - expected[ i ] );
287-
tol = EPS * abs( expected[ i ] );
288-
t.ok( delta <= tol, 'within tolerance. a: ' + a[ i ] + ' b: ' + b[ i ] + ' c: ' + c[ i ] + ' x: ' + x[ i ] + '. Value: ' + v + '. Expected: ' + expected[ i ] + '. Delta: ' + delta + '. Tolerance: ' + tol + '.' );
282+
t.strictEqual( isAlmostSameValue( v, expected[ i ], 1 ), true, 'returns expected value.' );
289283
}
290284
t.end();
291285
});
292286

293287
tape( 'the function correctly evaluates the hypergeometric function', function test( t ) {
294288
var expected;
295-
var delta;
296-
var tol;
297289
var a;
298290
var b;
299291
var c;

0 commit comments

Comments
 (0)