/// <summary> /// Returns the matrix of interpolation coefficients. /// </summary> /// <param name="points">Number of points</param> /// <returns>Matrix</returns> public static float[,] GetCoefficients(int points) { // Compute difference coefficient table float fac = Special.Factorial(points); float[,] deltas = new float[points, points]; float h, delta; int j, k; // do job for (j = 0; j < points; j++) { h = 1.0f; delta = j; for (k = 0; k < points; k++) { deltas[j, k] = h / Special.Factorial(k); h *= delta; } } // matrix invert deltas = Matrice.Invert(deltas); //// rounding //for (j = 0; j < points; j++) // for (k = 0; k < points; k++) // deltas[j, k] = (Math.Round(deltas[j, k] * fac, MidpointRounding.AwayFromZero)) / fac; return(deltas); }
/// <summary> /// Creates the interpolation coefficients. /// </summary> /// <param name="points">The number of points in the tableau.</param> /// private static double[][,] createInterpolationCoefficients(int points) { // Compute difference coefficient table double[][,] c = new double[points][, ]; double fac = Special.Factorial(points); for (int i = 0; i < points; i++) { double[,] deltas = new double[points, points]; for (int j = 0; j < points; j++) { double h = 1.0; double delta = j - i; for (int k = 0; k < points; k++) { deltas[j, k] = h / Special.Factorial(k); h *= delta; } } c[i] = Matrix.Inverse(deltas); for (int j = 0; j < points; j++) { for (int k = 0; k < points; k++) { c[i][j, k] = (Math.Round(c[i][j, k] * fac, MidpointRounding.AwayFromZero)) / fac; } } } return(c); }
/// <summary> /// Initializes a new instance of the <see cref="MultinomialDistribution"/> class. /// </summary> /// <param name="numberOfTrials">The total number of trials N.</param> /// <param name="probabilities">A vector containing the probabilities of seeing each of possible outcomes.</param> public MultinomialDistribution(int numberOfTrials, params double[] probabilities) : base(probabilities.Length) { N = numberOfTrials; this.probabilities = probabilities; nfac = Special.Factorial(numberOfTrials); }
/// <summary> /// Returns the value of the probability density function. /// </summary> /// <param name="x">Value</param> /// <returns>float precision floating point number</returns> public float Function(float x) { if (x < 0) { return(0); } return((float)Math.Exp(-l) * (float)Math.Pow(l, x) / Special.Factorial(x)); }
/// <summary> /// Returns the value of the probability distribution function. /// </summary> /// <param name="x">Value</param> /// <returns>float precision floating point number</returns> public float Distribution(float x) { if (x < 0) { return(float.NaN); } return(Special.GammaIncomplete(k, lambda * x) / Special.Factorial(k - 1)); }
/// <summary> /// Returns the value of the wavelet function. /// </summary> /// <param name="x">Argument</param> /// <returns>Function</returns> public float Wavelet(float x) { if (x < 0) { return(0); } return((x - n) / Special.Factorial(n) * (float)Math.Pow(x, n - 1) * (float)Math.Exp(-x)); }
private void createCoefficients(int degree) { coefficients = new double[degree]; for (int i = 0; i < coefficients.Length; i++) { coefficients[i] = Math.Sqrt(Math.Pow(2 * gaussian.Gamma, i + 1) / Special.Factorial(i + 1)); } }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="k"> /// A single point in the distribution range.</param> /// /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>k</c> will occur. /// </remarks> /// /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution.</returns> /// public override double ProbabilityMassFunction(int k) { if (k < 0) { return(0); } return((Math.Pow(lambda, k) / Special.Factorial(k)) * epml); }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// <param name="x">A single point in the distribution range.</param> /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution. /// </returns> /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> public override double ProbabilityMassFunction(int[] x) { double theta = 1.0; double prod = 1.0; for (int i = 0; i < x.Length; i++) { theta *= Special.Factorial(x[i]); prod *= System.Math.Pow(probabilities[i], x[i]); } return((nfac / theta) * prod); }
public void FactorialTest() { int n = 3; double expected = 6; double actual = Special.Factorial(n); Assert.AreEqual(expected, actual); n = 35; expected = 1.033314796638614e+40; actual = Special.Factorial(n); Assert.AreEqual(expected, actual, 1e27); }
/// <summary> /// /// </summary> /// <param name="l"></param> /// <returns></returns> private float Row(float l) { float sum = 0; int k, n = 20; float fac; for (k = 0; k < n; k++) { fac = Special.Factorial(k); sum += (float)Math.Pow(l, k) * (float)Math.Log(fac) / fac; } return(sum); }
/// <summary> /// Gets the cumulative distribution function (cdf) for /// this distribution evaluated at point <c>k</c>. /// </summary> /// /// <param name="k"> /// A single point in the distribution range.</param> /// /// <remarks> /// The Cumulative Distribution Function (CDF) describes the cumulative /// probability that a given value or any value smaller than it will occur. /// </remarks> /// public override double DistributionFunction(int k) { if (k < 0) { return(0); } if (k >= Int32.MaxValue) { return(1); } return(Gamma.LowerIncomplete(k + 1, lambda) / Special.Factorial(k)); }
/// <summary> /// Creates the interpolation coefficient table for interpolated numerical differentation. /// </summary> /// /// <param name="numberOfPoints">The number of points in the tableau.</param> /// public static double[][,] CreateCoefficients(int numberOfPoints) { if (numberOfPoints % 2 != 1) { throw new ArgumentException("The number of points must be odd.", "numberOfPoints"); } // Compute difference coefficient table double[][,] c = new double[numberOfPoints][, ]; // [center][order, i]; double fac = Special.Factorial(numberOfPoints); for (int i = 0; i < numberOfPoints; i++) { var deltas = new double[numberOfPoints, numberOfPoints]; for (int j = 0; j < numberOfPoints; j++) { double h = 1.0; double delta = j - i; for (int k = 0; k < numberOfPoints; k++) { deltas[j, k] = h / Special.Factorial(k); h *= delta; } } c[i] = Matrix.Inverse(deltas); for (int j = 0; j < numberOfPoints; j++) { for (int k = 0; k < numberOfPoints; k++) { c[i][j, k] = (Math.Round(c[i][j, k] * fac, MidpointRounding.AwayFromZero)) / fac; } } } return(c); }
protected override void ProcessInputObject(double value) { WriteObject(Special.Factorial(value)); }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="x"> /// A single point in the distribution range.</param> /// /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution.</returns> /// public override double ProbabilityMassFunction(int x) { return((System.Math.Pow(lambda, x) / Special.Factorial(x)) * epml); }
/// <summary> /// Gets the cumulative distribution function (cdf) for /// this distribution evaluated at point <c>k</c>. /// </summary> /// /// <param name="k"> /// A single point in the distribution range.</param> /// /// <remarks> /// The Cumulative Distribution Function (CDF) describes the cumulative /// probability that a given value or any value smaller than it will occur. /// </remarks> /// public override double DistributionFunction(int k) { return(Gamma.LowerIncomplete(k + 1, lambda) / Special.Factorial(k)); }
/// <summary> /// Gets the cumulative distribution function (cdf) for /// the this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="x"> /// A single point in the distribution range.</param> /// /// <remarks> /// The Cumulative Distribution Function (CDF) describes the cumulative /// probability that a given value or any value smaller than it will occur. /// </remarks> /// public override double DistributionFunction(int x) { return(Special.Igam(x + 1, lambda) / Special.Factorial(x)); }
/// <summary> /// Returns the value of the probability density function. /// </summary> /// <param name="x">Value</param> /// <returns>float precision floating point number</returns> public float Function(float x) { if (x < 0) { return(float.NaN); } return((float)Math.Pow(lambda, k) * (float)Math.Pow(x, k - 1) * (float)Math.Exp(-lambda * x) / Special.Factorial(k - 1)); }
/// <summary> /// Computes the Complementary Cumulative Distribution Function (1-CDF) /// for the Kolmogorov-Smirnov statistic's distribution. /// </summary> /// /// <param name="n">The sample size.</param> /// <param name="x">The Kolmogorov-Smirnov statistic.</param> /// <returns>Returns the complementary cumulative probability of the statistic /// <paramref name="x"/> under a sample size <paramref name="n"/>.</returns> /// public static double ComplementaryDistributionFunction(double n, double x) { double nxx = n * x * x; // nx² // First of all, check if the given values do not represent // a special case. There are some combination of values for // which the distribution has a known, exact solution. // Ruben-Gambino's Complement if (x >= 1.0 || nxx >= 370.0) { return(0.0); } if (x <= 0.5 / n || nxx <= 0.0274) { return(1.0); } if (n == 1) { return(2.0 - 2.0 * x); } if (x <= 1.0 / n) { return((n <= 20) ? 1.0 - Special.Factorial(n) * Math.Pow(2.0 * x - 1.0 / n, n) : 1.0 - Math.Exp(Special.LogFactorial(n) + n * Math.Log(2.0 * x - 1.0 / n))); } if (x >= 1.0 - 1.0 / n) { return(2.0 * Math.Pow(1.0 - x, n)); } // This is not a special case. Continue processing to // select the most adequate method for the given inputs if (n <= 140) { // This is the first region (i) of the complementary // CDF as detailed in Simard's paper. It is further // divided into two sub-regions. if (nxx >= 4.0) { // For x close to one, Simard's advocates the use of the one- // sided Kolmogorov-Smirnov statistic as given by Miller (1956). return(2 * OneSideUpperTail(n, x)); } else { // For higher values of x, the direct cumulative // distribution will be giving enough precision. return(1.0 - CumulativeFunction(n, x)); } } else { // This is the second region (ii) of the complementary // CDF discussed in Simard's paper. It is again divided // into two sub-regions depending on the value of nx². if (nxx >= 2.2) { // In this region, the Miller approximation returns // at least 6 digits of precision (Simard, 2010). return(2 * OneSideUpperTail(n, x)); } else { // In this region, the direct cumulative // distribution will give enough precision. return(1.0 - CumulativeFunction(n, x)); } } }
/// <summary> /// Computes the Cumulative Distribution Function (CDF) /// for the Kolmogorov-Smirnov statistic's distribution. /// </summary> /// /// <param name="n">The sample size.</param> /// <param name="x">The Kolmogorov-Smirnov statistic.</param> /// <returns>Returns the cumulative probability of the statistic /// <paramref name="x"/> under a sample size <paramref name="n"/>.</returns> /// /// <remarks> /// <para> /// This function computes the cumulative probability P[Dn <= x] of /// the Kolmogorov-Smirnov distribution using multiple methods as /// suggested by Richard Simard (2010).</para> /// /// <para> /// Simard partitioned the problem of evaluating the CDF using multiple /// approximation and asymptotic methods in order to achieve a best compromise /// between speed and precision. This function follows the same partitioning as /// Simard, which is described in the table below.</para> /// /// <list type="table"> /// <listheader><term>For n <= 140 and:</term></listheader> /// <item><term>1/n > x >= 1-1/n</term><description>Uses the Ruben-Gambino formula.</description></item> /// <item><term>1/n < nx² < 0.754693</term><description>Uses the Durbin matrix algorithm.</description></item> /// <item><term>0.754693 <= nx² < 4</term><description>Uses the Pomeranz algorithm.</description></item> /// <item><term>4 <= nx² < 18</term><description>Uses the complementary distribution function.</description></item> /// <item><term>nx² >= 18</term><description>Returns the constant 1.</description></item></list> /// /// <list type="table"> /// <listheader><term>For 140 < n <= 10^5</term></listheader> /// <item><term>nx² >= 18</term><description>Returns the constant 1.</description></item> /// <item><term>nx^(3/2) < 1.4</term><description>Durbin matrix algorithm.</description></item> /// <item><term>nx^(3/2) > 1.4</term><description>Pelz-Good asymptotic series.</description></item></list> /// /// <list type="table"> /// <listheader><term>For n > 10^5</term></listheader> /// <item><term>nx² >= 18</term><description>Returns the constant 1.</description></item> /// <item><term>nx² < 18</term><description>Pelz-Good asymptotic series.</description></item></list> /// /// </remarks> /// public static double CumulativeFunction(double n, double x) { if (Double.IsNaN(x)) { throw new ArgumentOutOfRangeException("x"); } double nxx = n * x * x; // nx² int nn = (int)Math.Ceiling(n); // First of all, check if the given values do not represent // a special case. There are some combination of values for // which the distribution has a known, exact solution. // Ruben-Gambino if (x >= 1.0 || nxx >= 18.0) { return(1.0); } if (x <= 0.5 / n) { return(0.0); } if (n == 1) { return(2.0 * x - 1.0); } if (x <= 1.0 / n) { return((n <= 20) ? Special.Factorial(n) * Math.Pow(2.0 * x - 1.0 / n, n) : Math.Exp(Special.LogFactorial(n) + n * Math.Log(2.0 * x - 1.0 / n))); } if (x >= 1.0 - 1.0 / n) { return(1.0 - 2.0 * Math.Pow(1.0 - x, n)); } // This is not a special case. Continue processing to // select the most adequate method for the given inputs if (n <= 140) { // This is the first case (i) as referred in Simard's // paper. Use exact algorithms depending on nx² with // at least 13 to 15 decimal digits of precision. // Durbin if (nxx < 0.754693) { return(Durbin(nn, x)); } // Pomeranz if (nxx < 4.0) { return(Pomeranz(nn, x)); } // Complementary CDF return(1.0 - ComplementaryDistributionFunction(n, x)); } else { if (n <= 100000) { // This is the second case (ii) referred in Simard's // paper. Use either the Durbin approximation or the // Pelz-Good asymptotic series depending on nx^(3/2). // Obs: // // x^(3/2) = x^(1 + 1/2) = x*x^(1/2) = x*sqrt(x) // // (n*x) * sqrt(x) <= 1.40 // sqrt((n*x)*(n*x)) * sqrt(x) <= 1.40 // sqrt((n*x)*(n*x) * x) <= 1.40 // (n*x)*(n*x) * x <= 1.96 // // n*n*x*x*x <= 1.96 // if (n * nxx * x <= 1.96) { return(Durbin(nn, x)); } else { return(PelzGood(n, x)); } } else { // This is the third case (iii) as referred in Simard's // paper. Use only the Pelz-Good asymptotic series. return(PelzGood(n, x)); } } }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="k"> /// A single point in the distribution range.</param> /// /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>k</c> will occur. /// </remarks> /// /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution.</returns> /// protected internal override double InnerProbabilityMassFunction(int k) { return((Math.Pow(lambda, k) / Special.Factorial(k)) * epml); }