function lgammaComplex (n) {
    const TWOPI = 6.2831853071795864769252842 // 2*pi
    const LOGPI = 1.1447298858494001741434262 // log(pi)

    const REFLECTION = 0.1

    if (n.isNaN()) {
      return new Complex(NaN, NaN)
    } else if (n.im === 0) {
      return new Complex(lgammaNumber(n.re), 0)
    } else if (n.re >= SMALL_RE || Math.abs(n.im) >= SMALL_IM) {
      return lgammaStirling(n)
    } else if (n.re <= REFLECTION) {
      // Reflection formula. see Proposition 3.1 in [1]
      const tmp = copysign(TWOPI, n.im) * Math.floor(0.5 * n.re + 0.25)
      const a = n.mul(Math.PI).sin().log()
      const b = lgammaComplex(new Complex(1 - n.re, -n.im))
      return new Complex(LOGPI, tmp).sub(a).sub(b)
    } else if (n.im >= 0) {
      return lgammaRecurrence(n)
    } else {
      return lgammaRecurrence(n.conjugate()).conjugate()
    }
  }
Logarithm of the gamma function for real, positive numbers and complex numbers,
using Lanczos approximation for numbers and Stirling series for complex numbers.

Syntax:

   math.lgamma(n)

Examples:

   math.lgamma(5)       // returns 3.178053830347945
   math.lgamma(0)       // returns Infinity
   math.lgamma(-0.5)    // returns NaN
   math.lgamma(math.i)  // returns -0.6509231993018536 - 1.8724366472624294i

See also:

   gamma

@param {number | Complex} n   A real or complex number
@return {number | Complex}    The log gamma of `n`