Skip to content

Commit c3aae70

Browse files
committed
Add initial implementation of quantile function
1 parent 4c644c4 commit c3aae70

22 files changed

Lines changed: 1865 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2022 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# Quantile Function
22+
23+
> [Studentized range][studentized-range] distribution [quantile function][quantile-function].
24+
25+
<section class="intro">
26+
27+
</section>
28+
29+
<!-- /.intro -->
30+
31+
<section class="usage">
32+
33+
## Usage
34+
35+
```javascript
36+
var quantile = require( '@stdlib/stats/base/dists/studentized-range/quantile' );
37+
```
38+
39+
#### quantile( p, r, v\[, nranges=1] )
40+
41+
Evaluates the [quantile function][quantile-function] for a [studentized range][studentized-range] distribution with sample size `r` and `v` degrees of freedom. Optionally. Optionally, the number of groups whose maximum range is considered can be specified via the `nranges` parameter.
42+
43+
```javascript
44+
var y = quantile( 0.5, 3.0, 2.0 );
45+
// returns ~0.0644
46+
47+
y = quantile( 0.9, 17.0, 2.0 );
48+
// returns ~0.913
49+
50+
y = quantile( 0.5, 3.0, 2.0, 2 );
51+
// returns ~0.01
52+
```
53+
54+
If provided a probability `p` outside the interval `[0,1]`, the function returns `NaN`.
55+
56+
```javascript
57+
var y = quantile( 1.9, 3.0, 2.0 );
58+
// returns NaN
59+
60+
y = quantile( -0.1, 3.0, 2.0 );
61+
// returns NaN
62+
```
63+
64+
If provided `NaN` as any argument, the function returns `NaN`.
65+
66+
```javascript
67+
var y = quantile( NaN, 2.0, 2.0 );
68+
// returns NaN
69+
70+
y = quantile( 0.0, NaN, 2.0 );
71+
// returns NaN
72+
```
73+
74+
If provided `v < 2` or `r < 2`, the function returns `NaN`.
75+
76+
```javascript
77+
var y = quantile( 0.4, -1.0, 3.0 );
78+
// returns NaN
79+
80+
y = quantile( 0.4, 3.0, 1.5 );
81+
// returns NaN
82+
```
83+
84+
#### quantile.factory( r, v\[, nranges=1] )
85+
86+
Returns a function for evaluating the [quantile function][quantile-function] of an [studentized range][studentized-range] distribution with sample size `r` and `v` degrees of freedom. Optionally, the number of groups whose maximum range is considered can be specified via the `nranges` parameter.
87+
88+
```javascript
89+
var myquantile = quantile.factory( 4.0 );
90+
91+
var y = myquantile( 0.2 );
92+
// returns ~-0.941
93+
94+
y = myquantile( 0.9 );
95+
// returns ~1.533
96+
```
97+
98+
</section>
99+
100+
<!-- /.usage -->
101+
102+
<section class="examples">
103+
104+
## Examples
105+
106+
<!-- eslint no-undef: "error" -->
107+
108+
```javascript
109+
var randu = require( '@stdlib/random/base/randu' );
110+
var quantile = require( '@stdlib/stats/base/dists/studentized-range/quantile' );
111+
112+
var v;
113+
var r;
114+
var p;
115+
var y;
116+
var i;
117+
118+
for ( i = 0; i < 10; i++ ) {
119+
p = randu();
120+
r = ( randu() * 20.0 ) + 2.0;
121+
v = ( randu() * 20.0 ) + 2.0;
122+
y = quantile( p, r, v );
123+
console.log( 'p: %d, r: %d, v: %d, Q(p;r,v): %d', p.toFixed( 4 ), r.toFixed( 4 ), v.toFixed( 4 ), y.toFixed( 4 ) );
124+
}
125+
```
126+
127+
</section>
128+
129+
<!-- /.examples -->
130+
131+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
132+
133+
<section class="related">
134+
135+
</section>
136+
137+
<!-- /.related -->
138+
139+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
140+
141+
<section class="links">
142+
143+
[quantile-function]: https://en.wikipedia.org/wiki/Quantile_function
144+
145+
[studentized-range]: https://en.wikipedia.org/wiki/Studentized_range_distribution
146+
147+
</section>
148+
149+
<!-- /.links -->
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2022 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+
'use strict';
20+
21+
// MODULES //
22+
23+
var bench = require( '@stdlib/bench' );
24+
var randu = require( '@stdlib/random/base/randu' );
25+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
26+
var pkg = require( './../package.json' ).name;
27+
var quantile = require( './../lib' );
28+
29+
30+
// MAIN //
31+
32+
bench( pkg, function benchmark( b ) {
33+
var v;
34+
var r;
35+
var p;
36+
var y;
37+
var i;
38+
39+
b.tic();
40+
for ( i = 0; i < b.iterations; i++ ) {
41+
p = randu();
42+
r = ( randu()*20.0 ) + 2.0;
43+
v = ( randu()*20.0 ) + 2.0;
44+
y = quantile( p, r, v );
45+
if ( isnan( y ) ) {
46+
b.fail( 'should not return NaN' );
47+
}
48+
}
49+
b.toc();
50+
if ( isnan( y ) ) {
51+
b.fail( 'should not return NaN' );
52+
}
53+
b.pass( 'benchmark finished' );
54+
b.end();
55+
});
56+
57+
bench( pkg+':factory', function benchmark( b ) {
58+
var myquantile;
59+
var r;
60+
var p;
61+
var v;
62+
var y;
63+
var i;
64+
65+
v = 5.0;
66+
r = 3.0;
67+
myquantile = quantile.factory( v, r );
68+
69+
b.tic();
70+
for ( i = 0; i < b.iterations; i++ ) {
71+
p = randu();
72+
y = myquantile( p );
73+
if ( isnan( y ) ) {
74+
b.fail( 'should not return NaN' );
75+
}
76+
}
77+
b.toc();
78+
if ( isnan( y ) ) {
79+
b.fail( 'should not return NaN' );
80+
}
81+
b.pass( 'benchmark finished' );
82+
b.end();
83+
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Package: qtukey-benchmarks
2+
Title: Benchmarks
3+
Version: 0.0.0
4+
Authors@R: person("stdlib", "js", role = c("aut","cre"))
5+
Description: Benchmarks.
6+
Depends: R (>=3.4.0)
7+
Imports:
8+
microbenchmark
9+
LazyData: true
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env Rscript
2+
#
3+
# @license Apache-2.0
4+
#
5+
# Copyright (c) 2022 The Stdlib Authors.
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
# Set the precision to 16 digits:
20+
options( digits = 16 );
21+
22+
#' Run benchmarks.
23+
#'
24+
#' @examples
25+
#' main();
26+
main <- function() {
27+
# Define benchmark parameters:
28+
name <- "dist-studentized-range-quantile";
29+
iterations <- 1000L;
30+
repeats <- 3;
31+
32+
#' Print the TAP version.
33+
#'
34+
#' @examples
35+
#' print_version();
36+
print_version <- function() {
37+
cat( "TAP version 13\n" );
38+
}
39+
40+
#' Print the TAP summary.
41+
#'
42+
#' @param total Total number of tests.
43+
#' @param passing Total number of passing tests.
44+
#'
45+
#' @examples
46+
#' print_summary( 3, 3 );
47+
print_summary <- function( total, passing ) {
48+
cat( "#\n" );
49+
cat( paste0( "1..", total, "\n" ) ); # TAP plan
50+
cat( paste0( "# total ", total, "\n" ) );
51+
cat( paste0( "# pass ", passing, "\n" ) );
52+
cat( "#\n" );
53+
cat( "# ok\n" );
54+
}
55+
56+
#' Print benchmark results.
57+
#'
58+
#' @param iterations Number of iterations.
59+
#' @param elapsed Elapsed time in seconds.
60+
#'
61+
#' @examples
62+
#' print_results( 10000L, 0.131009101868 );
63+
print_results <- function( iterations, elapsed ) {
64+
rate <- iterations / elapsed;
65+
cat( " ---\n" );
66+
cat( paste0( " iterations: ", iterations, "\n" ) );
67+
cat( paste0( " elapsed: ", elapsed, "\n" ) );
68+
cat( paste0( " rate: ", rate, "\n" ) );
69+
cat( " ...\n" );
70+
}
71+
72+
#' Run a benchmark.
73+
#'
74+
#' ## Notes
75+
#'
76+
#' * We compute and return a total "elapsed" time, rather than the minimum
77+
#' evaluation time, to match benchmark results in other languages (e.g.,
78+
#' Python).
79+
#'
80+
#'
81+
#' @param iterations Number of Iterations.
82+
#' @return Elapsed time in seconds.
83+
#'
84+
#' @examples
85+
#' elapsed <- benchmark( 10000L );
86+
benchmark <- function( iterations ) {
87+
# Run the benchmarks:
88+
results <- microbenchmark::microbenchmark( qtukey( runif( 1, 0.0, 1.0 ), round( runif( 1, 2.0, 101.0 ) ), runif( 1, 1.0, 20.0 ) ), times = iterations );
89+
90+
# Sum all the raw timing results to get a total "elapsed" time:
91+
elapsed <- sum( results$time );
92+
93+
# Convert the elapsed time from nanoseconds to seconds:
94+
elapsed <- elapsed / 1.0e9;
95+
96+
return( elapsed );
97+
}
98+
99+
print_version();
100+
for ( i in 1:repeats ) {
101+
cat( paste0( "# r::", name, "\n" ) );
102+
elapsed <- benchmark( iterations );
103+
print_results( iterations, elapsed );
104+
cat( paste0( "ok ", i, " benchmark finished", "\n" ) );
105+
}
106+
print_summary( repeats, repeats );
107+
}
108+
109+
main();

0 commit comments

Comments
 (0)