Distribution.prototype.mgf = function( t ) { var m, len, out, val, i; m = getMGF( this._a, this._b ); if ( !arguments.length ) { return m; } if ( isNumber( t ) ) { return m( t ); } if ( isMatrixLike( t ) ) { len = t.length; // Create an output matrix: out = matrix( new Float64Array( len ), t.shape ); for ( i = 0; i < len; i++ ) { out.data[ i ] = m( t.data[ i ] ); } return out; } if ( isArrayLike( t ) ) { len = t.length; out = new Array( len ); for ( i = 0; i < len; i++ ) { val = t[ i ]; if ( !isNumber( val ) ) { return NaN; } else { out[ i ] = m( val ); } } return out; } return NaN; }; // end METHOD mgf()
Distribution.prototype.quantile = function( p ) { var q, len, out, val, i; q = getQuantileFunction( this._a, this._b ); if ( !arguments.length ) { return q; } if ( isNumber( p ) ) { return q( p ); } if ( isMatrixLike( p ) ) { len = p.length; // Create an output matrix: out = matrix( new Float64Array( len ), p.shape ); for ( i = 0; i < len; i++ ) { out.data[ i ] = q( p.data[ i ] ); } return out; } if ( isArrayLike( p ) ) { len = p.length; out = new Array( len ); for ( i = 0; i < len; i++ ) { val = p[ i ]; if ( !isNumber( val ) ) { return NaN; } else { out[ i ] = q( val ); } } return out; } return NaN; }; // end METHOD quantile()
// APPLY // /** * FUNCTION: apply( fun, x ) * Applies function `fun` to all elements in `x`. * * @private * @param {Function} fun - function to be applied * @param {Number|Number[]|Array|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|Matrix} x - input object * @returns {Array|Matrix|Number} function value(s) */ function apply( fun, x ) { var len, out, val, i; if ( isNumber( x ) ) { return fun( x ); } if ( isMatrixLike( x ) ) { len = x.length; // Create an output matrix: out = matrix( new Float64Array( len ), x.shape ); for ( i = 0; i < len; i++ ) { out.data[ i ] = fun( x.data[ i ] ); } return out; } if ( isArrayLike( x ) ) { len = x.length; out = new Array( len ); for ( i = 0; i < len; i++ ) { val = x[ i ]; if ( !isNumber( val ) ) { out[ i ] = NaN; } else { out[ i ] = fun( val ); } } return out; } return NaN; }
Distribution.prototype.cdf = function( x ) { var cdf, len, out, val, i; cdf = getCDF( this._a, this._b ); if ( !arguments.length ) { return cdf; } if ( isNumber( x ) ) { return cdf( x ); } if ( isMatrixLike( x ) ) { len = x.length; // Create an output matrix: out = matrix( new Float64Array( len ), x.shape ); for ( i = 0; i < len; i++ ) { out.data[ i ] = cdf( x.data[ i ] ); } return out; } if ( isArrayLike( x ) ) { len = x.length; out = new Array( len ); for ( i = 0; i < len; i++ ) { val = x[ i ]; if ( !isNumber( val ) ) { return NaN; } else { out[ i ] = cdf( val ); } } return out; } return NaN; }; // end METHOD cdf()
} // end FUNCTION polyval() // EVALUATE // /** * FUNCTION: evaluate( coef, x[, options] ) * Evaluates a polynomial. * * @param {Number[]} coef - array of coefficients sorted in descending degree * @param {Array|Number[]|Number} x - value(s) at which to evaluate the polynomial * @param {Object} [options] - function options * @param {Boolean} [options.copy=true] - boolean indicating whether to return a new array * @param {Function} [options.accessor] - accessor function for accessing array values * @returns {Number|Number[]} evaluated polynomial */ function evaluate( c, x, opts ) { var copy = true, clbk, len, arr, v, i; if ( !isNumberArray( c ) ) { throw new TypeError( 'polynomial()::invalid input argument. Coefficients must be provided as an array of number primitives. Value: `' + c + '`.' ); } if ( isNumber( x ) ) { return polyval( c, x ); } if ( !isArray( x ) ) { throw new TypeError( 'polynomial()::invalid input argument. Second argument must be either a single number primitive or an array of values. Value: `' + x + '`.' ); } if ( arguments.length > 2 ) { if ( !isObject( opts ) ) { throw new TypeError( 'polynomial()::invalid input argument. Options argument must be an object. Value: `' + opts + '`.' ); } if ( opts.hasOwnProperty( 'copy' ) ) { copy = opts.copy; if ( !isBoolean( copy ) ) { throw new TypeError( 'polynomial()::invalid option. Copy option must be a boolean primitive. Option: `' + copy + '`.' ); } } if ( opts.hasOwnProperty( 'accessor' ) ) { clbk = opts.accessor; if ( !isFunction( clbk ) ) { throw new TypeError( 'polynomial()::invalid option. Accessor must be a function. Option: `' + clbk + '`.' ); } } } len = x.length; if ( copy ) { arr = new Array( len ); } else { arr = x; } if ( clbk ) { for ( i = 0; i < len; i++ ) { v = clbk( x[ i ], i ); if ( !isNumber( v ) ) { throw new TypeError( 'polynomial()::invalid input argument. Accessed array values must be number primitives. Value: `' + v + '`.' ); } arr[ i ] = polyval( c, v ); } } else { for ( i = 0; i < len; i++ ) { v = x[ i ]; if ( !isNumber( v ) ) { throw new TypeError( 'polynomial()::invalid input argument. Array values must be number primitives. Value: `' + v + '`.' ); } arr[ i ] = polyval( c, v ); } } return arr; } // end FUNCTION evaluate()
// OBSERVER // /** * FUNCTION: alphaMinChanged( oldVal, newVal ) * Event handler for changes to a minimum alpha-value. * * @param {Null|Number} oldVal - old value * @param {Null|Number} newVal - new value */ function alphaMinChanged( oldVal, newVal ) { /* jslint validthis:true */ var alphaScale = this._alphaScale, domain, err; if ( oldVal === void 0 ) { return; } if ( newVal !== null && !isNumber( newVal ) ) { err = new TypeError( 'alphaMin::invalid assignment. Must be a numeric or `null`. Value: `' + newVal + '`.' ); this.fire( 'err', err ); this.alphaMin = oldVal; return; } // [0] Update the domain: domain = alphaScale.domain(); domain = this._alphaDomain( newVal, domain[1] ); alphaScale.domain( domain ); if ( this.autoUpdate ) { this.$.dots.style( 'opacity', this._alpha ); } this.fire( 'alphaMin', { 'type': 'change' }); this.fire( 'change', { 'attr': 'alphaMin', 'prev': oldVal, 'curr': newVal }); } // end FUNCTION alphaMinChanged()
// DISTRIBUTION // /** * FUNCTION: Distribution( a, b ) * Distribution constructor. * * @constructor * @param {Number} [a] - minimum value * @param {Number} [b] - maximum value * @returns {Distribution} Distribution instance */ function Distribution( a, b ) { if ( a !== undefined && b !== undefined ) { if ( !isNumber( a ) ) { throw new TypeError( 'constructor()::invalid input argument. The minimum value `a` must be a number primitive. Value: `' + a + '`' ); } if ( !isNumber( b ) ) { throw new TypeError( 'constructor()::invalid input argument. The maximum value `b` must be a number primitive. Value: `' + b + '`' ); } if ( b <= a ) { throw new TypeError( 'constructor()::invalid input arguments. `a` must be smaller than `b`.' ); } } this._a = a || 0 ; // minimum this._b = b || 1; // maximum return this; } // end FUNCTION Distribution()
// SET // /** * FUNCTION: set( i, j, value ) * Sets a matrix element based on the provided row and column indices. * * @param {Number} i - row index * @param {Number} j - column index * @param {Number} value - value to set * @returns {Matrix} Matrix instance */ function set( i, j, v ) { /* jshint validthis: true */ if ( !isNonNegativeInteger( i ) || !isNonNegativeInteger( j ) ) { throw new TypeError( 'invalid input argument. Row and column indices must be nonnegative integers. Values: `[' + i + ',' + j + ']`.' ); } if ( !isNumber( v ) && !isnan( v ) ) { throw new TypeError( 'invalid input argument. An input value must be a number primitive. Value: `' + v + '`.' ); } i = this.offset + i*this.strides[0] + j*this.strides[1]; if ( i >= 0 ) { this.data[ i ] = v; } return this; } // end FUNCTION set()
// OBSERVER // /** * FUNCTION: xMaxChanged( newVal, oldVal ) * Event handler invoked when the `xMax` property changes. * * @param {Null|Number} newVal - new value * @param {Null|Number} oldVal - old value */ function xMaxChanged( newVal, oldVal ) { /* jshint validthis:true */ var xScale = this._xScale, domain, err; if ( oldVal === void 0 ) { return; } if ( newVal !== null && !isNumber( newVal ) ) { err = new TypeError( 'xMax::invalid assignment. Must be numeric or `null`. Value: `' + newVal + '`.' ); this.fire( 'err', err ); this.xMax = oldVal; return; } // [0] Update the domain: domain = xScale.domain(); domain = this._xDomain( domain[ 0 ], newVal ); // [1] Update the xScale: xScale.domain( domain ); if ( this.autoUpdate ) { // [2] Update the xAxis: this.$.xAxis.call( this._xAxis ); // [3] Update the dots: this.$.dots .attr('r', 3.5) .attr('cx', this._cx ) .attr('cy', this._cy ); } this.fire( 'xMax', { 'type': 'change' }); this.fire( 'change', { 'attr': 'xMax', 'prev': oldVal, 'curr': newVal }); } // end FUNCTION xMaxChanged()
// SUBSEQUENCE SET // /** * FUNCTION: sset( subsequence, value[, thisArg] ) * Sets matrix elements according to a specified subsequence. * * @param {String} subsequence - subsequence string * @param {Number|Matrix|Function} value - either a single numeric value, a matrix containing the values to set, or a function which returns a numeric value * @param {Object} [thisArg] - `this` context when executing a callback * @returns {Matrix} Matrix instance */ function sset( seq, val, thisArg ) { /* jshint validthis: true */ var nRows, nCols, clbk, rows, cols, seqs, mat, ctx, s0, s1, s2, s3, o0, o1, r0, r1, i, j, k; if ( !isString( seq ) ) { throw new TypeError( 'invalid input argument. Must provide a string primitive. Value: `' + seq + '`.' ); } seqs = seq.split( ',' ); if ( seqs.length !== 2 ) { throw new Error( 'invalid input argument. Subsequence string must specify row and column subsequences. Value: `' + seq + '`.' ); } if ( isFunction( val ) ) { clbk = val; } else if ( !isNumber( val ) ) { mat = val; } rows = ispace( seqs[ 0 ], this.shape[ 0 ] ); cols = ispace( seqs[ 1 ], this.shape[ 1 ] ); nRows = rows.length; nCols = cols.length; if ( !( nRows && nCols ) ) { return this; } s0 = this.strides[ 0 ]; s1 = this.strides[ 1 ]; o0 = this.offset; // Callback... if ( clbk ) { if ( arguments.length > 2 ) { ctx = thisArg; } else { ctx = this; } for ( i = 0; i < nRows; i++ ) { r0 = o0 + rows[i]*s0; for ( j = 0; j < nCols; j++ ) { k = r0 + cols[j]*s1; this.data[ k ] = clbk.call( ctx, this.data[ k ], rows[i], cols[j], k ); } } } // Input matrix... else if ( mat ) { if ( nRows !== mat.shape[ 0 ] ) { throw new Error( 'invalid input arguments. Row subsequence does not match input matrix dimensions. Expected a [' + nRows + ',' + nCols + '] matrix and instead received a [' + mat.shape.join( ',' ) + '] matrix.' ); } if ( nCols !== mat.shape[ 1 ] ) { throw new Error( 'invalid input arguments. Column subsequence does not match input matrix dimensions. Expected a [' + nRows + ',' + nCols + '] matrix and instead received a [' + mat.shape.join( ',' ) + '] matrix.' ); } s2 = mat.strides[ 0 ]; s3 = mat.strides[ 1 ]; o1 = mat.offset; for ( i = 0; i < nRows; i++ ) { r0 = o0 + rows[i]*s0; r1 = o1 + i*s2; for ( j = 0; j < nCols; j++ ) { this.data[ r0 + cols[j]*s1 ] = mat.data[ r1 + j*s3 ]; } } } // Single numeric value... else { for ( i = 0; i < nRows; i++ ) { r0 = o0 + rows[i]*s0; for ( j = 0; j < nCols; j++ ) { this.data[ r0 + cols[j]*s1 ] = val; } } } return this; } // end FUNCTION sset()
// DIVIDE // /** * FUNCTION: divide( arr, x[, opts] ) * Computes an element-wise division. * * @param {Number[]|Array} arr - input array * @param {Number[]|Array|Number} x - either an array of equal length or a scalar * @param {Object} [opts] - function options * @param {Boolean} [opts.copy=true] - boolean indicating whether to return a new array * @param {Function} [opts.accessor] - accessor function for accessing array values * @returns {Number[]} output array */ function divide( arr, x, opts ) { var isArr = isArray( x ), copy = true, arity, clbk, out, len, i; if ( !isArray( arr ) ) { throw new TypeError( 'divide()::invalid input argument. Must provide an array. Value: `' + arr + '`.' ); } if ( !isArr && !isNumber( x ) ) { throw new TypeError( 'divide()::invalid input argument. Second argument must either be an array or number primitive. Value: `' + x + '`.' ); } if ( arguments.length > 2 ) { if ( !isObject( opts ) ) { throw new TypeError( 'divide()::invalid input argument. Options argument must be an object. Value: `' + opts + '`.' ); } if ( opts.hasOwnProperty( 'copy' ) ) { copy = opts.copy; if ( !isBoolean( copy ) ) { throw new TypeError( 'divide()::invalid option. Copy option must be a boolean primitive. Option: `' + copy + '`.' ); } } if ( opts.hasOwnProperty( 'accessor' ) ) { clbk = opts.accessor; if ( !isFunction( clbk ) ) { throw new TypeError( 'divide()::invalid option. Accessor must be a function. Option: `' + clbk + '`.' ); } arity = clbk.length; } } len = arr.length; if ( copy ) { out = new Array( len ); } else { out = arr; } // Case 1: x is an array if ( isArr ) { if ( len !== x.length ) { throw new Error( 'divide()::invalid input argument. Array to be divideed must have a length equal to that of the input array.' ); } if ( arity === 3 ) { // clbk implied for ( i = 0; i < len; i++ ) { out[ i ] = clbk( arr[i], i, 0 ) / clbk( x[i], i, 1 ); } } else if ( clbk ) { for ( i = 0; i < len; i++ ) { out[ i ] = clbk( arr[i], i ) / x[ i ]; } } else { for ( i = 0; i < len; i++ ) { out[ i ] = arr[ i ] / x[ i ]; } } } // Case 2: accessor and scalar else if ( clbk ) { for ( i = 0; i < len; i++ ) { out[ i ] = clbk( arr[i], i ) / x; } } // Case 3: scalar else { for ( i = 0; i < len; i++ ) { out[ i ] = arr[ i ] / x; } } return out; } // end FUNCTION divide()
// GREATER THAN OR EQUAL TO // /** * FUNCTION: geq( arr, x[, opts] ) * Computes an element-wise comparison (greater than or equal to) of an array. * * @param {Number[]|Array} arr - input array * @param {Number[]|Array|Number|String} x - comparator * @param {Object} [opts] - function options * @param {Boolean} [opts.copy=true] - boolean indicating whether to return a new array * @param {Function} [opts.accessor] - accessor function for accessing array values * @returns {Number[]} array of 1s and 0s, where a `1` indicates that an input array element is greater than or equal to a compared value and `0` indicates that an input array element is not greater than or equal to a compared value */ function geq( arr, x, opts ) { var isArr = isArray( x ), copy = true, arity, clbk, out, len, i; if ( !isArray( arr ) ) { throw new TypeError( 'geq()::invalid input argument. Must provide an array. Value: `' + arr + '`.' ); } if ( !isArr && !isNumber( x ) && !isString( x ) ) { throw new TypeError( 'geq()::invalid input argument. Comparison input must either be an array, number primitive, or string primitive. Value: `' + x + '`.' ); } if ( arguments.length > 2 ) { if ( !isObject( opts ) ) { throw new TypeError( 'geq()::invalid input argument. Options argument must be an object. Value: `' + opts + '`.' ); } if ( opts.hasOwnProperty( 'copy' ) ) { copy = opts.copy; if ( !isBoolean( copy ) ) { throw new TypeError( 'geq()::invalid option. Copy option must be a boolean primitive. Option: `' + copy + '`.' ); } } if ( opts.hasOwnProperty( 'accessor' ) ) { clbk = opts.accessor; if ( !isFunction( clbk ) ) { throw new TypeError( 'geq()::invalid option. Accessor must be a function. Option: `' + clbk + '`.' ); } arity = clbk.length; } } len = arr.length; if ( copy ) { out = new Array( len ); } else { out = arr; } // Case 1: comparison array if ( isArr ) { if ( len !== x.length ) { throw new Error( 'geq()::invalid input argument. Comparison array must have a length equal to that of the input array.' ); } if ( arity === 3 ) { // clbk implied for ( i = 0; i < len; i++ ) { if ( clbk( arr[i], i, 0 ) >= clbk( x[i], i, 1 ) ) { out[ i ] = 1; } else { out[ i ] = 0; } } } else if ( clbk ) { for ( i = 0; i < len; i++ ) { if ( clbk( arr[i], i ) >= x[ i ] ) { out[ i ] = 1; } else { out[ i ] = 0; } } } else { for ( i = 0; i < len; i++ ) { if ( arr[ i ] >= x[ i ] ) { out[ i ] = 1; } else { out[ i ] = 0; } } } } // Case 2: accessor and single comparator else if ( clbk ) { for ( i = 0; i < len; i++ ) { if ( clbk( arr[ i ], i ) >= x ) { out[ i ] = 1; } else { out[ i ] = 0; } } } // Case 3: single comparator else { for ( i = 0; i < len; i++ ) { if ( arr[ i ] >= x ) { out[ i ] = 1; } else { out[ i ] = 0; } } } return out; } // end FUNCTION geq()
// MINKOWSKI DISTANCE // /** * FUNCTION: minkowski( x, y[, options] ) * Computes the Minkowski distance between two arrays. * * @param {Number[]|Array} x - input array * @param {Number[]|Array} y - input array * @param {Object} [options] - function options * @param {Number} [options.p=2] - norm order * @param {Function} [options.accessor] - accessor function for accessing array values * @returns {Number|Null} Minkowski distance or null */ function minkowski( x, y, opts ) { var p = 2, clbk, len, d, v, i; if ( arguments.length > 2 ) { if ( !isObject( opts ) ) { throw new TypeError( 'minkowski()::invalid input argument. Options argument must be an object. Value: `' + opts + '`.' ); } if ( opts.hasOwnProperty( 'p' ) ) { p = opts.p; if ( !isNumber( p ) || p <= 0 ) { throw new TypeError( 'minkowski()::invalid option. `p` option must be a positive number primitive. Option: `' + p + '`.' ); } } if ( opts.hasOwnProperty( 'accessor' ) ) { clbk = opts.accessor; if ( !isFunction( clbk ) ) { throw new TypeError( 'minkowski()::invalid option. Accessor must be a function. Option: `' + clbk + '`.' ); } } } // If norm order corresponds to a known metric, delegate type checking and execution to the respective implementation... if ( p === 2 ) { return ( clbk ) ? euclidean( x, y, clbk ) : euclidean( x, y ); } else if ( p === 1 ) { return ( clbk ) ? manhattan( x, y, clbk ) : manhattan( x, y ); } else if ( p === Number.POSITIVE_INFINITY ) { return ( clbk ) ? chebyshev( x, y, clbk ) : chebyshev( x, y ); } // Proceed with the general distance algorithm... if ( !isArray( x ) ) { throw new TypeError( 'minkowski()::invalid input argument. First argument must be a number array. Value: `' + x + '`.' ); } if ( !isArray( y ) ) { throw new TypeError( 'minkowski()::invalid input argument. Second argument must be a number array. Value: `' + y + '`.' ); } len = x.length; if ( len !== y.length ) { throw new TypeError( 'minkowski()::invalid input arguments. Input arrays must have the same length.' ); } if ( !len ) { return null; } d = 0; if ( clbk ) { for ( i = 0; i < len; i++ ) { v = clbk( x[i], i, 0 ) - clbk( y[i], i, 1 ); if ( v < 0 ) { v = -v; } d += Math.pow( v, p ); } } else { for ( i = 0; i < len; i++ ) { v = x[ i ] - y[ i ]; if ( v < 0 ) { v = -v; } d += Math.pow( v, p ); } } return Math.pow( d, 1/p ); } // end FUNCTION minkowski()
} // end FUNCTION getIndices() // MSET // /** * FUNCTION: mset( i[, j], value[, thisArg] ) * Sets multiple matrix elements. If provided a single array, `i` is treated as an array of linear indices. * * @param {Number[]|Null} i - linear/row indices * @param {Number[]|Null} [j] - column indices * @param {Number|Matrix|Function} value - either a single numeric value, a matrix containing the values to set, or a function which returns a numeric value * @returns {Matrix} Matrix instance */ function mset() { /*jshint validthis:true */ var nargs = arguments.length, args, rows, cols, i; args = new Array( nargs ); for ( i = 0; i < nargs; i++ ) { args[ i ] = arguments[ i ]; } // 2 input arguments... if ( nargs < 3 ) { if ( !isNonNegativeIntegerArray( args[ 0 ] ) ) { throw new TypeError( 'invalid input argument. First argument must be an array of nonnegative integers. Value: `' + args[ 0 ] + '`.' ); } // indices, clbk if ( isFunction( args[ 1 ] ) ) { mset2( this, args[ 0 ], args[ 1 ] ); } // indices, number else if ( isNumber( args[ 1 ] ) || isnan( args[ 1 ] ) ) { mset1( this, args[ 0 ], args[ 1 ] ); } // indices, matrix else { // NOTE: no validation for Matrix instance. mset3( this, args[ 0 ], args[ 1 ] ); } } // 3 input arguments... else if ( nargs === 3 ) { // indices, clbk, context if ( isFunction( args[ 1 ] ) ) { if ( !isNonNegativeIntegerArray( args[ 0 ] ) ) { throw new TypeError( 'invalid input argument. First argument must be an array of nonnegative integers. Value: `' + args[ 0 ] + '`.' ); } mset2( this, args[ 0 ], args[ 1 ], args[ 2 ] ); } // rows, cols, function else if ( isFunction( args[ 2 ] ) ) { rows = getIndices( args[ 0 ], this.shape[ 0 ] ); cols = getIndices( args[ 1 ], this.shape[ 1 ] ); mset4( this, rows, cols, args[ 2 ], this ); } // rows, cols, number else if ( isNumber( args[ 2 ] ) ) { rows = getIndices( args[ 0 ], this.shape[ 0 ] ); cols = getIndices( args[ 1 ], this.shape[ 1 ] ); mset5( this, rows, cols, args[ 2 ] ); } // rows, cols, matrix else { rows = getIndices( args[ 0 ], this.shape[ 0 ] ); cols = getIndices( args[ 1 ], this.shape[ 1 ] ); // NOTE: no validation for Matrix instance. mset6( this, rows, cols, args[ 2 ] ); } } // 4 input arguments... else { // rows, cols, function, context if ( !isFunction( args[ 2 ] ) ) { throw new TypeError( 'invalid input argument. Callback argument must be a function. Value: `' + args[ 2 ] + '`.' ); } rows = getIndices( args[ 0 ], this.shape[ 0 ] ); cols = getIndices( args[ 1 ], this.shape[ 1 ] ); mset4( this, rows, cols, args[ 2 ], args[ 3 ] ); } return this; } // end FUNCTION mset()
// ERROR FUNCTION // /** * FUNCTION: erf( x[, opts] ) * Computes the error function. * * @param {Number|Number[]|Array|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|Matrix} x - input value * @param {Object} [opts] - function options * @param {Boolean} [opts.copy=true] - boolean indicating if the function should return a new data structure * @param {Function} [opts.accessor] - accessor function for accessing array values * @param {String} [opts.path] - deep get/set key path * @param {String} [opts.sep="."] - deep get/set key path separator * @param {String} [opts.dtype="float64"] - output data type * @returns {Number|Number[]|Array|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|Matrix} error function value(s) */ function erf( x, options ) { /* jshint newcap:false */ var opts = {}, ctor, err, out, dt, d; if ( isNumber( x ) || isnan( x ) ) { return erf1( x ); } if ( arguments.length > 1 ) { err = validate( opts, options ); if ( err ) { throw err; } } if ( isMatrixLike( x ) ) { if ( opts.copy !== false ) { dt = opts.dtype || 'float64'; ctor = ctors( dt ); if ( ctor === null ) { throw new Error( 'erf()::invalid option. Data type option does not have a corresponding array constructor. Option: `' + dt + '`.' ); } // Create an output matrix: d = new ctor( x.length ); out = matrix( d, x.shape, dt ); } else { out = x; } return erf5( out, x ); } if ( isTypedArrayLike( x ) ) { if ( opts.copy === false ) { out = x; } else { dt = opts.dtype || 'float64'; ctor = ctors( dt ); if ( ctor === null ) { throw new Error( 'erf()::invalid option. Data type option does not have a corresponding array constructor. Option: `' + dt + '`.' ); } out = new ctor( x.length ); } return erf6( out, x ); } if ( isArrayLike( x ) ) { // Handle deepset first... if ( opts.path ) { opts.sep = opts.sep || '.'; return erf4( x, opts.path, opts.sep ); } // Handle regular and accessor arrays next... if ( opts.copy === false ) { out = x; } else if ( opts.dtype ) { ctor = ctors( opts.dtype ); if ( ctor === null ) { throw new Error( 'erf()::invalid option. Data type option does not have a corresponding array constructor. Option: `' + opts.dtype + '`.' ); } out = new ctor( x.length ); } else { out = new Array( x.length ); } if ( opts.accessor ) { return erf3( out, x, opts.accessor ); } return erf2( out, x ); } return NaN; } // end FUNCTION erf()