# Path: econtools/metrics/locallinear.py
# def llr(y: np.ndarray, x: np.ndarray,
#         x0: Optional[ArrayLike]=None,
#         N: Optional[int]=None, h: Optional[Union[str, float]]=None,
#         degree: int=1, kernel: str='epan', ci: bool=False):
#     """Local-linear Regression
# 
#     Args:
#         y (array): Dependent variable
#         x (array): Independent variable
# 
#     Keyword Args:
#         x0 (float or array-like): Default ``None``. Values at which to
#             caluculate regression. If ``None``, these values will be calculated
#             automatically. Default length of `x0` is min([len(x), 50]).  At
#             least one of ``x0`` and ``N`` must be ``None``.
#         N (int): Default ``None``. Number of ``x0`` values to calculate if
#             ``x0`` is not specified. At least one of ``x0`` and ``N`` must be
#             ``None``.
#         h (str or float): Defaults to None (Silverman's rule of thumb).
#             Bandwidth for kernel. May pass a float or any of the following for
#             Silverman's rule of thumb: ``'silverman'``, ``'thumb'``, ``'rot'``.
#         kernel (str): Type of kernel to be used. Options
#             are:
#                 - ``'epan'``, Epanechnikov (default)
#                 - ``'unif'``, Uniform
#                 - ``'tria'``, Triangle
#         degree (int): Defaults to 1. Degree of polynomial to use in local
#             regression.
#         ci (bool): Defaults to False. If True, also return confidence interval
#             for each point.
# 
#     Returns:
#         Stuff.
#     """
#     try:
#         assert len(y) == len(x)
#     except AssertionError:
#         raise ValueError("Vectors `y` and `x` must be same size.")
# 
#     # Set model parameters
#     kernel_obj = kernel_parser(kernel)
#     x0 = _set_x0(x, x0, N)      # TODO passed `x0` overwritten?
# 
#     if type(h) is str:
#         return_only = 'return' in cast(str, h)
#     else:
#         return_only = False
#     h_val = set_bandwidth(y, x, h, degree, kernel_obj, return_only=return_only)
#     if return_only:
#         return h_val
# 
#     # Loop over domain values
#     xG = model_loop(y, x, x0, h_val, degree, kernel_obj)
# 
#     est_stats = {
#         'h': h_val,
#         'kernel': kernel_obj.name,
#         'degree': degree
#     }
# 
#     if ci:
#         raise NotImplementedError   # TODO, see `NonParametrics2`, sec 3.11
#     else:
#         return xG, est_stats        # TODO, separate x0 and yhat


import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, cdist
from scipy.optimize import minimize
from econtools.metrics.locallinear import llr

    # Krige it
    weights = la.inv(K).dot(k)[:-1].T           # Drop Lagrange

    return weights


def check_variogram(X, y, maxd=None, scat=False,
                    npreg_args=dict(),
                    model_name='exp',
                    mle_args=dict(),
                    ):
    """
    Scatter p = (h_ij, (y_i - y_j) ^ 2).
    Kernel regression of p.
    MLE of variogram model to fit p.
    """

    # Estimate the MLE
    model = model_factory(model_name)
    mle, __ = variogram_mle(X, y, model, mle_args)
    est = mle['x']
    print(mle)

    # Get empirical variogram data
    xG, h, sqdiff, est_stats = llr_gamma(X, y, maxd=maxd, plot=False,
                                         ret_raw=True)

    # Plot everything
    x0 = xG[:, 0]                               # Kernel reg x's

# Path: econtools/metrics/locallinear.py
# def llr(y: np.ndarray, x: np.ndarray,
#         x0: Optional[ArrayLike]=None,
#         N: Optional[int]=None, h: Optional[Union[str, float]]=None,
#         degree: int=1, kernel: str='epan', ci: bool=False):
#     """Local-linear Regression
# 
#     Args:
#         y (array): Dependent variable
#         x (array): Independent variable
# 
#     Keyword Args:
#         x0 (float or array-like): Default ``None``. Values at which to
#             caluculate regression. If ``None``, these values will be calculated
#             automatically. Default length of `x0` is min([len(x), 50]).  At
#             least one of ``x0`` and ``N`` must be ``None``.
#         N (int): Default ``None``. Number of ``x0`` values to calculate if
#             ``x0`` is not specified. At least one of ``x0`` and ``N`` must be
#             ``None``.
#         h (str or float): Defaults to None (Silverman's rule of thumb).
#             Bandwidth for kernel. May pass a float or any of the following for
#             Silverman's rule of thumb: ``'silverman'``, ``'thumb'``, ``'rot'``.
#         kernel (str): Type of kernel to be used. Options
#             are:
#                 - ``'epan'``, Epanechnikov (default)
#                 - ``'unif'``, Uniform
#                 - ``'tria'``, Triangle
#         degree (int): Defaults to 1. Degree of polynomial to use in local
#             regression.
#         ci (bool): Defaults to False. If True, also return confidence interval
#             for each point.
# 
#     Returns:
#         Stuff.
#     """
#     try:
#         assert len(y) == len(x)
#     except AssertionError:
#         raise ValueError("Vectors `y` and `x` must be same size.")
# 
#     # Set model parameters
#     kernel_obj = kernel_parser(kernel)
#     x0 = _set_x0(x, x0, N)      # TODO passed `x0` overwritten?
# 
#     if type(h) is str:
#         return_only = 'return' in cast(str, h)
#     else:
#         return_only = False
#     h_val = set_bandwidth(y, x, h, degree, kernel_obj, return_only=return_only)
#     if return_only:
#         return h_val
# 
#     # Loop over domain values
#     xG = model_loop(y, x, x0, h_val, degree, kernel_obj)
# 
#     est_stats = {
#         'h': h_val,
#         'kernel': kernel_obj.name,
#         'degree': degree
#     }
# 
#     if ci:
#         raise NotImplementedError   # TODO, see `NonParametrics2`, sec 3.11
#     else:
#         return xG, est_stats        # TODO, separate x0 and yhat


# Path: econtools/geo/krig.py
import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, cdist
from scipy.optimize import minimize
from econtools.metrics.locallinear import llr


    # Krige it
    weights = la.inv(K).dot(k)[:-1].T           # Drop Lagrange

    return weights


def check_variogram(X, y, maxd=None, scat=False,
                    npreg_args=dict(),
                    model_name='exp',
                    mle_args=dict(),
                    ):
    """
    Scatter p = (h_ij, (y_i - y_j) ^ 2).
    Kernel regression of p.
    MLE of variogram model to fit p.
    """

    # Estimate the MLE
    model = model_factory(model_name)
    mle, __ = variogram_mle(X, y, model, mle_args)
    est = mle['x']
    print(mle)

    # Get empirical variogram data
    xG, h, sqdiff, est_stats = llr_gamma(X, y, maxd=maxd, plot=False,
                                         ret_raw=True)

    # Plot everything
    x0 = xG[:, 0]                               # Kernel reg x's

    llr = xG[:, 1]                              # Kernel reg y's