Пример #1
0
def _parse_shocks(optim_paras, params):
    """Parse the shock parameters and create the Cholesky factor."""
    if sum(f"shocks_{i}" in params.index for i in ["sdcorr", "cov", "chol"]) >= 2:
        raise ValueError("It is not allowed to define multiple shock matrices.")
    elif "shocks_sdcorr" in params.index:
        sorted_shocks = _sort_shocks_sdcorr(optim_paras, params.loc["shocks_sdcorr"])
        cov = sdcorr_params_to_matrix(sorted_shocks)
        optim_paras["shocks_cholesky"] = robust_cholesky(cov)
    elif "shocks_cov" in params.index:
        sorted_shocks = _sort_shocks_cov_chol(
            optim_paras, params.loc["shocks_cov"], "cov"
        )
        cov = cov_params_to_matrix(sorted_shocks)
        optim_paras["shocks_cholesky"] = robust_cholesky(cov)
    elif "shocks_chol" in params.index:
        sorted_shocks = _sort_shocks_cov_chol(
            optim_paras, params.loc["shocks_chol"], "chol"
        )
        optim_paras["shocks_cholesky"] = chol_params_to_lower_triangular_matrix(
            sorted_shocks
        )
    else:
        raise NotImplementedError

    return optim_paras
Пример #2
0
def covariance_to_internal_jacobian(external_values, constr):
    r"""Jacobian of ``covariance_to_internal``.

    For reference see docstring of ``jacobian_covariance_from_internal``. In
    comparison to that function, however, here we want to differentiate the
    reverse graph
                external --> cov --> cholesky --> internal

    Again use the vectors :math:`c` and :math:`x` to denote the external and
    internal values, respectively. To solve for the jacobian we make use of the
    identity

    .. math::
        \frac{\mathrm{d}x}{\mathrm{d}c} = (\frac{\mathrm{d}c}{\mathrm{d}x})^{-1}

    Args:
        external_values (np.ndarray): Row-wise half-vectorized covariance matrix

    Returns:
        deriv: The Jacobian matrix.

    """
    cov = cov_params_to_matrix(external_values)
    chol = robust_cholesky(cov)

    internal = chol[np.tril_indices(len(chol))]

    deriv = covariance_from_internal_jacobian(internal, constr=None)
    deriv = np.linalg.pinv(deriv)
    return deriv
Пример #3
0
def _parse_shocks(optim_paras, params):
    """Parse the shock parameters and create the Cholesky factor."""
    if sum(f"shocks_{i}" in params.index for i in ["sdcorr", "cov", "chol"]) >= 2:
        raise ValueError("It is not allowed to define multiple shock matrices.")
    elif "shocks_sdcorr" in params.index:
        cov = sdcorr_params_to_matrix(params.loc["shocks_sdcorr"])
        optim_paras["shocks_cholesky"] = robust_cholesky(cov)
    elif "shocks_cov" in params.index:
        cov = cov_params_to_matrix(params.loc["shocks_cov"])
        optim_paras["shocks_cholesky"] = robust_cholesky(cov)
    elif "shocks_chol" in params.index:
        optim_paras["shocks_cholesky"] = chol_params_to_lower_triangular_matrix(
            params.loc["shocks_chol"]
        )
    else:
        raise KeyError("No shock matrix is specified.")

    return optim_paras
Пример #4
0
def update_cholcov(shocks_cholesky, n_wages):
    """Calculate cholesky factors of conditional covs for all possible cases.

    Parameters
    ----------
    shocks_cholesky : numpy.ndarray
        cholesky factor of the covariance matrix before updating. Has
        dimension (n_choices, n_choices)
    n_wages : int
        Number of wage sectors.

    Returns
    -------
    updated_chols : numpy.ndarray
        Array of (shape n_wages + 1, n_choices, n_choices) with the cholesky factors
        of the updated covariance matrices for each possible observed shock. The
        last element corresponds to not observing any shock.

    """
    n_choices = len(shocks_cholesky)
    cov = shocks_cholesky @ shocks_cholesky.T

    updated_chols = np.zeros((n_wages + 1, n_choices, n_choices))

    for i in range(n_wages):
        reduced_cov = np.delete(np.delete(cov, i, axis=1), i, axis=0)
        choice_var = cov[i, i]

        f = np.delete(cov[i], i)

        updated_reduced_cov = reduced_cov - np.outer(f, f) / choice_var
        updated_reduced_chol = robust_cholesky(updated_reduced_cov)

        updated_chols[i, :i, :i] = updated_reduced_chol[:i, :i]
        updated_chols[i, :i, i + 1:] = updated_reduced_chol[:i, i:]
        updated_chols[i, i + 1:, :i] = updated_reduced_chol[i:, :i]
        updated_chols[i, i + 1:, i + 1:] = updated_reduced_chol[i:, i:]

    updated_chols[-1] = shocks_cholesky

    return updated_chols
Пример #5
0
        cov = sdcorr_params_to_matrix(params_subset["value"].to_numpy())
    else:
        raise ValueError("Invalid type_: {}".format(type_))

    dim = len(cov)

    e, v = np.linalg.eigh(cov)
    assert np.all(e > -1e-8), "Invalid covariance matrix."

    if case == "uncorrelated":

        res["lower"] = np.maximum(res["lower"], np.zeros(len(res)))
        assert (res["upper"] >=
                res["lower"]).all(), "Invalid upper bound for variance."
    elif case == "free":
        chol = robust_cholesky(cov, threshold=1e-8)
        chol_coeffs = chol[np.tril_indices(dim)]
        res["value"] = chol_coeffs

        lower_bound_helper = np.full((dim, dim), -np.inf)
        lower_bound_helper[np.diag_indices(dim)] = bounds_distance
        res["lower"] = lower_bound_helper[np.tril_indices(dim)]
        res["upper"] = np.inf

        for bound in ["lower", "upper"]:
            if np.isfinite(params_subset[bound]).any():
                warnings.warn("Bounds are ignored for covariance parameters.",
                              UserWarning)
    return res

Пример #6
0
def test_robust_cholesky_with_extreme_cases():
    for cov in [np.ones((5, 5)), np.zeros((5, 5))]:
        chol = robust_cholesky(cov)
        aaae(chol.dot(chol.T), cov)
Пример #7
0
def test_robust_cholesky_with_zero_variance(dim, seed):
    cov = random_cov(dim, seed)
    chol = robust_cholesky(cov)
    aaae(chol.dot(chol.T), cov)
    assert (chol[np.triu_indices(len(cov), k=1)] == 0).all()
Пример #8
0
def covariance_to_internal(external_values, constr):
    """Do a cholesky reparametrization."""
    cov = cov_params_to_matrix(external_values)
    chol = robust_cholesky(cov)
    return chol[np.tril_indices(len(cov))]
Пример #9
0
def sdcorr_to_internal(external_values, constr):
    """Convert sdcorr to cov and do a cholesky reparametrization."""
    cov = sdcorr_params_to_matrix(external_values)
    chol = robust_cholesky(cov)
    return chol[np.tril_indices(len(cov))]