/// <summary> /// Computes the given harmonic number. /// </summary> /// <param name="n">The index of the harmonic number to compute, which must be non-negative.</param> /// <returns>The harmonic number H<sub>n</sub>.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="n"/> is negative.</exception> /// <remarks> /// <para>H<sub>n</sub> is the nth partial sum of the harmonic series.</para> /// <img src="..\images\HarmonicSeries.png" /> /// <para>Since the harmonic series diverges, H<sub>n</sub> grows without bound as n increases, but /// it does so extremely slowly, approximately as log(n).</para> /// </remarks> /// <exception cref="ArgumentOutOfRangeException"><paramref name="n"/> is negative.</exception> /// <seealso href="http://en.wikipedia.org/wiki/Harmonic_series_(mathematics)"/> public static double HarmonicNumber(int n) { if (n < 0) { throw new ArgumentOutOfRangeException(nameof(n)); } else if (n < 32) { // for small values, just add up the harmonic series double H = 0.0; for (int i = 1; i <= n; i++) { H += 1.0 / i; } return(H); } else { // for large values, use the digamma function // this will route to the the Stirling asymptotic expansion return(AdvancedMath.Psi(n + 1) + AdvancedMath.EulerGamma); } }