/// <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);
     }
 }