///|
let k0_arrA : ReadOnlyArray[Double] = [
  1.37446543561352307156E-16, 4.25981614279661018399E-14, 1.03496952576338420167E-11,
  1.90451637722020886025E-9, 2.53479107902614945675E-7, 2.28621210311945178607E-5,
  1.26461541144692592338E-3, 3.59799365153615016266E-2, 3.44289899924628486886E-1,
  -5.35327393233902768720E-1,
]

///|
let k0_arrB : ReadOnlyArray[Double] = [
  5.30043377268626276149E-18, -1.64758043015242134646E-17, 5.21039150503902756861E-17,
  -1.67823109680541210385E-16, 5.51205597852431940784E-16, -1.84859337734377901440E-15,
  6.34007647740507060557E-15, -2.22751332699166985548E-14, 8.03289077536357521100E-14,
  -2.98009692317273043925E-13, 1.14034058820847496303E-12, -4.51459788337394416547E-12,
  1.85594911495471785253E-11, -7.95748924447710747776E-11, 3.57739728140030116597E-10,
  -1.69753450938905987466E-9, 8.57403401741422608519E-9, -4.66048989768794782956E-8,
  2.76681363944501510342E-7, -1.83175552271911948767E-6, 1.39498137188764993662E-5,
  -1.28495495816278026384E-4, 1.56988388573005337491E-3, -3.14481013119645005427E-2,
  2.44030308206595545468E0,
]

///|
/// Returns modified Bessel function of the third kind of order zero of the argument.
pub fn bessel_k0(x : Double) -> Double {
  if x <= 0.0 {
    return @double.not_a_number
  }
  if x <= 2.0 {
    let y = x * x - 2.0
    let y = chbevl(y, k0_arrA) - log(0.5 * x) * bessel_i0(x)
    return y
  }
  let z = 8.0 / x - 2.0
  return exp(-x) * chbevl(z, k0_arrB) / sqrt(x)
}

///|
/// `k0` is an alias for `bessel_k0`.
pub let k0 : (Double) -> Double = bessel_k0