public void ThrowsOnNegativeArgument() { Assert.That(() => SpecialFunctions.Factorial(Int32.MinValue), Throws.TypeOf <ArgumentOutOfRangeException>()); Assert.That(() => SpecialFunctions.Factorial(-1), Throws.TypeOf <ArgumentOutOfRangeException>()); Assert.That(() => SpecialFunctions.FactorialLn(-1), Throws.TypeOf <ArgumentOutOfRangeException>()); }
public void ValidateDensity( [Values(0.1, 0.1, 0.1, 1.0, 1.0, 1.0, Double.PositiveInfinity, Double.PositiveInfinity, Double.PositiveInfinity)] double a, [Values(0.1, 1.0, Double.PositiveInfinity, 0.1, 1.0, Double.PositiveInfinity, 0.1, 1.0, Double.PositiveInfinity)] double b, [Values(1.2, 2.0, 1.1, 1.5, 1.2, 1.5, 5.0, 2.5, 1.0)] double x) { var n = new InverseGamma(a, b); if (x >= 0) { Assert.AreEqual(Math.Pow(b, a) * Math.Pow(x, -a - 1.0) * Math.Exp(-b / x) / SpecialFunctions.Gamma(a), n.Density(x)); } else { Assert.AreEqual(0.0, n.Density(x)); } }
public string DisplayString(double scoreOpt) { return(SpecialFunctions.CreateTabString(Name, VaccineAsString.TotalNumberOfAminoAcids, VaccineAsString.NumberOfComponents, scoreOpt, VaccineAsString.NiceString())); }
public void DiGammaInv(double x, double f) { AssertHelpers.AlmostEqual(x, SpecialFunctions.DiGammaInv(f), 13); }
/// <summary> /// Computes the inverse of the cumulative distribution function (InvCDF) for the distribution /// at the given probability. This is also known as the quantile or percent point function. /// </summary> /// <param name="p">The location at which to compute the inverse cumulative density.</param> /// <returns>the inverse cumulative density at <paramref name="p"/>.</returns> /// <seealso cref="InvCDF"/> public double InverseCumulativeDistribution(double p) { return(_mean - (_stdDev * Constants.Sqrt2 * SpecialFunctions.ErfcInv(2.0 * p))); }
public void BetaRegularized(double a, double b, double x, double f) { AssertHelpers.AlmostEqual(f, SpecialFunctions.BetaRegularized(a, b, x), 12); }
public void Logistic(double x, double p) { AssertHelpers.AlmostEqual(x, SpecialFunctions.Logistic(p), 15); }
/// <summary> /// Computes the probability mass (PMF) at k, i.e. P(X = k). /// </summary> /// <param name="k">The location in the domain where we want to evaluate the probability mass function.</param> /// <returns>the probability mass at location <paramref name="k"/>.</returns> public double Probability(int k) { return(Math.Pow(_lambda, k) / Math.Pow(SpecialFunctions.Factorial(k), _nu) / Z); }
/// <summary> /// Computes the log probability mass (lnPMF) at k, i.e. ln(P(X = k)). /// </summary> /// <param name="k">The location in the domain where we want to evaluate the log probability mass function.</param> /// <returns>the log probability mass at location <paramref name="k"/>.</returns> public double ProbabilityLn(int k) { return(k * Math.Log(_lambda) - _nu * SpecialFunctions.FactorialLn(k) - Math.Log(Z)); }
/// <summary> /// Evaluates the log probability density function for a NormalGamma distribution. /// </summary> /// <param name="mean">The mean of the distribution</param> /// <param name="prec">The precision of the distribution</param> /// <returns>The log of the density value</returns> public double DensityLn(double mean, double prec) { if (double.IsPositiveInfinity(_precisionInvScale) && _meanScale == 0.0) { throw new NotSupportedException(); } if (double.IsPositiveInfinity(_precisionInvScale)) { throw new NotSupportedException(); } if (_meanScale <= 0.0) { throw new NotSupportedException(); } // double e = -0.5 * prec * (mean - _meanLocation) * (mean - _meanLocation) - prec * _precisionInvScale; // return (_precisionShape - 0.5) * System.Math.Log(prec) + _precisionShape * System.Math.Log(_precisionInvScale) + e - Constants.LogSqrt2Pi - SpecialFunctions.GammaLn(_precisionShape); double e = -(0.5 * prec * _meanScale * (mean - _meanLocation) * (mean - _meanLocation)) - (prec * _precisionInvScale); return(((_precisionShape - 0.5) * System.Math.Log(prec)) + (_precisionShape * System.Math.Log(_precisionInvScale)) - (0.5 * System.Math.Log(_meanScale)) + e - Constants.LogSqrt2Pi - SpecialFunctions.GammaLn(_precisionShape)); }
public Vector <double> Apply(Vector <double> value) => value.Map(element => SpecialFunctions.Logistic(element));
/// <summary> /// Событие "Сказана реплика" /// </summary> /// <param name="speechName"></param> public void SpeechSaid(string speechName) { SpecialFunctions.StartStoryEvent(this, SpeechSaidEvent, new StoryEventArgs(speechName, 0)); }
/// <summary> /// Computes the log density of the distribution. /// </summary> /// <param name="x">The locations at which to compute the density.</param> /// <returns>the density at <paramref name="x"/>.</returns> public double DensityLn(double[] x) { if (x == null) { throw new ArgumentNullException("x"); } var shortVersion = x.Length == (_alpha.Length - 1); if ((x.Length != _alpha.Length) && !shortVersion) { throw new ArgumentException("x"); } var term = 0.0; var sumxi = 0.0; var sumalpha = 0.0; for (var i = 0; i < x.Length; i++) { var xi = x[i]; if ((xi <= 0.0) || (xi >= 1.0)) { return(0.0); } term += (_alpha[i] - 1.0) * Math.Log(xi) - SpecialFunctions.GammaLn(_alpha[i]); sumxi += xi; sumalpha += _alpha[i]; } // Calculate x[Length - 1] element, if needed if (shortVersion) { if (sumxi >= 1.0) { return(0.0); } term += (_alpha[_alpha.Length - 1] - 1.0) * Math.Log(1.0 - sumxi) - SpecialFunctions.GammaLn(_alpha[_alpha.Length - 1]); sumalpha += _alpha[_alpha.Length - 1]; } else if (!sumxi.AlmostEqualInDecimalPlaces(1.0, 8)) { return(0.0); } return(term + SpecialFunctions.GammaLn(sumalpha)); }
public void FactorialOverflowsToInfinity() { Assert.AreEqual(Double.PositiveInfinity, SpecialFunctions.Factorial(172)); Assert.AreEqual(Double.PositiveInfinity, SpecialFunctions.Factorial(Int32.MaxValue)); }
public void Beta() { AssertHelpers.AlmostEqual(0.5, SpecialFunctions.Beta(1.0, 2.0), 14); AssertHelpers.AlmostEqual(1.0, SpecialFunctions.Beta(1.0, 1.0), 14); }
/// <summary> /// Computes the probability density of the distribution (PDF) at x, i.e. ∂P(X ≤ x)/∂x. /// </summary> /// <param name="x">The location at which to compute the density.</param> /// <returns>the density at <paramref name="x"/>.</returns> /// <seealso cref="PDF"/> public double Density(double x) { return((Math.Pow(x, (_freedom / 2.0) - 1.0) * Math.Exp(-x / 2.0)) / (Math.Pow(2.0, _freedom / 2.0) * SpecialFunctions.Gamma(_freedom / 2.0))); }
public void BetaIncomplete(double a, double b, double x, double f) { AssertHelpers.AlmostEqual(f, SpecialFunctions.BetaIncomplete(a, b, x), 12); }
/// <summary> /// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x). /// </summary> /// <param name="x">The location at which to compute the log density.</param> /// <returns>the log density at <paramref name="x"/>.</returns> /// <seealso cref="PDFLn"/> public double DensityLn(double x) { return((-x / 2.0) + (((_freedom / 2.0) - 1.0) * Math.Log(x)) - ((_freedom / 2.0) * Math.Log(2)) - SpecialFunctions.GammaLn(_freedom / 2.0)); }
public void Logit(double p, double x) { AssertHelpers.AlmostEqual(x, SpecialFunctions.Logit(p), 15); }
/// <summary> /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). /// </summary> /// <param name="x">The location at which to compute the cumulative distribution function.</param> /// <returns>the cumulative distribution at location <paramref name="x"/>.</returns> /// <seealso cref="CDF"/> public double CumulativeDistribution(double x) { return(SpecialFunctions.GammaLowerRegularized(_freedom / 2.0, x / 2.0)); }
public void DiGamma(double x, double f) { AssertHelpers.AlmostEqual(f, SpecialFunctions.DiGamma(x), 13); }
/// <summary> /// Computes the probability density of the distribution (PDF) at x, i.e. ∂P(X ≤ x)/∂x. /// </summary> /// <param name="freedom">The degrees of freedom (k) of the distribution. Range: k > 0.</param> /// <param name="x">The location at which to compute the density.</param> /// <returns>the density at <paramref name="x"/>.</returns> /// <seealso cref="Density"/> public static double PDF(double freedom, double x) { if (freedom <= 0.0) { throw new ArgumentException(Resources.InvalidDistributionParameters); } return((Math.Pow(x, (freedom / 2.0) - 1.0) * Math.Exp(-x / 2.0)) / (Math.Pow(2.0, freedom / 2.0) * SpecialFunctions.Gamma(freedom / 2.0))); }
/// <summary> /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). /// </summary> /// <param name="x">The location at which to compute the cumulative distribution function.</param> /// <returns>the cumulative distribution at location <paramref name="x"/>.</returns> /// <seealso cref="CDF"/> public double CumulativeDistribution(double x) { return(0.5 * SpecialFunctions.Erfc((_mean - x) / (_stdDev * Constants.Sqrt2))); }
/// <summary> /// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x). /// </summary> /// <param name="freedom">The degrees of freedom (k) of the distribution. Range: k > 0.</param> /// <param name="x">The location at which to compute the density.</param> /// <returns>the log density at <paramref name="x"/>.</returns> /// <seealso cref="DensityLn"/> public static double PDFLn(double freedom, double x) { if (freedom <= 0.0) { throw new ArgumentException(Resources.InvalidDistributionParameters); } return((-x / 2.0) + (((freedom / 2.0) - 1.0) * Math.Log(x)) - ((freedom / 2.0) * Math.Log(2)) - SpecialFunctions.GammaLn(freedom / 2.0)); }
/// <summary> /// Nonsymmetric reduction from Hessenberg to real Schur form. /// </summary> /// <param name="eigenVectors">The eigen vectors to work on.</param> /// <param name="eigenValues">The eigen values to work on.</param> /// <param name="matrixH">Array for internal storage of nonsymmetric Hessenberg form.</param> /// <param name="order">Order of initial matrix</param> /// <remarks>This is derived from the Algol procedure hqr2, /// by Martin and Wilkinson, Handbook for Auto. Comp., /// Vol.ii-Linear Algebra, and the corresponding /// Fortran subroutine in EISPACK.</remarks> static void NonsymmetricReduceHessenberToRealSchur(Matrix <Complex> eigenVectors, Vector <Complex> eigenValues, Complex[,] matrixH, int order) { // Initialize var n = order - 1; var eps = Precision.DoublePrecision; double norm; Complex x, y, z, exshift = Complex.Zero; // Outer loop over eigenvalue index var iter = 0; while (n >= 0) { // Look for single small sub-diagonal element var l = n; while (l > 0) { var tst1 = Math.Abs(matrixH[l - 1, l - 1].Real) + Math.Abs(matrixH[l - 1, l - 1].Imaginary) + Math.Abs(matrixH[l, l].Real) + Math.Abs(matrixH[l, l].Imaginary); if (Math.Abs(matrixH[l, l - 1].Real) < eps * tst1) { break; } l--; } // Check for convergence // One root found if (l == n) { matrixH[n, n] += exshift; eigenValues[n] = matrixH[n, n]; n--; iter = 0; } else { // Form shift Complex s; if (iter != 10 && iter != 20) { s = matrixH[n, n]; x = matrixH[n - 1, n] * matrixH[n, n - 1].Real; if (x.Real != 0.0 || x.Imaginary != 0.0) { y = (matrixH[n - 1, n - 1] - s) / 2.0; z = ((y * y) + x).SquareRoot(); if ((y.Real * z.Real) + (y.Imaginary * z.Imaginary) < 0.0) { z *= -1.0; } x /= y + z; s = s - x; } } else { // Form exceptional shift s = Math.Abs(matrixH[n, n - 1].Real) + Math.Abs(matrixH[n - 1, n - 2].Real); } for (var i = 0; i <= n; i++) { matrixH[i, i] -= s; } exshift += s; iter++; // Reduce to triangle (rows) for (var i = l + 1; i <= n; i++) { s = matrixH[i, i - 1].Real; norm = SpecialFunctions.Hypotenuse(matrixH[i - 1, i - 1].Magnitude, s.Real); x = matrixH[i - 1, i - 1] / norm; eigenValues[i - 1] = x; matrixH[i - 1, i - 1] = norm; matrixH[i, i - 1] = new Complex(0.0, s.Real / norm); for (var j = i; j < order; j++) { y = matrixH[i - 1, j]; z = matrixH[i, j]; matrixH[i - 1, j] = (x.Conjugate() * y) + (matrixH[i, i - 1].Imaginary * z); matrixH[i, j] = (x * z) - (matrixH[i, i - 1].Imaginary * y); } } s = matrixH[n, n]; if (s.Imaginary != 0.0) { s /= matrixH[n, n].Magnitude; matrixH[n, n] = matrixH[n, n].Magnitude; for (var j = n + 1; j < order; j++) { matrixH[n, j] *= s.Conjugate(); } } // Inverse operation (columns). for (var j = l + 1; j <= n; j++) { x = eigenValues[j - 1]; for (var i = 0; i <= j; i++) { z = matrixH[i, j]; if (i != j) { y = matrixH[i, j - 1]; matrixH[i, j - 1] = (x * y) + (matrixH[j, j - 1].Imaginary * z); } else { y = matrixH[i, j - 1].Real; matrixH[i, j - 1] = new Complex((x.Real * y.Real) - (x.Imaginary * y.Imaginary) + (matrixH[j, j - 1].Imaginary * z.Real), matrixH[i, j - 1].Imaginary); } matrixH[i, j] = (x.Conjugate() * z) - (matrixH[j, j - 1].Imaginary * y); } for (var i = 0; i < order; i++) { y = eigenVectors.At(i, j - 1); z = eigenVectors.At(i, j); eigenVectors.At(i, j - 1, (x * y) + (matrixH[j, j - 1].Imaginary * z)); eigenVectors.At(i, j, (x.Conjugate() * z) - (matrixH[j, j - 1].Imaginary * y)); } } if (s.Imaginary != 0.0) { for (var i = 0; i <= n; i++) { matrixH[i, n] *= s; } for (var i = 0; i < order; i++) { eigenVectors.At(i, n, eigenVectors.At(i, n) * s); } } } } // All roots found. // Backsubstitute to find vectors of upper triangular form norm = 0.0; for (var i = 0; i < order; i++) { for (var j = i; j < order; j++) { norm = Math.Max(norm, Math.Abs(matrixH[i, j].Real) + Math.Abs(matrixH[i, j].Imaginary)); } } if (order == 1) { return; } if (norm == 0.0) { return; } for (n = order - 1; n > 0; n--) { x = eigenValues[n]; matrixH[n, n] = 1.0; for (var i = n - 1; i >= 0; i--) { z = 0.0; for (var j = i + 1; j <= n; j++) { z += matrixH[i, j] * matrixH[j, n]; } y = x - eigenValues[i]; if (y.Real == 0.0 && y.Imaginary == 0.0) { y = eps * norm; } matrixH[i, n] = z / y; // Overflow control var tr = Math.Abs(matrixH[i, n].Real) + Math.Abs(matrixH[i, n].Imaginary); if ((eps * tr) * tr > 1) { for (var j = i; j <= n; j++) { matrixH[j, n] = matrixH[j, n] / tr; } } } } // Back transformation to get eigenvectors of original matrix for (var j = order - 1; j > 0; j--) { for (var i = 0; i < order; i++) { z = Complex.Zero; for (var k = 0; k <= j; k++) { z += eigenVectors.At(i, k) * matrixH[k, j]; } eigenVectors.At(i, j, z); } } }
public void Harmonic(int i) { AssertHelpers.AlmostEqual(ExactHarmonic(i), SpecialFunctions.Harmonic(i), 13); }
public static Move MaxOrNull(Move moveOrNull, Move bestMoveOrNull) { CompareZone zone = Zone(moveOrNull); CompareZone bestZone = Zone(bestMoveOrNull); if (zone > bestZone) { return(moveOrNull); } if (bestZone > zone) { return(bestMoveOrNull); } Debug.Assert(bestZone == zone); switch (zone) { case CompareZone.Null: return(null); case CompareZone.LengthIncreases: { double scorePerLength = moveOrNull.ScoreImprovement / (double)moveOrNull.LengthIncrease; double scorePerLengthBest = bestMoveOrNull.ScoreImprovement / (double)bestMoveOrNull.LengthIncrease; if (scorePerLength > scorePerLengthBest) { return(moveOrNull); } else { return(bestMoveOrNull); } } case CompareZone.LengthUnchanged: { if (moveOrNull.ScoreImprovement > bestMoveOrNull.ScoreImprovement) { return(moveOrNull); } else { return(bestMoveOrNull); } } case CompareZone.LengthDecreases: { Debug.Assert(moveOrNull.ScoreImprovement == 0 && bestMoveOrNull.ScoreImprovement == 0); // real assert if (moveOrNull.LengthIncrease < bestMoveOrNull.LengthIncrease) { return(moveOrNull); } else { return(bestMoveOrNull); } } default: { SpecialFunctions.CheckCondition(false, "Unknown zone (shouldn't get here"); return(null); } } }
public void BetaLn() { AssertHelpers.AlmostEqual(System.Math.Log(0.5), SpecialFunctions.BetaLn(1.0, 2.0), 14); AssertHelpers.AlmostEqual(System.Math.Log(1.0), SpecialFunctions.BetaLn(1.0, 1.0), 14); }
/// <summary> /// Symmetric tridiagonal QL algorithm. /// </summary> /// <param name="eigenVectors">The eigen vectors to work on.</param> /// <param name="d">Arrays for internal storage of real parts of eigenvalues</param> /// <param name="e">Arrays for internal storage of imaginary parts of eigenvalues</param> /// <param name="order">Order of initial matrix</param> /// <remarks>This is derived from the Algol procedures tql2, by /// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for /// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding /// Fortran subroutine in EISPACK.</remarks> /// <exception cref="NonConvergenceException"></exception> static void SymmetricDiagonalize(Matrix <float> eigenVectors, float[] d, float[] e, int order) { const int maxiter = 1000; for (var i = 1; i < order; i++) { e[i - 1] = e[i]; } e[order - 1] = 0.0f; var f = 0.0f; var tst1 = 0.0f; var eps = Precision.DoublePrecision; for (var l = 0; l < order; l++) { // Find small subdiagonal element tst1 = Math.Max(tst1, Math.Abs(d[l]) + Math.Abs(e[l])); var m = l; while (m < order) { if (Math.Abs(e[m]) <= eps * tst1) { break; } m++; } // If m == l, d[l] is an eigenvalue, // otherwise, iterate. if (m > l) { var iter = 0; do { iter = iter + 1; // (Could check iteration count here.) // Compute implicit shift var g = d[l]; var p = (d[l + 1] - g) / (2.0f * e[l]); var r = SpecialFunctions.Hypotenuse(p, 1.0f); if (p < 0) { r = -r; } d[l] = e[l] / (p + r); d[l + 1] = e[l] * (p + r); var dl1 = d[l + 1]; var h = g - d[l]; for (var i = l + 2; i < order; i++) { d[i] -= h; } f = f + h; // Implicit QL transformation. p = d[m]; var c = 1.0f; var c2 = c; var c3 = c; var el1 = e[l + 1]; var s = 0.0f; var s2 = 0.0f; for (var i = m - 1; i >= l; i--) { c3 = c2; c2 = c; s2 = s; g = c * e[i]; h = c * p; r = SpecialFunctions.Hypotenuse(p, e[i]); e[i + 1] = s * r; s = e[i] / r; c = p / r; p = (c * d[i]) - (s * g); d[i + 1] = h + (s * ((c * g) + (s * d[i]))); // Accumulate transformation. for (var k = 0; k < order; k++) { h = eigenVectors.At(k, i + 1); eigenVectors.At(k, i + 1, (s * eigenVectors.At(k, i)) + (c * h)); eigenVectors.At(k, i, (c * eigenVectors.At(k, i)) - (s * h)); } } p = (-s) * s2 * c3 * el1 * e[l] / dl1; e[l] = s * p; d[l] = c * p; // Check for convergence. If too many iterations have been performed, // throw exception that Convergence Failed if (iter >= maxiter) { throw new NonConvergenceException(); } } while (Math.Abs(e[l]) > eps * tst1); } d[l] = d[l] + f; e[l] = 0.0f; } // Sort eigenvalues and corresponding vectors. for (var i = 0; i < order - 1; i++) { var k = i; var p = d[i]; for (var j = i + 1; j < order; j++) { if (d[j] < p) { k = j; p = d[j]; } } if (k != i) { d[k] = d[i]; d[i] = p; for (var j = 0; j < order; j++) { p = eigenVectors.At(j, i); eigenVectors.At(j, i, eigenVectors.At(j, k)); eigenVectors.At(j, k, p); } } } }
/// <summary> /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). /// </summary> /// <param name="x">The location at which to compute the cumulative distribution function.</param> /// <returns>the cumulative distribution at location <paramref name="x"/>.</returns> /// <seealso cref="CDF"/> public double CumulativeDistribution(double x) { return(SpecialFunctions.GammaLowerIncomplete(_freedom / 2.0, x / 2.0) / SpecialFunctions.Gamma(_freedom / 2.0)); }