/* harmony default export */

/* harmony import */

/*#__PURE__*/

/**
	* Returns a uniformly distributed pseudorandom number with minimum support `a` and maximum support `b`.
	*
	* @private
	* @param {number} a - minimum support (inclusive)
	* @param {number} b - maximum support (exclusive)
	* @returns {number} pseudorandom number
	*
	* @example
	* var v = uniform2( 0.0, 1.0 );
	* // returns <number>
	*
	* @example
	* var v = uniform2( 1.0, 0.0 );
	* // returns NaN
	*/

/**
	* Returns a uniformly distributed pseudorandom number with minimum support `a` and maximum support `b`.
	*
	* @private
	* @returns {number} pseudorandom number
	*
	* @example
	* var v = uniform1();
	* // returns <number>
	*/

/**
	* Returns the PRNG seed length.
	*
	* @private
	* @returns {PositiveInteger} seed length
	*/

/**
	* Returns the PRNG seed.
	*
	* @private
	* @returns {PRNGSeedMT19937} seed
	*/

/**
	* Returns the PRNG state length.
	*
	* @private
	* @returns {PositiveInteger} state length
	*/

/**
	* Returns the PRNG state size (in bytes).
	*
	* @private
	* @returns {PositiveInteger} state size (in bytes)
	*/

/**
	* Returns the current pseudorandom number generator state.
	*
	* @private
	* @returns {PRNGStateMT19937} current state
	*/

/**
	* Samples elements from a population.
	*
	* @private
	* @param {Options} [options] - function options
	* @param {NonNegativeInteger} [options.size] - sample size
	* @param {boolean} [options.replace=true] - boolean indicating whether to sample with replacement
	* @param {boolean} [options.mutate=false] - boolean indicating whether to mutate the `pool` when sampling without replacement
	* @throws {TypeError} options argument must be an object
	* @throws {TypeError} must provide valid options
	* @throws {RangeError} `size` option must be less than or equal to the population when the `replace` option is `false`
	* @returns {Array} sample
	*/

/**
	* Samples elements from an array-like object.
	*
	* @private
	* @param {ArrayLike} x - array-like object from which to sample elements
	* @param {Options} [options] - function options
	* @param {NonNegativeInteger} [options.size] - sample size
	* @param {ProbabilityArray} [options.probs] - element probabilities
	* @param {boolean} [options.replace=true] - boolean indicating whether to sample with replacement
	* @throws {TypeError} first argument must be array-like
	* @throws {TypeError} options argument must be an object
	* @throws {TypeError} must provide valid options
	* @throws {RangeError} `size` option must be less than or equal to the length of `x` when the `replace` option is `false`
	* @returns {Array} sample
	*/

/**
	* Serializes the pseudorandom number generator as a JSON object.
	*
	* ## Notes
	*
	* -   `JSON.stringify()` implicitly calls this method when stringifying a PRNG.
	*
	* @private
	* @returns {Object} JSON representation
	*/

/**
	* Sets the pseudorandom number generator state.
	*
	* @private
	* @param {PRNGStateMT19937} s - generator state
	* @throws {Error} must provide a valid state
	*/

/**
* @license Apache-2.0
*
* Copyright (c) 2018 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.
*/

/**
* Compute the absolute difference.
*
* @module @stdlib/math/base/utils/absolute-difference
*
* @example
* var diff = require( '@stdlib/math/base/utils/absolute-difference' );
*
* var d = diff( 2.0, 5.0 );
* // returns 3.0
*
* d = diff( -1.0, 3.14 );
* // returns ~4.14
*
* d = diff( 10.1, -2.05 );
* // returns ~12.15
*
* d = diff( -0.0, 0.0 );
* // returns +0.0
*
* d = diff( NaN, 5.0 );
* // returns NaN
*
* d = diff( Infinity, -Infinity  );
* // returns Infinity
*
* d = diff( Infinity, Infinity  );
* // returns NaN
*/

/**
* Computes the absolute difference.
*
* @param {number} x - first number
* @param {number} y - second number
* @returns {number} absolute difference
*
* @example
* var d = absoluteDifference( 2.0, 5.0 );
* // returns 3.0
*
* @example
* var d = absoluteDifference( -1.0, 3.14 );
* // returns ~4.14
*
* @example
* var d = absoluteDifference( 10.1, -2.05 );
* // returns ~12.15
*
* @example
* var d = absoluteDifference( -0.0, 0.0 );
* // returns +0.0
*
* @example
* var d = absoluteDifference( NaN, 5.0 );
* // returns NaN
*
* @example
* var d = absoluteDifference( Infinity, -Infinity  );
* // returns Infinity
*
* @example
* var d = absoluteDifference( Infinity, Infinity  );
* // returns NaN
*/

/**
* Returns a function to sample elements from an array-like object.
*
* @param {ArrayLike} [pool] - array-like object from which to sample
* @param {Options} [options] - function options
* @param {PositiveInteger} [options.seed] - integer-valued seed
* @param {NonNegativeInteger} [options.size] - sample size
* @param {boolean} [options.replace=true] - boolean indicating whether to sample with replacement
* @param {boolean} [options.mutate=false] - boolean indicating whether to mutate the `pool` when sampling without replacement
* @throws {TypeError} `pool` must be an array-like object
* @throws {TypeError} options argument must be an object
* @throws {TypeError} must provide valid options
* @returns {Function} function to sample elements from an array-like object
*
* @example
* var sample = factory({
*     'seed': 232
* });
* var out = sample( 'abcdefg' );
* // e.g., returns [ 'g', 'd', 'g', 'f', 'c', 'e', 'f' ]
*
* @example
* var sample = factory( [ 1, 2, 3, 4, 5, 6 ], {
*     'seed': 232,
*     'size': 2
* });
* var out = sample();
* // e.g., returns [ 6, 4 ]
*
* out = sample();
* // e.g., returns [ 6, 5 ]
*
* @example
* var sample = factory( [ 1, 2, 3, 4, 5, 6 ], {
*     'seed': 474,
*     'size': 3,
*     'mutate': true,
*     'replace': false
* });
* var out = sample();
* // e.g., returns [ 4, 3, 6 ]
*
* out = sample();
* // e.g., returns [ 1, 5, 2 ]
*
* out = sample();
* // returns null
*
* @example
* var sample = factory( [ 0, 1 ], {
*     'size': 2
* });
*
* var out = sample();
* // e.g., returns [ 1, 1 ]
*
* out = sample({
*     'size': 10
* });
* // e.g., returns [ 0, 1, 1, 1, 0, 1, 0, 0, 1, 1 ]
*
* @example
* var sample = factory( [ 0, 1 ], {
*     'size': 2
* });
*
* var out = sample();
* // e.g., returns [ 1, 1 ]
*
* out = sample({
*     'replace': false
* });
* // e.g., returns [ 0, 1 ] or [ 1, 0 ]
*
* out = sample();
* // e.g., returns [ 1, 1 ]
*
* @example
* var sample = factory( [ 0, 1 ], {
*     'size': 2,
*     'mutate': true
* });
*
* var out = sample();
* // e.g., returns [ 1, 1 ]
*
* out = sample({
*     'replace': false
* });
* // e.g., returns [ 0, 1 ] or [ 1, 0 ]
*
* out = sample();
* // returns null
*/

/**
* Returns a pseudorandom number generator for generating uniformly distributed random numbers.
*
* @param {number} [a] - minimum support (inclusive)
* @param {number} [b] - maximum support (exclusive)
* @param {Options} [options] - function options
* @param {PRNG} [options.prng] - pseudorandom number generator which generates uniformly distributed pseudorandom numbers
* @param {PRNGSeedMT19937} [options.seed] - pseudorandom number generator seed
* @param {PRNGStateMT19937} [options.state] - pseudorandom number generator state
* @param {boolean} [options.copy=true] - boolean indicating whether to copy a provided pseudorandom number generator state
* @throws {TypeError} `a` must be a number
* @throws {TypeError} `b` must be a number
* @throws {RangeError} `a` must be less than `b`
* @throws {TypeError} options argument must be an object
* @throws {TypeError} must provide valid options
* @throws {Error} must provide a valid state
* @returns {PRNG} pseudorandom number generator
*
* @example
* var uniform = factory( 0.0, 1.0 );
*
* var v = uniform();
* // returns <number>
*
* @example
* var uniform = factory( -3.0, -1.0, {
*     'seed': 297
* });
* var v = uniform();
* // returns <number>
*/

/**
* Returns a uniformly distributed pseudorandom number with minimum support `a` and maximum support `b`.
*
* @name uniform
* @type {PRNG}
* @param {number} a - minimum support (inclusive)
* @param {number} b - maximum support (exclusive)
* @returns {number} pseudorandom number
*
* @example
* var v = uniform( 0.0, 1.0 );
* // returns <number>
*/

/**
* Returns a uniformly distributed pseudorandom number with minimum support `a` and maximum support `b`.
*
* @private
* @param {PRNG} rand - pseudorandom number generator
* @param {number} a - minimum support (inclusive)
* @param {number} b - maximum support (exclusive)
* @returns {number} pseudorandom number
*/

/**
* Sample elements from an array-like object.
*
* @module @stdlib/random/sample
*
* @example
* var sample = require( '@stdlib/random/sample' );
*
* var out = sample( 'abc' );
* // e.g., returns [ 'a', 'a', 'b' ]
*
* out = sample( [ 3, 6, 9 ] );
* // e.g., returns [ 3, 9, 6 ]
*
* var bool = ( out.length === 3 );
* // returns true
*
* @example
* var sample = require( '@stdlib/random/sample' );
*
* var mysample = sample.factory({
*     'seed': 323
* });
* var out = mysample( [ 3, 6, 9 ], {
*     'size': 10
* });
* // e.g., returns [ 3, 9, 3, 3, 3, 6, 3, 3, 3, 6 ]
*/

/**
* Samples elements from an array-like object.
*
* @name sample
* @type {Function}
* @param {ArrayLike} x - array-like object from which to sample
* @param {Options} [options] - function options
* @param {NonNegativeInteger} [options.size] - sample size
* @param {ProbabilityArray} [options.probs] - element probabilities
* @param {boolean} [options.replace=true] - boolean indicating whether to sample with replacement
* @throws {TypeError} first argument must be array-like
* @throws {TypeError} options argument must be an object
* @throws {TypeError} must provide valid options
* @throws {RangeError} `size` option must be less than or equal to the length of `x` when the `replace` option is `false`
* @returns {Array} sample
*
* @example
* var out = sample( [ 3, null, NaN, 'abc', function(){} ] );
* // e.g., returns [ 3, 'abc', null, 3, null ]
*/

/**
* Samples from a discrete uniform distribution (equal probabilities and with replacement).
*
* @private
* @param {ArrayLike} x - array-like object from which to sample
* @param {NonNegativeInteger} size - sample size
* @param {Function} rand - PRNG for generating uniformly distributed numbers
* @returns {Array} sample
*/

/**
* Samples uniformly without replacement using the Fisher-Yates shuffle.
*
* ## References
*
* -   Knuth, Donald E. 1997. _The Art of Computer Programming, Volume 2 (3rd Ed.): Seminumerical Algorithms_. Boston, MA, USA: Addison-Wesley Longman Publishing Co., Inc.
*
* @private
* @param {ArrayLike} x - array-like object from which to sample
* @param {NonNegativeInteger} size - sample size
* @param {Function} rand - PRNG for generating uniformly distributed numbers
* @returns {Array} sample
*/

/**
* Samples with replacement and non-uniform probabilities using Vose's [alias method][alias-method].
*
* ## References
*
* -   Vose, Michael D. 1991. "A linear algorithm for generating random numbers with a given distribution." _IEEE Transactions on Software Engineering_ 17 (9): 972–75. doi:[10.1109/32.92917][@vose:1991].
*
* [alias-method]: http://keithschwarz.com/darts-dice-coins/
* [@vose:1991]: https://doi.org/10.1109/32.92917
*
*
* @private
* @param {ArrayLike} x - array-like object from which to sample
* @param {NonNegativeInteger} size - sample size
* @param {Function} rand - PRNG for generating uniformly distributed numbers
* @param {ProbabilityArray} probabilities - element probabilities
* @returns {Array} sample
*/

/**
* Samples without replacement from a discrete set using custom probabilities.
*
* ## Notes
*
* -   After each draw, the probabilities of the remaining observations are renormalized so that they sum to one.
*
*
* @private
* @param {ArrayLike} x - array-like object from which to sample
* @param {NonNegativeInteger} size - sample size
* @param {Function} rand - PRNG for generating uniformly distributed numbers
* @param {ProbabilityArray} probabilities - element probabilities
* @returns {Array} sample
*/

/**
* Test if a value is an array of probabilities that sum to one.
*
* @module @stdlib/assert/is-unity-probability-array
*
* @example
* var isUnityProbabilityArray = require( '@stdlib/assert/is-unity-probability-array' );
*
* var bool = isUnityProbabilityArray( [ 0.25, 0.5, 0.25 ] );
* // returns true
*
* bool = isUnityProbabilityArray( new Uint8Array( [ 0, 1 ] ) );
* // returns true
*
* bool = isUnityProbabilityArray( [ 0.4, 0.4, 0.4 ] );
* // returns false
*
* bool = isUnityProbabilityArray( [ 3.14, 0.0 ] );
* // returns false
*/

/**
* Test whether a string contains only numeric digits.
*
* @module @stdlib/assert/is-digit-string
*
* @example
* var isDigitString = require( '@stdlib/assert/is-digit-string' );
*
* var out = isDigitString( '0123456789' );
* // returns true
*
* out = isDigitString( '0xffffff' );
* // returns false
*
* out = isDigitString( '' );
* // returns false
*/

/**
* Tests if a value is an array of probabilities that sum to one.
*
* @param {*} v - value to test
* @returns {boolean} boolean indicating if a value is a probability array
*
* @example
* var bool = isUnityProbabilityArray( [ 0.25, 0.5, 0.25 ] );
* // returns true
*
* @example
* var bool = isUnityProbabilityArray( new Uint8Array( [ 0, 1 ] ) );
* // returns true
*
* @example
* var bool = isUnityProbabilityArray( [ 0.4, 0.4, 0.4 ] );
* // returns false
*
* @example
* var bool = isUnityProbabilityArray( [ 3.14, 0.0 ] );
* // returns false
*/

/**
* Tests whether a string contains only numeric digits.
*
* @param {*} x - value to test
* @returns {boolean} boolean indicating if a string contains only numeric digits
*
* @example
* var out = isDigitString( '0123456789' );
* // returns true
*
* @example
* var out = isDigitString( '0xffffff' );
* // returns false
*
* @example
* var out = isDigitString( '' );
* // returns false
*
* @example
* var out = isDigitString( 123 );
* // returns false
*/

/**
* Uniform distribution pseudorandom numbers.
*
* @module @stdlib/random/base/uniform
*
* @example
* var uniform = require( '@stdlib/random/base/uniform' );
*
* var v = uniform( 0.0, 1.0 );
* // returns <number>
*
* @example
* var factory = require( '@stdlib/random/base/uniform' ).factory;
* var uniform = factory( -5.0, 5.0, {
*     'seed': 297
* });
*
* var v = uniform();
* // returns <number>
*
* @example
* var factory = require( '@stdlib/random/base/uniform' ).factory;
* var uniform = factory({
*     'seed': 297
* });
*
* var v = uniform( -5.0, 5.0 );
* // returns <number>
*/

/**
* Validates function options.
*
* @private
* @param {Object} opts - destination for validated options
* @param {Options} options - function options
* @param {NonNegativeInteger} [options.size] - sample size
* @param {ProbabilityArray} [options.probs] - element probabilities
* @param {boolean} [options.replace] - boolean indicating whether to sample with replacement
* @param {boolean} [options.mutate] - boolean indicating whether to mutate the `pool` when sampling without replacement
* @returns {(null|Error)} null or an error
*
* @example
* var opts = {};
* var options = {
*     'size': 10,
*     'replace': false,
*     'mutate': true,
*     'probs': [ 0.7, 0.3 ]
* };
* var err = validate( opts, options );
* if ( err ) {
*     throw err;
* }
*/

/**
* Validates values provided for minimum and maximum support.
*
* @private
* @param {number} a - minimum support
* @param {number} b - maximum support
* @returns {(Error|null)} error or null
*
* @example
* var err = validate( 1.0, 2.0 );
* if ( err ) {
*     throw err;
* }
*/

/***/

// All elements equally likely...

// Character codes:

// Custom probabilities...

// EXPORTS //

// FUNCTIONS //

// Generate an integer index on the interval: [0,i]

// If we are provided an "external" PRNG, we don't support getting or setting PRNG state, as we'd need to check for compatible state value types, etc, entailing considerable complexity.

// MAIN //

// MODULES //

// Note: we skip the first element, as no further swaps are possible given that all other indices are excluded from swapping...

// Remove the sample observations:

// Swap elements:

// VARIABLES //

// equivalent to (b-a)*r + a
