diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/README.md b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/README.md new file mode 100644 index 00000000000..0e591399aeb --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/README.md @@ -0,0 +1,159 @@ + + +# Probability Mass Function + +> [Boltzmann][boltzmann-distribution] distribution probability mass function (PMF). + +
+ +The [probability mass function][pmf] (PMF) for a [boltzmann][boltzmann-distribution] random variable is + +```math +f(x; \lambda, N) = P(X=x; \lambda, N) = \begin{cases} +\frac{{(\exp(-\lambda k))}{(1-\exp(-\lambda))}}{{(1-\exp(-\lambda N))}} & \text{for } k = 0, 1, 2, \ldots, N \\0 & \text{otherwise} +\end{cases} +``` + +where `λ` is the inverse temperature parameter (equal to `1/KbT`) and `N` is the total number of energy states in the system. + +
+ + + +
+ +## Usage + +```javascript +var pmf = require( '@stdlib/stats/base/dists/boltzmann/pmf' ); +``` + +#### pmf( x, λ, N ) + +Evaluates the [probability mass function][pmf] (PMF) for a [boltzmann][boltzmann-distribution] distribution with total number of energy states `N` and inverse temperature parameter `λ`. + +```javascript +var y = pmf( 1, 0.8, 4 ); +// returns ~0.258 + +y = pmf( 2, 0.8, 4 ); +// returns ~0.116 + +y = pmf( 0, 0.8, 4 ); +// returns ~0.574 +``` + +If provided `NaN` as any argument, the function returns `NaN`. + +```javascript +var y = pmf( NaN, 1.5, 5 ); +// returns NaN + +y = pmf( 2, NaN, 5 ); +// returns NaN + +y = pmf( 2, 1.5, NaN ); +// returns NaN +``` + +If provided total number if energy states `N` is not a nonnegative integer, the function returns `NaN`. + +```javascript +var y = pmf( 2, 1.5, 4.5 ); +// returns NaN + +y = pmf( 2, 2.0, -5 ); +// returns NaN +``` + +If provided inverse temperature parameter `λ` is not a positive number, the function returns `NaN`. + +```javascript +var y = pmf( 8, -2.5, 15 ); +// returns NaN +``` + +#### pmf.factory( λ, N ) + +Returns a function for evaluating the [probability mass function][pmf] (PMF) of a [boltzmann][boltzmann-distribution] distribution with total number of energy states `N` and inverse Temperature `λ`. + +```javascript +var mypmf = pmf.factory( 1.4, 8 ); + +var y = mypmf( 3 ); +// returns ~0.011 + +y = mypmf( 1 ); +// returns ~0.186 +``` + +
+ + + +
+ +## Examples + + + +```javascript +var randu = require( '@stdlib/random/base/randu' ); +var round = require( '@stdlib/math/base/special/round' ); +var pmf = require( '@stdlib/stats/base/dists/boltzmann/pmf' ); + +var N; +var lambda; +var x; +var y; +var i; + +for ( i = 0; i < 10; i++ ) { + N = round( randu() * 20 ); + x = round( randu() * N ); + lambda = randu(); + y = pmf( x, lambda, N ); + console.log( 'x: %d, λ: %d, N: %d, P(X = x;λ,N): %d', x, lambda.toFixed( 4 ), N, y.toFixed( 4 ) ); +} +``` + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/benchmark/benchmark.js new file mode 100644 index 00000000000..cdf9407c03e --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/benchmark/benchmark.js @@ -0,0 +1,84 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var round = require( '@stdlib/math/base/special/round' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pkg = require( './../package.json' ).name; +var pmf = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var lambda; + var N; + var x; + var y; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + lambda = randu(); + N = round( randu()*20 ); + x = round( randu()*N ); + y = pmf( x, lambda, N ); + if ( isnan( y ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':factory', function benchmark( b ) { + var lambda; + var mypmf; + var N; + var x; + var i; + var y; + + lambda = randu(); + N = round( randu()*20 ); + mypmf = pmf.factory( lambda, N ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + x = round( randu()*N ); + y = mypmf( x ); + if ( isnan( y ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/docs/repl.txt b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/docs/repl.txt new file mode 100644 index 00000000000..85c99eafad9 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/docs/repl.txt @@ -0,0 +1,80 @@ + +{{alias}}( x, λ, N ) + Evaluates the probability mass function (PMF) for a boltzmann + distribution with total number of energy states `N` and inverse + temperature analysis `λ` at a value `x`. + + If provided `NaN` as any argument, the function returns `NaN`. + + If provided total number of energy states `N`, inverse temperature + parameter `λ` or draws `n` which is not a nonnegative integer, + the function returns `NaN`. + + Parameters + ---------- + x: integer + Input value. + + λ: number + Inverse temperature parameter. + + N: integer + Total number of energy states. + + Returns + ------- + out: number + Evaluated PMF. + + Examples + -------- + > var y = {{alias}}( 1, 0.8, 4 ) + ~0.258 + > y = {{alias}}( 2, 0.8, 4 ) + ~0.116 + > y = {{alias}}( 0, 0.8, 4 ) + ~0.574 + + > y = {{alias}}( NaN, 1.5, 5 ) + NaN + > y = {{alias}}( 2, NaN, 5 ) + NaN + > y = {{alias}}( 2, 1.5, NaN ) + NaN + + > y = {{alias}}( 2, 1.5, 4.5 ) + NaN + > y = {{alias}}( 2, 1.5, -2 ) + NaN + > y = {{alias}}( 2, -1.5, 5 ) + NaN + + +{{alias}}.factory( λ, N ) + Returns a function for evaluating the probability mass function (PMF) of a + boltzmann distribution with total number of energy states `N`, and + inverse temperature parameter `λ`. + + Parameters + ---------- + λ: number + Inverse temperature parameter. + + N: integer + Total number of energy states. + + Returns + ------- + pmf: Function + Probability mass function (PMF). + + Examples + -------- + > var myPMF = {{alias}}.factory( 1.4, 8 ); + > var y = myPMF( 3 ) + ~0.011 + > y = myPMF( 1.0 ) + ~0.186 + + See Also + -------- diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/docs/types/index.d.ts new file mode 100644 index 00000000000..93d0a5d8869 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/docs/types/index.d.ts @@ -0,0 +1,130 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// TypeScript Version: 4.1 + +/** +* Evaluates the probability mass function (PMF) for a boltzmann distribution. +* +* @param x - input value +* @returns evaluated PMF +*/ +type Unary = ( x: number ) => number; + +/** +* Interface for the probability mass function (PMF) of a boltzmann distribution. +*/ +interface PMF { + /** + * Evaluates the probability mass function (PMF) for a boltzmann distribution with total number of energy states `N`, and inverse temperature parameter `λ`. + * + * ## Notes + * + * - If provided a total number of energy states `N` and inverse temperature parameter `λ` which is not a nonnegative integer, the function returns `NaN`. + * + * @param x - input value + * @param N - total number of energy states + * @param lambda - inverse temperature parameter + * @returns evaluated PMF + * + * @example + * var y = pmf( 1, 8, 4 ); + * // returns ~0.257 + * + * @example + * var y = pmf( 2, 8, 4 ); + * // returns ~0.115 + * + * @example + * var y = pmf( 0, 8, 4 ); + * // returns ~0.574 + * + * @example + * var y = pmf( 5, 8, 4 ); + * // returns 0.0 + * + * @example + * var y = pmf( NaN, 1.5, 5 ); + * // returns NaN + * + * @example + * var y = pmf( 2, NaN, 5 ); + * // returns NaN + * + * @example + * var y = pmf( 2, 1.5, NaN ); + * // returns NaN + * + * @example + * var y = pmf( 2, 1.5, 4.5 ); + * // returns NaN + * + * @example + * var y = pmf( 2, 1.5, -5 ); + * // returns NaN + * + * @example + * var y = pmf( 2, -1.5, 5 ); + * // returns NaN + * + * @example + * var y = pmf( 5.2, 10, 5 ); + * // returns NaN + */ + ( x: number, lambda: number, N: number ): number; + + /** + * Returns a function for evaluating the probability mass function (PMF) for a boltzmann distribution with total number of energy states `N`, and inverse temperature parameter `λ`. + * + * @param N - total number of energy states + * @param lambda - inverse temperature parameter + * @returns PMF + * + * @example + * var mypmf = pmf.factory( 1.4, 8 ); + * var y = mypmf( 3 ); + * // returns ~0.011 + * + * y = mypmf( 1 ); + * // returns ~0.185 + */ + factory( N: number, lambda: number ): Unary; +} + +/** +* Boltzmann distribution probability mass function (PMF). +* +* @param x - input value +* @param N - total states of energy +* @param lambda - inverse temperature parameter +* @returns evaluated PMF +* +* @example +* var mypmf = pmf.factory( 1.2, 10 ); +* y = mypmf( 4 ); +* // returns ~0.0.57 +* +* y = mypmf( 1 ); +* // returns ~0.2104 +*/ +declare var pmf: PMF; + + +// EXPORTS // + +export = pmf; diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/docs/types/test.ts b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/docs/types/test.ts new file mode 100644 index 00000000000..ae2881fb3f9 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/docs/types/test.ts @@ -0,0 +1,119 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import pmf = require( './index' ); + + +// TESTS // + +// The function returns a number... +{ + pmf( 2, 10, 4 ); // $ExpectType number + pmf( 1, 10, 8 ); // $ExpectType number +} + +// The compiler throws an error if the function is provided values other than four numbers... +{ + pmf( true, 10, 6 ); // $ExpectError + pmf( false, 10, 4 ); // $ExpectError + pmf( '5', 10, 2 ); // $ExpectError + pmf( [], 10, 2 ); // $ExpectError + pmf( {}, 10, 4 ); // $ExpectError + pmf( ( x: number ): number => x, 2, 4 ); // $ExpectError + + pmf( 9, true, 12 ); // $ExpectError + pmf( 9, false, 12 ); // $ExpectError + pmf( 5, '5', 10 ); // $ExpectError + pmf( 8, [], 16 ); // $ExpectError + pmf( 9, {}, 18 ); // $ExpectError + pmf( 8, ( x: number ): number => x, 16 ); // $ExpectError + + pmf( 9, 5, true ); // $ExpectError + pmf( 9, 5, false ); // $ExpectError + pmf( 5, 2, '5' ); // $ExpectError + pmf( 8, 4, [] ); // $ExpectError + pmf( 9, 4, {} ); // $ExpectError + pmf( 8, 5, ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + pmf(); // $ExpectError + pmf( 2 ); // $ExpectError + pmf( 2, 10 ); // $ExpectError + pmf( 2, 10, 4, 1, 5 ); // $ExpectError +} + +// Attached to main export is a `factory` method which returns a function... +{ + pmf.factory( 13, 5 ); // $ExpectType Unary +} + +// The `factory` method returns a function which returns a number... +{ + const fcn = pmf.factory( 13, 5 ); + fcn( 2 ); // $ExpectType number +} + +// The compiler throws an error if the function returned by the `factory` method is provided invalid arguments... +{ + const fcn = pmf.factory( 13, 5 ); + fcn( true ); // $ExpectError + fcn( false ); // $ExpectError + fcn( '5' ); // $ExpectError + fcn( [] ); // $ExpectError + fcn( {} ); // $ExpectError + fcn( ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function returned by the `factory` method is provided an unsupported number of arguments... +{ + const fcn = pmf.factory( 13, 5 ); + fcn(); // $ExpectError + fcn( 2, 0 ); // $ExpectError + fcn( 2, 0, 1 ); // $ExpectError +} + +// The compiler throws an error if the `factory` method is provided values other than three numbers.. +{ + pmf.factory( true, 3 ); // $ExpectError + pmf.factory( false, 3 ); // $ExpectError + pmf.factory( '5', 1 ); // $ExpectError + pmf.factory( [], 1 ); // $ExpectError + pmf.factory( {}, 2 ); // $ExpectError + pmf.factory( ( x: number ): number => x, 2 ); // $ExpectError + + pmf.factory( 9, true ); // $ExpectError + pmf.factory( 9, false ); // $ExpectError + pmf.factory( 5, '5' ); // $ExpectError + pmf.factory( 8, [] ); // $ExpectError + pmf.factory( 9, {} ); // $ExpectError + pmf.factory( 8, ( x: number ): number => x ); // $ExpectError + + pmf.factory( [], true ); // $ExpectError + pmf.factory( {}, false ); // $ExpectError + pmf.factory( false, '5' ); // $ExpectError + pmf.factory( {}, [] ); // $ExpectError + pmf.factory( '5', ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the `factory` method is provided an unsupported number of arguments... +{ + pmf.factory( 10 ); // $ExpectError + pmf.factory( 10, 4, 3, 7 ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/example/index.js b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/example/index.js new file mode 100644 index 00000000000..abf6198e399 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/example/index.js @@ -0,0 +1,37 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var randu = require( '@stdlib/random/base/randu' ); +var round = require( '@stdlib/math/base/special/round' ); +var pmf = require( './../lib' ); + +var i; +var N; +var lambda; +var x; +var y; + +for ( i = 0; i < 10; i++ ) { + lambda = randu(); + N = round( randu() * 20.0 ); + x = round( randu() * N ); + y = pmf( x, lambda, N ); + console.log( 'x: %d, λ: %d, N: %d, P(X=x;λ,N): %d', x, lambda.toFixed( 4 ), N, y.toFixed( 4 ) ); +} diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/lib/factory.js new file mode 100644 index 00000000000..fa89efe4afc --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/lib/factory.js @@ -0,0 +1,89 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var isNonNegativeInteger = require( '@stdlib/math/base/assert/is-nonnegative-integer' ); +var isNonNegativeFinite = require( '@stdlib/math/base/assert/is-nonnegative-finite' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var constantFunction = require( '@stdlib/utils/constant-function' ); +var exp = require( '@stdlib/math/base/special/exp' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); + + +// MAIN // + +/** +* Returns a function for evaluating the probability mass function (PMF) for a Boltzmann distribution with total number of energy states `N`, and the inverse temperature `lambda`. +* +* @param {PositiveNumber} lambda - Inverse Temperature +* @param {NonNegativeInteger} N - Total Number of energy states +* @returns {Function} PMF +* +* @example +* var mypmf = factory( 1.2, 10 ); +* var y = mypmf( 4 ); +* // returns ~0.0058 +* +* y = mypmf( 1 ); +* // returns ~0.2105 +*/ +function factory( lambda, N ) { + if ( + isnan( N ) || + isnan( lambda ) || + !isNonNegativeInteger( N ) || + !isNonNegativeFinite( lambda ) || + N === PINF || + lambda === PINF + ) { + return constantFunction( NaN ); + } + + return pmf; + + /** + * Evaluates the probability mass function (PMF) for a Boltzmann distribution. + * + * @private + * @param {number} x - input value + * @returns {Probability} evaluated PMF + */ + function pmf( x ) { + var fact; + + if ( isnan( x ) ) { + return NaN; + } + if ( + isNonNegativeInteger( x ) && + x < N + ) { + fact = ( 1 - exp( -lambda ) ) / ( 1 - exp( -lambda * N ) ); + return fact * exp( -lambda * x ); + } + return 0.0; + } +} + + +// EXPORTS // + +module.exports = factory; diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/lib/index.js b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/lib/index.js new file mode 100644 index 00000000000..49d75e3b72e --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/lib/index.js @@ -0,0 +1,60 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Boltzmann distribution probability mass function (PMF). +* +* @module @stdlib/stats/base/dists/boltzmann/pmf +* +* @example +* var pmf = require( '@stdlib/stats/base/dists/boltzmann/pmf' ); +* +* var y = pmf( 1, 0.8, 4 ); +* // returns ~0.257 +* +* y = pmf( 2, 0.8, 4 ); +* // returns ~0.115 +* +* y = pmf( 0, 0.8, 4 ); +* // returns ~0.574 +* +* var mypmf = pmf.factory( 1.5, 5 ); +* y = mypmf( 4.0 ); +* // returns ~0.0019 +* +* y = mypmf( 1.0 ); +* // returns ~0.173 +*/ + +// MODULES // + +var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); +var main = require( './main.js' ); +var factory = require( './factory.js' ); + + +// MAIN // + +setReadOnly( main, 'factory', factory ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/lib/main.js new file mode 100644 index 00000000000..4d9c5dd3a55 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/lib/main.js @@ -0,0 +1,105 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var isNonNegativeInteger = require( '@stdlib/math/base/assert/is-nonnegative-integer' ); +var isNonNegativeFinite = require( '@stdlib/math/base/assert/is-nonnegative-finite' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var exp = require( '@stdlib/math/base/special/exp' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); + + +// MAIN // + +/** +* Returns a function for evaluating the probability mass function (PMF) for a Boltzmann distribution with total number of energy states `N`, and the inverse temperature `lambda`. +* +* @param {NonNegativeInteger} x - Input value of energy +* @param {PositiveNumber} lambda - Inverse Temperature +* @param {NonNegativeInteger} N - Total Number of energy states +* @returns {Function} PMF +* +* @example +* var y = pmf( 1, 0.8, 4 ); +* // returns ~0.258 +* +* @example +* y = pmf( 2, 0.8, 4 ); +* // returns ~0.116 +* +* @example +* y = pmf( 0, 0.8, 4 ); +* // returns ~0.574 +* +* @example +* var y = pmf( NaN, 0.5, 5 ); +* // returns NaN +* +* @example +* var y = pmf( 2, NaN, 5 ); +* // returns NaN +* +* @example +* var y = pmf( 2, 0.8, NaN ); +* // returns NaN +* +* @example +* var y = pmf( 2.0, -10.5, 5 ); +* // returns NaN +* +* @example +* var y = pmf( 2.0, 5, 1.5 ); +* // returns NaN +* +* @example +* var y = pmf( 6.0, 0.8, 5 ) +* // return 0.0 +* +*/ +function pmf( x, lambda, N ) { + var fact; + + if ( + isnan( x ) || + isnan( N ) || + isnan( lambda ) || + !isNonNegativeInteger( N ) || + !isNonNegativeInteger( x ) || + !isNonNegativeFinite( lambda ) || + N === PINF || + lambda === PINF + ) { + return NaN; + } + if ( + isNonNegativeInteger( x ) && + x < N + ) { + fact = ( 1 - exp( -lambda ) ) / ( 1 - exp( -lambda * N ) ); + return fact * exp( -lambda * x ); + } + return 0.0; +} + + +// EXPORTS // + +module.exports = pmf; diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/package.json b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/package.json new file mode 100644 index 00000000000..be27a77e12b --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/package.json @@ -0,0 +1,64 @@ +{ + "name": "@stdlib/stats/base/dists/boltzmann/pmf", + "version": "0.0.0", + "description": "Boltzmann distribution probability mass function (PMF).", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdmath", + "statistics", + "stats", + "distribution", + "dist", + "probability", + "pmf", + "hypergeometric", + "univariate", + "discrete" + ] + } \ No newline at end of file diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/fixtures/julia/REQUIRE b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/fixtures/julia/REQUIRE new file mode 100644 index 00000000000..b95eaf528e9 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/fixtures/julia/REQUIRE @@ -0,0 +1,3 @@ +Distributions 0.23.8 +julia 1.5 +JSON 0.21 \ No newline at end of file diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/fixtures/julia/data.json b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/fixtures/julia/data.json new file mode 100644 index 00000000000..4bedce412a1 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/fixtures/julia/data.json @@ -0,0 +1,210 @@ +{ + "expected": [ + 1.6894024658203856e-08, + 0.0017111735253480995, + 4.335124169281193e-06, + 1.4137977957263547e-08, + 9.297737679321286e-07, + 1.4340917335819795e-08, + 1.195748460493818e-10, + 6.561413624202478e-14, + 2.516786068799857e-06, + 2.799398817837934e-11, + 1.0572291019068076e-05, + 3.77023451376494e-09, + 0.222036849409128, + 0.19743936971721374, + 7.567022726893674e-12, + 4.068498556625846e-08, + 1.388323939572844e-12, + 1.8104201808034692e-07, + 8.762739789129443e-14, + 0.1295631741766526, + 0.0006401229790481351, + 9.708689970886001e-08, + 4.7832281543773015e-05, + 0.00012297924148380054, + 3.6658796729520696e-06, + 1.0811991791156922e-09, + 6.034361062893161e-08, + 0.0053704747063018695, + 0.0032582790209853283, + 4.573380515881846e-11, + 0.13093186067155696, + 0.09844632997256281, + 9.556070157676168e-10, + 3.547489846106477e-11, + 2.599529476727121e-05, + 0.006153547432807735, + 1.8230372131433778e-06, + 0.23523369402522293, + 8.785402815409199e-10, + 2.7886419606076006e-09, + 1.2258706960139622e-08, + 8.394338901630111e-10, + 8.423218070966707e-13, + 8.609172869784758e-06, + 8.58541500699885e-08, + 0.23487252294206842, + 1.4931141842151473e-11, + 3.004761984595269e-06, + 0.0302949574244473, + 2.986606901465607e-13 + ], + "lambda": [ + 1.6065861904183274, + 3.1636935985364647, + 1.338283136043986, + 3.003922854186611, + 2.297058002327272, + 1.3666011872343966, + 3.258266384852774, + 3.368883395896117, + 3.212863637874012, + 1.856084052053615, + 2.8494133123340486, + 1.0537473863751488, + 1.1011748620815691, + 1.3066035816802408, + 2.5526143902162364, + 3.396669734783293, + 1.9391168932760494, + 0.8306819661484934, + 3.0014690415597554, + 1.8775818253402554, + 0.7456174750318285, + 2.679431776143072, + 1.3797029876026845, + 1.0731301365181418, + 3.117794612454915, + 1.3564918752521802, + 1.6407750441731193, + 2.5737636487474815, + 2.8329577666186925, + 2.969435839121422, + 1.864733566891929, + 2.20092192586656, + 1.872892581990154, + 1.7043889451216478, + 2.0849701979936484, + 1.1810118768163949, + 3.294301808399455, + 0.9743654808997182, + 3.470192347424726, + 2.4509442847235774, + 3.0279001339152964, + 3.477822024417545, + 3.0839729278256245, + 2.901544435512654, + 3.2461831398793413, + 0.9765177687620732, + 3.11024465869721, + 3.1680791930398673, + 3.465001607719712, + 2.8781586784884143 + ], + "N": [ + 13, + 9, + 14, + 7, + 10, + 17, + 8, + 10, + 12, + 16, + 11, + 20, + 7, + 10, + 20, + 11, + 17, + 19, + 17, + 7, + 20, + 17, + 17, + 18, + 13, + 19, + 11, + 8, + 8, + 9, + 12, + 13, + 19, + 16, + 8, + 15, + 13, + 7, + 16, + 20, + 11, + 17, + 11, + 5, + 6, + 8, + 11, + 5, + 18, + 14 + ], + "x": [ + 11, + 2, + 9, + 6, + 6, + 13, + 7, + 9, + 4, + 13, + 4, + 18, + 1, + 1, + 10, + 5, + 14, + 18, + 10, + 1, + 9, + 6, + 7, + 8, + 4, + 15, + 10, + 2, + 2, + 8, + 1, + 1, + 11, + 14, + 5, + 4, + 4, + 1, + 6, + 8, + 6, + 6, + 9, + 4, + 5, + 1, + 8, + 4, + 1, + 10 + ] +} \ No newline at end of file diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/fixtures/julia/runner.jl b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/fixtures/julia/runner.jl new file mode 100644 index 00000000000..f78eb2f2393 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/fixtures/julia/runner.jl @@ -0,0 +1,76 @@ +#!/usr/bin/env julia +# +# @license Apache-2.0 +# +# Copyright (c) 2024 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import Distributions: pmf, Boltzmann +import JSON + +""" + gen( x, λ, N, name ) + +Generate fixture data and write to file. + +# Arguments + +* `x`: input value of energy +* `N`: ptotal number of energy states +* `λ`: Inverse Temperature parameter +* `name::AbstractString`: output filename + +# Examples + +``` julia +julia> lambda = round.( ( rand( 100 ) ) .+ 20 ); +julia> N = round.( rand( 1000 ) .* 10 ); +julia> x = round.( rand( 1000 ) .* N ); +julia> gen( x, N, K, n, "data.json" ); +``` +""" +function gen( x, lambda, N, name ) + z = Array{Float64}( undef, length(x) ); + for i in eachindex(x) + z[ i ] = pdf( Hypergeometric( lambda[i], N[i] ), x[i] ); + end + + # Store data to be written to file as a collection: + data = Dict([ + ("x", x), + ("lambda", lambda), + ("N", N), + ("expected", z) + ]); + + # Based on the script directory, create an output filepath: + filepath = joinpath( dir, name ); + + # Write the data to the output filepath as JSON: + outfile = open( filepath, "w" ); + write( outfile, JSON.json(data) ); + close( outfile ); +end + +# Get the filename: +file = @__FILE__; + +# Extract the directory in which this file resides: +dir = dirname( file ); + +# Random: +N = round.( ( rand( 100 ) ) .+ 50 ); +K = round.( rand( 1000 ) .* 10 ); +x = round.( rand( 1000 ) .* N ); +gen( x, N, K, n, "data.json" ); \ No newline at end of file diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/test.factory.js b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/test.factory.js new file mode 100644 index 00000000000..9d6594bcec7 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/test.factory.js @@ -0,0 +1,157 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var abs = require( '@stdlib/math/base/special/abs' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); +var EPS = require( '@stdlib/constants/float64/eps' ); +var factory = require( './../lib/factory.js' ); + + +// FIXTURES // + +var data = require( './fixtures/julia/data.json' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof factory, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a function', function test( t ) { + var pmf = factory( 1.5, 10 ); + t.equal( typeof pmf, 'function', 'returns a function' ); + t.end(); +}); + +tape( 'if provided `NaN` for any parameter, the created function returns `NaN`', function test( t ) { + var pmf; + var y; + + pmf = factory( 1.5, 10 ); + y = pmf( NaN ); + t.equal( isnan( y ), true, 'returns NaN' ); + + pmf = factory( NaN, 1.5 ); + y = pmf( 0 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + pmf = factory( NaN, NaN ); + y = pmf( 0 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + pmf = factory( NaN, NaN ); + y = pmf( NaN ); + t.equal( isnan( y ), true, 'returns NaN' ); + + t.end(); +}); + +tape( 'if provided valid parameters, the function returns a function which returns `0` when provided an integer `x` greater than `N`', function test( t ) { + var pmf; + var y; + + pmf = factory( 1.5, 10 ); + + y = pmf( 12.0 ); + t.equal( y, 0.0, 'returns 0' ); + + y = pmf( 11.0 ); + t.equal( y, 0.0, 'returns 0' ); + + t.end(); +}); + +tape( 'if provided an `N` which is not a nonnegative integer, the created function always returns `NaN`', function test( t ) { + var pmf; + var y; + + pmf = factory( 2.5, 10.5 ); + + y = pmf( 2.0 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + y = pmf( 0.0 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + pmf = factory( 1.5, -10 ); + y = pmf( 2.0 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + pmf = factory( 1.5, PINF ); + y = pmf( 2.0 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + t.end(); +}); + +tape( 'if provided a `λ` which is not a nonnegative integer, the created function always returns `NaN`', function test( t ) { + var pmf; + var y; + + pmf = factory( -2.5, 10 ); + + y = pmf( 2.0 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + y = pmf( 0.0 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + pmf = factory( PINF, 10 ); + y = pmf( 2.0 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + t.end(); +}); + +tape( 'the created function evaluates the pmf for `x`', function test( t ) { + var expected; + var lambda; + var delta; + var pmf; + var tol; + var i; + var N; + var x; + var y; + + expected = data.expected; + x = data.x; + N = data.N; + lambda = data.lambda; + for ( i = 0; i < x.length; i++ ) { + pmf = factory( lambda[i], N[i] ); + y = pmf( x[i] ); + if ( y === expected[i] ) { + t.equal( y, expected[i], 'x: '+x[i]+', lambda: '+lambda[i]+', N: '+N[i]+', y: '+y+', expected: '+expected[i] ); + } else { + delta = abs( y - expected[ i ] ); + tol = 1040.0 * EPS * abs( expected[ i ] ); + t.ok( delta <= tol, 'within tolerance. x: '+x[i]+'. lambda: '+lambda[i]+'. N: '+N[i]+'. y: '+y+'. E: '+expected[ i ]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/test.js b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/test.js new file mode 100644 index 00000000000..bbf5e7fc9af --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/test.js @@ -0,0 +1,38 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var pmf = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof pmf, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'attached to the main export is a factory method for generating `pmf` functions', function test( t ) { + t.equal( typeof pmf.factory, 'function', 'exports a factory method' ); + t.end(); +}); diff --git a/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/test.pmf.js b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/test.pmf.js new file mode 100644 index 00000000000..e335047efb3 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/boltzmann/pmf/test/test.pmf.js @@ -0,0 +1,122 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var abs = require( '@stdlib/math/base/special/abs' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); +var EPS = require( '@stdlib/constants/float64/eps' ); +var pmf = require( './../lib' ); + + +// FIXTURES // + +var data = require( './fixtures/julia/data.json' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof pmf, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'if provided `NaN` for any parameter, the function returns `NaN`', function test( t ) { + var y = pmf( NaN, 1.5, 10 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + y = pmf( 3, NaN, 10 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + y = pmf( 3, 1.5, NaN ); + t.equal( isnan( y ), true, 'returns NaN' ); + + t.end(); +}); + +tape( 'if provided an integer `x` greater than `N`, the function returns `0` (provided all parameters are valid)', function test( t ) { + var y = pmf( 12, 1.2, 10 ); + t.equal( y, 0.0, 'returns 0' ); + + y = pmf( 100, 1.2, 10 ); + t.equal( y, 0.0, 'returns 0' ); + + t.end(); +}); + +tape( 'if provided an `N` which is not a nonnegative integer, the function returns `NaN`', function test( t ) { + var y; + + y = pmf( 2, 3.5, -10 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + y = pmf( 2, 2.5, 10.5 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + y = pmf( 2, 2.5, PINF ); + t.equal( isnan( y ), true, 'returns NaN' ); + + t.end(); +}); + +tape( 'if provided a `λ` which is not a nonnegative integer, the function returns `NaN`', function test( t ) { + var y; + + y = pmf( 2, -3.5, 10 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + y = pmf( 2, -2, 10 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + y = pmf( 0, PINF, 10 ); + t.equal( isnan( y ), true, 'returns NaN' ); + + t.end(); +}); + +tape( 'the function evaluates the pmf for `x`', function test( t ) { + var expected; + var lambda; + var delta; + var tol; + var x; + var N; + var y; + var i; + + expected = data.expected; + x = data.x; + lambda = data.lambda; + N = data.N; + for ( i = 0; i < x.length; i++ ) { + y = pmf( x[i], lambda[i], N[i] ); + if ( y === expected[i] ) { + t.equal( y, expected[i], 'x: '+x[i]+', lambda: '+lambda[i]+', N: '+N[i]+', y: '+y+', expected: '+expected[i] ); + } else { + delta = abs( y - expected[ i ] ); + tol = 1040.0 * EPS * abs( expected[ i ] ); + t.ok( delta <= tol, 'within tolerance. x: '+x[i]+'. lambda: '+lambda[i]+'. N: '+N[i]+'. y: '+y+'. E: '+expected[ i ]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +});