<commit_before>'use strict';

/*
* The original C++ code and copyright notice is from the [Boost library]{@link http://www.boost.org/doc/libs/1_65_0/boost/math/special_functions/detail/polygamma.hpp}.
*
* The implementation follows the original but has been reformatted and modified for JavaScript.
*/

/*
* (C) Copyright <NAME> 2013.
* (C) Copyright <NAME> 2013.
* (C) Copyright <NAME> 2014.
* (C) Copyright <NAME> 2013.
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
*/

// MODULES //

var logger = require( 'debug' );
var isNonNegativeInteger = require( '@stdlib/math/base/assert/is-nonnegative-integer' );
var factorial = require( '@stdlib/math/base/special/factorial' );
var trigamma = require( '@stdlib/math/base/special/trigamma' );
var digamma = require( '@stdlib/math/base/special/digamma' );
var signum = require( '@stdlib/math/base/special/signum' );
var ldexp = require( '@stdlib/math/base/special/ldexp' );
var floor = require( '@stdlib/math/base/special/floor' );
var trunc = require( '@stdlib/math/base/special/trunc' );
var zeta = require( '@stdlib/math/base/special/riemann-zeta' );
var abs = require( '@stdlib/math/base/special/abs' );
var min = require( '@stdlib/math/base/special/min' );
var PINF = require( '@stdlib/constants/math/float64-pinf' );
var NINF = require( '@stdlib/constants/math/float64-ninf' );
var MAX = require( '@stdlib/constants/math/float64-max' );
var PI = require( '@stdlib/constants/math/float64-pi' );
var attransitionplus = require( './attransitionplus.js' );
var atinfinityplus = require( './atinfinityplus.js' );
var polycotpi = require( './polycotpi.js' );
var nearzero = require( './nearzero.js' );


// VARIABLES //

var debug = logger( 'polygamma' );
var DIGITS_BASE10 = 19;


// MAIN //

/**
* Evaluates the polygamma function.
*
* @param {NonNegativeInteger} n - order of derivative
* @param {number} x - input value
* @returns {number} (n+1)'th derivative
*
* @example
* var v = polygamma( 3, 1.2 );
* // returns ~3.245
*
* @example
* var v = polygamma( 5, 1.2 );
* // returns ~41.39
*
* @example
* var v = polygamma( 3, -4.9 );
* // returns ~60014.239
*
* @example
* var v = polygamma( 2.5, -1.2 );
* // returns NaN
*
* @example
* var v = polygamma( -1, 5.3 );
* // returns NaN
*
* @example
* var v = polygamma( 2, 0.0 );
* // returns NaN
*
* @example
* var v = polygamma( 2, -1.0 );
* // returns NaN
*
* @example
* var v = polygamma( 2, -2.0 );
* // returns NaN
*
* @example
* var v = polygamma( NaN, 2.1 );
* // returns NaN
*
* @example
* var v = polygamma( 1, NaN );
* // returns NaN
*
* @example
* var v = polygamma( NaN, NaN );
* // returns NaN
*/
function polygamma( n, x ) {
	var xSmallLimit;
	var result;
	var z;

	if ( !isNonNegativeInteger( n ) ) {
		return NaN;
	}
	if ( n === 0 ) {
		return digamma( x );
	}
	if ( n === 1 ) {
		return trigamma( x );
	}
	if ( x < 0.0 ) {
		if ( floor(x) === x ) {
			// Result is infinity if x is odd, and a pole error if x is even.
			if ( trunc( x ) & 1 ) {
				return PINF;
			}
			debug( 'Evaluation at negative integer: %d.', x );
			return NaN;
		}
		z = 1.0 - x;
		result = polygamma( n, z ) + ( PI * polycotpi( n, z, x ) );
		return ( n & 1 ) ? -result : result;
	}
	// Limit for use of small-x series is chosen so that the series doesn't go too divergent in the first few terms. Ordinarily, this would mean setting the limit to `~1/n`, but we can tolerate a small amount of divergence:
	xSmallLimit = min( 5.0 / n, 0.25 );
	if ( x < xSmallLimit ) {
		return nearzero( n, x );
	}
	if ( x > ( 0.4 * DIGITS_BASE10 ) + ( 4*n ) ) {
		return atinfinityplus( n, x );
	}
	if ( x === 1.0 ) {
		return ( ( n & 1 ) ? 1.0 : -1.0 ) * factorial( n ) * zeta( n+1 );
	}
	if ( x === 0.5 ) {
		result = ( ( n & 1 ) ? 1.0 : -1.0 ) * factorial( n ) * zeta( n+1 );
		if ( abs( result ) >= ldexp( MAX, -n-1 ) ) {
			return ( signum( result ) === 1 ) ? PINF : NINF;
		}
		result *= ldexp( 1.0, n + 1 ) - 1.0;
		return result;
	}
	return attransitionplus( n, x );
} // end FUNCTION polygamma()

<commit_msg>Update formatting<commit_after>'use strict';

/*
* The original C++ code and copyright notice is from the [Boost library]{@link http://www.boost.org/doc/libs/1_65_0/boost/math/special_functions/detail/polygamma.hpp}.
*
* The implementation follows the original but has been reformatted and modified for JavaScript.
*/

/*
* (C) Copyright <NAME> 2013.
* (C) Copyright <NAME> 2013.
* (C) Copyright <NAME> 2014.
* (C) Copyright <NAME> 2013.
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
*/

// MODULES //

var logger = require( 'debug' );
var isNonNegativeInteger = require( '@stdlib/math/base/assert/is-nonnegative-integer' );
var factorial = require( '@stdlib/math/base/special/factorial' );
var trigamma = require( '@stdlib/math/base/special/trigamma' );
var digamma = require( '@stdlib/math/base/special/digamma' );
var signum = require( '@stdlib/math/base/special/signum' );
var ldexp = require( '@stdlib/math/base/special/ldexp' );
var floor = require( '@stdlib/math/base/special/floor' );
var trunc = require( '@stdlib/math/base/special/trunc' );
var zeta = require( '@stdlib/math/base/special/riemann-zeta' );
var abs = require( '@stdlib/math/base/special/abs' );
var min = require( '@stdlib/math/base/special/min' );
var PINF = require( '@stdlib/constants/math/float64-pinf' );
var NINF = require( '@stdlib/constants/math/float64-ninf' );
var MAX = require( '@stdlib/constants/math/float64-max' );
var PI = require( '@stdlib/constants/math/float64-pi' );
var attransitionplus = require( './attransitionplus.js' );
var atinfinityplus = require( './atinfinityplus.js' );
var polycotpi = require( './polycotpi.js' );
var nearzero = require( './nearzero.js' );


// VARIABLES //

var debug = logger( 'polygamma' );
var DIGITS_BASE10 = 19;


// MAIN //

/**
* Evaluates the polygamma function.
*
* @param {NonNegativeInteger} n - order of derivative
* @param {number} x - input value
* @returns {number} (n+1)'th derivative
*
* @example
* var v = polygamma( 3, 1.2 );
* // returns ~3.245
*
* @example
* var v = polygamma( 5, 1.2 );
* // returns ~41.39
*
* @example
* var v = polygamma( 3, -4.9 );
* // returns ~60014.239
*
* @example
* var v = polygamma( 2.5, -1.2 );
* // returns NaN
*
* @example
* var v = polygamma( -1, 5.3 );
* // returns NaN
*
* @example
* var v = polygamma( 2, 0.0 );
* // returns NaN
*
* @example
* var v = polygamma( 2, -1.0 );
* // returns NaN
*
* @example
* var v = polygamma( 2, -2.0 );
* // returns NaN
*
* @example
* var v = polygamma( NaN, 2.1 );
* // returns NaN
*
* @example
* var v = polygamma( 1, NaN );
* // returns NaN
*
* @example
* var v = polygamma( NaN, NaN );
* // returns NaN
*/
function polygamma( n, x ) {
	var xSmallLimit;
	var result;
	var z;

	if ( !isNonNegativeInteger( n ) ) {
		return NaN;
	}
	if ( n === 0 ) {
		return digamma( x );
	}
	if ( n === 1 ) {
		return trigamma( x );
	}
	if ( x < 0.0 ) {
		if ( floor(x) === x ) {
			// Result is infinity if `x` is odd, and a pole error if `x` is even.
			if ( trunc( x ) & 1 ) {
				return PINF;
			}
			debug( 'Evaluation at negative integer: %d.', x );
			return NaN;
		}
		z = 1.0 - x;
		result = polygamma( n, z ) + ( PI * polycotpi( n, z, x ) );
		return ( n & 1 ) ? -result : result;
	}
	// Limit for use of small-x series is chosen so that the series doesn't go too divergent in the first few terms. Ordinarily, this would mean setting the limit to `~1/n`, but we can tolerate a small amount of divergence:
	xSmallLimit = min( 5.0/n, 0.25 );
	if ( x < xSmallLimit ) {
		return nearzero( n, x );
	}
	if ( x > ( 0.4 * DIGITS_BASE10 ) + ( 4*n ) ) {
		return atinfinityplus( n, x );
	}
	if ( x === 1.0 ) {
		return ( ( n & 1 ) ? 1.0 : -1.0 ) * factorial( n ) * zeta( n+1 );
	}
	if ( x === 0.5 ) {
		result = ( ( n & 1 ) ? 1.0 : -1.0 ) * factorial( n ) * zeta( n+1 );
		if ( abs( result ) >= ldexp( MAX, -n-1 ) ) {
			return ( signum( result ) === 1 ) ? PINF : NINF;
		}
		result *= ldexp( 1.0, n+1 ) - 1.0;
		return result;
	}
	return attransitionplus( n, x );
} // end FUNCTION polygamma()


{'fraction_non_alphanumeric': 0.17677012609117362, 'fraction_numerical': 0.02982541222114452, 'mean_word_length': 3.0836633663366335, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2277526', 'n_tokens_mistral': 3324, 'n_tokens_neox': 3012, 'n_words': 905}