'use strict';

// INCRKURTOSIS //

/**
* Returns an accumulator function which incrementally computes a corrected sample excess kurtosis.
*
* @returns {Function} accumulator function
*
* @example
* var accumulator = incrkurtosis();
*/
function incrkurtosis() {
	var deltaN2 = 0;
	var deltaN = 0;
	var delta = 0;
	var term1 = 0;
	var mean = 0;
	var M2 = 0;
	var M3 = 0;
	var M4 = 0;
	var N = 0;
	var g2;
	/**
	* If provided a value, the accumulator function returns an updated corrected sample excess kurtosis. If not provided a value, the accumulator function returns the current corrected sample excess kurtosis.
	*
	* #### Method
	*
	* This implementation computes the sample excess kurtosis using the formula for `G_2` in
	*
	*   > Jones and Gill (1998). "Comparing measures of sample skewness and kurtosis." *The Statistician*. [DOI: 10.1111/1467-9884.00122]{@link http://onlinelibrary.wiley.com/doi/10.1111/1467-9884.00122/}
	*
	* In contrast to alternatives for calculating a sample kurtosis, `G_2` is an unbiased estimator under normality.
	*
	*
	* @param {number} [x] - new value
	* @returns {number} corrected sample excess kurtosis
	*
	* @example
	* var kurtosis = accumulator();
	* // returns null
	*
	* kurtosis = accumulator( 2.0 );
	* // returns null
	*
	* kurtosis = accumulator( 2.0 );
	* // returns null
	*
	* kurtosis = accumulator( -4.0 );
	* // returns null
	*
	* kurtosis = accumulator( -4.0 );
	* // returns -6.0
	*/
	return function accumulator( x ) {
		if ( arguments.length === 0 ) {
			if ( N < 4 ) {
				return null;
			}
			// Calculate the population excess kurtosis:
			g2 = ( N*M4 ) / ( M2*M2 ) - 3.0;
			// Return the corrected sample excess kurtosis:
			return (N-1) / ( (N-2)*(N-3) ) * ( (N+1)*g2 + 6.0 );
		}
		N += 1;
		delta = x - mean;
		deltaN = delta / N;
		deltaN2 = deltaN * deltaN;

		term1 = delta * deltaN * (N-1);

		M4 += term1 * deltaN2 * (N*N - 3*N + 3) + 6.0 * deltaN2 * M2 - 4.0 * deltaN * M3;
		M3 += term1 * deltaN * (N-2) - 3.0 * deltaN * M2;
		M2 += term1;
		mean += deltaN;
		if ( N < 4 ) {
			return null;
		}
		// Calculate the population excess kurtosis:
		g2 = N*M4 / ( M2*M2 ) - 3.0;

		// Return the corrected sample excess kurtosis:
		return (N-1) / ( (N-2)*(N-3) ) * ( (N+1)*g2 + 6.0 );
	};
} // end FUNCTION incrkurtosis()


// EXPORTS //

module.exports = incrkurtosis;

'use strict';

// MAIN //

/**
* Returns an accumulator function which incrementally computes a corrected sample excess kurtosis.
*
* #### Method
*
* The algorithm computes the sample excess kurtosis using the formula for `G_2` in [Joanes and Gill 1998][@joanes:1998]. In contrast to alternatives for calculating a sample kurtosis, `G_2` is an unbiased estimator under normality.
*
* #### References
*
* * Joanes, D. N., and C. A. Gill. 1998. "Comparing measures of sample skewness and kurtosis." *Journal of the Royal Statistical Society: Series D (The Statistician)* 47 (1). Blackwell Publishers Ltd: 183–89. doi:[10.1111/1467-9884.00122][@joanes:1998].
*
* [@joanes:1998]: http://dx.doi.org/10.1111/1467-9884.00122
*
* @returns {Function} accumulator function
*
* @example
* var accumulator = incrkurtosis();
*
* var kurtosis = accumulator();
* // returns null
*
* kurtosis = accumulator( 2.0 );
* // returns null
*
* kurtosis = accumulator( 2.0 );
* // returns null
*
* kurtosis = accumulator( -4.0 );
* // returns null
*
* kurtosis = accumulator( -4.0 );
* // returns -6.0
*/
function incrkurtosis() {
	var deltaN2 = 0;
	var deltaN = 0;
	var delta = 0;
	var term1 = 0;
	var mean = 0;
	var M2 = 0;
	var M3 = 0;
	var M4 = 0;
	var N = 0;
	var g2;
	/**
	* If provided a value, the accumulator function returns an updated corrected sample excess kurtosis. If not provided a value, the accumulator function returns the current corrected sample excess kurtosis.
	*
	*
	* @private
	* @param {number} [x] - new value
	* @returns {number} corrected sample excess kurtosis
	*
	* @example
	* var kurtosis = accumulator();
	* // returns null
	*
	* kurtosis = accumulator( 2.0 );
	* // returns null
	*
	* kurtosis = accumulator( 2.0 );
	* // returns null
	*
	* kurtosis = accumulator( -4.0 );
	* // returns null
	*
	* kurtosis = accumulator( -4.0 );
	* // returns -6.0
	*/
	return function accumulator( x ) {
		if ( arguments.length === 0 ) {
			if ( N < 4 ) {
				return null;
			}
			// Calculate the population excess kurtosis:
			g2 = ( N*M4 ) / ( M2*M2 ) - 3.0;
			// Return the corrected sample excess kurtosis:
			return (N-1) / ( (N-2)*(N-3) ) * ( (N+1)*g2 + 6.0 );
		}
		N += 1;
		delta = x - mean;
		deltaN = delta / N;
		deltaN2 = deltaN * deltaN;

		term1 = delta * deltaN * (N-1);

		M4 += term1 * deltaN2 * (N*N - 3*N + 3) + 6.0 * deltaN2 * M2 - 4.0 * deltaN * M3;
		M3 += term1 * deltaN * (N-2) - 3.0 * deltaN * M2;
		M2 += term1;
		mean += deltaN;
		if ( N < 4 ) {
			return null;
		}
		// Calculate the population excess kurtosis:
		g2 = N*M4 / ( M2*M2 ) - 3.0;

		// Return the corrected sample excess kurtosis:
		return (N-1) / ( (N-2)*(N-3) ) * ( (N+1)*g2 + 6.0 );
	};
} // end FUNCTION incrkurtosis()


// EXPORTS //

module.exports = incrkurtosis;

Move extended comment to parent function and make internal function private