def von_mises(x, alpha, reference=Rotation((1, 0, 0, 0))): """A vastly simplified Von Mises-Fisher distribution calculation. Parameters ---------- x : Rotation alpha : float Lower values of alpha lead to "looser" distributions. reference : Rotation Notes ----- This simplified version of the distribution is calculated using .. math:: \\frac{\\exp\\left(2\\alpha\\cos\\left(\\omega\\right)\\right)}{_0F_1\\left(\\frac{N}{2}, \\alpha^2\\right)} where :math:`\omega` is the angle between orientations and :math:`N` is the number of relevant dimensions, in this case 3. Returns ------- ndarray """ angle = x.angle_with(reference) return np.exp(2 * alpha * np.cos(angle.data)) / hyp0f1(1.5, alpha**2)
def _get_C(self): C = np.empty((self.N, self.K)) for k, j in np.ndindex(self.N, self.K): t = 0.5 if j == 0 else 1 C[k, j] = t * math.exp(-self.shape_param ** 2 * self.in_mesh[0, k]) * self.in_mesh[0, k] ** j * \ hyp0f1(j + 1, self.shape_param ** 4 * self.in_mesh[0, k] ** 2) return C
def noncentral_chisquare_log_pdf( x, ddof, noncentrality ): assert ddof > 0, "ddof must be > 0" assert noncentrality > 0, "noncentrality must be > 0" # this version lacks log modified bessel of first kind # lp = -np.log(2) - 0.5*(x+noncentrality) + (ddof/4.0 - 0.5)*np.log( x / noncentrality ) lp = - 0.5*(x+noncentrality) - 0.5*ddof*np.log(2.0) + (0.5*ddof-1)*np.log(x) - special.gammaln( 0.5*ddof ) lp += np.log( special.hyp0f1( ddof/2.0, noncentrality*x/4.0 ) ) return lp
def noncentral_chisquare_log_pdf(x, ddof, noncentrality): assert ddof > 0, "ddof must be > 0" assert noncentrality > 0, "noncentrality must be > 0" # this version lacks log modified bessel of first kind # lp = -np.log(2) - 0.5*(x+noncentrality) + (ddof/4.0 - 0.5)*np.log( x / noncentrality ) lp = -0.5 * (x + noncentrality) - 0.5 * ddof * np.log(2.0) + ( 0.5 * ddof - 1) * np.log(x) - special.gammaln(0.5 * ddof) lp += np.log(special.hyp0f1(ddof / 2.0, noncentrality * x / 4.0)) return lp
def test_hyp0f1ln(xp): from scipy.special import hyp0f1 if xp == cp: hyp0f1_np = hyp0f1 def hyp0f1(arr1, arr2): # pylint: disable=function-redefined arr1 = xp.asnumpy(arr1) arr2 = xp.asnumpy(arr2) return xp.array(hyp0f1_np(arr1, arr2)) arr1 = xp.array([2.0, 1e-8, 1e5]) arr2 = xp.array([3.0, 2e-8, 2e5]) assert xp.allclose(utils.hyp0f1ln(arr1, arr2), xp.log(hyp0f1(arr1, arr2))) arr2[...] = 0.0 assert xp.allclose(utils.hyp0f1ln(arr1, arr2), 0)
def monopole(uvecs: [float, np.ndarray], order: int = 3) -> [float, np.ndarray]: """ Solution for I(r) = 1. Also handles nonzero-w case. Parameters ---------- uvecs: float or ndarray of float The cartesian baselines in units of wavelengths. If a float, assumed to be the magnitude of the baseline. If an array of one dimension, each entry is assumed to be a magnitude. If a 2D array, may have shape (Nbls, 2) or (Nbls, 3). In the first case, w is assumed to be zero. order: int Expansion order to use for non-flat array case (w != 0). Returns ------- ndarray of complex Visibilities, shape (Nbls,) """ if np.isscalar( uvecs) or uvecs.ndim == 1 or uvecs.shape[1] == 2 or np.allclose( uvecs[:, 2], 0): # w is zero. uamps = vec_to_amp(uvecs) return 2 * np.pi * np.sinc(2 * uamps) uvecs = uvecs[..., None] ks = np.arange(order)[None, :] fac0 = (2 * np.pi * 1j * uvecs[:, 2, :])**ks / (gamma(ks + 2)) fac1 = hyp0f1((3 + ks) / 2, -np.pi**2 * (uvecs[:, 0, :]**2 + uvecs[:, 1, :]**2)) return 2 * np.pi * np.sum(fac0 * fac1, axis=-1)
def test_hyp0f1_complex(self): assert_mpmath_equal(lambda a, z: sc.hyp0f1(a.real, z), _exception_to_nan(lambda a, x: mpmath.hyp0f1(a, x, **HYPERKW)), [Arg(), ComplexArg()])
def _pdf(self, x, df, nc): a = df/2.0 fac = (-nc-x)/2.0 + (a-1)*np.log(x)-a*np.log(2)-special.gammaln(a) fac += np.nan_to_num(np.log(special.hyp0f1(a, nc * x/4.0))) return np.np.exp(fac)
def test_hyp0f1_complex(self): assert_mpmath_equal( lambda a, z: sc.hyp0f1(a.real, z), _exception_to_nan(lambda a, x: mpmath.hyp0f1(a, x, **HYPERKW)), [Arg(), ComplexArg()])