def function(self, x, y, kappa_0, theta_c, center_x=0, center_y=0, slope=8): """ :param x: angular position (normally in units of arc seconds) :param y: angular position (normally in units of arc seconds) :param kappa_0: central convergence of profile :param theta_c: core radius (in arcsec) :param slope: exponent entering the profile :param center_x: center of halo (in angular units) :param center_y: center of halo (in angular units) :return: lensing potential (in arcsec^2) """ x_ = x - center_x y_ = y - center_y r = np.sqrt(x_**2 + y_**2) r = np.maximum(r, self._s) a_factor_sqrt = np.sqrt((0.5)**(-1. / slope) - 1) if np.isscalar(r) == True: hypgeom = float(kappa_0 / 2 * r**2 * hyp3f2( 1, 1, slope - 0.5, 2, 2, -(a_factor_sqrt * r / theta_c)**2)) else: hypgeom = np.array([ kappa_0 / 2. * r_i**2. * hyp3f2(1, 1, slope - 0.5, 2, 2, -(a_factor_sqrt * r_i / theta_c)**2.) for r_i in r ], dtype=float) return hypgeom
def eval(self, x, order): mp.dps = 25 mp.pretty = True return ( special.poch(1 - self.N, order) * hyp3f2(-order, -x, 1 + order, 1, 1 - self.N, 1) )
def func_ppf(x, a0, b0, a1, b1, p): """Function CDF ratio of beta function for root-finding.""" mp.mp.dps = 100 one = mp.mp.one c = mp.beta(a0 + a1, b0) / (mp.beta(a0, b0) * mp.beta(a1, b1)) c *= mp.mpf(x) ** -a1 / a1 f = mp.hyp3f2(a1, a0 + a1, one - b1, a1 + one, a0 + a1 + b0, one / x) return float(one - c * f) - p
def __compute_surprise_weighted(self, mi, pi, m, p): b1 = mpmath.binomial(pi, mi) b2 = mpmath.binomial(p - pi, m - mi) b3 = mpmath.binomial(p, m) h3f2 = mpmath.hyp3f2(1, mi - m, mi - pi, mi + 1, -m + mi + p - pi + 1, 1) #h3f2 = hyper1([mpf(1),mi-m, mi-pi], [mpf(1),mpf(1)+mi, mi+p-pi-m+mpf(1)], 10, 10) log10cdf = mpmath.log10(b1) + mpmath.log10(b2) + mpmath.log10( h3f2) - mpmath.log10(b3) return -float(log10cdf)
def sf(k, ntotal, ngood, nsample): """ Survival function of the hypergeometric distribution. """ _validate(ntotal, ngood, nsample) h = mpmath.hyp3f2(1, k + 1 - ngood, k + 1 - nsample, k + 2, ntotal + k + 2 - ngood - nsample, 1) num = (mpmath.binomial(nsample, k + 1) * mpmath.binomial(ntotal - nsample, ngood - k - 1)) den = mpmath.binomial(ntotal, ngood) sf = (num / den) * h return sf
def mte1Dsum_tau1(fixedPoints, stoch, cap, N, delta): #MAB """ Function that calculates the Mean Time for Extinction (MTE) using the (found in Mathematica) 1D sum solution for tau(1) n.b. this requires the hypergeometric function from mpmath Args: fixPoints(array): The fixed points of our equations. - THIS IS NOT USED stoch(float): The stochastic variable in our equations cap(array): The capacity of our population. - THIS ONLY SEEMS TO WORK WITH A FLOAT N: Factor that scales the FP such that n << N - really, N=K=cap - THIS IS NOT USED delta: The coefficient which determines the stochasticity of the population. Returns: The Mean Time for extinction """ return abs(float(2*cap*mp.hyp3f2(1,1,1-cap/stoch-delta*cap/(2*stoch),2,(2+delta*cap/2-2*stoch)/(stoch-2),stoch/(stoch-1))/(2+delta*cap-2*stoch)))
def sigma(n, rho): inner0 = n / 2 * mm.log(1 - rho**2) inner1 = mm.log(mm.hyp3f2(3 / 2, n / 2, n / 2, 1 / 2, n / 2 + 1, rho**2)) inner2 = -mm.log(n) inner = mm.mp.e**(inner0 + inner1 + inner2) outer0 = n / 2 * np.log(1 - rho**2) + np.log(abs(rho)) outer1 = 2 * sc.gammaln(n / 2 + 1 / 2) outer2 = mm.log(mm.hyp2f1(n / 2 + 1 / 2, n / 2 + 1 / 2, n / 2 + 1, rho**2)) outer3 = -sc.gammaln(n / 2) outer4 = -sc.gammaln(n / 2 + 1) outer = outer0 + outer1 + outer2 + outer3 + outer4 outer = 2 * outer return float(mm.sqrt(inner - mm.mp.e**(outer)))
def bayesfactor_pearson(r, n, tail='two-sided', method='ly', kappa=1.): """ Bayes Factor of a Pearson correlation. Parameters ---------- r : float Pearson correlation coefficient. n : int Sample size. tail : float Tail of the alternative hypothesis. Can be *'two-sided'*, *'one-sided'*, *'greater'* or *'less'*. *'greater'* corresponds to a positive correlation, *'less'* to a negative correlation. If *'one-sided'*, the directionality is inferred based on the ``r`` value (= *'greater'* if ``r`` > 0, *'less'* if ``r`` < 0). method : str Method to compute the Bayes Factor. Can be *'ly'* (default) or *'wetzels'*. The former has an exact analytical solution, while the latter requires integral solving (and is therefore slower). *'wetzels'* was the default in Pingouin <= 0.2.5. See Notes for details. kappa : float Kappa factor. This is sometimes called the *rscale* parameter, and is only used when ``method`` is *'ly'*. Returns ------- bf : float Bayes Factor (BF10). The Bayes Factor quantifies the evidence in favour of the alternative hypothesis. See also -------- corr : (Robust) correlation between two variables pairwise_corr : Pairwise correlation between columns of a pandas DataFrame bayesfactor_ttest : Bayes Factor of a T-test bayesfactor_binom : Bayes Factor of a binomial test Notes ----- To compute the Bayes Factor directly from the raw data, use the :py:func:`pingouin.corr` function. The two-sided **Wetzels Bayes Factor** (also called *JZS Bayes Factor*) is calculated using the equation 13 and associated R code of [1]_: .. math:: \\text{BF}_{10}(n, r) = \\frac{\\sqrt{n/2}}{\\gamma(1/2)}* \\int_{0}^{\\infty}e((n-2)/2)* log(1+g)+(-(n-1)/2)log(1+(1-r^2)*g)+(-3/2)log(g)-n/2g where :math:`n` is the sample size, :math:`r` is the Pearson correlation coefficient and :math:`g` is is an auxiliary variable that is integrated out numerically. Since the Wetzels Bayes Factor requires solving an integral, it is slower than the analytical solution described below. The two-sided **Ly Bayes Factor** (also called *Jeffreys exact Bayes Factor*) is calculated using equation 25 of [2]_: .. math:: \\text{BF}_{10;k}(n, r) = \\frac{2^{\\frac{k-2}{k}}\\sqrt{\\pi}} {\\beta(\\frac{1}{k}, \\frac{1}{k})} \\cdot \\frac{\\Gamma(\\frac{2+k(n-1)}{2k})}{\\Gamma(\\frac{2+nk}{2k})} \\cdot 2F_1(\\frac{n-1}{2}, \\frac{n-1}{2}, \\frac{2+nk}{2k}, r^2) The one-sided version is described in eq. 27 and 28 of Ly et al, 2016. Please take note that the one-sided test requires the `mpmath <http://mpmath.org/>`_ package. Results have been validated against JASP and the BayesFactor R package. References ---------- .. [1] Ly, A., Verhagen, J. & Wagenmakers, E.-J. Harold Jeffreys’s default Bayes factor hypothesis tests: Explanation, extension, and application in psychology. J. Math. Psychol. 72, 19–32 (2016). .. [2] Wetzels, R. & Wagenmakers, E.-J. A default Bayesian hypothesis test for correlations and partial correlations. Psychon. Bull. Rev. 19, 1057–1064 (2012). Examples -------- Bayes Factor of a Pearson correlation >>> from pingouin import bayesfactor_pearson >>> r, n = 0.6, 20 >>> bf = bayesfactor_pearson(r, n) >>> print("Bayes Factor: %.3f" % bf) Bayes Factor: 10.634 Compare to Wetzels method: >>> bf = bayesfactor_pearson(r, n, method='wetzels') >>> print("Bayes Factor: %.3f" % bf) Bayes Factor: 8.221 One-sided test >>> bf10pos = bayesfactor_pearson(r, n, tail='greater') >>> bf10neg = bayesfactor_pearson(r, n, tail='less') >>> print("BF-pos: %.3f, BF-neg: %.3f" % (bf10pos, bf10neg)) BF-pos: 21.185, BF-neg: 0.082 We can also only pass ``tail='one-sided'`` and Pingouin will automatically infer the directionality of the test based on the ``r`` value. >>> print("BF: %.3f" % bayesfactor_pearson(r, n, tail='one-sided')) BF: 21.185 """ from scipy.special import gamma, betaln, hyp2f1 assert method.lower() in ['ly', 'wetzels'], 'Method not recognized.' assert tail.lower() in ['two-sided', 'one-sided', 'greater', 'less', 'g', 'l', 'positive', 'negative', 'pos', 'neg'] # Wrong input if not np.isfinite(r) or n < 2: return np.nan assert -1 <= r <= 1, 'r must be between -1 and 1.' if tail.lower() != 'two-sided' and method.lower() == 'wetzels': warnings.warn("One-sided Bayes Factor are not supported by the " "Wetzels's method. Switching to method='ly'.") method = 'ly' if method.lower() == 'wetzels': # Wetzels & Wagenmakers, 2012. Integral solving def fun(g, r, n): return exp(((n - 2) / 2) * log(1 + g) + (-(n - 1) / 2) * log(1 + (1 - r**2) * g) + (-3 / 2) * log(g) + - n / (2 * g)) integr = quad(fun, 0, np.inf, args=(r, n))[0] bf10 = np.sqrt((n / 2)) / gamma(1 / 2) * integr else: # Ly et al, 2016. Analytical solution. k = kappa lbeta = betaln(1 / k, 1 / k) log_hyperterm = log(hyp2f1(((n - 1) / 2), ((n - 1) / 2), ((n + 2 / k) / 2), r**2)) bf10 = exp((1 - 2 / k) * log(2) + 0.5 * log(pi) - lbeta + lgamma((n + 2 / k - 1) / 2) - lgamma((n + 2 / k) / 2) + log_hyperterm) if tail.lower() != 'two-sided': # Directional test. # We need mpmath for the generalized hypergeometric function from .utils import _is_mpmath_installed _is_mpmath_installed(raise_error=True) from mpmath import hyp3f2 hyper_term = float(hyp3f2(1, n / 2, n / 2, 3 / 2, (2 + k * (n + 1)) / (2 * k), r**2)) log_term = 2 * (lgamma(n / 2) - lgamma((n - 1) / 2)) - lbeta C = 2**((3 * k - 2) / k) * k * r / (2 + (n - 1) * k) * \ exp(log_term) * hyper_term bf10neg = bf10 - C bf10pos = 2 * bf10 - bf10neg if tail.lower() in ['one-sided']: # Automatically find the directionality of the test based on r bf10 = bf10pos if r >= 0 else bf10neg elif tail.lower() in ['greater', 'g', 'positive', 'pos']: # We expect the correlation to be positive bf10 = bf10pos else: # We expect the correlation to be negative bf10 = bf10neg return bf10