Exemple #1
0
def test_trans_mat_rows_one():
    rand_dict = random_init()
    control = np.ones(rand_dict["estimation"]["states"])
    assert_array_almost_equal(
        create_transition_matrix(
            rand_dict["estimation"]["states"],
            np.array(rand_dict["simulation"]["known_trans"]),
        ).sum(axis=1),
        control,
    )
Exemple #2
0
def estimate(init_dict, df, repl_4=False):
    """
    This function calls the auxiliary functions to estimate the decision parameters.
    Therefore it manages the estimation process. As mentioned in the model theory
    chapter of the paper, the estimation of the transition probabilities and the
    estimation of the parameters shaping the cost function
    are completely separate.

    :param init_dict: A dictionary containing the following variables as keys:

        :beta: (float)       : Discount factor.
        :states: (int)       : The size of the statespace.
        :maint_func: (func)  : The maintenance cost function. Default is the linear
                               from the paper.

    :param df:        A pandas dataframe, which contains for each observation the Bus
                      ID, the current state of the bus, the current period and the
                      decision made in this period.

    :param repl_4: Auxiliary variable indicating the complete setting of the
                   replication of the paper with group 4.

    :return: The function returns the optimization result of the transition
             probabilities and of the cost parameters as separate dictionaries.

    """
    beta = init_dict["beta"]
    transition_results = estimate_transitions(df, repl_4=repl_4)
    endog = df.loc[:, "decision"].to_numpy()
    states = df.loc[:, "state"].to_numpy()
    num_obs = df.shape[0]
    num_states = init_dict["states"]
    maint_func = lin_cost  # For now just set this to a linear cost function
    decision_mat = np.vstack(((1 - endog), endog))
    trans_mat = create_transition_matrix(num_states,
                                         np.array(transition_results["x"]))
    state_mat = create_state_matrix(states, num_states, num_obs)
    result = opt.minimize(
        loglike_opt_rule,
        args=(maint_func, num_states, trans_mat, state_mat, decision_mat,
              beta),
        x0=np.array([5, 5]),
        bounds=[(1e-6, None), (1e-6, None)],
        method="L-BFGS-B",
    )
    return transition_results, result
Exemple #3
0
def test_regression_simulation(inputs):
    init_dict = random_init(inputs)
    df, unobs, utilities, num_states = simulate(init_dict["simulation"])
    num_buses = init_dict["simulation"]["buses"]
    num_periods = init_dict["simulation"]["periods"]
    beta = init_dict["simulation"]["beta"]
    params = np.array(init_dict["simulation"]["params"])
    probs = np.array(init_dict["simulation"]["known probs"])
    v_disc_ = [0.0, 0.0]
    v_disc = discount_utility(
        v_disc_, num_buses, num_periods, num_periods, utilities, beta
    )
    trans_mat = create_transition_matrix(num_states, probs)
    costs = myopic_costs(num_states, lin_cost, params)
    v_calc = calc_fixp(num_states, trans_mat, costs, beta)
    un_ob_av = 0
    for bus in range(num_buses):
        un_ob_av += unobs[bus, 0, 0]
    un_ob_av = un_ob_av / num_buses
    assert_allclose(v_disc[1] / (v_calc[0] + un_ob_av), 1, rtol=1e-02)
Exemple #4
0
def params_hess(params, df, beta, maint_func, repl_4=False):
    """Calculates the hessian of the cost parameters."""
    transition_results = estimate_transitions(df, repl_4=repl_4)
    ll_trans = transition_results["fun"]
    states = df.loc[:, "state"].to_numpy()
    num_obs = df.shape[0]
    if repl_4:
        num_states = 90
    else:
        num_states = int(1.2 * np.max(states))
    trans_mat = create_transition_matrix(num_states,
                                         np.array(transition_results["x"]))
    state_mat = create_state_matrix(states, num_states, num_obs)
    endog = df.loc[:, "decision"].to_numpy()
    decision_mat = np.vstack(((1 - endog), endog))
    params_df = pd.DataFrame(index=["RC", "theta_1_1"],
                             columns=["value"],
                             data=params)
    wrap_func = create_wrap_func(maint_func, num_states, trans_mat, state_mat,
                                 decision_mat, beta, ll_trans)
    return hessian(wrap_func, params_df)
Exemple #5
0
def plot_convergence(init_dict):
    beta = init_dict["simulation"]["beta"]

    df, unobs, utilities, num_states = simulate(init_dict["simulation"])

    costs = myopic_costs(num_states, lin_cost,
                         init_dict["simulation"]["params"])
    trans_probs = np.array(init_dict["simulation"]["known probs"])
    trans_mat = create_transition_matrix(num_states, trans_probs)
    ev = calc_fixp(num_states, trans_mat, costs, beta)
    num_buses = init_dict["simulation"]["buses"]
    num_periods = init_dict["simulation"]["periods"]
    gridsize = init_dict["plot"]["gridsize"]
    num_points = int(num_periods / gridsize)

    v_exp = np.full(num_points, calc_ev_0(ev, unobs, num_buses))

    v_start = np.zeros(num_points)
    v_disc = discount_utility(v_start, num_buses, gridsize, num_periods,
                              utilities, beta)

    periods = np.arange(0, num_periods, gridsize)

    ax = plt.figure(figsize=(14, 6))

    ax1 = ax.add_subplot(111)

    ax1.set_ylim([0, 1.3 * v_disc[-1]])

    ax1.set_ylabel(r"Value at time 0")
    ax1.set_xlabel(r"Periods")

    ax1.plot(periods, v_disc, color="blue")
    ax1.plot(periods, v_exp, color="orange")

    plt.tight_layout()
    os.makedirs("figures", exist_ok=True)
    plt.savefig("figures/figure_1.png", dpi=300)
Exemple #6
0
def test_create_trans_mat(inputs, outputs):
    assert_array_almost_equal(
        create_transition_matrix(inputs["nstates"], inputs["trans_prob"]),
        outputs["trans_mat"],
    )
for roh in np.arange(0, 4, 0.1):
    roh_plot += [roh]
    init_dict["simulation"]["roh"] = roh
    worst_trans = get_worst_trans(init_dict["simulation"])
    init_dict["simulation"]["real probs"] = worst_trans

    df, unobs, utilities, num_states = simulate(init_dict["simulation"])

    costs = myopic_costs(num_states, lin_cost, init_dict["simulation"]["params"])

    num_buses = init_dict["simulation"]["buses"]
    num_periods = init_dict["simulation"]["periods"]
    gridsize = init_dict["plot"]["gridsize"]

    real_trans_probs = np.array(init_dict["simulation"]["real probs"])
    real_trans_mat = create_transition_matrix(num_states, real_trans_probs)
    ev_real = calc_fixp(num_states, real_trans_mat, costs, beta)

    known_trans_probs = np.array(init_dict["simulation"]["known probs"])
    known_trans_mat = create_transition_matrix(num_states, known_trans_probs)
    ev_known = calc_fixp(num_states, known_trans_mat, costs, beta)

    v_calc = 0
    for i in range(num_buses):
        v_calc = v_calc + unobs[i, 0, 0] + ev_known[0]
    v_calc = v_calc / num_buses
    v_exp_known += [v_calc]

    v_calc = 0
    for i in range(num_buses):
        v_calc = v_calc + unobs[i, 0, 0] + ev_real[0]
Exemple #8
0
from ruspy.plotting.value_zero import calc_ev_0
from ruspy.estimation.estimation_cost_parameters import calc_fixp
from ruspy.estimation.estimation_cost_parameters import lin_cost
from ruspy.estimation.estimation_cost_parameters import myopic_costs
from ruspy.estimation.estimation_cost_parameters import create_transition_matrix

with open("init.yml") as y:
    init_dict = yaml.safe_load(y)

beta = init_dict["simulation"]["beta"]

df, unobs, utilities, num_states = simulate(init_dict["simulation"])

costs = myopic_costs(num_states, lin_cost, init_dict["simulation"]["params"])
trans_probs = np.array(init_dict["simulation"]["probs"])
trans_mat = create_transition_matrix(num_states, trans_probs)
ev = calc_fixp(num_states, trans_mat, costs, beta)
num_buses = init_dict["simulation"]["buses"]
num_periods = init_dict["simulation"]["periods"]
gridsize = init_dict["plot"]["gridsize"]
num_points = int(num_periods / gridsize)

v_exp = np.full(num_points, calc_ev_0(ev, unobs, num_buses))

v_start = np.zeros(num_points)
v_disc = discount_utility(v_start, num_buses, gridsize, num_periods, utilities,
                          beta)

periods = np.arange(0, num_periods, gridsize)

ax = plt.figure(figsize=(14, 6))
def simulate_strategy(known_trans, increments, num_buses, num_periods, params,
                      beta, unobs, maint_func):
    """
    This function manages the simulation process. It initializes the auxiliary
    variables and calls therefore the subfuctions from estimation auxiliary. It then
    calls the decision loop, written for numba. As the state size of the fixed point
    needs to be a lot larger than the actual state, the size is doubled, if the loop
    hasn't run yet through all the periods.

    :param known_trans: A numpy array containing the transition probabilities the agent
                        assumes.
    :param increments:  A two dimensional numpy array containing for each bus in each
                        period a random drawn state increase as integer.
    :param num_buses:   The number of buses to be simulated.
    :type num_buses:    int
    :param num_periods: The number of periods to be simulated.
    :type num_periods:  int
    :param params:      A numpy array containing the parameters shaping the cost
                        function.
    :param beta:        The discount factor.
    :type beta:         float
    :param unobs:       A three dimensional numpy array containing for each bus,
                        for each period for the decision to maintain or replace the
                        bus engine a random drawn utility as float.
    :param maint_func:  The maintenance cost function. Only linear implemented so
                        far.

    :return: The function returns the following objects:

        :states:           : A two dimensional numpy array containing for each bus in
                             each period the state as an integer.
        :decisions:        : A two dimensional numpy array containing for each bus in
                             each period the decision as an integer.
        :utilities:        : A two dimensional numpy array containing for each bus in
                             each period the utility as a float.
        :num_states: (int) : The size of the state space.
    """
    num_states = int(200)
    start_period = int(0)
    states = np.zeros((num_buses, num_periods), dtype=int)
    decisions = np.zeros((num_buses, num_periods), dtype=int)
    utilities = np.zeros((num_buses, num_periods), dtype=float)
    while start_period < num_periods - 1:
        num_states = 2 * num_states
        known_trans_mat = create_transition_matrix(num_states, known_trans)
        costs = myopic_costs(num_states, maint_func, params)
        ev = calc_fixp(num_states, known_trans_mat, costs, beta)
        states, decisions, utilities, start_period = simulate_strategy_loop(
            num_buses,
            states,
            decisions,
            utilities,
            costs,
            ev,
            increments,
            num_states,
            start_period,
            num_periods,
            beta,
            unobs,
        )
    return states, decisions, utilities, num_states
Exemple #10
0
def select_fixp(trans_probs, state, num_states, costs, beta, max_it):
    trans_mat = create_transition_matrix(num_states, trans_probs)
    fixp = calc_fixp(num_states, trans_mat, costs, beta, max_it=max_it)
    return fixp[state]
Exemple #11
0
def estimate(init_dict, df, repl_4=True):
    """
    This function calls the auxiliary functions to estimate the decision parameters.
    Therefore it manages the estimation process. As mentioned in the model theory
    chapter of the paper, the estimation of the transition probabilities and the
    estimation of the parameters shaping the cost function
    are completely separate.

    :param init_dict: A dictionary containing the following variables as keys:

        :beta: (float)       : Discount factor.
        :states: (int)       : The size of the statespace.
        :maint_func: (string): The type of cost function, as string. Only linear
                               implemented so far.

    :param df:        A pandas dataframe, which contains for each observation the Bus
                      ID, the current state of the bus, the current period and the
                      decision made in this period.
    :param repl_4: Auxiliary variable for the convention of the replacement increase.

    :return: The function returns the optimization result of the transition
             probabilities and of the cost parameters as separate dictionaries.
    """
    beta = init_dict["beta"]
    if repl_4:
        transition_results = estimate_transitions(df)
    else:
        transition_results, state_count = estimate_transitions(df,
                                                               repl_4=repl_4)
    endog = df.loc[:, "decision"]
    states = df.loc[:, "state"]
    num_obs = df.shape[0]
    num_states = init_dict["states"]
    if init_dict["maint_func"] == "linear":
        maint_func = lin_cost
    else:
        maint_func = lin_cost
    decision_mat = np.vstack(((1 - endog), endog))
    trans_mat = create_transition_matrix(num_states,
                                         np.array(transition_results["x"]))
    state_mat = create_state_matrix(states, num_states, num_obs)
    if "max_it" in init_dict.keys():
        max_it = int(init_dict["max_it"])
        result = opt.minimize(
            loglike_opt_rule,
            args=(
                maint_func,
                num_states,
                trans_mat,
                state_mat,
                decision_mat,
                beta,
                max_it,
            ),
            x0=np.array([10, 2]),
            bounds=[(1e-6, None), (1e-6, None)],
            method="L-BFGS-B",
        )
    else:
        result = opt.minimize(
            loglike_opt_rule,
            args=(maint_func, num_states, trans_mat, state_mat, decision_mat,
                  beta),
            x0=np.array([10, 2]),
            bounds=[(1e-6, None), (1e-6, None)],
            method="L-BFGS-B",
        )
    if repl_4:
        return transition_results, result
    else:
        return transition_results, state_count, result