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
8 changes: 8 additions & 0 deletions lib/node_modules/@stdlib/math/base/special/asech/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
// MODULES //

var acosh = require( '@stdlib/math/base/special/acosh' );
var log1p = require( '@stdlib/math/base/special/log1p' );
var sqrt = require( '@stdlib/math/base/special/sqrt' );


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

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

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Unknown word: "asech"
* ```
*
* @param {number} x - input value
Expand All @@ -51,6 +53,12 @@
* // returns NaN
*/
function asech( x ) {
var d;
if ( x >= 0.5 && x <= 1.0 ) {
// `acosh( 1/x )` loses the low bits of `1/x - 1` to the rounding of `1/x`, which near one is most of the result, so there use `asech(x) = ln( (1+sqrt(1-x^2))/x ) = log1p( ((1-x) + sqrt((1-x)*(1+x)))/x )`, where `1-x` is exact:
d = 1.0 - x;
return log1p( ( d + sqrt( d * ( 1.0 + x ) ) ) / x );
}
return acosh( 1.0 / x );
}

Expand Down
12 changes: 9 additions & 3 deletions lib/node_modules/@stdlib/math/base/special/asech/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/acosh"
"@stdlib/math/base/special/acosh",
"@stdlib/math/base/special/log1p",
"@stdlib/math/base/special/sqrt"
]
},
{
Expand All @@ -51,7 +53,9 @@
"libraries": [],
"libpath": [],
"dependencies": [
"@stdlib/math/base/special/acosh"
"@stdlib/math/base/special/acosh",
"@stdlib/math/base/special/log1p",
"@stdlib/math/base/special/sqrt"
]
},
{
Expand All @@ -65,7 +69,9 @@
"libraries": [],
"libpath": [],
"dependencies": [
"@stdlib/math/base/special/acosh"
"@stdlib/math/base/special/acosh",
"@stdlib/math/base/special/log1p",
"@stdlib/math/base/special/sqrt"
]
}
]
Expand Down
8 changes: 8 additions & 0 deletions lib/node_modules/@stdlib/math/base/special/asech/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include "stdlib/math/base/special/asech.h"
#include "stdlib/math/base/special/acosh.h"
#include "stdlib/math/base/special/log1p.h"
#include "stdlib/math/base/special/sqrt.h"

/**
* Computes the hyperbolic arcsecant of a number.
Expand All @@ -30,5 +32,11 @@
* // returns 0.0
*/
double stdlib_base_asech( const double x ) {
double d;
if ( x >= 0.5 && x <= 1.0 ) {
// `acosh( 1/x )` loses the low bits of `1/x - 1` to the rounding of `1/x`, which near one is most of the result, so there use `asech(x) = ln( (1+sqrt(1-x^2))/x ) = log1p( ((1-x) + sqrt((1-x)*(1+x)))/x )`, where `1-x` is exact:
d = 1.0 - x;
return stdlib_base_log1p( ( d + stdlib_base_sqrt( d * ( 1.0 + x ) ) ) / x );
}
return stdlib_base_acosh( 1.0 / x );
}

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/asech/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 = asech.( x );
y = setprecision( BigFloat, 256 ) do
Float64.( asech.( BigFloat.( x ) ) );
end

# Store data to be written to file as a collection:
data = Dict([
Expand All @@ -64,3 +66,18 @@
# Generate values over the function domain:
x = range( 0.00001, stop = 1.0, length = 2003 );
gen( x, "data.json" );

# Values close to one, evaluated in extended precision (in `Float64`, `asech` is `acosh(1/x)` and loses the low bits of `1/x - 1`):
x = 1.0 .- exp10.( range( -16.0, stop = -1.0, length = 1000 ) );
y = setprecision( BigFloat, 256 ) do
Float64.( asech.( BigFloat.( x ) ) );
end
data = Dict([
("x", x),
("expected", y)
]);
outfile = open( joinpath( dir, "near_one.json" ), "w" );
write( outfile, JSON.json(data) );
write( outfile, "\n" );
close( outfile );

19 changes: 18 additions & 1 deletion lib/node_modules/@stdlib/math/base/special/asech/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ var asech = require( './../lib' );
// FIXTURES //

var data = require( './fixtures/julia/data.json' );
var nearOne = require( './fixtures/julia/near_one.json' );


// TESTS //
Expand All @@ -53,7 +54,23 @@ tape( 'the function computes the hyperbolic arcsecant on the interval (0, 1]', f

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

tape( 'the function computes the hyperbolic arcsecant close to one', 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 = asech( x[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 2 ), true, 'returns expected value' );
}
t.end();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var opts = {
// FIXTURES //

var data = require( './fixtures/julia/data.json' );
var nearOne = require( './fixtures/julia/near_one.json' );


// TESTS //
Expand All @@ -62,7 +63,23 @@ tape( 'the function computes the hyperbolic arcsecant on the interval (0, 1]', o

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

tape( 'the function computes the hyperbolic arcsecant close to one', 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 = asech( x[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 2 ), true, 'returns expected value' );
}
t.end();
});
Expand Down
Loading