Skip to content

Commit

Permalink
[UPDATE] return empty data structure, not null. handle non-numerics. …
Browse files Browse the repository at this point in the history
…move typed-array support to sep file. README. [TESTS] empty data structure. non-numerics. typed-arrays.
  • Loading branch information
kgryte committed Jun 24, 2015
1 parent 2bb782d commit 2262480
Show file tree
Hide file tree
Showing 15 changed files with 405 additions and 186 deletions.
76 changes: 67 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var erfcinv = require( 'compute-erfcinv' );

#### erfcinv( x[, options] )

Evaluates the [inverse complementary error function](https://en.wikipedia.org/wiki/Error_function#Inverse_function). `x` may be either a [`number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), an [`array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array), a [`typed array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays), or a [`matrix`](https://github.com/dstructs/matrix). All values __must__ reside on the interval `[0,2]`.
Evaluates the [inverse complementary error function](https://en.wikipedia.org/wiki/Error_function#Inverse_function). `x` may be either a [`number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), an [`array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array), a [`typed array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays), or a [`matrix`](https://github.com/dstructs/matrix). All numeric values __must__ reside on the interval `[0,2]`.

``` javascript
var matrix = require( 'dstructs-matrix' ),
Expand Down Expand Up @@ -60,14 +60,14 @@ for ( i = 0; i < 4; i++ ) {
}
mat = matrix( data, [2,2], 'float64' );
/*
[ 0 0.5
1 1.5 ]
[ 0 0.5
1 1.5 ]
*/

out = erfcinv( mat );
/*
[ +infinity 0.477
0 -0.477 ]
[ +infinity 0.477
0 -0.477 ]
*/
```

Expand Down Expand Up @@ -179,22 +179,80 @@ for ( i = 0; i < 4; i++ ) {
}
mat = matrix( data, [2,2], 'float64' );
/*
[ 0 0.5
1 1.5 ]
[ 0 0.5
1 1.5 ]
*/

out = erfcinv( mat, {
'copy': false
});
/*
[ +infinity 0.477
0 -0.477 ]
[ +infinity 0.477
0 -0.477 ]
*/

bool = ( mat === out );
// returns true
```


## Notes

* If an element is __not__ a numeric value, the evaluated [inverse complementary error function](https://en.wikipedia.org/wiki/Error_function#Inverse_function) is `NaN`.

``` javascript
var data, out;

out = erfcinv( null );
// returns NaN

out = erfcinv( true );
// returns NaN

out = erfcinv( {'a':'b'} );
// returns NaN

out = erfcinv( [ true, null, [] ] );
// returns [ NaN, NaN, NaN ]

function getValue( d, i ) {
return d.x;
}
data = [
{'x':true},
{'x':[]},
{'x':{}},
{'x':null}
];

out = erfcinv( data, {
'accessor': getValue
});
// returns [ NaN, NaN, NaN, NaN ]

out = erfcinv( data, {
'path': 'x'
});
/*
[
{'x':NaN},
{'x':NaN},
{'x':NaN,
{'x':NaN}
]
*/
```

* Be careful when providing a data structure which contains non-numeric elements and specifying an `integer` output data type, as `NaN` values are cast to `0`.

``` javascript
var out = erfcinv( [ true, null, [] ], {
'dtype': 'int8'
});
// returns Int8Array( [0,0,0] );
```


## Examples

``` javascript
Expand Down
16 changes: 9 additions & 7 deletions lib/accessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ var ERFCINV = require( './number.js' );
* FUNCTION: erfcinv( out, arr, accessor )
* Computes the inverse complementary error function for each array element using an accessor function.
*
* @param {Array} out - output array
* @param {Array|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} out - output array
* @param {Array} arr - input array
* @param {Function} accessor - accessor function for accessing array values
* @returns {Number[]|Null} output array or null
* @returns {Number[]|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} output array
*/
function erfcinv( y, x, clbk ) {
var len = x.length,
i;
if ( !len ) {
return null;
}
v, i;
for ( i = 0; i < len; i++ ) {
y[ i ] = ERFCINV( clbk( x[ i ], i ) );
v = clbk( x[ i ], i );
if ( typeof v === 'number' ) {
y[ i ] = ERFCINV( v );
} else {
y[ i ] = NaN;
}
}
return y;
} // end FUNCTION erfcinv()
Expand Down
15 changes: 8 additions & 7 deletions lib/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@ var ERFCINV = require( './number.js' );
* FUNCTION: erfcinv( out, arr )
* Computes the inverse complementary error function for each array element.
*
* @param {Number[]|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} out - output array
* @param {Number[]|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} arr - input array
* @returns {Number[]|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|Null} output array or null
* @param {Array|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} out - output array
* @param {Array} arr - input array
* @returns {Number[]|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} output array
*/
function erfcinv( y, x ) {
var len = x.length,
i;
if ( !len ) {
return null;
}
for ( i = 0; i < len; i++ ) {
y[ i ] = ERFCINV( x[ i ] );
if ( typeof x[ i ] === 'number' ) {
y[ i ] = ERFCINV( x[ i ] );
} else {
y[ i ] = NaN;
}
}
return y;
} // end FUNCTION erfcinv()
Expand Down
21 changes: 12 additions & 9 deletions lib/deepset.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,21 @@ function erfcinv( x, path, sep ) {
opts = {},
dget,
dset,
i;

if ( !len ) {
return null;
}
v, i;
if ( arguments.length > 2 ) {
opts.sep = sep;
}
dget = deepGet( path, opts );
dset = deepSet( path, opts );
for ( i = 0; i < len; i++ ) {
dset( x[i], ERFCINV( dget( x[i] ) ) );
if ( len ) {
dget = deepGet( path, opts );
dset = deepSet( path, opts );
for ( i = 0; i < len; i++ ) {
v = dget( x[ i ] );
if ( typeof v === 'number' ) {
dset( x[i], ERFCINV( v ) );
} else {
dset( x[i], NaN );
}
}
}
return x;
} // end FUNCTION erfcinv()
Expand Down
34 changes: 24 additions & 10 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
// MODULES //

var isNumber = require( 'validate.io-number-primitive' ),
isArray = require( 'validate.io-array' ),
isnan = require( 'validate.io-nan' ),
isArrayLike = require( 'validate.io-array-like' ),
isTypedArrayLike = require( 'validate.io-typed-array-like' ),
isMatrixLike = require( 'validate.io-matrix-like' ),
ctors = require( 'compute-array-constructors' ),
matrix = require( 'dstructs-matrix' ),
Expand All @@ -17,7 +18,8 @@ var erfcinv1 = require( './number.js' ),
erfcinv2 = require( './array.js' ),
erfcinv3 = require( './accessor.js' ),
erfcinv4 = require( './deepset.js' ),
erfcinv5 = require( './matrix.js' );
erfcinv5 = require( './matrix.js' ),
erfcinv6 = require( './typedarray.js' );


// INVERSE COMPLEMENTARY ERROR FUNCTION //
Expand All @@ -33,7 +35,7 @@ var erfcinv1 = require( './number.js' ),
* @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|Null} evaluated complementary inverse error function value(s) or null
* @returns {Number|Number[]|Array|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|Matrix} evaluated complementary inverse error function value(s)
*/
function erfcinv( x, options ) {
/* jshint newcap:false */
Expand All @@ -44,7 +46,7 @@ function erfcinv( x, options ) {
dt,
d;

if ( isNumber( x ) ) {
if ( isNumber( x ) || isnan( x ) ) {
return erfcinv1( x );
}
if ( arguments.length > 1 ) {
Expand All @@ -68,21 +70,33 @@ function erfcinv( x, options ) {
}
return erfcinv5( 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( 'erfcinv()::invalid option. Data type option does not have a corresponding array constructor. Option: `' + dt + '`.' );
}
out = new ctor( x.length );
}
return erfcinv6( out, x );
}
if ( isArrayLike( x ) ) {
// Handle deepset first...
if ( opts.path ) {
opts.sep = opts.sep || '.';
return erfcinv4( x, opts.path, opts.sep );
}
// Handle regular, typed, and accessor arrays next...
// Handle regular and accessor arrays next...
if ( opts.copy === false ) {
out = x;
}
else if ( opts.dtype || !isArray( x ) ) {
dt = opts.dtype || 'float64';
ctor = ctors( dt );
else if ( opts.dtype ) {
ctor = ctors( opts.dtype );
if ( ctor === null ) {
throw new TypeError( 'erfcinv()::invalid input argument. Unrecognized/unsupported array-like object. Provide either a plain or typed array. Value: `' + x + '`.' );
throw new TypeError( 'erfcinv()::invalid option. Data type option does not have a corresponding array constructor. Option: `' + opts.dtype + '`.' );
}
out = new ctor( x.length );
}
Expand All @@ -94,7 +108,7 @@ function erfcinv( x, options ) {
}
return erfcinv2( out, x );
}
throw new TypeError( 'erfcinv()::invalid input argument. Input value type not currently supported. Value: `' + x + '`.' );
return NaN;
} // end FUNCTION erfcinv()


Expand Down
5 changes: 1 addition & 4 deletions lib/matrix.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,11 @@ var ERFCINV = require( './number.js' );
*
* @param {Matrix} out - output matirx
* @param {Matrix} arr - input matrix
* @returns {Matrix|Null} output matrix or null
* @returns {Matrix} output matrix or null
*/
function erfcinv( y, x ) {
var len = x.length,
i;
if ( !len ) {
return null;
}
if ( y.length !== len ) {
throw new Error( 'erfcinv()::invalid input arguments. Input and output matrices must be the same length.' );
}
Expand Down
Loading

0 comments on commit 2262480

Please sign in to comment.