# Path: econtools/metrics/core.py
# class RegBase(object):
# class Regression(RegBase):
# class IVReg(RegBase):
#     def __init__(self, df, y_name, x_name, **kwargs):
#     def main(self):
#     def set_sample(self):
#     def _demean_sample(self):
#     def _weight_sample(self):
#     def estimate(self):
#     def get_vce(self):
#     def _prep_inference_mats(self):
#     def set_dof(self):
#     def _set_NK(self):
#     def inference(self):
# def _set_vce_type(vce_type, cluster, shac):
# def _demean(A, df):
# def _calc_aweights(aw):
# def _fe_nested_in_cluster(cluster_id, A):
# def _wrapSigma(Sigma, cols):
#     def __init__(self, *args, **kwargs):
#     def estimate(self):
#     def __init__(self, df, y_name, x_name, z_name, w_name, **kwargs):
#     def estimate(self):
#     def _first_stage(self, x, w, z):
#     def _liml(self, y, x, z, w, _kappa_debug, vce_type):
#     def _liml_kappa(self, y, x, w, Z):
#     def _prep_inference_mats(self):
#     def _set_NK(self):
# def fitguts(y, x):
# def check_colinear_cols(matrix: pd.DataFrame) -> None:
# def _get_colinear_cols(matrix: pd.DataFrame) -> List[str]:
# def _raise_colinear_cols(colinear_cols: list) -> None:
# def vce_homosk(xpx_inv, resid):
# def vce_robust(xpx_inv, resid, x):
# def vce_hc23(xpx_inv, resid, x, hctype='hc2'):
# def _get_h(x, xpx_inv):
# def vce_cluster(xpx_inv, resid, x, cluster):
# def vce_shac(xpx_inv, resid, x, shac_x, shac_y, shac_kern, shac_band):
# def _shac_weights(xu, lon, lat, kernel, band):
# def _shac_kernels(kernel, band):
#     def unif(x):
#     def tria(x):
# def sandwich(left, B, right):
# def df_std(n, k):
# def df_hc23(n, k):
# def df_cluster(n, k, cluster_id):
# def df_shac(n, k):
#         N, K = self._set_NK()
#         N, K = self.x.shape
#         X = pd.concat((x, w), axis=1)
#         Z = pd.concat((z, w), axis=1)
#         Z = pd.concat((z, w), axis=1)
#         X = pd.concat((x, w), axis=1)
#         XX = X.T.dot(X)
#         XZ = X.T.dot(Z)
#         Y = pd.concat((y, x), axis=1).astype(np.float64)
#         YY = Y.T.dot(Y)
#         YZ = Y.T.dot(Z)
#         N, K = super(IVReg, self)._set_NK()
#     K = matrix.shape[1]
#     B = xu.T.dot(xu)
#     B = xu.T.dot(xu)
#     B = xu.T.dot(xu)
#     B = xu.T.dot(Wxu)
#     N, K = xu.shape
# 
# Path: econtools/util/gentools.py
# def force_iterable(x) -> Iterable:
#     """If not iterable, wrap in tuple"""
#     if hasattr(x, '__iter__') and type(x) is not str:
#         return x
#     else:
#         return (x,)


import os
from typing import Optional, List, Tuple, Union, Iterable
from econtools.metrics.core import Results
from econtools.util.gentools import force_iterable
                  regs: Union[Results, Tuple[Results]],
                  name_just: int = 24,
                  stat_just: int = 12,
                  digits: int = 3,
                  se: str = "(",
                  stars: bool = True) -> str:

    """Add a table row of regression coefficients with standard errors.

    Args:
        rowname (str): First cell of table row, i.e., the row's name.
        varname (str): Name of variable to pull from ``Results`` object.
        regs (Results or iterable of Results): Regressions from which
          to pull coefficients named ``varname``.

    Keyword Args:
        name_just (int):
        stat_just (int):
        digits (int):
        se (str):
        stars (bool):

    Returns:
        str: String of table row.
    """

    # Start beta and SE rows
    beta_vals = []
    se_vals = []
    # Extract beta/sig and se values to pass to `table_statrow`

# Path: econtools/metrics/core.py
# class RegBase(object):
# class Regression(RegBase):
# class IVReg(RegBase):
#     def __init__(self, df, y_name, x_name, **kwargs):
#     def main(self):
#     def set_sample(self):
#     def _demean_sample(self):
#     def _weight_sample(self):
#     def estimate(self):
#     def get_vce(self):
#     def _prep_inference_mats(self):
#     def set_dof(self):
#     def _set_NK(self):
#     def inference(self):
# def _set_vce_type(vce_type, cluster, shac):
# def _demean(A, df):
# def _calc_aweights(aw):
# def _fe_nested_in_cluster(cluster_id, A):
# def _wrapSigma(Sigma, cols):
#     def __init__(self, *args, **kwargs):
#     def estimate(self):
#     def __init__(self, df, y_name, x_name, z_name, w_name, **kwargs):
#     def estimate(self):
#     def _first_stage(self, x, w, z):
#     def _liml(self, y, x, z, w, _kappa_debug, vce_type):
#     def _liml_kappa(self, y, x, w, Z):
#     def _prep_inference_mats(self):
#     def _set_NK(self):
# def fitguts(y, x):
# def check_colinear_cols(matrix: pd.DataFrame) -> None:
# def _get_colinear_cols(matrix: pd.DataFrame) -> List[str]:
# def _raise_colinear_cols(colinear_cols: list) -> None:
# def vce_homosk(xpx_inv, resid):
# def vce_robust(xpx_inv, resid, x):
# def vce_hc23(xpx_inv, resid, x, hctype='hc2'):
# def _get_h(x, xpx_inv):
# def vce_cluster(xpx_inv, resid, x, cluster):
# def vce_shac(xpx_inv, resid, x, shac_x, shac_y, shac_kern, shac_band):
# def _shac_weights(xu, lon, lat, kernel, band):
# def _shac_kernels(kernel, band):
#     def unif(x):
#     def tria(x):
# def sandwich(left, B, right):
# def df_std(n, k):
# def df_hc23(n, k):
# def df_cluster(n, k, cluster_id):
# def df_shac(n, k):
#         N, K = self._set_NK()
#         N, K = self.x.shape
#         X = pd.concat((x, w), axis=1)
#         Z = pd.concat((z, w), axis=1)
#         Z = pd.concat((z, w), axis=1)
#         X = pd.concat((x, w), axis=1)
#         XX = X.T.dot(X)
#         XZ = X.T.dot(Z)
#         Y = pd.concat((y, x), axis=1).astype(np.float64)
#         YY = Y.T.dot(Y)
#         YZ = Y.T.dot(Z)
#         N, K = super(IVReg, self)._set_NK()
#     K = matrix.shape[1]
#     B = xu.T.dot(xu)
#     B = xu.T.dot(xu)
#     B = xu.T.dot(xu)
#     B = xu.T.dot(Wxu)
#     N, K = xu.shape
# 
# Path: econtools/util/gentools.py
# def force_iterable(x) -> Iterable:
#     """If not iterable, wrap in tuple"""
#     if hasattr(x, '__iter__') and type(x) is not str:
#         return x
#     else:
#         return (x,)


# Path: econtools/util/to_latex.py
import os
from typing import Optional, List, Tuple, Union, Iterable
from econtools.metrics.core import Results
from econtools.util.gentools import force_iterable

                  regs: Union[Results, Tuple[Results]],
                  name_just: int = 24,
                  stat_just: int = 12,
                  digits: int = 3,
                  se: str = "(",
                  stars: bool = True) -> str:

    """Add a table row of regression coefficients with standard errors.

    Args:
        rowname (str): First cell of table row, i.e., the row's name.
        varname (str): Name of variable to pull from ``Results`` object.
        regs (Results or iterable of Results): Regressions from which
          to pull coefficients named ``varname``.

    Keyword Args:
        name_just (int):
        stat_just (int):
        digits (int):
        se (str):
        stars (bool):

    Returns:
        str: String of table row.
    """

    # Start beta and SE rows
    beta_vals = []
    se_vals = []
    # Extract beta/sig and se values to pass to `table_statrow`

    for reg in force_iterable(regs):