jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
n=10
estimates=np.arange(n,dtype='float64')
x=np.random.random()+1
for i in range(n):
    d=np.arange(i)
    c=1.0/s.factorial(d)
    d=np.power(x,d)
    estimates[i]=np.sum(np.multiply(c,d))
//  [python]
n=10
estimates=np.arange(n,dtype='float64')
x=np.random.random()+1
for i in range(n):
    d=np.arange(i)
    c=1.0/sp.special.factorial(d)
    d=np.power(x,d)
    estimates[i]=np.sum(np.multiply(c,d))
//  [python]
def factorial(self,*args,**dargs) : return s.factorial(*args,**dargs)
//  [python]
def factorial(self,*args,**dargs) : return scipy.special.factorial(*args,**dargs)
//  [python]
def __init__(self, p):
        """
        Constructor; initialized a Jacobi basis function
        """

        super(Jacobi, self).__init__(p)

        # determine polynomial normalization factor
        beta_norm = (scipy.special.gamma(self.p["q"]) * scipy.special.gamma(self.p["p"]) /
                     scipy.special.gamma(self.p["p"] + self.p["q"]) * 2.0 ** (self.p["p"] + self.p["q"] - 1)) ** (-1)

        jacobi_norm = 2 ** (self.p["p"] + self.p["q"] - 1) / (
                      (2.0 * self.p["i"] + self.p["p"] + self.p["q"] - 1)) * (
                      scipy.special.gamma(self.p["i"] + self.p["p"])) * (
                      scipy.special.gamma(self.p["i"] + self.p["q"])) / (
                              scipy.special.gamma(self.p["i"] + self.p["p"] + self.p["q"] - 1) *
                              scipy.special.factorial(self.p["i"]))

        # normalization factor of polynomial (to later normalize basis functions <psi^2> = int(psi^2*p)dx)
        self.fun_norm = jacobi_norm * beta_norm

        # define basis function
        self.fun = scipy.special.jacobi(self.p["i"],
                                        self.p["q"] - 1,  # beta-pdf: alpha=p /// jacobi-poly: alpha=q-1  !!!
                                        self.p["p"] - 1,  # beta-pdf: beta=q  /// jacobi-poly: beta=p-1   !!!
                                        monic=False) / np.sqrt(self.fun_norm)

        # derivative of polynomial
        self.fun_der = np.polyder(self.fun)

        # integral of fun and fun_der w.r.t. pdf (numerical integration with corresponding weights)
        knots, weights = get_quadrature_jacobi_1d(n=10 * self.p["i"], p=self.p["p"] - 1, q=self.p["q"] - 1)
        self.fun_int = np.dot(self.fun(knots), weights)
        self.fun_der_int = np.dot(self.fun_der(knots), weights)
//  [python]
def test_factorial(self):
        """Test the custom factorial implementation up to 15"""
        for x in range(16):
            f1 = b.fock.factorial(x)
            f2 = int(s.factorial(x))
            self.assertEqual(f1, f2)
//  [python]
def test_factorial(self):
        """Test the custom factorial implementation up to 15"""
        for x in range(16):
            f1 = b.fock.factorial(x)
            f2 = int(factorial(x))
            self.assertEqual(f1, f2)
//  [python]
def _qfunc_iterative_single(
    vector: np.ndarray, alpha_grid: _QFuncCoherentGrid, g: float,
):
    r"""
    Get the Q function (without the :math:`\pi` scaling factor) of a single
    state vector, using the iterative algorithm which recomputes the powers of
    the coherent-state matrix.
    """
    ns = np.arange(vector.shape[0])
    out = np.polyval(
        (0.5*g * vector / np.sqrt(s.factorial(ns)))[::-1],
        alpha_grid.grid,
    )
    out *= alpha_grid.prefactor
    return np.abs(out)**2
//  [python]
def _qfunc_iterative_single(
    vector: np.ndarray, alpha_grid: _QFuncCoherentGrid, g: float,
):
    r"""
    Get the Q function (without the :math:`\pi` scaling factor) of a single
    state vector, using the iterative algorithm which recomputes the powers of
    the coherent-state matrix.
    """
    ns = np.arange(vector.shape[0])
    out = np.polyval(
        (0.5*g * vector / np.sqrt(scipy.special.factorial(ns)))[::-1],
        alpha_grid.grid,
    )
    out *= alpha_grid.prefactor
    return np.abs(out)**2
//  [python]
def _par_wig_eval(args):
    """
    Private function for calculating terms of Laguerre Wigner function
    using parfor.
    """
    m, rho, A, B = args
    W1 = zeros(np.shape(A))
    for jj in range(rho.data.indptr[m], rho.data.indptr[m + 1]):
        n = rho.data.indices[jj]

        if m == n:
            W1 += real(rho[m, m] * (-1) ** m * genlaguerre(m, 0)(B))

        elif n > m:
            W1 += 2.0 * real(rho[m, n] * (-1) ** m *
                             (2 * A) ** (n - m) *
                             sqrt(s.factorial(m) / s.factorial(n)) *
                             genlaguerre(m, n - m)(B))
    return W1
//  [python]
def _par_wig_eval(args):
    """
    Private function for calculating terms of Laguerre Wigner function
    using parfor.
    """
    m, rho, A, B = args
    W1 = zeros(np.shape(A))
    for jj in range(rho.data.indptr[m], rho.data.indptr[m + 1]):
        n = rho.data.indices[jj]

        if m == n:
            W1 += real(rho[m, m] * (-1) ** m * genlaguerre(m, 0)(B))

        elif n > m:
            W1 += 2.0 * real(rho[m, n] * (-1) ** m *
                             (2 * A) ** (n - m) *
                             sqrt(factorial(m) / factorial(n)) *
                             genlaguerre(m, n - m)(B))
    return W1
//  [python]
def __call__(self, first: int, last: int = None):
        """
        Get a 3D array of shape ``(yvec.size, xvec.size, last - first)`` of the
        coherent-state vectors for all the Fock states in the range ``first``
        to ``last``, excluding the end point.  The first two axes are the y-
        and x-coordinates of phase space (i.e. Cartesian indexing, like
        ``numpy.meshgrid``), and the last runs over the selected range of
        Fock-space dimensions.
        """
        ns = np.arange(first, last).reshape(1, 1, -1)
        # Technically we could avoid hitting the limits of floating-point
        # exponents for longer by doing all this in logarithmic space (using
        # scipy.special.gammaln), but that ends up involving more
        # floating-point operations overall, and needs special care around the
        # point alpha = 0 to avoid nan appearing, due to how Python handles
        # mixed-width arithmetic operations.
        out = np.empty(self.grid.shape + (ns.size,), dtype=np.complex128)
        out[:, :, 0] = self._start(ns.flat[0])
        for i in range(ns.size - 1):
            out[:, :, i+1] = out[:, :, i] * self.grid
        out /= np.sqrt(s.factorial(ns))
        return out
//  [python]
def __call__(self, first: int, last: int = None):
        """
        Get a 3D array of shape ``(yvec.size, xvec.size, last - first)`` of the
        coherent-state vectors for all the Fock states in the range ``first``
        to ``last``, excluding the end point.  The first two axes are the y-
        and x-coordinates of phase space (i.e. Cartesian indexing, like
        ``numpy.meshgrid``), and the last runs over the selected range of
        Fock-space dimensions.
        """
        ns = np.arange(first, last).reshape(1, 1, -1)
        # Technically we could avoid hitting the limits of floating-point
        # exponents for longer by doing all this in logarithmic space (using
        # scipy.special.gammaln), but that ends up involving more
        # floating-point operations overall, and needs special care around the
        # point alpha = 0 to avoid nan appearing, due to how Python handles
        # mixed-width arithmetic operations.
        out = np.empty(self.grid.shape + (ns.size,), dtype=np.complex128)
        out[:, :, 0] = self._start(ns.flat[0])
        for i in range(ns.size - 1):
            out[:, :, i+1] = out[:, :, i] * self.grid
        out /= np.sqrt(scipy.special.factorial(ns))
        return out
//  [python]
def taylor_vector_polynomial(dvv):
    return VectorPolynomial((1./s.factorial(np.arange(dvv.shape[1]))).reshape((1,-1)) * dvv)
//  [python]
def taylor_vector_polynomial(dvv):
    return VectorPolynomial((1./factorial(np.arange(dvv.shape[1]))).reshape((1,-1)) * dvv)
//  [python]
def get_norm_optimize_a(aval, bval, ctab, binw,  cmag, n_obs, t_per, info=False):
    """
    Computes a norm using a slightly different strategy than the one used in
    `get_norm_optimize` - based on the probability of observing n events in each
    magnitude bin relative to an exponential (GR) frequency-magnitude distribution

    :param aval:
        GR a-value
    :param bval:
        GR b-value
    :param ctab:
        Completeness table
    :param cmag:
        An array with the magnitude values at the center of each occurrence
        bins
    :param t_per:
    :param n_obs:
    :param last_year:
    :param info:
    """
    #breakpoint()
    # Rates of occurrence in each magnitude bin in the completeness interval
    rates = (10**(-bval * (cmag - binw/2) + aval) -
             10**(-bval * (cmag + binw/2) + aval))*t_per


    # Probability of observing n-occurrences in each magnitude bin
    # These are Poisson probabilities
    # and these probabilities are never large, even for synthetic data

    occ_prob = np.ones_like(rates) * 0.999999
    num = (rates)**n_obs * np.exp(-rates)
    occ_prob = num / scipy.misc.factorial(n_obs)
    #print("occ_prob: ", occ_prob)
    
    n_obs = n_obs.astype(int)
    log_prob = np.ones_like(n_obs) * 0.999999
    for i, obs in enumerate(n_obs):
        log_prob[i] = (-rates[i]) + (n_obs[i]*np.math.log(rates[i])) - np.math.log(scipy.misc.factorial(n_obs[i]))

    #log_prob = (-rates) + (n_obs*np.math.log(rates)) - np.math.log(np.math.factorial(n_obs))

    #norm = 1. - np.prod(occ_prob)
    #print("from log prob: ", np.exp(log_prob))
    #print("log likelihood = ", np.sum(log_prob))
    #norm = np.sum(log_prob)
    norm = 1 - np.prod(np.exp(log_prob))
    return norm
//  [python]
def get_norm_optimize_a(aval, bval, ctab, binw,  cmag, n_obs, t_per, info=False):
    """
    Computes a norm using a slightly different strategy than the one used in
    `get_norm_optimize` - based on the probability of observing n events in each
    magnitude bin relative to an exponential (GR) frequency-magnitude distribution

    :param aval:
        GR a-value
    :param bval:
        GR b-value
    :param ctab:
        Completeness table
    :param cmag:
        An array with the magnitude values at the center of each occurrence
        bins
    :param t_per:
    :param n_obs:
    :param last_year:
    :param info:
    """
    #breakpoint()
    # Rates of occurrence in each magnitude bin in the completeness interval
    rates = (10**(-bval * (cmag - binw/2) + aval) -
             10**(-bval * (cmag + binw/2) + aval))*t_per


    # Probability of observing n-occurrences in each magnitude bin
    # These are Poisson probabilities
    # and these probabilities are never large, even for synthetic data

    occ_prob = np.ones_like(rates) * 0.999999
    num = (rates)**n_obs * np.exp(-rates)
    occ_prob = num / scipy.special.factorial(n_obs)
    #print("occ_prob: ", occ_prob)
    
    n_obs = n_obs.astype(int)
    log_prob = np.ones_like(n_obs) * 0.999999
    for i, obs in enumerate(n_obs):
        log_prob[i] = (-rates[i]) + (n_obs[i]*np.math.log(rates[i])) - np.math.log(np.math.factorial(n_obs[i]))

    #log_prob = (-rates) + (n_obs*np.math.log(rates)) - np.math.log(np.math.factorial(n_obs))

    #norm = 1. - np.prod(occ_prob)
    #print("from log prob: ", np.exp(log_prob))
    #print("log likelihood = ", np.sum(log_prob))
    #norm = np.sum(log_prob)
    norm = 1 - np.prod(np.exp(log_prob))
    return norm
//  [python]
def _bspline(u, n=4):
    fac = 1. / s.factorial(n-1)
    M = 0
    for k in range(n+1):
        fac1 = ((-1)**k) * scipy.special.binom(n, k)
        M += fac1 * ((np.maximum(u-k, 0)) ** (n-1))
    M *= fac
    return M
//  [python]
def _bspline(u, n=4):
    fac = 1. / scipy.special.factorial(n-1)
    M = 0
    for k in range(n+1):
        fac1 = ((-1)**k) * scipy.special.binom(n, k)
        M += fac1 * ((np.maximum(u-k, 0)) ** (n-1))
    M *= fac
    return M
//  [python]
def YslmBase(s, l, m, z):
    rmax = l - s
    pref = (0.5)**(l)*(-1.)**m*np.sqrt(s.factorial(l+m)/s.factorial(l+s)*s.factorial(l-m)/s.factorial(l-s)*(2*l+1)/(4.*np.pi))*np.sqrt(1. - z)**(s + m)*np.sqrt(1. + z)**(s - m)
    
    yslm = 0.*pref
    for r in range(0, rmax + 1):
        yslm += binom(l - s, r)*binom(l + s, r + s - m)*(z - 1.)**(rmax - r)*(z + 1.)**(r)
    
    return pref*yslm
//  [python]
def YslmBase(s, l, m, z):
    rmax = l - s
    pref = (0.5)**(l)*(-1.)**m*np.sqrt(factorial(l+m)/factorial(l+s)*factorial(l-m)/factorial(l-s)*(2*l+1)/(4.*np.pi))*np.sqrt(1. - z)**(s + m)*np.sqrt(1. + z)**(s - m)
    
    yslm = 0.*pref
    for r in range(0, rmax + 1):
        yslm += binom(l - s, r)*binom(l + s, r + s - m)*(z - 1.)**(rmax - r)*(z + 1.)**(r)
    
    return pref*yslm
//  [python]
def test_factorial_array_corner_cases(self, content, dim, exact, dtype):
        if dtype == np.int64 and any(np.isnan(x) for x in content):
            pytest.skip("impossible combination")
        n = np.array(content, ndmin=dim, dtype=dtype)
        result = None
        if not content:
            result = s.factorial(n, exact=exact)
        elif not (np.issubdtype(n.dtype, np.integer)
                  or np.issubdtype(n.dtype, np.floating)):
            with pytest.raises(ValueError, match="Unsupported datatype*"):
                s.factorial(n, exact=exact)
        elif (exact and not np.issubdtype(n.dtype, np.integer) and n.size and
              np.allclose(n[~np.isnan(n)], n[~np.isnan(n)].astype(np.int64))):
            # using integers but in array with wrong dtype (e.g. due to NaNs)
            with pytest.warns(DeprecationWarning, match="Non-integer array.*"):
                result = s.factorial(n, exact=exact)
                # expected dtype is integer, unless there are NaNs
                dtype = np.float_ if np.any(np.isnan(n)) else np.int_
        elif exact and not np.issubdtype(n.dtype, np.integer):
            with pytest.raises(ValueError, match="factorial with exact=.*"):
                s.factorial(n, exact=exact)
        else:
            # no error
            result = s.factorial(n, exact=exact)

        if result is not None:
            # expected result is empty if and only if n is empty,
            # and has the same dtype & dimension as n
            with suppress_warnings() as sup:
                sup.filter(DeprecationWarning)
                r = s.factorial(n.ravel(), exact=exact) if n.size else []
            expected = np.array(r, ndmin=dim, dtype=dtype)
            assert_equal(result, expected)
//  [python]
def test_factorial_array_corner_cases(self, content, dim, exact, dtype):
        if dtype == np.int64 and any(np.isnan(x) for x in content):
            pytest.skip("impossible combination")
        n = np.array(content, ndmin=dim, dtype=dtype)
        result = None
        if not content:
            result = special.factorial(n, exact=exact)
        elif not (np.issubdtype(n.dtype, np.integer)
                  or np.issubdtype(n.dtype, np.floating)):
            with pytest.raises(ValueError, match="Unsupported datatype*"):
                special.factorial(n, exact=exact)
        elif (exact and not np.issubdtype(n.dtype, np.integer) and n.size and
              np.allclose(n[~np.isnan(n)], n[~np.isnan(n)].astype(np.int64))):
            # using integers but in array with wrong dtype (e.g. due to NaNs)
            with pytest.warns(DeprecationWarning, match="Non-integer array.*"):
                result = special.factorial(n, exact=exact)
                # expected dtype is integer, unless there are NaNs
                dtype = np.float_ if np.any(np.isnan(n)) else np.int_
        elif exact and not np.issubdtype(n.dtype, np.integer):
            with pytest.raises(ValueError, match="factorial with exact=.*"):
                special.factorial(n, exact=exact)
        else:
            # no error
            result = special.factorial(n, exact=exact)

        if result is not None:
            # expected result is empty if and only if n is empty,
            # and has the same dtype & dimension as n
            with suppress_warnings() as sup:
                sup.filter(DeprecationWarning)
                r = special.factorial(n.ravel(), exact=exact) if n.size else []
            expected = np.array(r, ndmin=dim, dtype=dtype)
            assert_equal(result, expected)
//  [python]
x = np.linspace(0, 5, 200)
fracSum = np.cumsum([1 / s.factorial(i) for i in range(6)])
//  [python]
x = np.linspace(0, 5, 200)
fracSum = np.cumsum([1 / scipy.special.factorial(i) for i in range(6)])
//  [python]
def get_coefficients(demo, observed):
    """
    Get the binomial coefficients for calculating the probability of a PHC
    producing an election result.

    demo (dict): the demographics of the district, per precinct
    observed (dict): the number of votes a candidate got in each precinct

    return: a Python dictionary containing the integer partitions and their
    binomial coefficients for each precinct
    """
    coeff_dict = {}
    observed_factorials = {prec_id: (obs_votes, math.factorial(obs_votes)) for prec_id, obs_votes in observed.items()}

    for prec, (obs_votes, observed_factorial) in observed_factorials.items():
        prec_coeff_dict = {}
        for p in tools.permute_integer_partition(obs_votes, len(demo[prec])):
            factorial_list = tf.convert_to_tensor(
                s.factorial(p), dtype=float)
            coefficient = observed_factorial / tf.math.reduce_prod(factorial_list)

            prec_coeff_dict[p] = tf.cast(coefficient, tf.float32)
        coeff_dict[prec] = prec_coeff_dict

    return coeff_dict
//  [python]
def get_coefficients(demo, observed):
    """
    Get the binomial coefficients for calculating the probability of a PHC
    producing an election result.

    demo (dict): the demographics of the district, per precinct
    observed (dict): the number of votes a candidate got in each precinct

    return: a Python dictionary containing the integer partitions and their
    binomial coefficients for each precinct
    """
    coeff_dict = {}
    observed_factorials = {prec_id: (obs_votes, math.factorial(obs_votes)) for prec_id, obs_votes in observed.items()}

    for prec, (obs_votes, observed_factorial) in observed_factorials.items():
        prec_coeff_dict = {}
        for p in tools.permute_integer_partition(obs_votes, len(demo[prec])):
            factorial_list = tf.convert_to_tensor(
                scipy.special.factorial(p), dtype=float)
            coefficient = observed_factorial / tf.math.reduce_prod(factorial_list)

            prec_coeff_dict[p] = tf.cast(coefficient, tf.float32)
        coeff_dict[prec] = prec_coeff_dict

    return coeff_dict
//  [python]
def compute_expansion_coefficients(self, w0, n_max=5):
        r"""Obtain Taylor expansion coefficients at given frequency.

        Note:
            Uses scipy.misc.derivative and scipy.misc.factorial for computing
            the expansion coefficients.

        Args:
            w0 (:obj:`float`):
                    Frequency value about which to expand.
            n_max (:obj:`int`):
                    Number of expansion coefficients to compute (default = 5).

        Returns:
            :obj:`numpy.ndarray`: Taylor expansion coefficients.

        """
        return np.asarray(
            [
                smi.derivative(self.beta, w0, dx=self.dw, n=n, order=2 * n + 1)
                / smi.factorial(n)
                for n in range(n_max + 1)
            ]
        )
//  [python]
def compute_expansion_coefficients(self, w0, n_max=5):
        r"""Obtain Taylor expansion coefficients at given frequency.

        Note:
            Uses scipy.misc.derivative and scipy.misc.factorial for computing
            the expansion coefficients.

        Args:
            w0 (:obj:`float`):
                    Frequency value about which to expand.
            n_max (:obj:`int`):
                    Number of expansion coefficients to compute (default = 5).

        Returns:
            :obj:`numpy.ndarray`: Taylor expansion coefficients.

        """
        return np.asarray(
            [
                smi.derivative(self.beta, w0, dx=self.dw, n=n, order=2 * n + 1)
                / ssp.factorial(n)
                for n in range(n_max + 1)
            ]
        )
//  [python]
def eig_phase_coord(self, k: int, grid: Sequence[ndarray]) -> ndarray:
        """
        Return the phase coordinate representations of the eigenvectors as
        ndarray.

        Parameters
        ----------
            k:
                The eigenvector index. For example, we set it to 0 for the
                ground state and 1 for the first excited state.
            grid:
                A list that contains the range of values of phase φ for which
                we want to evaluate the wavefunction.
        """

        assert isinstance(k, int), ("The k (index of eigenstate) should be "
                                    "an integer.")

        phi_list = [*np.meshgrid(*grid, indexing='ij')]

        # The total dimension of the circuit Hilbert Space
        netDimension = np.prod(self.m)

        state = 0

        for i in range(netDimension):

            # decomposes the tensor product space index (i) to each mode
            # indices as a list
            indList = self._tensor_to_modes(i)

            term = self._evecs[k][i][0, 0]

            for mode in range(self.n):

                # mode number related to that node
                n = indList[mode]

                # For charge basis
                if self._is_charge_mode(mode):
                    term *= 1 / np.sqrt(2 * np.pi) * np.exp(
                        1j * phi_list[mode] * n)
                # For harmonic basis
                else:
                    x0 = np.sqrt(unt.hbar * np.sqrt(
                        self.cInvTrans[mode, mode] / self.lTrans[mode, mode]))

                    coef = 1 / np.sqrt(np.sqrt(np.pi) * (2 ** n) *
                                       s.factorial(
                                           n) * x0 / unt.Phi0)

                    term *= coef * np.exp(
                        -(phi_list[mode]*unt.Phi0/x0)**2/2) * \
                            eval_hermite(n, phi_list[mode] * unt.Phi0 / x0)

            state += term

        state = np.squeeze(state)

        # transposing the first two modes
        if len(state.shape) > 1:
            indModes = list(range(len(state.shape)))
            indModes[0] = 1
            indModes[1] = 0
            state = state.transpose(*indModes)

        return state
//  [python]
def eig_phase_coord(self, k: int, grid: Sequence[ndarray]) -> ndarray:
        """
        Return the phase coordinate representations of the eigenvectors as
        ndarray.

        Parameters
        ----------
            k:
                The eigenvector index. For example, we set it to 0 for the
                ground state and 1 for the first excited state.
            grid:
                A list that contains the range of values of phase φ for which
                we want to evaluate the wavefunction.
        """

        assert isinstance(k, int), ("The k (index of eigenstate) should be "
                                    "an integer.")

        phi_list = [*np.meshgrid(*grid, indexing='ij')]

        # The total dimension of the circuit Hilbert Space
        netDimension = np.prod(self.m)

        state = 0

        for i in range(netDimension):

            # decomposes the tensor product space index (i) to each mode
            # indices as a list
            indList = self._tensor_to_modes(i)

            term = self._evecs[k][i][0, 0]

            for mode in range(self.n):

                # mode number related to that node
                n = indList[mode]

                # For charge basis
                if self._is_charge_mode(mode):
                    term *= 1 / np.sqrt(2 * np.pi) * np.exp(
                        1j * phi_list[mode] * n)
                # For harmonic basis
                else:
                    x0 = np.sqrt(unt.hbar * np.sqrt(
                        self.cInvTrans[mode, mode] / self.lTrans[mode, mode]))

                    coef = 1 / np.sqrt(np.sqrt(np.pi) * (2 ** n) *
                                       scipy.special.factorial(
                                           n) * x0 / unt.Phi0)

                    term *= coef * np.exp(
                        -(phi_list[mode]*unt.Phi0/x0)**2/2) * \
                            eval_hermite(n, phi_list[mode] * unt.Phi0 / x0)

            state += term

        state = np.squeeze(state)

        # transposing the first two modes
        if len(state.shape) > 1:
            indModes = list(range(len(state.shape)))
            indModes[0] = 1
            indModes[1] = 0
            state = state.transpose(*indModes)

        return state
//  [python]
def spherical_harmonic_matrix(l, theta, phi):
    # calculate legendre polynomials
    nth = len(theta)
    Pl = legendre(l, np.cos(theta)).transpose()
    # calculate degree dependent factors C and F
    m = np.arange(0, l+1)  # spherical harmonic orders up to degree l
    C = np.sqrt((2.0*l + 1.0)/(4.0*np.pi))
    F = np.sqrt(s.factorial(1 + l - m - 1)/s.factorial(1 + l + m - 1))
    F = np.kron(np.ones((nth, 1)), F[np.newaxis, :])
    # calculate Euler's of spherical harmonic order multiplied by azimuth phi
    mphi = np.exp(1j*np.dot(np.squeeze(phi)[:, np.newaxis], m[np.newaxis, :]))
    # calculate spherical harmonics
    Ylms = F*Pl[:, 0:l+1]*mphi
    # multiply by C and convert to reduced matrix (theta,Slm:Clm)
    SPH = C*np.concatenate((np.imag(Ylms[:, :0:-1]), np.real(Ylms)), axis=1)
    return SPH
//  [python]
def spherical_harmonic_matrix(l, theta, phi):
    # calculate legendre polynomials
    nth = len(theta)
    Pl = legendre(l, np.cos(theta)).transpose()
    # calculate degree dependent factors C and F
    m = np.arange(0, l+1)  # spherical harmonic orders up to degree l
    C = np.sqrt((2.0*l + 1.0)/(4.0*np.pi))
    F = np.sqrt(spc.factorial(1 + l - m - 1)/spc.factorial(1 + l + m - 1))
    F = np.kron(np.ones((nth, 1)), F[np.newaxis, :])
    # calculate Euler's of spherical harmonic order multiplied by azimuth phi
    mphi = np.exp(1j*np.dot(np.squeeze(phi)[:, np.newaxis], m[np.newaxis, :]))
    # calculate spherical harmonics
    Ylms = F*Pl[:, 0:l+1]*mphi
    # multiply by C and convert to reduced matrix (theta,Slm:Clm)
    SPH = C*np.concatenate((np.imag(Ylms[:, :0:-1]), np.real(Ylms)), axis=1)
    return SPH
//  [python]
def get_strain_from_stress(self, stress) -> float:
        """Get the strain from a stress state according to the compliance
        expansion corresponding to the tensor expansion.
        """
        compl_exp = self.get_compliance_expansion()
        strain = 0
        for idx, compl in enumerate(compl_exp, start=1):
            strain += compl.einsum_sequence([stress] * (idx)) / s.factorial(idx)
        return strain
//  [python]
def get_strain_from_stress(self, stress) -> float:
        """Get the strain from a stress state according to the compliance
        expansion corresponding to the tensor expansion.
        """
        compl_exp = self.get_compliance_expansion()
        strain = 0
        for idx, compl in enumerate(compl_exp, start=1):
            strain += compl.einsum_sequence([stress] * (idx)) / factorial(idx)
        return strain
//  [python]
def test_exponential_pade(taylor_order=9):
    exp_taylor = 1 / s.factorial(np.arange(taylor_order+1))[::-1]
    hfF = s.factorial
    hf_p_kmj = lambda k,m,j: hfF(k+m-j) * hfF(k) / (hfF(k+m) * hfF(k-j) * hfF(j))
    hf_q_kmj = lambda k,m,j: (-1)**j * hfF(k+m-j) * hfF(m) / (hfF(k+m) * hfF(m-j) * hfF(j))
    for q_order in range(taylor_order+1):
        p_order = taylor_order - q_order
        ret_p_ = np.array([hf_p_kmj(p_order,q_order,x) for x in range(p_order+1)])[::-1]
        ret_q_ = np.array([hf_q_kmj(p_order,q_order,x) for x in range(q_order+1)])[::-1]
        tmp0 = scipy.interpolate.pade(exp_taylor[::-1], q_order)
        ret_p = tmp0[0].coefficients
        ret_q = tmp0[1].coefficients
        assert hfe(ret_p_, ret_p) < 1e-7
        assert hfe(ret_q_, ret_q) < 1e-7
//  [python]
def test_exponential_pade(taylor_order=9):
    exp_taylor = 1 / scipy.special.factorial(np.arange(taylor_order+1))[::-1]
    hfF = scipy.special.factorial
    hf_p_kmj = lambda k,m,j: hfF(k+m-j) * hfF(k) / (hfF(k+m) * hfF(k-j) * hfF(j))
    hf_q_kmj = lambda k,m,j: (-1)**j * hfF(k+m-j) * hfF(m) / (hfF(k+m) * hfF(m-j) * hfF(j))
    for q_order in range(taylor_order+1):
        p_order = taylor_order - q_order
        ret_p_ = np.array([hf_p_kmj(p_order,q_order,x) for x in range(p_order+1)])[::-1]
        ret_q_ = np.array([hf_q_kmj(p_order,q_order,x) for x in range(q_order+1)])[::-1]
        tmp0 = scipy.interpolate.pade(exp_taylor[::-1], q_order)
        ret_p = tmp0[0].coefficients
        ret_q = tmp0[1].coefficients
        assert hfe(ret_p_, ret_p) < 1e-7
        assert hfe(ret_q_, ret_q) < 1e-7
//  [python]
def calculate_stress(self, strain):
        """
        Calculate's a given elastic tensor's contribution to the
        stress using Einstein summation.

        Args:
            strain (3x3 array-like): matrix corresponding to strain
        """
        strain = np.array(strain)
        if strain.shape == (6,):
            strain = Strain.from_voigt(strain)
        assert strain.shape == (3, 3), "Strain must be 3x3 or Voigt notation"
        stress_matrix = self.einsum_sequence([strain] * (self.order - 1)) / s.factorial(self.order - 1)
        return Stress(stress_matrix)
//  [python]
def calculate_stress(self, strain):
        """
        Calculate's a given elastic tensor's contribution to the
        stress using Einstein summation.

        Args:
            strain (3x3 array-like): matrix corresponding to strain
        """
        strain = np.array(strain)
        if strain.shape == (6,):
            strain = Strain.from_voigt(strain)
        assert strain.shape == (3, 3), "Strain must be 3x3 or Voigt notation"
        stress_matrix = self.einsum_sequence([strain] * (self.order - 1)) / factorial(self.order - 1)
        return Stress(stress_matrix)
//  [python]
def get_effective_ecs(self, strain, order=2):
        """Get the effective elastic constants
        from the elastic tensor expansion.

        Args:
            strain (Strain or 3x3 array-like): strain condition
                under which to calculate the effective constants
            order (int): order of the ecs to be returned
        """
        ec_sum = 0
        for n, ecs in enumerate(self[order - 2 :]):
            ec_sum += ecs.einsum_sequence([strain] * n) / s.factorial(n)
        return ec_sum
//  [python]
def get_effective_ecs(self, strain, order=2):
        """Get the effective elastic constants
        from the elastic tensor expansion.

        Args:
            strain (Strain or 3x3 array-like): strain condition
                under which to calculate the effective constants
            order (int): order of the ecs to be returned
        """
        ec_sum = 0
        for n, ecs in enumerate(self[order - 2 :]):
            ec_sum += ecs.einsum_sequence([strain] * n) / factorial(n)
        return ec_sum
//  [python]
def get_diff_coeff(hvec, n=1):
    """
    Helper function to find difference coefficients of an
    derivative on an arbitrary mesh.

    Args:
        hvec (1D array-like): sampling stencil
        n (int): degree of derivative to find
    """
    hvec = np.array(hvec, dtype=np.float64)
    acc = len(hvec)
    exp = np.column_stack([np.arange(acc)] * acc)
    a = np.vstack([hvec] * acc) ** exp
    b = np.zeros(acc)
    b[n] = s.factorial(n)
    return np.linalg.solve(a, b)
//  [python]
def get_diff_coeff(hvec, n=1):
    """
    Helper function to find difference coefficients of an
    derivative on an arbitrary mesh.

    Args:
        hvec (1D array-like): sampling stencil
        n (int): degree of derivative to find
    """
    hvec = np.array(hvec, dtype=np.float64)
    acc = len(hvec)
    exp = np.column_stack([np.arange(acc)] * acc)
    a = np.vstack([hvec] * acc) ** exp
    b = np.zeros(acc)
    b[n] = factorial(n)
    return np.linalg.solve(a, b)
//  [python]
def buildSCFpyrlevs(self, lodft, log_rad, angle, Xrcos, Yrcos, ht):
		if (ht <=1):
			lo0 = np.fft.ifft2(np.fft.ifftshift(lodft))
			coeff = [lo0.real]
		
		else:
			Xrcos = Xrcos - 1

			# ==================== Orientation bandpass =======================
			himask = self.pointOp(log_rad, Yrcos, Xrcos)

			lutsize = 1024
			Xcosn = np.pi * np.array(range(-(2*lutsize+1),(lutsize+2)))/lutsize
			order = self.nbands - 1
			const = np.power(2, 2*order) * np.square(s.factorial(order)) / (self.nbands * s.factorial(2*order))

			alpha = (Xcosn + np.pi) % (2*np.pi) - np.pi
			Ycosn = 2*np.sqrt(const) * np.power(np.cos(Xcosn), order) * (np.abs(alpha) < np.pi/2)

			orients = []

			for b in range(self.nbands):
				anglemask = self.pointOp(angle, Ycosn, Xcosn + np.pi*b/self.nbands)
				banddft = np.power(np.complex(0,-1), self.nbands - 1) * lodft * anglemask * himask
				band = np.fft.ifft2(np.fft.ifftshift(banddft))
				orients.append(band)

			# ================== Subsample lowpass ============================
			dims = np.array(lodft.shape)
			
			lostart = np.ceil((dims+0.5)/2) - np.ceil((np.ceil((dims-0.5)/2)+0.5)/2)
			loend = lostart + np.ceil((dims-0.5)/2)

			lostart = lostart.astype(int)
			loend = loend.astype(int)

			log_rad = log_rad[lostart[0]:loend[0], lostart[1]:loend[1]]
			angle = angle[lostart[0]:loend[0], lostart[1]:loend[1]]
			lodft = lodft[lostart[0]:loend[0], lostart[1]:loend[1]]
			YIrcos = np.abs(np.sqrt(1 - Yrcos*Yrcos))
			lomask = self.pointOp(log_rad, YIrcos, Xrcos)

			lodft = lomask * lodft

			coeff = self.buildSCFpyrlevs(lodft, log_rad, angle, Xrcos, Yrcos, ht-1)
			coeff.insert(0, orients)

		return coeff
//  [python]
def buildSCFpyrlevs(self, lodft, log_rad, angle, Xrcos, Yrcos, ht):
		if (ht <=1):
			lo0 = np.fft.ifft2(np.fft.ifftshift(lodft))
			coeff = [lo0.real]
		
		else:
			Xrcos = Xrcos - 1

			# ==================== Orientation bandpass =======================
			himask = self.pointOp(log_rad, Yrcos, Xrcos)

			lutsize = 1024
			Xcosn = np.pi * np.array(range(-(2*lutsize+1),(lutsize+2)))/lutsize
			order = self.nbands - 1
			const = np.power(2, 2*order) * np.square(factorial(order)) / (self.nbands * factorial(2*order))

			alpha = (Xcosn + np.pi) % (2*np.pi) - np.pi
			Ycosn = 2*np.sqrt(const) * np.power(np.cos(Xcosn), order) * (np.abs(alpha) < np.pi/2)

			orients = []

			for b in range(self.nbands):
				anglemask = self.pointOp(angle, Ycosn, Xcosn + np.pi*b/self.nbands)
				banddft = np.power(np.complex(0,-1), self.nbands - 1) * lodft * anglemask * himask
				band = np.fft.ifft2(np.fft.ifftshift(banddft))
				orients.append(band)

			# ================== Subsample lowpass ============================
			dims = np.array(lodft.shape)
			
			lostart = np.ceil((dims+0.5)/2) - np.ceil((np.ceil((dims-0.5)/2)+0.5)/2)
			loend = lostart + np.ceil((dims-0.5)/2)

			lostart = lostart.astype(int)
			loend = loend.astype(int)

			log_rad = log_rad[lostart[0]:loend[0], lostart[1]:loend[1]]
			angle = angle[lostart[0]:loend[0], lostart[1]:loend[1]]
			lodft = lodft[lostart[0]:loend[0], lostart[1]:loend[1]]
			YIrcos = np.abs(np.sqrt(1 - Yrcos*Yrcos))
			lomask = self.pointOp(log_rad, YIrcos, Xrcos)

			lodft = lomask * lodft

			coeff = self.buildSCFpyrlevs(lodft, log_rad, angle, Xrcos, Yrcos, ht-1)
			coeff.insert(0, orients)

		return coeff
//  [python]
def __init__(self, n=0, fused: bool = False, **kwargs):
        r"""Initialize layer with constant n.

        Args:
            n (int): Positive integer for :math:`n` in :math:`P_n(x)`.
            fused (bool): Whether to compute polynomial in a fused tensor representation.
        """
        super(LegendrePolynomialPn, self).__init__(**kwargs)
        self.fused = fused
        self.n = n
        self._pre_factors = [
            float((-1) ** k * s.factorial(2 * n - 2 * k) / s.factorial(n - k) / s.factorial(
                n - 2 * k) / s.factorial(k) / 2 ** n) for k in range(0, int(np.floor(n / 2)) + 1)
        ]
        self._powers = [float(n - 2 * k) for k in range(0, int(np.floor(n / 2)) + 1)]
        if self.fused:
            # Or maybe also as weight.
            self._powers = ops.convert_to_tensor(self._powers, dtype=self.dtype)
            self._pre_factors = ops.convert_to_tensor(self._pre_factors, dtype=self.dtype)
//  [python]
def __init__(self, n=0, fused: bool = False, **kwargs):
        r"""Initialize layer with constant n.

        Args:
            n (int): Positive integer for :math:`n` in :math:`P_n(x)`.
            fused (bool): Whether to compute polynomial in a fused tensor representation.
        """
        super(LegendrePolynomialPn, self).__init__(**kwargs)
        self.fused = fused
        self.n = n
        self._pre_factors = [
            float((-1) ** k * sp.special.factorial(2 * n - 2 * k) / sp.special.factorial(n - k) / sp.special.factorial(
                n - 2 * k) / sp.special.factorial(k) / 2 ** n) for k in range(0, int(np.floor(n / 2)) + 1)
        ]
        self._powers = [float(n - 2 * k) for k in range(0, int(np.floor(n / 2)) + 1)]
        if self.fused:
            # Or maybe also as weight.
            self._powers = ops.convert_to_tensor(self._powers, dtype=self.dtype)
            self._pre_factors = ops.convert_to_tensor(self._pre_factors, dtype=self.dtype)
//  [python]
def decode(self, epochs, binsize=0.02, slideby=0.005):

        assert isinstance(epochs, pd.DataFrame)

        spks = self._spks
        Ncells = len(spks)
        # self.fit()
        ratemap = self.ratemap
        gridcntr = self.gridcenter

        nbins = np.zeros(len(epochs))
        spkcount = []
        for i, epoch in enumerate(epochs.itertuples()):
            bins = np.arange(epoch.start, epoch.end - binsize, slideby)
            nbins[i] = len(bins)
            for j in bins:
                spkcount.append(
                    np.asarray(
                        [np.histogram(_, bins=[j, j + binsize])[0] for _ in spks]
                    )
                )

        spkcount = np.hstack(spkcount)
        print(spkcount.shape)

        """ 
        ===========================
        Probability is calculated using this formula
        prob = (1 / nspike!)* ((0.1 * frate)^nspike) * exp(-0.1 * frate)
        =========================== 
        """

        cell_prob = np.zeros((ratemap.shape[1], spkcount.shape[1], Ncells))
        for cell in range(Ncells):
            cell_spkcnt = spkcount[cell, :][np.newaxis, :]
            cell_ratemap = ratemap[cell, :][:, np.newaxis]

            coeff = 1 / (s.factorial(cell_spkcnt))
            # broadcasting
            cell_prob[:, :, cell] = (((0.1 * cell_ratemap) ** cell_spkcnt) * coeff) * (
                np.exp(-0.1 * cell_ratemap)
            )
        posterior = np.prod(cell_prob, axis=2)
        posterior /= np.sum(posterior, axis=0)

        decodedPos = gridcntr[:, np.argmax(posterior, axis=0)]
        cum_nbins = np.append(0, np.cumsum(nbins)).astype(int)

        posterior = [
            posterior[:, cum_nbins[i] : cum_nbins[i + 1]]
            for i in range(len(cum_nbins) - 1)
        ]

        decodedPos = [
            decodedPos[:, cum_nbins[i] : cum_nbins[i + 1]]
            for i in range(len(cum_nbins) - 1)
        ]

        return decodedPos, posterior
//  [python]
def decode(self, epochs, binsize=0.02, slideby=0.005):

        assert isinstance(epochs, pd.DataFrame)

        spks = self._spks
        Ncells = len(spks)
        # self.fit()
        ratemap = self.ratemap
        gridcntr = self.gridcenter

        nbins = np.zeros(len(epochs))
        spkcount = []
        for i, epoch in enumerate(epochs.itertuples()):
            bins = np.arange(epoch.start, epoch.end - binsize, slideby)
            nbins[i] = len(bins)
            for j in bins:
                spkcount.append(
                    np.asarray(
                        [np.histogram(_, bins=[j, j + binsize])[0] for _ in spks]
                    )
                )

        spkcount = np.hstack(spkcount)
        print(spkcount.shape)

        """ 
        ===========================
        Probability is calculated using this formula
        prob = (1 / nspike!)* ((0.1 * frate)^nspike) * exp(-0.1 * frate)
        =========================== 
        """

        cell_prob = np.zeros((ratemap.shape[1], spkcount.shape[1], Ncells))
        for cell in range(Ncells):
            cell_spkcnt = spkcount[cell, :][np.newaxis, :]
            cell_ratemap = ratemap[cell, :][:, np.newaxis]

            coeff = 1 / (factorial(cell_spkcnt))
            # broadcasting
            cell_prob[:, :, cell] = (((0.1 * cell_ratemap) ** cell_spkcnt) * coeff) * (
                np.exp(-0.1 * cell_ratemap)
            )
        posterior = np.prod(cell_prob, axis=2)
        posterior /= np.sum(posterior, axis=0)

        decodedPos = gridcntr[:, np.argmax(posterior, axis=0)]
        cum_nbins = np.append(0, np.cumsum(nbins)).astype(int)

        posterior = [
            posterior[:, cum_nbins[i] : cum_nbins[i + 1]]
            for i in range(len(cum_nbins) - 1)
        ]

        decodedPos = [
            decodedPos[:, cum_nbins[i] : cum_nbins[i + 1]]
            for i in range(len(cum_nbins) - 1)
        ]

        return decodedPos, posterior
//  [python]
def tf_legendre_polynomial_pn(x, n=0):
    r"""Compute the (non-associated) Legendre polynomial :math:`P_n(x)` for constant positive integer :math:`n`
    via explicit formula.
    TensorFlow has to cache the function for each :math:`n`. No gradient through :math:`n` or very large number
    of :math:`n` is possible.
    Closed form can be viewed at https://en.wikipedia.org/wiki/Legendre_polynomials.

    :math:`P_n(x)=\sum_{k=0}^{\lfloor n/2\rfloor} (-1)^k \frac{(2n - 2k)! \, }{(n-k)! \, (n-2k)! \, k! \, 2^n} x^{n-2k}`

    Args:
        x (Tensor): Values to compute :math:`P_n(x)` for.
        n (int): Positive integer for :math:`n` in :math:`P_n(x)`.

    Returns:
        Tensor: Legendre Polynomial of order :math:`n`.
    """
    out_sum = ops.zeros_like(x)
    prefactors = [
        float((-1) ** k * s.factorial(2 * n - 2 * k) / s.factorial(n - k) / s.factorial(
            n - 2 * k) / s.factorial(k) / 2 ** n) for k in range(0, int(np.floor(n / 2)) + 1)]
    powers = [float(n - 2 * k) for k in range(0, int(np.floor(n / 2)) + 1)]
    for i in range(len(powers)):
        out_sum = out_sum + prefactors[i] * ops.power(x, powers[i])
    return out_sum
//  [python]
def tf_legendre_polynomial_pn(x, n=0):
    r"""Compute the (non-associated) Legendre polynomial :math:`P_n(x)` for constant positive integer :math:`n`
    via explicit formula.
    TensorFlow has to cache the function for each :math:`n`. No gradient through :math:`n` or very large number
    of :math:`n` is possible.
    Closed form can be viewed at https://en.wikipedia.org/wiki/Legendre_polynomials.

    :math:`P_n(x)=\sum_{k=0}^{\lfloor n/2\rfloor} (-1)^k \frac{(2n - 2k)! \, }{(n-k)! \, (n-2k)! \, k! \, 2^n} x^{n-2k}`

    Args:
        x (Tensor): Values to compute :math:`P_n(x)` for.
        n (int): Positive integer for :math:`n` in :math:`P_n(x)`.

    Returns:
        Tensor: Legendre Polynomial of order :math:`n`.
    """
    out_sum = ops.zeros_like(x)
    prefactors = [
        float((-1) ** k * sp.special.factorial(2 * n - 2 * k) / sp.special.factorial(n - k) / sp.special.factorial(
            n - 2 * k) / sp.special.factorial(k) / 2 ** n) for k in range(0, int(np.floor(n / 2)) + 1)]
    powers = [float(n - 2 * k) for k in range(0, int(np.floor(n / 2)) + 1)]
    for i in range(len(powers)):
        out_sum = out_sum + prefactors[i] * ops.power(x, powers[i])
    return out_sum
//  [python]
def __init__(self, n=0, fused: bool = False, **kwargs):
        r"""Initialize layer with constant n.

        Args:
            n (int): Positive integer for the bessel order :math:`n`.
            fused (bool): Whether to compute polynomial in a fused tensor representation.
        """
        super(SphericalBesselJnExplicit, self).__init__(**kwargs)
        self.n = n
        self.fused = fused
        self._pre_factor_sin = []
        self._pre_factor_cos = []
        self._powers_sin = []
        self._powers_cos = []

        for k in range(int(np.floor(n / 2)) + 1):
            if 2 * k < n + 1:
                fac_sin = float(s.factorial(n + 2 * k) / np.power(2, 2 * k) / s.factorial(
                    2 * k) / s.factorial(n - 2 * k) * np.power(-1, k))
                pow_sin = - (2 * k + 1)
                self._pre_factor_sin.append(fac_sin)
                self._powers_sin.append(pow_sin)

        for k in range(int(np.floor((n - 1) / 2)) + 1):
            if 2 * k + 1 < n + 1:
                fac_cos = float(s.factorial(n + 2 * k + 1) / np.power(2, 2 * k + 1) / s.factorial(
                        2 * k + 1) / s.factorial(n - 2 * k - 1) * np.power(-1, k))
                pow_cos = - (2 * k + 2)
                self._pre_factor_cos.append(fac_cos)
                self._powers_cos.append(pow_cos)

        if self.fused:
            self._pre_factor_sin = ops.convert_to_tensor(self._pre_factor_sin, dtype=self.dtype)
            self._pre_factor_cos = ops.convert_to_tensor(self._pre_factor_cos, dtype=self.dtype)
            self._powers_sin = ops.convert_to_tensor(self._powers_sin, dtype=self.dtype)
            self._powers_cos = ops.convert_to_tensor(self._powers_cos, dtype=self.dtype)
//  [python]
def __init__(self, n=0, fused: bool = False, **kwargs):
        r"""Initialize layer with constant n.

        Args:
            n (int): Positive integer for the bessel order :math:`n`.
            fused (bool): Whether to compute polynomial in a fused tensor representation.
        """
        super(SphericalBesselJnExplicit, self).__init__(**kwargs)
        self.n = n
        self.fused = fused
        self._pre_factor_sin = []
        self._pre_factor_cos = []
        self._powers_sin = []
        self._powers_cos = []

        for k in range(int(np.floor(n / 2)) + 1):
            if 2 * k < n + 1:
                fac_sin = float(sp.special.factorial(n + 2 * k) / np.power(2, 2 * k) / sp.special.factorial(
                    2 * k) / sp.special.factorial(n - 2 * k) * np.power(-1, k))
                pow_sin = - (2 * k + 1)
                self._pre_factor_sin.append(fac_sin)
                self._powers_sin.append(pow_sin)

        for k in range(int(np.floor((n - 1) / 2)) + 1):
            if 2 * k + 1 < n + 1:
                fac_cos = float(sp.special.factorial(n + 2 * k + 1) / np.power(2, 2 * k + 1) / sp.special.factorial(
                        2 * k + 1) / sp.special.factorial(n - 2 * k - 1) * np.power(-1, k))
                pow_cos = - (2 * k + 2)
                self._pre_factor_cos.append(fac_cos)
                self._powers_cos.append(pow_cos)

        if self.fused:
            self._pre_factor_sin = ops.convert_to_tensor(self._pre_factor_sin, dtype=self.dtype)
            self._pre_factor_cos = ops.convert_to_tensor(self._pre_factor_cos, dtype=self.dtype)
            self._powers_sin = ops.convert_to_tensor(self._powers_sin, dtype=self.dtype)
            self._powers_cos = ops.convert_to_tensor(self._powers_cos, dtype=self.dtype)
//  [python]
def __init__(self, l=0, fused: bool = False, **kwargs):
        r"""Initialize layer with constant l.

        Args:
            l (int): Positive integer for :math:`l` in :math:`Y_l(\cos\theta)`.
            fused (bool): Whether to compute polynomial in a fused tensor representation.
        """
        super(SphericalHarmonicsYl, self).__init__(**kwargs)
        self.l = l
        self.fused = fused
        self._pre_factors = [
            float((-1) ** k * s.factorial(2 * l - 2 * k) / s.factorial(l - k) / s.factorial(
                l - 2 * k) / s.factorial(k) / 2 ** l) for k in range(0, int(np.floor(l / 2)) + 1)]
        self._powers = [float(l - 2 * k) for k in range(0, int(np.floor(l / 2)) + 1)]
        self._scale = float(np.sqrt((2 * l + 1) / 4 / np.pi))
        if self.fused:
            # Or maybe also as weight.
            self._powers = ops.convert_to_tensor(self._powers, dtype=self.dtype)
            self._pre_factors = ops.convert_to_tensor(self._pre_factors, dtype=self.dtype)