Source code for ruspy.estimation.criterion_function

"""
This module specifies the criterion function and its derivative.
"""
from functools import partial

import numpy as np

from ruspy.estimation.estimation_transitions import create_transition_matrix
from ruspy.estimation.estimation_transitions import estimate_transitions
from ruspy.estimation.mpec import mpec_constraint
from ruspy.estimation.mpec import mpec_constraint_derivative
from ruspy.estimation.mpec import mpec_loglike_cost_params
from ruspy.estimation.mpec import mpec_loglike_cost_params_derivative
from ruspy.estimation.nfxp import create_state_matrix
from ruspy.estimation.nfxp import derivative_loglike_cost_params
from ruspy.estimation.nfxp import derivative_loglike_cost_params_individual
from ruspy.estimation.nfxp import loglike_cost_params
from ruspy.estimation.nfxp import loglike_cost_params_individual
from ruspy.estimation.pre_processing import select_model_parameters


[docs]def get_criterion_function( init_dict, df, ): """ This function specifies the criterion function with its derivative, transition probabilites (for NXFP and MPEC) as well as the contraint function with its derivative (for MPEC). Parameters ---------- init_dict : dictionary see :ref:`init_dict` df : pandas.DataFrame see :ref:`df` Returns ------- func_dict : see :ref:`func_dict` transition_results : dictionary see :ref:`result_trans` """ transition_results = estimate_transitions(df) endog = df.loc[(slice(None), slice(1, None)), "decision"].to_numpy(int) states = df.loc[(slice(None), slice(1, None)), "state"].to_numpy(int) ( disc_fac, num_states, maint_func, maint_func_dev, num_params, scale, ) = select_model_parameters(init_dict) decision_mat = np.vstack(((1 - endog), endog)) trans_mat = create_transition_matrix(num_states, transition_results["x"]) state_mat = create_state_matrix(states, num_states) alg_details = {} if "alg_details" not in init_dict else init_dict["alg_details"] basic_kwargs = { "maint_func": maint_func, "maint_func_dev": maint_func_dev, "num_states": num_states, "disc_fac": disc_fac, "scale": scale, } if "method" in init_dict: method = init_dict["method"] else: raise ValueError("The key 'method' must be in init_dict") func_dict = {} nfxp_kwargs = { **basic_kwargs, "trans_mat": trans_mat, "state_mat": state_mat, "decision_mat": decision_mat, "alg_details": alg_details, } if method == "NFXP": func_dict["criterion_function"] = partial(loglike_cost_params, **nfxp_kwargs) func_dict["criterion_derivative"] = partial( derivative_loglike_cost_params, **nfxp_kwargs ) elif method == "NFXP_BHHH": func_dict["criterion_function"] = partial( loglike_cost_params_individual, **nfxp_kwargs ) func_dict["criterion_derivative"] = partial( derivative_loglike_cost_params_individual, **nfxp_kwargs ) elif method == "MPEC": mpec_crit_kwargs = { **basic_kwargs, "state_mat": state_mat, "decision_mat": decision_mat, } func_dict["criterion_function"] = partial( mpec_loglike_cost_params, **mpec_crit_kwargs ) func_dict["criterion_derivative"] = partial( mpec_loglike_cost_params_derivative, **mpec_crit_kwargs ) mpec_constr_kwargs = { **basic_kwargs, "trans_mat": trans_mat, } func_dict["constraint"] = partial(mpec_constraint, **mpec_constr_kwargs) func_dict["constraint_derivative"] = partial( mpec_constraint_derivative, **mpec_constr_kwargs ) else: raise ValueError( f"{method} is not implemented. Only MPEC or NFXP are valid choices" ) return func_dict, transition_results