Source code for sstudentt.sstudentt

"""Main module."""

import numpy as np
from scipy import stats
from scipy.special import beta


[docs]class SST: # Init Parameters def __init__(self, mu, sigma, nu, tau): """ Creates an Instance of the Skewed Student T Distribution. In this parameterization the expectation equals mu and standard deviation equals sigma. :param mu: mu parameter :type mu: scalar or array_like :param sigma: sigma parameter :type sigma: scalar or array_like :param nu: nu parameter :type nu: scalar or array_like :param tau: tau parameter :type tau: scalar or array_like """ self.mu = np.asarray(mu).astype(float) self.sigma = np.asarray(sigma).astype(float) self.nu = np.asarray(nu).astype(float) self.tau = np.asarray(tau).astype(float) self.c = 2 * self.nu * ((1 + self.nu ** 2) * beta(0.5, self.tau / 2) * self.tau ** 0.5) ** -1 self.m = ((2 * self.tau ** 0.5) * (self.nu - self.nu ** -1)) / ( (self.tau - 1) * beta(0.5, 0.5 * self.tau)) self.s2 = ((self.tau / (self.tau - 2)) * ( self.nu ** 2 + self.nu ** -2 - 1) - self.m ** 2) self.mu_0 = self.mu - (self.sigma * self.m / np.sqrt(self.s2)) self.sigma_0 = self.sigma / np.sqrt(self.s2) # Density Function
[docs] def d(self, y): """Density Function :param y: distribution values :type y: scalar or array_like :return: density at the specified y values :rtype: array """ mu_0 = self.mu_0 sigma_0 = self.sigma_0 c = self.c nu = self.nu tau = self.tau z = (y - mu_0) / sigma_0 p = np.where(y < mu_0, (c / sigma_0) * (1 + ((nu ** 2) * (z ** 2)) / tau) ** ( -(tau + 1) / 2), (c / sigma_0) * (1 + (z ** 2) / ((nu ** 2) * tau)) ** ( -(tau + 1) / 2)) return p
[docs] def q(self, p): """Quantile Function / Inverse CDF / Percent Point Function :param p: probabilities :type p: scalar or array_like :return: Quantile values corresponding to the specified probabilities. :rtype: array """ p = np.asarray(p).astype(float) mu_0 = self.mu_0 sigma_0 = self.sigma_0 nu = self.nu tau = self.tau # Calculate quantile quantile = np.where(p <= (1 + nu ** 2) ** -1, mu_0 + (sigma_0 / nu) * stats.t.ppf( (p * (1 + nu ** 2)) * 0.5, tau), mu_0 + sigma_0 * nu * stats.t.ppf( (p * (1 + nu ** 2) - 1 + nu ** 2) / ( 2 * nu ** 2), tau) ) return quantile
# Cumulative Distribution Function
[docs] def p(self, q): """Distribution Function :param q: value :type q: scalar or array_like :return: The probability that the SST distributed variable will take a value less than or equal to q. :rtype: array """ nu = self.nu mu_0 = self.mu_0 tau = self.tau sigma_0 = self.sigma_0 # Calculate CDF prob = np.where(q < mu_0, (2 / (1 + nu ** 2)) * stats.t.cdf( x=(nu * (q - mu_0) / sigma_0), df=tau), (1 / (1 + nu ** 2)) * ( 1 + 2 * nu ** 2 * ( stats.t.cdf(x=(q - mu_0) / (sigma_0 * nu), df=tau) - 0.5)) ) return prob
# Draw Random Numbers using Inversion Sampling
[docs] def r(self, n=1): """Draws Random Numbers which Follow the SST Distribution :param n: sample size :type n: int or tuple of return shape, optional :return: random sample drawn from the SST distribution :rtype: array .. note:: n is ignored if the distribution parameters are provided as arrays. In that case, a sample with the shape of the provided arrays will be drawn. i.e. n = 1. """ return self.q(p=np.random.random(size=n))