Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// MODULES //

var constantFunction = require( '@stdlib/utils/constant-function' );
var ln = require( '@stdlib/math/base/special/ln' );
var log1p = require( '@stdlib/math/base/special/log1p' );
var pow = require( '@stdlib/math/base/special/pow' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );

Expand Down Expand Up @@ -69,7 +69,7 @@ function factory( k, lambda ) {
if ( isnan( p ) || p < 0.0 || p > 1.0 ) {
return NaN;
}
return lambda * pow( -ln( 1.0 - p ), 1.0/k );
return lambda * pow( -log1p( -p ), 1.0/k );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

// MODULES //

var ln = require( '@stdlib/math/base/special/ln' );
var log1p = require( '@stdlib/math/base/special/log1p' );
var pow = require( '@stdlib/math/base/special/pow' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );

Expand Down Expand Up @@ -79,7 +79,7 @@ function quantile( p, k, lambda ) {
) {
return NaN;
}
return lambda * pow( -ln( 1.0 - p ), 1.0/k );
return lambda * pow( -log1p( -p ), 1.0/k );
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"dependencies": [
"@stdlib/math/base/napi/ternary",
"@stdlib/math/base/assert/is-nan",
"@stdlib/math/base/special/ln",
"@stdlib/math/base/special/log1p",
"@stdlib/math/base/special/pow"
]
},
Expand All @@ -57,7 +57,7 @@
"libpath": [],
"dependencies": [
"@stdlib/math/base/assert/is-nan",
"@stdlib/math/base/special/ln",
"@stdlib/math/base/special/log1p",
"@stdlib/math/base/special/pow"
]
},
Expand All @@ -74,7 +74,7 @@
"libpath": [],
"dependencies": [
"@stdlib/math/base/assert/is-nan",
"@stdlib/math/base/special/ln",
"@stdlib/math/base/special/log1p",
"@stdlib/math/base/special/pow"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#include "stdlib/stats/base/dists/weibull/quantile.h"
#include "stdlib/math/base/assert/is_nan.h"
#include "stdlib/math/base/special/ln.h"
#include "stdlib/math/base/special/log1p.h"
#include "stdlib/math/base/special/pow.h"

/**
Expand All @@ -37,5 +37,5 @@ double stdlib_base_dists_weibull_quantile( const double p, const double k, const
if ( stdlib_base_is_nan( k ) || stdlib_base_is_nan( lambda ) || stdlib_base_is_nan( p ) || k <= 0.0 || lambda <= 0.0 || p < 0.0 || p > 1.0 ) {
return 0.0 / 0.0; // NaN
}
return lambda * stdlib_base_pow( -stdlib_base_ln( 1.0 - p ), 1.0 / k );
return lambda * stdlib_base_pow( -stdlib_base_log1p( -p ), 1.0 / k );
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
Distributions 0.23.8
julia 1.5
JSON 0.21

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 @@ -16,14 +16,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import Distributions: quantile, Weibull
import JSON

"""
gen( p, k, lambda, name )

Generate fixture data and write to file.

The quantile is evaluated in extended precision from the textbook formula `lambda * (-ln(1-p))^(1/k)`, as forming `1-p` in double precision rounds away the low-order bits of `p` (all of them for `p < 2^-53`).

# Arguments

* `p`: input value
Expand All @@ -41,9 +42,8 @@ julia> gen( p, k, lambda, "data.json" );
```
"""
function gen( p, k, lambda, name )
z = Array{Float64}( undef, length(p) );
for i in eachindex(p)
z[ i ] = quantile( Weibull( k[i], lambda[i] ), p[i] );
z = setprecision( BigFloat, 2048 ) do
Float64.( BigFloat.( lambda ) .* ( .-log.( 1 .- BigFloat.( p ) ) ) .^ ( 1 ./ BigFloat.( k ) ) )
end

# Store data to be written to file as a collection:
Expand Down Expand Up @@ -87,3 +87,9 @@ p = rand( 1000 );
lambda = ( rand( 1000 ) .* 20.0 ) .+ 10.0;
k = ( rand( 1000 ) .* 20.0 ) .+ 10.0;
gen( p, k, lambda, "both_large.json" );

# Small `p` (shape parameters are powers of two, so that `1/k` is exact and the test measures the error from `1-p`):
p = exp10.( range( -300.0, stop = -1.0, length = 1000 ) );
lambda = ( rand( 1000 ) .* 10.0 ) .+ 0.1;
k = repeat( [ 1.0, 2.0, 4.0, 8.0 ], 250 );
gen( p, k, lambda, "small_p.json" );

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var factory = require( './../lib/factory.js' );
var largeScale = require( './fixtures/julia/large_scale.json' );
var largeShape = require( './fixtures/julia/large_shape.json' );
var bothLarge = require( './fixtures/julia/both_large.json' );
var smallP = require( './fixtures/julia/small_p.json' );


// TESTS //
Expand Down Expand Up @@ -180,7 +181,7 @@ tape( 'the created function evaluates the quantile for `p` given large `lambda`
for ( i = 0; i < p.length; i++ ) {
quantile = factory( k[i], lambda[i] );
y = quantile( p[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 0 ), true, 'returns expected value' );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 1 ), true, 'returns expected value' );
}
t.end();
});
Expand Down Expand Up @@ -222,7 +223,28 @@ tape( 'the created function evaluates the quantile for `p` given large scale par
for ( i = 0; i < p.length; i++ ) {
quantile = factory( k[i], lambda[i] );
y = quantile( p[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 6 ), true, 'returns expected value' );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 56 ), true, 'returns expected value' );
}
t.end();
});

tape( 'the created function evaluates the quantile for small `p`', function test( t ) {
var expected;
var quantile;
var lambda;
var i;
var k;
var p;
var y;

expected = smallP.expected;
p = smallP.p;
lambda = smallP.lambda;
k = smallP.k;
for ( i = 0; i < p.length; i++ ) {
quantile = factory( k[i], lambda[i] );
y = quantile( p[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 1 ), true, 'returns expected value' );
}
t.end();
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var NINF = require( '@stdlib/constants/float64/ninf' );
var bothLarge = require( './fixtures/julia/both_large.json' );
var largeScale = require( './fixtures/julia/large_scale.json' );
var largeShape = require( './fixtures/julia/large_shape.json' );
var smallP = require( './fixtures/julia/small_p.json' );


// VARIABLES //
Expand Down Expand Up @@ -106,7 +107,7 @@ tape( 'the function evaluates the quantile for `p` given large `k` and `lambda`'
lambda = bothLarge.lambda;
for ( i = 0; i < p.length; i++ ) {
y = quantile( p[ i ], k[ i ], lambda[ i ] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 0 ), true, 'returns expected value' );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 1 ), true, 'returns expected value' );
}
t.end();
});
Expand All @@ -125,7 +126,7 @@ tape( 'the function evaluates the quantile for `p` given large `lambda`', opts,
lambda = largeScale.lambda;
for ( i = 0; i < p.length; i++ ) {
y = quantile( p[ i ], k[ i ], lambda[ i ] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 6 ), true, 'returns expected value' );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 56 ), true, 'returns expected value' );
}
t.end();
});
Expand All @@ -148,3 +149,22 @@ tape( 'the function evaluates the quantile for `p` given large `k`', opts, funct
}
t.end();
});

tape( 'the function evaluates the quantile for small `p`', opts, function test( t ) {
var expected;
var lambda;
var p;
var k;
var y;
var i;

expected = smallP.expected;
p = smallP.p;
lambda = smallP.lambda;
k = smallP.k;
for ( i = 0; i < p.length; i++ ) {
y = quantile( p[ i ], k[ i ], lambda[ i ] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 1 ), true, 'returns expected value' );
}
t.end();
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var quantile = require( './../lib' );
var largeScale = require( './fixtures/julia/large_scale.json' );
var largeShape = require( './fixtures/julia/large_shape.json' );
var bothLarge = require( './fixtures/julia/both_large.json' );
var smallP = require( './fixtures/julia/small_p.json' );


// TESTS //
Expand Down Expand Up @@ -129,7 +130,7 @@ tape( 'the function evaluates the p-th quantile given large parameters `lambda`
k = bothLarge.k;
for ( i = 0; i < p.length; i++ ) {
y = quantile( p[i], k[i], lambda[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 0 ), true, 'returns expected value' );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 1 ), true, 'returns expected value' );
}
t.end();
});
Expand Down Expand Up @@ -167,7 +168,26 @@ tape( 'the function evaluates the p-th quantile given large scale parameter `k`'
k = largeScale.k;
for ( i = 0; i < p.length; i++ ) {
y = quantile( p[i], k[i], lambda[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 6 ), true, 'returns expected value' );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 56 ), true, 'returns expected value' );
}
t.end();
});

tape( 'the function evaluates the p-th quantile for small `p`', function test( t ) {
var expected;
var lambda;
var p;
var k;
var y;
var i;

expected = smallP.expected;
p = smallP.p;
lambda = smallP.lambda;
k = smallP.k;
for ( i = 0; i < p.length; i++ ) {
y = quantile( p[i], k[i], lambda[i] );
t.strictEqual( isAlmostSameValue( y, expected[ i ], 1 ), true, 'returns expected value' );
}
t.end();
});
Loading