AIM-PIbd-32-Kurbanova-A-A/aimenv/Lib/site-packages/statsmodels/distributions/copula/_special.py

111 lines
2.4 KiB
Python
Raw Normal View History

2024-10-02 22:15:59 +04:00
"""
Special functions for copulas not available in scipy
Created on Jan. 27, 2023
"""
import numpy as np
from scipy.special import factorial
class Sterling1():
"""Stirling numbers of the first kind
"""
# based on
# https://rosettacode.org/wiki/Stirling_numbers_of_the_first_kind#Python
def __init__(self):
self._cache = {}
def __call__(self, n, k):
key = str(n) + "," + str(k)
if key in self._cache.keys():
return self._cache[key]
if n == k == 0:
return 1
if n > 0 and k == 0:
return 0
if k > n:
return 0
result = sterling1(n - 1, k - 1) + (n - 1) * sterling1(n - 1, k)
self._cache[key] = result
return result
def clear_cache(self):
"""clear cache of Sterling numbers
"""
self._cache = {}
sterling1 = Sterling1()
class Sterling2():
"""Stirling numbers of the second kind
"""
# based on
# https://rosettacode.org/wiki/Stirling_numbers_of_the_second_kind#Python
def __init__(self):
self._cache = {}
def __call__(self, n, k):
key = str(n) + "," + str(k)
if key in self._cache.keys():
return self._cache[key]
if n == k == 0:
return 1
if (n > 0 and k == 0) or (n == 0 and k > 0):
return 0
if n == k:
return 1
if k > n:
return 0
result = k * sterling2(n - 1, k) + sterling2(n - 1, k - 1)
self._cache[key] = result
return result
def clear_cache(self):
"""clear cache of Sterling numbers
"""
self._cache = {}
sterling2 = Sterling2()
def li3(z):
"""Polylogarithm for negative integer order -3
Li(-3, z)
"""
return z * (1 + 4 * z + z**2) / (1 - z)**4
def li4(z):
"""Polylogarithm for negative integer order -4
Li(-4, z)
"""
return z * (1 + z) * (1 + 10 * z + z**2) / (1 - z)**5
def lin(n, z):
"""Polylogarithm for negative integer order -n
Li(-n, z)
https://en.wikipedia.org/wiki/Polylogarithm#Particular_values
"""
if np.size(z) > 1:
z = np.array(z)[..., None]
k = np.arange(n+1)
st2 = np.array([sterling2(n + 1, ki + 1) for ki in k])
res = (-1)**(n+1) * np.sum(factorial(k) * st2 * (-1 / (1 - z))**(k+1),
axis=-1)
return res