Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/node_modules/@stdlib/math/base/special/asec/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
// MODULES //

var acos = require( '@stdlib/math/base/special/acos' );
var atan = require( '@stdlib/math/base/special/atan' );
var sqrt = require( '@stdlib/math/base/special/sqrt' );


// MAIN //
Expand All @@ -32,7 +34,7 @@
* ## Method
*
* ```tex
* \operatorname{asec}(x) = \operatorname{acos}(\frac{1}{x})

Check warning on line 37 in lib/node_modules/@stdlib/math/base/special/asec/lib/main.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Unknown word: "asec"
* ```
*
* @param {number} x - input value
Expand All @@ -51,6 +53,10 @@
* // returns NaN
*/
function asec( x ) {
// Near `x = 1`, `acos( 1/x )` loses the low bits of `1-1/x` to the rounding of `1/x`, and those bits are most of the (small) result. Use `asec(x) = atan( sqrt(x^2-1) ) = atan( sqrt((x-1)*(x+1)) )` instead, where `x-1` is exact for `1 <= x <= 2`:
if ( x >= 1.0 && x <= 2.0 ) {
return atan( sqrt( ( x - 1.0 ) * ( x + 1.0 ) ) );
}
return acos( 1.0 / x );
}

Expand Down
12 changes: 9 additions & 3 deletions lib/node_modules/@stdlib/math/base/special/asec/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
"libpath": [],
"dependencies": [
"@stdlib/math/base/napi/unary",
"@stdlib/math/base/special/acos"
"@stdlib/math/base/special/acos",
"@stdlib/math/base/special/atan",
"@stdlib/math/base/special/sqrt"
]
},
{
Expand All @@ -51,7 +53,9 @@
"libraries": [],
"libpath": [],
"dependencies": [
"@stdlib/math/base/special/acos"
"@stdlib/math/base/special/acos",
"@stdlib/math/base/special/atan",
"@stdlib/math/base/special/sqrt"
]
},
{
Expand All @@ -65,7 +69,9 @@
"libraries": [],
"libpath": [],
"dependencies": [
"@stdlib/math/base/special/acos"
"@stdlib/math/base/special/acos",
"@stdlib/math/base/special/atan",
"@stdlib/math/base/special/sqrt"
]
}
]
Expand Down
6 changes: 6 additions & 0 deletions lib/node_modules/@stdlib/math/base/special/asec/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include "stdlib/math/base/special/asec.h"
#include "stdlib/math/base/special/acos.h"
#include "stdlib/math/base/special/atan.h"
#include "stdlib/math/base/special/sqrt.h"

/**
* Computes the inverse (arc) secant of a double-precision floating-point number.
Expand All @@ -30,5 +32,9 @@
* // returns 0.0
*/
double stdlib_base_asec( const double x ) {
// Near `x = 1`, `acos( 1/x )` loses the low bits of `1-1/x` to the rounding of `1/x`, and those bits are most of the (small) result. Use `asec(x) = atan( sqrt(x^2-1) ) = atan( sqrt((x-1)*(x+1)) )` instead, where `x-1` is exact for `1 <= x <= 2`:
if ( x >= 1.0 && x <= 2.0 ) {
return stdlib_base_atan( stdlib_base_sqrt( ( x - 1.0 ) * ( x + 1.0 ) ) );
}
return stdlib_base_acos( 1.0 / x );
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import JSON

"""
gen( domain, name )

Check failure on line 22 in lib/node_modules/@stdlib/math/base/special/asec/test/fixtures/julia/runner.jl

View workflow job for this annotation

GitHub Actions / Lint Changed Files

wrong indentation type (spaces instead of tabs)

Generate fixture data and write to file.

Expand All @@ -37,7 +37,9 @@
"""
function gen( domain, name )
x = collect( domain );
y = asec.( x );
y = setprecision( BigFloat, 256 ) do
Float64.( asec.( BigFloat.( x ) ) );
end

# Store data to be written to file as a collection:
data = Dict([
Expand Down Expand Up @@ -92,3 +94,8 @@
# Huge positive values:
x = range( 1e300, stop = 1e308, length = 503 );
gen( x, "huge_positive.json" );

# Values close to one (in `Float64`, `asec` is `acos(1/x)` and loses the low bits of `1-1/x`):
x = 1.0 .+ exp10.( range( -15.0, stop = -1.0, length = 1000 ) );
gen( x, "near_one.json" );

17 changes: 17 additions & 0 deletions lib/node_modules/@stdlib/math/base/special/asec/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var mediumNegative = require( './fixtures/julia/medium_negative.json' );
var mediumPositive = require( './fixtures/julia/medium_positive.json' );
var hugeNegative = require( './fixtures/julia/huge_negative.json' );
var hugePositive = require( './fixtures/julia/huge_positive.json' );
var nearOne = require( './fixtures/julia/near_one.json' );


// TESTS //
Expand Down Expand Up @@ -174,6 +175,22 @@ tape( 'the function computes the inverse (arc) secant on the interval `[1e300,1e
t.end();
});

tape( 'the function computes the inverse (arc) secant close to `1`', function test( t ) {
var expected;
var x;
var y;
var i;

x = nearOne.x;
expected = nearOne.expected;

for ( i = 0; i < x.length; i++ ) {
y = asec( x[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 2 ), true, 'returns expected value' );
}
t.end();
});

tape( 'the function returns `NaN` if provided `NaN`', function test( t ) {
var v = asec( NaN );
t.strictEqual( isnan( v ), true, 'returns expected value' );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var mediumNegative = require( './fixtures/julia/medium_negative.json' );
var mediumPositive = require( './fixtures/julia/medium_positive.json' );
var hugeNegative = require( './fixtures/julia/huge_negative.json' );
var hugePositive = require( './fixtures/julia/huge_positive.json' );
var nearOne = require( './fixtures/julia/near_one.json' );


// VARIABLES //
Expand Down Expand Up @@ -183,6 +184,22 @@ tape( 'the function computes the inverse (arc) secant on the interval `[1e300,1e
t.end();
});

tape( 'the function computes the inverse (arc) secant close to `1`', opts, function test( t ) {
var expected;
var x;
var y;
var i;

x = nearOne.x;
expected = nearOne.expected;

for ( i = 0; i < x.length; i++ ) {
y = asec( x[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 2 ), true, 'returns expected value' );
}
t.end();
});

tape( 'the function returns `NaN` if provided `NaN`', opts, function test( t ) {
var v = asec( NaN );
t.strictEqual( isnan( v ), true, 'returns expected value' );
Expand Down
Loading