Beispiel #1
0
    def _combine_polyvals(self, coors, polyvals, idx):

        from scipy.special import eval_jacobi
        if len(idx) == 1:  # 1D
            return nm.prod(polyvals[..., range(len(idx)), idx], axis=-1)
        elif len(idx) == 2:  # 2D
            r = coors[..., 0]
            s = coors[..., 1]
            a = 2 * (1 + r) / (1 - s) - 1
            a[nm.isnan(a)] = -1.
            b = s
            return eval_jacobi(idx[0], 0, 0, a) \
                   * eval_jacobi(idx[1],2 * idx[0] + 1, 0,b) * (1 - b) ** idx[0]
        elif len(idx) == 3:  # 3D
            r = coors[..., 0]
            s = coors[..., 1]
            t = coors[..., 2]
            a = -2 * (1 + r) / (s + t) - 1
            b = 2 * (1 + s) / (1 - t) - t
            c = t
            a[nm.isnan(a)] = -1.
            b[nm.isnan(b)] = -1.
            return eval_jacobi(idx[0], 0, 0, a) * \
                   eval_jacobi(idx[1], 2 * idx[0] + 1, 0, 0, b) * \
                   eval_jacobi(idx[2], 2 * idx[0] + 2 * idx[1] + 2, 0, c) * \
                                                    (1 - c) ** (idx[0] + idx[1])
    def eval_poly_multiD(self, X, normalize='norm'):
        """Evaluate (and potentially normalize) multivariate Jacobi polynomials :math:`P_{k}(x) = \\prod_{i=1}^d P_{k_i}^{a_i, b_i}(x_i)`

        :param X:
            Array of points :math:`\\in [-1, 1]^d`, with size :math:`n\\times d` where :math:`n` is the number of points
        :type X:
            array_like

        :param normalize:
            - 'norm'
            - 'square_norm'
        :type normalize:
            str (default 'norm')

        :return:
            - ``normalize='norm'`` :math:`P_k(X) / \\left\\| P_k \\right\\|`
            - ``normalize='square_norm'`` :math:`P_k(X) / \\left\\| P_k \\right\\|^2`
        :rtype:
            array_like

        .. seealso::

            - evaluation of the kernel :py:meth:`~dppy.multivariate_jacobi_ope.MultivariateJacobiOPE.K`
        """

        if X.size == self.dim:
            poly_1D_jacobi = eval_jacobi(self.poly_1D_degrees,
                                         self.jacobi_params[:, 0],
                                         self.jacobi_params[:, 1], X)

            if normalize == 'square_norm':
                poly_1D_jacobi /= self.poly_1D_square_norms

            elif normalize == 'norm':
                poly_1D_jacobi /= np.sqrt(self.poly_1D_square_norms)

            else:
                pass

            return np.prod(poly_1D_jacobi[self.ordering,
                                          range(self.dim)],
                           axis=1)

        else:
            poly_1D_jacobi = eval_jacobi(self.poly_1D_degrees,
                                         self.jacobi_params[:, 0],
                                         self.jacobi_params[:, 1], X[:, None])

            if normalize == 'square_norm':
                poly_1D_jacobi /= self.poly_1D_square_norms

            elif normalize == 'norm':
                poly_1D_jacobi /= np.sqrt(self.poly_1D_square_norms)

            else:
                pass

            return np.prod(poly_1D_jacobi[:, self.ordering,
                                          range(self.dim)],
                           axis=2)
Beispiel #3
0
def A(i, j, d):
    return quad(
        lambda x: (ks(i, d) * ((math.cos(x)) ** d) * eval_jacobi(i, 0.5 * d - 1, 0.5 * d, math.cos(2 * x)))
        * (ks(j, d) * ((math.cos(x)) ** d) * eval_jacobi(j, 0.5 * d - 1, 0.5 * d, math.cos(2 * x)))
        * math.sin(x)
        * math.cos(x),
        0,
        math.pi / 2.0,
    )[0]
Beispiel #4
0
def __integrand(x1, x2, k1, k2, n, c, t, theta, m, weights):
    x1_eval = eval_jacobi(m, theta - 1, theta - 1,
                          2 * np.expand_dims(x1, -1) - 1)
    x2_eval = eval_jacobi(m, theta - 1, theta - 1,
                          2 * np.expand_dims(x2, -1) - 1)
    jacobi_total = np.sum(x2_eval * x1_eval * weights, axis=-1)
    bc1 = binom_cdf(k1, n, (1 - c) * x1 + c * x2)
    bc2 = binom_cdf(k2, n, c * x1 + (1 - c) * x2)
    return bc1 * bc2 * jacobi_total
Beispiel #5
0
def W10(i, j, k, l, d):
    return dblquad(
        lambda x, y: (ep(i, d)(x))
        * (ep(j, d)(x))
        * math.sin(x)
        * math.cos(x)
        * (ks(l, d) * ((math.cos(y)) ** d) * eval_jacobi(l, 0.5 * d - 1, 0.5 * d, math.cos(2 * y)))
        * (ks(k, d) * ((math.cos(y)) ** d) * eval_jacobi(k, 0.5 * d - 1, 0.5 * d, math.cos(2 * y)))
        * (math.tan(y)) ** (d - 1.0),
        0,
        math.pi / 2,
        lambda x: 0,
        lambda x: x,
    )[0]
Beispiel #6
0
 def test_jacobi(self):
     assert_mpmath_equal(sc.eval_jacobi,
                         _exception_to_nan(lambda a, b, c, x: mpmath.jacobi(a, b, c, x, **HYPERKW)),
                         [Arg(), Arg(), Arg(), Arg()])
     assert_mpmath_equal(lambda n, b, c, x: sc.eval_jacobi(int(n), b, c, x),
                         _exception_to_nan(lambda a, b, c, x: mpmath.jacobi(a, b, c, x, **HYPERKW)),
                         [IntArg(), Arg(), Arg(), Arg()])
 def calcWignerMatrices(self, rot):
     a,b,y = rot
     sinb2 = sin(b/2)
     cosb2 = cos(b/2)
     cosb = cos(b)
     sinb = sin(b)
     Jmax = self.Jmax
     Js, m1s, m2s = self.Js, self.m1s, self.m2s
     Ds = np.zeros((Jmax+1, 2*Jmax+1, 2*Jmax+1), np.complex128)
     grad = np.zeros((3, Jmax+1, 2*Jmax+1, 2*Jmax+1), np.complex128)
     mu = abs(m1s-m2s)
     nu = abs(m1s+m2s)
     s = Js - (mu + nu)/2
     xi = np.ones_like(s)
     xi[m2s<m1s] = (-1)**(m1s-m2s)[m2s<m1s]
     factor = sqrt(factorial(s)*factorial(s+mu+nu)/
                       factorial(s+mu)/factorial(s+nu)) * xi
     jac = eval_jacobi(s, mu, nu, cosb)
     d = (factor * jac * sinb2 ** mu * cosb2 ** nu)
     ##
     gradjac = eval_grad_jacobi(s, mu, nu, cosb) * - sinb
     gradd = (factor * gradjac * sinb2 ** mu * cosb2 ** nu +
                  factor * jac * sinb2 ** (mu-1) * cosb2 ** (nu+1) * mu/2 - 
                  factor * jac * sinb2 ** (mu+1) * cosb2 ** (nu-1) * nu/2)
     ##
     Ds[Js, m1s, m2s] = exp(-1j*m1s*a) * d * exp(-1j*m2s*y)
     grad[0,Js, m1s, m2s] = -1j*m1s * Ds[Js, m1s, m2s]
     grad[1,Js, m1s, m2s] = exp(-1j*m1s*a) * gradd * exp(-1j*m2s*y)
     grad[2,Js, m1s, m2s] = -1j*m2s * Ds[Js, m1s, m2s]
     return Ds, grad
Beispiel #8
0
 def evaluate_basis(self, x, i=0, output_array=None):
     x = np.atleast_1d(x)
     if output_array is None:
         output_array = np.zeros(x.shape)
     output_array[:] = (1 - x**2)**3 * eval_jacobi(
         i, 3, 3, x, out=output_array)
     return output_array
Beispiel #9
0
 def evaluate_basis_derivative(self, x=None, i=0, k=0, output_array=None):
     if x is None:
         x = self.mesh(False, False)
         #x = self.points_and_weights(mode='mpmath')[0]
     dj = np.prod(
         np.array([i + self.alpha + self.beta + 1 + j for j in range(k)]))
     return dj / 2**k * eval_jacobi(i - k, self.alpha + k, self.beta + k, x)
Beispiel #10
0
    def test_square_norms(self):

        N = 100
        dims = np.arange(2, 5)

        max_deg = 50  # to avoid quad warning in dimension 1
        for d in dims:

            jacobi_params = 0.5 - np.random.rand(d, 2)
            jacobi_params[0, :] = -0.5

            dpp = MultivariateJacobiOPE(N, jacobi_params)
            pol_2_eval = dpp.poly_1D_degrees[:max_deg]

            quad_square_norms =\
                [[quad(lambda x:
                        (1-x)**a * (1+x)**b * eval_jacobi(n, a, b, x)**2,
                        -1, 1)[0]
                        for n, a, b in zip(deg,
                                            dpp.jacobi_params[:, 0],
                                            dpp.jacobi_params[:, 1])]
                 for deg in pol_2_eval]

            self.assertTrue(
                np.allclose(
                    dpp.poly_1D_square_norms[pol_2_eval,
                                             range(dpp.dim)],
                    quad_square_norms))
Beispiel #11
0
def jacobi_poly (si,c,alfa, beta):
    phi=[0.]*len(si)
    for i in range(0, len(c)):
        if c[i] != 0:
            for j in range(0, len(si)): 
                phi[j] +=c[i]*sps.eval_jacobi(i, alfa, beta, si[j])
            
    return np.array(phi) 
def jacobi_value(n, a, b, x):
    if (isinstance(n, types.int32) and isinstance(a, types.float64) and\
        isinstance(b, types.float64) and isinstance(x, types.float64)):
        outval = eval_jacobi(n, a, b, x)

        def my_jacobi(n, a, b, x):
            return outval

        return my_jacobi
Beispiel #13
0
 def evaluate_basis(self, x, i=0, output_array=None):
     x = np.atleast_1d(x)
     if output_array is None:
         output_array = np.zeros(x.shape)
     output_array = eval_jacobi(i,
                                self.alpha,
                                self.beta,
                                x,
                                out=output_array)
     return output_array
Beispiel #14
0
def lagrangeToJacobi(t, a, b, axis=0):
    n = t.shape[axis]
    points = chebNodes(n=n)
    JacobiM = np.zeros([n, n])
    for i in range(n):
        JacobiM[:, i] = special.eval_jacobi(i, a, b, points)
    if axis == 0:
        return sp_lin.solve(JacobiM, t)
    else:
        return (sp_lin.solve(JacobiM, t.T))
Beispiel #15
0
 def jacobi(self, x, alpha, beta, N):
     V = np.zeros((x.shape[0], N))
     if mode == 'numpy':
         for n in range(N):
             V[:, n] = eval_jacobi(n, alpha, beta, x)
     else:
         for n in range(N):
             V[:, n] = sp.lambdify(xp, sp.jacobi(n, alpha, beta, xp),
                                   'mpmath')(x)
     return V
def jacobf(z, n, alpha, beta):
    """
    evaluate Jacobi polynomial P_n^{alpha,beta} on a set of points
    :param z: numpy array, values of the points to evaluate Jacobi polynomial on
    :param n: order of Jacobi polynomial in P_n^{alpha,beta}
    :param alpha: parameters, alpha > -1
    :param beta: parameters, beta > -1
    :return: vector of Jacobi polynomial values on these points
    """
    return eval_jacobi(n, alpha, beta, z)
Beispiel #17
0
 def evaluate_basis(self, x, i=0, output_array=None):
     x = np.atleast_1d(x)
     if output_array is None:
         output_array = np.zeros(x.shape)
     if mode == 'numpy':
         output_array[:] = (1 - x**2)**3 * eval_jacobi(
             i, 3, 3, x, out=output_array)
     else:
         f = self.sympy_basis(i, xp)
         output_array[:] = sp.lambdify(xp, f, 'mpmath')(x)
     return output_array
Beispiel #18
0
 def test_jacobi(self):
     assert_mpmath_equal(
         sc.eval_jacobi,
         _exception_to_nan(
             lambda a, b, c, x: mpmath.jacobi(a, b, c, x, **HYPERKW)),
         [Arg(), Arg(), Arg(), Arg()])
     assert_mpmath_equal(
         lambda n, b, c, x: sc.eval_jacobi(int(n), b, c, x),
         _exception_to_nan(
             lambda a, b, c, x: mpmath.jacobi(a, b, c, x, **HYPERKW)),
         [IntArg(), Arg(), Arg(), Arg()])
Beispiel #19
0
    def radial_polynomial(self, rho, m, n):
        # See https://mathworld.wolfram.com/ZernikePolynomial.html
        if (n - m) % 2 == 1:
            print("ODD")
            return 0

        eff_n = (n - m) // 2
        alpha = m
        beta = 0
        x = 1 - 2 * (rho**2.0)
        return (-1)**(eff_n) * (rho**m) * eval_jacobi(eff_n, alpha, beta, x)
Beispiel #20
0
 def jacobi(self, x, alpha, beta, N):
     V = np.zeros((x.shape[0], N))
     if mode == 'numpy':
         for n in range(N):
             V[:, n] = eval_jacobi(n, alpha, beta, x)
     else:
         X = sp.symbols('x', real=True)
         for n in range(N):
             V[:, n] = sp.lambdify(X, sp.jacobi(n, alpha, beta, X),
                                   'mpmath')(x)
     return V
Beispiel #21
0
 def evaluate_basis(self, x, i=0, output_array=None):
     x = np.atleast_1d(x)
     if output_array is None:
         output_array = np.zeros(x.shape)
     if mode == 'numpy':
         output_array[:] = (1 - x**2)**2 * eval_jacobi(
             i, 2, 2, x, out=output_array)
     else:
         X = sp.symbols('x', real=True)
         f = self.sympy_basis(i, X)
         output_array[:] = sp.lambdify(X, f, 'mpmath')(x)
     return output_array
Beispiel #22
0
def eval_zernike_R(n, m, rho):
    """Return the value of the radial Zernike polynomial"""
    # n>=m
    # m>=0

    k = n - m

    if k % 2 == 1:
        return 0.0

    n_jacobi = k // 2

    comp = 1 - 2 * rho * rho
    # jacobi form
    return (-1)**n_jacobi * rho**m * eval_jacobi(n_jacobi, m, 0, comp)
Beispiel #23
0
def wigner_d_naive(l, m, n, beta):
    """
    Numerically naive implementation of the Wigner-d function.
    This is useful for checking the correctness of other implementations.

    :param l: the degree of the Wigner-d function. l >= 0
    :param m: the order of the Wigner-d function. -l <= m <= l
    :param n: the order of the Wigner-d function. -l <= n <= l
    :param beta: the argument. 0 <= beta <= pi
    :return: d^l_mn(beta) in the TODO: what basis? complex, quantum(?), centered, cs(?)
    """
    from scipy.special import eval_jacobi
    try:
        from scipy.misc import factorial
    except:
        from scipy.special import factorial

    from sympy.functions.special.polynomials import jacobi, jacobi_normalized
    from sympy.abc import j, a, b, x
    from sympy import N
    #jfun = jacobi_normalized(j, a, b, x)
    jfun = jacobi(j, a, b, x)
    # eval_jacobi = lambda q, r, p, o: float(jfun.eval(int(q), int(r), int(p), float(o)))
    # eval_jacobi = lambda q, r, p, o: float(N(jfun, int(q), int(r), int(p), float(o)))
    eval_jacobi = lambda q, r, p, o: float(
        jfun.subs({
            j: int(q),
            a: int(r),
            b: int(p),
            x: float(o)
        }))

    mu = np.abs(m - n)
    nu = np.abs(m + n)
    s = l - (mu + nu) / 2
    xi = 1 if n >= m else (-1)**(n - m)

    # print(s, mu, nu, np.cos(beta), type(s), type(mu), type(nu), type(np.cos(beta)))
    jac = eval_jacobi(s, mu, nu, np.cos(beta))
    z = np.sqrt((factorial(s) * factorial(s + mu + nu)) /
                (factorial(s + mu) * factorial(s + nu)))

    # print(l, m, n, beta, np.isfinite(mu), np.isfinite(nu), np.isfinite(s), np.isfinite(xi), np.isfinite(jac), np.isfinite(z))
    assert np.isfinite(mu) and np.isfinite(nu) and np.isfinite(
        s) and np.isfinite(xi) and np.isfinite(jac) and np.isfinite(z)
    assert np.isfinite(xi * z * np.sin(beta / 2)**mu * np.cos(beta / 2)**nu *
                       jac)
    return xi * z * np.sin(beta / 2)**mu * np.cos(beta / 2)**nu * jac
Beispiel #24
0
    def evaluate_basis_derivative(self, x=None, i=0, k=0, output_array=None):
        if x is None:
            x = self.points_and_weights(mode=mode)[0]
        #x = np.atleast_1d(x)
        if output_array is None:
            output_array = np.zeros(x.shape, dtype=self.dtype)

        if mode == 'numpy':
            dj = np.prod(
                np.array(
                    [i + self.alpha + self.beta + 1 + j for j in range(k)]))
            output_array[:] = dj / 2**k * eval_jacobi(i - k, self.alpha + k,
                                                      self.beta + k, x)
        else:
            f = sp.jacobi(i, self.alpha, self.beta, xp)
            output_array[:] = sp.lambdify(xp, f.diff(xp, k), 'mpmath')(x)
        return output_array
Beispiel #25
0
def _radial_zernike(r, n, m):
    """The radial part of the zernike polynomial

    Formula from http://mathworld.wolfram.com/ZernikePolynomial.html"""
    rad_zern = np.zeros_like(r)
    # zernike polynomials are only valid for r <= 1
    valid_points = r <= 1.0
    if m == 0 and n == 0:
        rad_zern[valid_points] = 1
        return rad_zern
    rprime = r[valid_points]
    # for the radial part m is always positive
    m = abs(m)
    # calculate the coefs
    coef1 = (n + m) // 2
    coef2 = (n - m) // 2
    jacobi = eval_jacobi(coef2, m, 0, 1 - 2 * rprime**2)
    rad_zern[valid_points] = (-1)**coef1 * rprime**m * jacobi
    return rad_zern
Beispiel #26
0
    def eval_multiD_polynomials(self, X):
        """Evaluate

        .. math::

            \\mathbf{\\Phi}(X)
                := \\begin{pmatrix}
                    \\Phi(x_1)^{\\top}\\\\
                    \\vdots\\\\
                    \\Phi(x_M)^{\\top}
                  \\end{pmatrix}

        where :math:`\\Phi(x) = \\left(P_{\\mathfrak{b}^{-1}(0)}(x), \\dots, P_{\\mathfrak{b}^{-1}(N-1)}(x) \\right)^{\\top}` such that
        :math:`K(x, y) = \\Phi(x)^{\\top} \\Phi(y)`.
        Recall that :math:`\\mathfrak{b}` denotes the ordering chosen to order multi-indices :math:`k\\in \\mathbb{N}^d`.

        This is done by evaluating each of the `three-term recurrence relations <https://en.wikipedia.org/wiki/Jacobi_polynomials#Recurrence_relations>`_ satisfied by each univariate orthogonal Jacobi polynomial, using the dedicated `see also SciPy <https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.eval_jacobi.html>`_ :func:`scipy.special.eval_jacobi` satistified by the respective univariate Jacobi polynomials :math:`P_{k_i}^{(a_i, b_i)}(x_i)`.
        Then we use the slicing feature of the Python language to compute :math:`\\Phi(x)=\\left(P_{k}(x) = \\prod_{i=1}^d P_{k_i}^{(a_i, b_i)}(x_i)\\right)_{k=\\mathfrak{b}^{-1}(0), \\dots, \\mathfrak{b}^{-1}(N-1)}^{\\top}`

        :param X:
            :math:`M\\times d` array of :math:`M` points :math:`\\in [-1, 1]^d`
        :type X:
            array_like

        :return:
            :math:`\\mathbf{\\Phi}(X)` - :math:`M\\times N` array
        :rtype:
            array_like

        .. seealso::

            - evaluation of the kernel :py:meth:`~dppy.multivariate_jacobi_ope.MultivariateJacobiOPE.K`
        """
        poly_1D_jacobi = eval_jacobi(self.degrees_1D_polynomials,
                                     self.jacobi_params[:, 0],
                                     self.jacobi_params[:, 1],
                                     np.atleast_2d(X)[:, None])\
                        / self.norms_1D_polynomials

        return np.prod(poly_1D_jacobi[:, self.ordering,
                                      range(self.dim)],
                       axis=2)
def Wigner_d(j, m1, m2, x):
    # using definition from A.R. Edmonds, eq 4.1.23
    from scipy.special import factorial, eval_jacobi
    from numpy import sqrt
    mp, m = m1, m2
    p = 1
    if mp + m < 0:
        mp, m = -mp, -m
        p *= (-1) ** (mp - m)
    if mp < m:
        mp, m = m, mp
        p *= (-1) ** (mp - m)
    return (p * 
        sqrt(
            factorial(j + mp) * factorial(j - mp) / 
            (factorial(j + m) * factorial(j - m))
            ) * 
        sqrt(.5 + .5 * x) ** (mp + m) * 
        sqrt(.5 - .5 * x) ** (mp - m) * 
        eval_jacobi(j - mp, mp - m, mp + m, x)
    )
Beispiel #28
0
 def calcWignerMatrices(self):
     bw = self.bw
     bws = self.bws
     beta = self.b
     sinb2 = sin(beta / 2)
     cosb2 = cos(beta / 2)
     cosb = cos(beta)
     Js, m1s, m2s = self.Js, self.m1s, self.m2s
     Dfull = np.zeros((bw, 2 * bw - 1, 2 * bw - 1, 2 * bw))
     mu = abs(m1s - m2s)
     nu = abs(m1s + m2s)
     s = Js - (mu + nu) / 2
     xi = np.ones_like(s)
     xi[m2s < m1s] = (-1)**(m1s - m2s)[m2s < m1s]
     factor = sqrt(
         factorial(s) * factorial(s + mu + nu) / factorial(s + mu) /
         factorial(s + nu)) * xi
     jac = eval_jacobi(s[:, None], mu[:, None], nu[:, None], cosb[None, :])
     Dfull[Js[:, None], m1s[:, None], m2s[:, None],
           bws[None, :]] = (((2. * Js[:, None] + 1.) / 2.)**0.5 *
                            factor[:, None] * jac *
                            sinb2[None, :]**mu[:, None] *
                            cosb2[None, :]**nu[:, None])
     return Dfull
def test_roots_jacobi():
    rf = lambda a, b: lambda n, mu: sc.roots_jacobi(n, a, b, mu)
    ef = lambda a, b: lambda n, x: sc.eval_jacobi(n, a, b, x)
    wf = lambda a, b: lambda x: (1 - x)**a * (1 + x)**b

    vgq = verify_gauss_quad
    vgq(rf(-0.5, -0.75), ef(-0.5, -0.75), wf(-0.5, -0.75), -1., 1., 5)
    vgq(rf(-0.5, -0.75), ef(-0.5, -0.75), wf(-0.5, -0.75), -1., 1.,
        25, atol=1e-12)
    vgq(rf(-0.5, -0.75), ef(-0.5, -0.75), wf(-0.5, -0.75), -1., 1.,
        100, atol=1e-11)

    vgq(rf(0.5, -0.5), ef(0.5, -0.5), wf(0.5, -0.5), -1., 1., 5)
    vgq(rf(0.5, -0.5), ef(0.5, -0.5), wf(0.5, -0.5), -1., 1., 25, atol=1.5e-13)
    vgq(rf(0.5, -0.5), ef(0.5, -0.5), wf(0.5, -0.5), -1., 1., 100, atol=2e-12)

    vgq(rf(1, 0.5), ef(1, 0.5), wf(1, 0.5), -1., 1., 5, atol=2e-13)
    vgq(rf(1, 0.5), ef(1, 0.5), wf(1, 0.5), -1., 1., 25, atol=2e-13)
    vgq(rf(1, 0.5), ef(1, 0.5), wf(1, 0.5), -1., 1., 100, atol=1e-12)

    vgq(rf(0.9, 2), ef(0.9, 2), wf(0.9, 2), -1., 1., 5)
    vgq(rf(0.9, 2), ef(0.9, 2), wf(0.9, 2), -1., 1., 25, atol=1e-13)
    vgq(rf(0.9, 2), ef(0.9, 2), wf(0.9, 2), -1., 1., 100, atol=3e-13)

    vgq(rf(18.24, 27.3), ef(18.24, 27.3), wf(18.24, 27.3), -1., 1., 5)
    vgq(rf(18.24, 27.3), ef(18.24, 27.3), wf(18.24, 27.3), -1., 1., 25,
        atol=1.1e-14)
    vgq(rf(18.24, 27.3), ef(18.24, 27.3), wf(18.24, 27.3), -1., 1.,
        100, atol=1e-13)

    vgq(rf(47.1, -0.2), ef(47.1, -0.2), wf(47.1, -0.2), -1., 1., 5, atol=1e-13)
    vgq(rf(47.1, -0.2), ef(47.1, -0.2), wf(47.1, -0.2), -1., 1., 25, atol=2e-13)
    vgq(rf(47.1, -0.2), ef(47.1, -0.2), wf(47.1, -0.2), -1., 1.,
        100, atol=1e-11)

    vgq(rf(2.25, 68.9), ef(2.25, 68.9), wf(2.25, 68.9), -1., 1., 5)
    vgq(rf(2.25, 68.9), ef(2.25, 68.9), wf(2.25, 68.9), -1., 1., 25, atol=1e-13)
    vgq(rf(2.25, 68.9), ef(2.25, 68.9), wf(2.25, 68.9), -1., 1.,
        100, atol=1e-13)

    # when alpha == beta == 0, P_n^{a,b}(x) == P_n(x)
    xj, wj = sc.roots_jacobi(6, 0.0, 0.0)
    xl, wl = sc.roots_legendre(6)
    assert_allclose(xj, xl, 1e-14, 1e-14)
    assert_allclose(wj, wl, 1e-14, 1e-14)

    # when alpha == beta != 0, P_n^{a,b}(x) == C_n^{alpha+0.5}(x)
    xj, wj = sc.roots_jacobi(6, 4.0, 4.0)
    xc, wc = sc.roots_gegenbauer(6, 4.5)
    assert_allclose(xj, xc, 1e-14, 1e-14)
    assert_allclose(wj, wc, 1e-14, 1e-14)

    x, w = sc.roots_jacobi(5, 2, 3, False)
    y, v, m = sc.roots_jacobi(5, 2, 3, True)
    assert_allclose(x, y, 1e-14, 1e-14)
    assert_allclose(w, v, 1e-14, 1e-14)

    muI, muI_err = integrate.quad(wf(2,3), -1, 1)
    assert_allclose(m, muI, rtol=muI_err)

    assert_raises(ValueError, sc.roots_jacobi, 0, 1, 1)
    assert_raises(ValueError, sc.roots_jacobi, 3.3, 1, 1)
    assert_raises(ValueError, sc.roots_jacobi, 3, -2, 1)
    assert_raises(ValueError, sc.roots_jacobi, 3, 1, -2)
    assert_raises(ValueError, sc.roots_jacobi, 3, -2, -2)
Beispiel #30
0
    def sample_chain_rule_proposal(self,
                                   nb_trials_max=10000,
                                   random_state=None):
        """Use a rejection sampling mechanism to sample

        .. math::

            \\frac{1}{N} K(x, x) w(x) dx
            = \\frac{1}{N}
                \\sum_{\\mathfrak{b}(k)=0}^{N-1}
                \\left( \\frac{P_k(x)}{\\left\\| P_k \\right\\|} \\right)^2
                w(x)

        with proposal distribution

        .. math::

            w_{eq}(x) d x
                = \\prod_{i=1}^{d}
                    \\frac{1}{\\pi\\sqrt{1-(x_i)^2}}
                    d x_i

        Since the target density is a mixture, we can sample from it by

        1. Select a multi-index :math:`k` uniformly at random in :math:`\\left\\{ \\mathfrak{b}^{-1}(0), \\dots, \\mathfrak{b}^{-1}(N-1) \\right\\}`
        2. Sample from :math:`\\left( \\frac{P_k(x)}{\\left\\| P_k \\right\\|} \\right)^2 w(x) dx` with proposal :math:`w_{eq}(x) d x`.

            The acceptance ratio writes

            .. math::

                \\frac{
                    \\left( \\frac{P_k(x)}{\\left\\| P_k \\right\\|} \\right)^2
                        w(x)}
                    {w_{eq}(x)}
                = \\prod_{i=1}^{d}
                    \\pi
                    \\left(
                        \\frac{P_{k_i}^{(a_i, b_i)}(x)}
                               {\\left\\| P_{k_i}^{(a_i, b_i)} \\right\\|}
                    \\right)^2
                    (1-x_i)^{a_i+\\frac{1}{2}}
                    (1+x_i)^{b_i+\\frac{1}{2}}
                \\leq C_{k}

            which can be bounded using the result of :cite:`Gau09` on Jacobi polynomials.

            .. note::

                Each of the rejection constant :math:`C_{k}` is computed at initialization of the :py:class:`MultivariateJacobiOPE` object using :py:meth:`compute_rejection_bounds`

        :return:
            A sample :math:`x\\in[-1,1]^d` with probability distribution :math:`\\frac{1}{N} K(x,x) w(x)`
        :rtype:
            array_like

        .. seealso::

            - :py:meth:`compute_rejection_bounds`
            - :py:meth:`sample`
        """
        rng = check_random_state(random_state)

        a, b = self.jacobi_params.T
        a_05, b_05 = a + 0.5, b + 0.5
        d = self.dim

        ind = rng.randint(self.N)
        k = self.ordering[ind]
        Pk_square_norm = self.square_norms_multiD_polynomials[ind]
        # norm_Pk = self.poly_multiD_norm[ind]
        rejection_bound = self.rejection_bounds[ind]

        for trial in range(nb_trials_max):

            # Propose x ~ w_eq(x) = \prod_{i=1}^{d} 1/pi 1/sqrt(1-(x_i)^2)
            # rng.beta is defined as beta(a, b) = x^(a-1) (1-x)^(b-1)
            x = 1.0 - 2.0 * rng.beta(0.5, 0.5, size=self.dim)

            # Compute (P_k(x)/||P_k||)^2
            Pk2_x = np.prod(eval_jacobi(k, a, b, x))**2 / Pk_square_norm
            # Pk2_x = (np.prod(eval_jacobi(k, a, b, x)) / norm_Pk)**2

            # Compute w(x) / w_eq(x)
            w_over_w_eq =\
                np.pi**d * np.prod((1.0 - x)**a_05 * (1.0 + x)**b_05)

            if rng.rand() * rejection_bound < Pk2_x * w_over_w_eq:
                break
        else:
            print(
                'marginal distribution 1/N K(x,x), rejection fails after {} proposals'
                .format(trial))

        return x
def e(x, i):
    return K(i) * (np.cos(x))**Dpl * eval_jacobi(i, d / 2 - 1, Dpl - d / 2,
                                                 np.cos(2 * x))
def ep(x, j):
    return -1. * np.tan(x) * (np.cos(x)) ** Dpl * (2 * (Dpl + j) *\
            np.cos(x) ** 2 * eval_jacobi(j - 1, d/2, Dpl + 1 - d/2, np.cos(2 * x))\
            + Dpl * eval_jacobi(j, d/2 - 1, Dpl - d/2, np.cos(2 * x)))
Beispiel #33
0
def eval_grad_jacobi(n, alpha, beta, x, out=None):
    fact = gamma(alpha + beta + n + 2) / 2 / gamma(alpha + beta + n + 1)
    return eval_jacobi(n - 1, alpha + 1, beta + 1, x, out) * fact
Beispiel #34
0
    def sample_proposal_lev_score(self,
                                  nb_trials_max=10000,
                                  random_state=None):
        """Use a rejection sampling mechanism to sample

        .. math::

            \\frac{1}{N} K(x, x) w(x) dx
            = \\frac{1}{N} \\sum_{\\mathfrak{k}=0}^{N-1} P_k(x)^2 w(x)

        with proposal distribution

        .. math::

            w_{eq}(x) d x
            = \\frac{1}{\\pi^d} \\prod_{i=1}^{d} \\frac{1}{\\sqrt{1-(x^i)^2}} d x

        Since the target density is a mixture, we can sample it by

        1. Draw a multi-index :math:`k` uniformly at random
        2. Sample from :math:`P_k(x)^2 w(x) dx` with proposal :math:`w_{eq}(x) d x`.

            The acceptance ratio writes

            .. math::

                P_k(x)^2 w(x) \\frac{1}{\\frac{w_{\\text{eq}}(x)}{\\pi^d}}
                = \\prod_{i=1}^{d} \\pi P_{k^i}(x)^2 (1-x^i)^{a^i+\\frac{1}{2}} (1+x^i)^{b^i+\\frac{1}{2}}

            which can be bounded using the result of :cite:`Gau09` on Jacobi polynomials.
            It is computed at initialization of the :py:class:`MultivariateJacobiOPE` object with :py:meth:`compute_Gautschi_bounds`

        :return:
            A sample :math:`x\\in[-1,1]^d` with probability distribution :math:`\\frac{1}{N} K(x,x) w(x)`
        :rtype:
            array_like

        .. seealso::

            - :py:meth:`compute_Gautschi_bounds`
            - :py:meth:`sample`
        """
        rng = check_random_state(random_state)

        ind = rng.randint(self.N)
        k_multi_ind = self.ordering[ind]
        square_norm = self.poly_multiD_square_norms[ind]
        Gautschi_bound = self.Gautschi_bounds[ind]

        for trial in range(nb_trials_max):

            # Propose x ~ arcsine = \prod_{i=1}^{d} 1/pi 1/sqrt(1-(x^i)^2)
            x = 1.0 - 2.0 * rng.beta(0.5, 0.5, size=self.dim)

            Pk2_x = np.prod(
                eval_jacobi(k_multi_ind, self.jacobi_params[:, 0],
                            self.jacobi_params[:, 1], x))**2
            Pk2_x /= square_norm

            ratio_w_proposal =\
                self._pi_power_dim\
                * np.prod((1.0 - x)**(self._jacobi_params_plus_05[:, 0])
                        * (1.0 + x)**(self._jacobi_params_plus_05[:, 1]))

            if rng.rand() * Gautschi_bound < Pk2_x * ratio_w_proposal:
                break
        else:
            print('proposal not enough trials')

        return x, self.K(x, None)
Beispiel #35
0
def jacobi_15_4_6(a,b,c,z):
    n = -a
    alpha = c-1
    beta = b-n-alpha-1

    return np.exp(gammaln(n+1)-pochln(alpha+1,n))*eval_jacobi(n,alpha,beta,1-2*z)
    def K(self, X, Y=None):
        '''Evaluate the orthogonal projection kernel :math:`K`.
        It is based on the `3-terms recurrence relations <https://en.wikipedia.org/wiki/Jacobi_polynomials#Recurrence_relations>`_ satisfied by each univariate orthogonal Jacobi polynomial, `see also SciPy <https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.eval_jacobi.html>`_ :func:`eval_jacobi`

        .. math::
            K(x, y) = \\sum_{\\mathfrak{b}(k)=0}^{N-1}
                        \\frac{P_{k}(x)P_{k}(y)}
                              {\\|P_{k}\\|^2}

        where

        - :math:`k \\in \\mathbb{N}^d` is a multi-index ordered according to the ordering :math:`\\mathfrak{b}`, :py:meth:`compute_ordering_BaHa16`

        - :math:`P_{k}(x) = \\prod_{i=1}^d P_{k_i}^{a_i, b_i}(x^i)` is the product of orthogonal Jacobi polynomials w.r.t. :math:`\\mu(dx) = \\prod_{i=1}^{d} (1-x^i)^{a_i} (1+x^i)^{b_i} d x^i`

            .. math::

                \\int_{-1}^{1}
                    P_{k}^{(a_i,b_i)}(x) P_{\\ell}^{(a_i,b_i)}(x)
                    (1-x)^{a_i} (1+x)^{b_i} d x
                \\propto \\delta_{k\\ell}

        :param X:
            Array of points :math:`\\in [-1, 1]^d`, with size :math:`n\\times d` where :math:`n` is the number of points
        :type X:
            array_like

        :param Y:
            Array of points :math:`\\in [-1, 1]^d`, with size :math:`n\\times d` where :math:`n` is the number of points
        :type Y:
            array_like (default None)

        :return:
            Pointwise evaluation of :math:`K` as depicted in the following pseudo code output

            - if ``Y`` is ``None``

                - ``K(X, X)`` if ``X.size`` :math:`=d`
                - ``[K(x, x) for x in X]`` otherwise

            - otherwise

                - ``K(X, Y)`` if ``X.size=Y.size``:math:`=d`
                - ``[K(X, y) for y in Y]`` if ``X.size`` :math:`=d`
                - ``[K(x, y) for x, y in zip(X, Y)]`` otherwise
        :rtype:
            - float if ``Y`` is ``None`` and ``X.size`` :math:`=d`
            - array_like otherwise
        '''
        if Y is None:

            if X.size == self.dim:  # X is vector in R^d
                polys_X_2 = eval_jacobi(self.poly_1D_degrees,
                                        self.jacobi_params[:, 0],
                                        self.jacobi_params[:, 1],
                                        X)**2\
                            / self.poly_1D_square_norms

                return np.sum(np.prod(polys_X_2[self.ordering,
                                                range(self.dim)],
                                      axis=1),
                              axis=0)

            else:
                polys_X_2 = eval_jacobi(self.poly_1D_degrees,
                                        self.jacobi_params[:, 0],
                                        self.jacobi_params[:, 1],
                                        X[:, None])**2\
                            / self.poly_1D_square_norms

                return np.sum(np.prod(polys_X_2[:, self.ordering,
                                                range(self.dim)],
                                      axis=2),
                              axis=1)

        else:

            lenX = X.size // self.dim  # X.shape[0] if X.ndim > 1 else 1
            lenY = Y.size // self.dim  # Y.shape[0] if Y.ndim > 1 else 1

            polys_X_Y = eval_jacobi(self.poly_1D_degrees,
                                    self.jacobi_params[:, 0],
                                    self.jacobi_params[:, 1],
                                    np.vstack((X, Y))[:, None])

            if lenX > lenY:

                polys_X_Y[:
                          lenX] *= polys_X_Y[lenX:] / self.poly_1D_square_norms

                return np.sum(np.prod(polys_X_Y[:lenX, self.ordering,
                                                range(self.dim)],
                                      axis=2),
                              axis=1)

            else:  # if lenX < lenY:

                polys_X_Y[
                    lenX:] *= polys_X_Y[:lenX] / self.poly_1D_square_norms

                return np.sum(np.prod(polys_X_Y[lenX:, self.ordering,
                                                range(self.dim)],
                                      axis=2),
                              axis=1)