def scipy_modified_levy(x, alpha, beta, mu=0.0, sigma=1.0, a=0, b=np.inf, cdf=False): """ Levy distribution with the tail replaced by the analytical (power law) approximation. `alpha` in (0, 2] is the index of stability, or characteristic exponent. `beta` in [-1, 1] is the skewness. `mu` in the reals and `sigma` > 0 are the location and scale of the distribution (corresponding to `delta` and `gamma` in Nolan's notation; note that sigma in levy corresponds to sqrt(2) sigma in the Normal distribution). 'a' and 'b' are the cut off limits for the distribution. Both a and b are > 0 and the distribution is built on the assumption. It uses parametrization 0 (to get it from another parametrization, convert). Example: >>> x = np.array([1, 2, 3]) >>> modified_levy(x, 1.5, 0, a=0.1, b=3.1) array([0.23897864, 0.09999616, 0.0372704]) :param x: values where the function is evaluated :type x: :class:`~numpy.ndarray` :param alpha: alpha :type alpha: float :param beta: beta :type beta: float :param mu: mu :type mu: float :param sigma: sigma :type sigma: float :param a: a :type a: float :param b: b :type b: float :return: values of the pdf (or cdf if parameter 'cdf' is set to True) at 'x' :rtype: :class:`~numpy.ndarray` """ if x == 0: raise ValueError else: if cdf == False: if b == np.inf: return levy_stable.pdf(x, alpha, beta, loc=mu, scale=sigma) / 2 / (1 - levy_stable.cdf(x, alpha, beta, loc=mu, scale=sigma)) else: return levy_stable.pdf(x, alpha, beta, loc=mu, scale=sigma) / 2 / (levy_stable.cdf(b, alpha, beta, loc=mu, scale=sigma) - levy_stable.cdf(a, alpha, beta, loc=mu, scale=sigma)) else: if x < 0: return (levy_stable.cdf(x, alpha, beta, loc=mu, scale=sigma) - levy_stable.cdf(-b, alpha, beta, loc=mu, scale=sigma)) / 2 / (levy_stable.cdf(b, alpha, beta, loc=mu, scale=sigma) - levy_stable.cdf(a, alpha, beta, loc=mu, scale=sigma)) else: return (levy_stable.cdf(x, alpha, beta, loc=mu, scale=sigma) - levy_stable.cdf(a, alpha, beta, loc=mu, scale=sigma)) / 2 / (levy_stable.cdf(b, alpha, beta, loc=mu, scale=sigma) - levy_stable.cdf(a, alpha, beta, loc=mu, scale=sigma))
def plot_marginal(self, bounds=(-.5, .5), bins=50, show=False): """ Plot a histogram of the marginal distribution of increments, with the expected PDF overlayed on top of it :param bounds: largest increments to be included in histogram :param bins: number of bins in histogram of empirical distribution :param show: show the plot when done :type bounds: tuple :type bins: int :type show: bool """ x = np.linspace(bounds[0], bounds[1], 1000) hist, bin_edges = np.histogram(self.noise.flatten(), bins=bins, range=bounds, density=True) # account for part of PDF that is chopped off. Using density=True makes hist sum to 1 area_covered = levy_stable.cdf(bounds[1], self.alpha, 0, loc=0, scale=self.scale) - \ levy_stable.cdf(bounds[0], self.alpha, 0, loc=0, scale=self.scale) hist *= area_covered # plot bars. Can't use plt.hist since I needed to modify the bin heights bin_width = bin_edges[1] - bin_edges[0] bin_centers = [i + bin_width / 2 for i in bin_edges[:-1]] plt.bar(bin_centers, hist, width=bin_width) plt.plot(x, levy_stable.pdf(x, self.alpha, 0, loc=0, scale=self.scale), '--', color='black', lw=2) # print(np.abs(x).sum(), levy_stable.pdf(x, self.alpha, 0, loc=0, scale=self.scale).sum()) # exit() # formatting plt.xlabel('Step Size', fontsize=14) plt.ylabel('Frequency', fontsize=14) plt.gcf().get_axes()[0].tick_params(labelsize=14) plt.tight_layout() if show: plt.show()
def cdf(x): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", category=IntegrationWarning) result = levy_stable.cdf(x, alpha, beta) # Scipy has only an experimental .cdf() function for alpha=1, beta!=0. # It sometimes passes and sometimes xfails. if w and alpha == 1 and beta != 0: pytest.xfail(reason="scipy.stats.levy_stable.cdf is unstable") return result
x = np.linspace(levy_stable.ppf(0.01, alpha, beta), levy_stable.ppf(0.99, alpha, beta), 100) ax.plot(x, levy_stable.pdf(x, alpha, beta), 'r-', lw=5, alpha=0.6, label='levy_stable pdf') # Alternatively, the distribution object can be called (as a function) # to fix the shape, location and scale parameters. This returns a "frozen" # RV object holding the given parameters fixed. # Freeze the distribution and display the frozen ``pdf``: rv = levy_stable(alpha, beta) ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf') # Check accuracy of ``cdf`` and ``ppf``: vals = levy_stable.ppf([0.001, 0.5, 0.999], alpha, beta) np.allclose([0.001, 0.5, 0.999], levy_stable.cdf(vals, alpha, beta)) # True # Generate random numbers: r = levy_stable.rvs(alpha, beta, size=1000) # And compare the histogram: ax.hist(r, density=True, histtype='stepfilled', alpha=0.2) ax.legend(loc='best', frameon=False) plt.show()
def scipy_levy(x, alpha, beta, mu=0.0, sigma=1.0, cdf=False): if cdf == False: return levy_stable.pdf(x, alpha, beta, loc=mu, scale=sigma) else: return levy_stable.cdf(x, alpha, beta, loc=mu, scale=sigma)
def cdf(x, alpha, beta): if alpha != 1: x += beta * tan(pi * alpha / 2) return levy_stable.cdf(x, alpha, beta)
#which is the number of distribution parameters chisqnorm, pvalnorm = st.chisquare(observed, expected, ddof=2) print("Chi-square for normal =", chisqnorm) print("Normal skew =", skew(z), ";\nexcess kurtosis =", kurtosis(z)) #Levy-stable fit [al, be, de, ga] = levy_stable._fitstart(z) print("Levy stable fit parameters:", al, be, de, ga) #Calculate chi-square test statistic: k = 34 #number of bins in histogram #use numpy histogram for the expected value observed, hist_binedges = np.histogram(z, bins=k) #use the cumulative density function (c.d.f.) #of the distribution for the expected value: cdf = levy_stable.cdf(hist_binedges, al, be, de, ga) expected = len(z) * np.diff(cdf) #use scipy.stats chisquare function, where #ddof is the adjustment to the k-1 degrees of freedom, #which is the number of distribution parameters chisqlevy, pvallevy = st.chisquare(observed, expected, ddof=4) print("Chi-square for levy stable =", chisqlevy) #Plotting matplotlib.style.use('ggplot') data = pd.Series(z) #determines left and right limits of fit displayed (adjust numbers for more/less) x = np.linspace(norm.ppf(0.001, mean, var), norm.ppf(0.999, mean, var), 1000) y = norm.pdf(x, mean, var)