# Path: pygeoid/sharm/legendre.py
# def lplm(lmax, x):
#     """Associated Legendre functions of the first kind.
# 
#     Parameters
#     ----------
#     lmax : int
#         Maximum degree and order of the Plm(x).
#     x : float
#         Input value.
# 
#     Returns
#     -------
#     Plm(x) : (lmax + 1, lmax + 1) array
#         Values of Plm(x) for all orders and degrees.
#     """
#     return PlmBar(lmax, x)[_lplm_index(lmax)]
# 
# def lplm_d1(lmax, x):
#     """Associated Legendre functions of the first kind and their derivatives.
# 
#     Parameters
#     ----------
#     lmax : int
#         Maximum degree and order.
#     x : float
#         Input value.
# 
#     Returns
#     -------
#     Plm(x) : (lmax + 1, lmax + 1) array
#         Values of Plm(x) for all orders and degrees.
#     Plm_d(x) : {(lmax + 1, lmax + 1), None} array
#         Values of Plm_d(x) for all orders and degrees.
#         Will return None if `x` is very close or equal
#         to -1 or 1.
#     """
#     if not (np.allclose(-1, x) or np.allclose(1, x)):
#         index = _lplm_index(lmax)
#         p, p_d1 = PlmBar_d1(lmax, x)
#         return p[index], p_d1[index]
#     else:
#         p = lplm(lmax, x)
#         return p, None


import warnings
import numpy as np
from joblib import Parallel, delayed
from .legendre import lplm, lplm_d1
        lat_d = 0.0

    return lat_d


def in_coeff_lon_derivative(x, q, lmax, degrees, m_coeff):
    pole = np.allclose(x, -1) | np.allclose(x, 1)
    if not pole:
        p = lplm(lmax, x)
        q = np.power(q, degrees)
        l_coeff = np.tile(q, (lmax + 1, 1)).T
        in_coeff = l_coeff * m_coeff * p
    else:
        in_coeff = 0.0

    return in_coeff


def sum_lon_derivative(in_coeff, cosin, cilm):
    if not np.all(in_coeff == 0.0):
        lon_d = np.sum(in_coeff * (-cilm[1] * cosin[0] +
                                   cilm[0] * cosin[1]))
    else:
        lon_d = 0.0

    return lon_d


def in_coeff_gradient(x, q, lmax, degrees, m_coeff):


# Path: pygeoid/sharm/legendre.py
# def lplm(lmax, x):
#     """Associated Legendre functions of the first kind.
# 
#     Parameters
#     ----------
#     lmax : int
#         Maximum degree and order of the Plm(x).
#     x : float
#         Input value.
# 
#     Returns
#     -------
#     Plm(x) : (lmax + 1, lmax + 1) array
#         Values of Plm(x) for all orders and degrees.
#     """
#     return PlmBar(lmax, x)[_lplm_index(lmax)]
# 
# def lplm_d1(lmax, x):
#     """Associated Legendre functions of the first kind and their derivatives.
# 
#     Parameters
#     ----------
#     lmax : int
#         Maximum degree and order.
#     x : float
#         Input value.
# 
#     Returns
#     -------
#     Plm(x) : (lmax + 1, lmax + 1) array
#         Values of Plm(x) for all orders and degrees.
#     Plm_d(x) : {(lmax + 1, lmax + 1), None} array
#         Values of Plm_d(x) for all orders and degrees.
#         Will return None if `x` is very close or equal
#         to -1 or 1.
#     """
#     if not (np.allclose(-1, x) or np.allclose(1, x)):
#         index = _lplm_index(lmax)
#         p, p_d1 = PlmBar_d1(lmax, x)
#         return p[index], p_d1[index]
#     else:
#         p = lplm(lmax, x)
#         return p, None


# Path: pygeoid/sharm/expand.py
import warnings
import numpy as np
from joblib import Parallel, delayed
from .legendre import lplm, lplm_d1

        lat_d = 0.0

    return lat_d


def in_coeff_lon_derivative(x, q, lmax, degrees, m_coeff):
    pole = np.allclose(x, -1) | np.allclose(x, 1)
    if not pole:
        p = lplm(lmax, x)
        q = np.power(q, degrees)
        l_coeff = np.tile(q, (lmax + 1, 1)).T
        in_coeff = l_coeff * m_coeff * p
    else:
        in_coeff = 0.0

    return in_coeff


def sum_lon_derivative(in_coeff, cosin, cilm):
    if not np.all(in_coeff == 0.0):
        lon_d = np.sum(in_coeff * (-cilm[1] * cosin[0] +
                                   cilm[0] * cosin[1]))
    else:
        lon_d = 0.0

    return lon_d


def in_coeff_gradient(x, q, lmax, degrees, m_coeff):


    p, p_d1 = lplm_d1(lmax, x)