From f4d80265a780f19824ffe7d57d509eb3153fa22f Mon Sep 17 00:00:00 2001 From: MaxBlesch Date: Mon, 25 Nov 2024 12:55:23 +0100 Subject: [PATCH 1/5] introduced sim model. Refactored utility. Started test. --- src/dcegm/simulation/simulate.py | 34 ++++----- .../utility_functions.py | 52 -------------- .../utility_functions_log_crra.py | 55 ++++++++++++++ tests/test_biased_sim.py | 71 +++++++++++++++++++ tests/test_pre_processing.py | 2 + tests/test_replication.py | 2 + 6 files changed, 148 insertions(+), 68 deletions(-) create mode 100644 src/toy_models/cons_ret_model_dcegm_paper/utility_functions_log_crra.py create mode 100644 tests/test_biased_sim.py diff --git a/src/dcegm/simulation/simulate.py b/src/dcegm/simulation/simulate.py index 09e786a3..11b47175 100644 --- a/src/dcegm/simulation/simulate.py +++ b/src/dcegm/simulation/simulate.py @@ -27,7 +27,9 @@ def simulate_all_periods( policy_solved, value_solved, model, + model_sim=None, ): + model_sim = model if model_sim is None else model_sim second_continuous_state_dict = next( ( @@ -54,7 +56,7 @@ def simulate_all_periods( if key in discrete_state_space } - if "dummy_exog" in model["model_structure"]["exog_states_names"]: + if "dummy_exog" in model_sim["model_structure"]["exog_states_names"]: states_initial_dtype["dummy_exog"] = np.zeros_like( states_initial_dtype["period"] ) @@ -73,31 +75,31 @@ def simulate_all_periods( ] ) - model_structure = model["model_structure"] - model_funcs = model["model_funcs"] + model_structure_solution = model["model_structure"] + model_funcs_sim = model_sim["model_funcs"] compute_next_period_states = { - "get_next_period_state": model_funcs["get_next_period_state"], - "update_continuous_state": model_funcs["update_continuous_state"], + "get_next_period_state": model_funcs_sim["get_next_period_state"], + "update_continuous_state": model_funcs_sim["update_continuous_state"], } simulate_body = partial( simulate_single_period, params=params, - discrete_states_names=model_structure["discrete_states_names"], + discrete_states_names=model_structure_solution["discrete_states_names"], endog_grid_solved=endog_grid_solved, value_solved=value_solved, policy_solved=policy_solved, map_state_choice_to_index=jnp.asarray( - model_structure["map_state_choice_to_index"] + model_structure_solution["map_state_choice_to_index"] ), - choice_range=model_structure["choice_range"], - compute_exog_transition_vec=model_funcs["compute_exog_transition_vec"], - compute_utility=model_funcs["compute_utility"], - compute_beginning_of_period_wealth=model_funcs[ + choice_range=model_structure_solution["choice_range"], + compute_exog_transition_vec=model_funcs_sim["compute_exog_transition_vec"], + compute_utility=model_funcs_sim["compute_utility"], + compute_beginning_of_period_wealth=model_funcs_sim[ "compute_beginning_of_period_wealth" ], - exog_state_mapping=model_funcs["exog_state_mapping"], + exog_state_mapping=model_funcs_sim["exog_state_mapping"], compute_next_period_states=compute_next_period_states, second_continuous_state_dict=second_continuous_state_dict, ) @@ -118,10 +120,10 @@ def simulate_all_periods( states_and_wealth_beginning_of_final_period, sim_specific_keys=sim_specific_keys[-1], params=params, - discrete_states_names=model_structure["discrete_states_names"], - choice_range=model_structure["choice_range"], - map_state_choice_to_index=model_structure["map_state_choice_to_index"], - compute_utility_final_period=model_funcs["compute_utility_final"], + discrete_states_names=model_structure_solution["discrete_states_names"], + choice_range=model_structure_solution["choice_range"], + map_state_choice_to_index=model_structure_solution["map_state_choice_to_index"], + compute_utility_final_period=model_funcs_sim["compute_utility_final"], ) result = { diff --git a/src/toy_models/cons_ret_model_dcegm_paper/utility_functions.py b/src/toy_models/cons_ret_model_dcegm_paper/utility_functions.py index aed1a7ee..4d0a8997 100644 --- a/src/toy_models/cons_ret_model_dcegm_paper/utility_functions.py +++ b/src/toy_models/cons_ret_model_dcegm_paper/utility_functions.py @@ -17,58 +17,6 @@ def create_utility_function_dict(): } -def utiility_log_crra( - consumption: jnp.array, - choice: int, - params: Dict[str, float], # delta: float -) -> jnp.array: - """Compute the agent's utility in case of theta equal to 1. - - Args: - consumption (jnp.array): Level of the agent's consumption. - Array of shape (i) (n_quad_stochastic * n_grid_wealth,) - when called by :func:`~dcgm.call_egm_step.map_exog_to_endog_grid` - and :func:`~dcgm.call_egm_step.get_next_period_value`, or - (ii) of shape (n_grid_wealth,) when called by - :func:`~dcgm.call_egm_step.get_current_period_value`. - choice (int): Choice of the agent, e.g. 0 = "retirement", 1 = "working". - params (dict): Dictionary containing model parameters. - Relevant here is the CRRA coefficient theta. - - Returns: - utility (jnp.array): Agent's utility . Array of shape - (n_quad_stochastic * n_grid_wealth,) or (n_grid_wealth,). - - """ - return jnp.log(consumption) - (1 - choice) * params["delta"] - - -def utiility_log_crra_final_consume_all( - wealth: jnp.array, - choice: int, - params: Dict[str, float], # delta: float -) -> jnp.array: - """Compute the agent's utility in case of theta equal to 1. - - Args: - consumption (jnp.array): Level of the agent's consumption. - Array of shape (i) (n_quad_stochastic * n_grid_wealth,) - when called by :func:`~dcgm.call_egm_step.map_exog_to_endog_grid` - and :func:`~dcgm.call_egm_step.get_next_period_value`, or - (ii) of shape (n_grid_wealth,) when called by - :func:`~dcgm.call_egm_step.get_current_period_value`. - choice (int): Choice of the agent, e.g. 0 = "retirement", 1 = "working". - params (dict): Dictionary containing model parameters. - Relevant here is the CRRA coefficient theta. - - Returns: - utility (jnp.array): Agent's utility . Array of shape - (n_quad_stochastic * n_grid_wealth,) or (n_grid_wealth,). - - """ - return jnp.log(wealth) - (1 - choice) * params["delta"] - - def utility_crra( consumption: jnp.array, choice: int, diff --git a/src/toy_models/cons_ret_model_dcegm_paper/utility_functions_log_crra.py b/src/toy_models/cons_ret_model_dcegm_paper/utility_functions_log_crra.py new file mode 100644 index 00000000..ca2ade87 --- /dev/null +++ b/src/toy_models/cons_ret_model_dcegm_paper/utility_functions_log_crra.py @@ -0,0 +1,55 @@ +from typing import Dict + +from jax import numpy as jnp + + +def utiility_log_crra( + consumption: jnp.array, + choice: int, + params: Dict[str, float], # delta: float +) -> jnp.array: + """Compute the agent's utility in case of theta equal to 1. + + Args: + consumption (jnp.array): Level of the agent's consumption. + Array of shape (i) (n_quad_stochastic * n_grid_wealth,) + when called by :func:`~dcgm.call_egm_step.map_exog_to_endog_grid` + and :func:`~dcgm.call_egm_step.get_next_period_value`, or + (ii) of shape (n_grid_wealth,) when called by + :func:`~dcgm.call_egm_step.get_current_period_value`. + choice (int): Choice of the agent, e.g. 0 = "retirement", 1 = "working". + params (dict): Dictionary containing model parameters. + Relevant here is the CRRA coefficient theta. + + Returns: + utility (jnp.array): Agent's utility . Array of shape + (n_quad_stochastic * n_grid_wealth,) or (n_grid_wealth,). + + """ + return jnp.log(consumption) - (1 - choice) * params["delta"] + + +def utiility_log_crra_final_consume_all( + wealth: jnp.array, + choice: int, + params: Dict[str, float], # delta: float +) -> jnp.array: + """Compute the agent's utility in case of theta equal to 1. + + Args: + consumption (jnp.array): Level of the agent's consumption. + Array of shape (i) (n_quad_stochastic * n_grid_wealth,) + when called by :func:`~dcgm.call_egm_step.map_exog_to_endog_grid` + and :func:`~dcgm.call_egm_step.get_next_period_value`, or + (ii) of shape (n_grid_wealth,) when called by + :func:`~dcgm.call_egm_step.get_current_period_value`. + choice (int): Choice of the agent, e.g. 0 = "retirement", 1 = "working". + params (dict): Dictionary containing model parameters. + Relevant here is the CRRA coefficient theta. + + Returns: + utility (jnp.array): Agent's utility . Array of shape + (n_quad_stochastic * n_grid_wealth,) or (n_grid_wealth,). + + """ + return jnp.log(wealth) - (1 - choice) * params["delta"] diff --git a/tests/test_biased_sim.py b/tests/test_biased_sim.py new file mode 100644 index 00000000..12e68742 --- /dev/null +++ b/tests/test_biased_sim.py @@ -0,0 +1,71 @@ +import jax +import numpy as np +import pytest + +from dcegm.pre_processing.setup_model import setup_model +from dcegm.solve import get_solve_func_for_model +from toy_models.load_example_model import load_example_models + + +def utility_crra( + consumption, + choice, + married, + params, +): + + utility_consumption = (consumption ** (1 - params["rho"]) - 1) / (1 - params["rho"]) + + utility = ( + utility_consumption + + married * params["married_util"] + - (1 - choice) * params["delta"] + ) + + return utility + + +@pytest.fixture +def state_space_options(): + state_space_options_sol = { + "state_space": { + "n_periods": 5, + "choices": np.arange(2), + "endogenous_states": { + "married": np.arange(2, dtype=int), + }, + "continuous_states": { + "wealth": np.arange(0, 100, 5, dtype=float), + }, + }, + "model_params": {"quadrature_points_stochastic": 5, "min_age": 18}, + } + state_space_options = {"solution": state_space_options_sol} + + return state_space_options + + +def test_sim_and_sol_model(state_space_options, load_example_model): + params, model_params = load_example_model("retirement_taste_shocks") + params["married_util"] = 0.5 + + model_funcs = load_example_models("dcegm_paper") + utility_functions = model_funcs["utility_functions"] + utility_functions["utility"] = utility_crra + + options_sol = { + "state_space": state_space_options["solution"]["state_space"], + "model_params": model_params, + } + + model_sol = setup_model( + options=options_sol, + state_space_functions=model_funcs["state_space_functions"], + utility_functions=utility_functions, + utility_functions_final_period=model_funcs["final_period_utility_functions"], + budget_constraint=model_funcs["budget_constraint"], + ) + solve_func = get_solve_func_for_model(model_sol) + + value, policy, endog_grid = solve_func(params) + breakpoint() diff --git a/tests/test_pre_processing.py b/tests/test_pre_processing.py index b1690b7d..2263c5d4 100644 --- a/tests/test_pre_processing.py +++ b/tests/test_pre_processing.py @@ -19,6 +19,8 @@ from toy_models.cons_ret_model_dcegm_paper.utility_functions import ( create_final_period_utility_function_dict, create_utility_function_dict, +) +from toy_models.cons_ret_model_dcegm_paper.utility_functions_log_crra import ( utiility_log_crra, ) diff --git a/tests/test_replication.py b/tests/test_replication.py index 360060c4..93e10728 100644 --- a/tests/test_replication.py +++ b/tests/test_replication.py @@ -18,6 +18,8 @@ from toy_models.cons_ret_model_dcegm_paper.utility_functions import ( create_final_period_utility_function_dict, create_utility_function_dict, +) +from toy_models.cons_ret_model_dcegm_paper.utility_functions_log_crra import ( utiility_log_crra, utiility_log_crra_final_consume_all, ) From b9cd9a1f8c3f297bd5ec543c6edf8de5d0e83003 Mon Sep 17 00:00:00 2001 From: MaxBlesch Date: Mon, 25 Nov 2024 16:41:49 +0100 Subject: [PATCH 2/5] Finished test. --- src/dcegm/simulation/simulate.py | 9 +- tests/test_biased_sim.py | 159 ++++++++++++++++++++++++++++--- tests/utils/markov_simulator.py | 17 ++++ 3 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 tests/utils/markov_simulator.py diff --git a/src/dcegm/simulation/simulate.py b/src/dcegm/simulation/simulate.py index 11b47175..da539389 100644 --- a/src/dcegm/simulation/simulate.py +++ b/src/dcegm/simulation/simulate.py @@ -47,7 +47,8 @@ def simulate_all_periods( else None ) - discrete_state_space = model["model_structure"]["state_space_dict"] + model_structure_solution = model["model_structure"] + discrete_state_space = model_structure_solution["state_space_dict"] # Set initial states to internal dtype states_initial_dtype = { @@ -56,7 +57,7 @@ def simulate_all_periods( if key in discrete_state_space } - if "dummy_exog" in model_sim["model_structure"]["exog_states_names"]: + if "dummy_exog" in model_structure_solution["exog_states_names"]: states_initial_dtype["dummy_exog"] = np.zeros_like( states_initial_dtype["period"] ) @@ -74,8 +75,6 @@ def simulate_all_periods( for period in range(n_periods) ] ) - - model_structure_solution = model["model_structure"] model_funcs_sim = model_sim["model_funcs"] compute_next_period_states = { @@ -130,6 +129,8 @@ def simulate_all_periods( key: np.vstack([sim_dict[key], final_period_dict[key]]) for key in sim_dict.keys() } + if "dummy_exog" not in model_sim["model_structure"]["exog_states_names"]: + result.pop("dummy_exog") return result diff --git a/tests/test_biased_sim.py b/tests/test_biased_sim.py index 12e68742..0779013a 100644 --- a/tests/test_biased_sim.py +++ b/tests/test_biased_sim.py @@ -1,8 +1,11 @@ import jax +import jax.numpy as jnp import numpy as np import pytest from dcegm.pre_processing.setup_model import setup_model +from dcegm.simulation.sim_utils import create_simulation_df +from dcegm.simulation.simulate import simulate_all_periods from dcegm.solve import get_solve_func_for_model from toy_models.load_example_model import load_example_models @@ -25,22 +28,42 @@ def utility_crra( return utility +def marriage_transition(married, options): + trans_mat = options["marriage_trans_mat"] + return trans_mat[married, :] + + @pytest.fixture def state_space_options(): state_space_options_sol = { - "state_space": { - "n_periods": 5, - "choices": np.arange(2), - "endogenous_states": { - "married": np.arange(2, dtype=int), - }, - "continuous_states": { - "wealth": np.arange(0, 100, 5, dtype=float), + "n_periods": 5, + "choices": np.arange(2), + "endogenous_states": { + "married": np.arange(2, dtype=int), + }, + "continuous_states": { + "wealth": np.arange(0, 100, 5, dtype=float), + }, + } + + state_space_options_sim = { + "n_periods": 5, + "choices": np.arange(2), + "exogenous_processes": { + "married": { + "states": np.arange(2, dtype=int), + "transition": marriage_transition, }, }, - "model_params": {"quadrature_points_stochastic": 5, "min_age": 18}, + "continuous_states": { + "wealth": np.arange(0, 100, 5, dtype=float), + }, + } + + state_space_options = { + "solution": state_space_options_sol, + "simulation": state_space_options_sim, } - state_space_options = {"solution": state_space_options_sol} return state_space_options @@ -54,7 +77,7 @@ def test_sim_and_sol_model(state_space_options, load_example_model): utility_functions["utility"] = utility_crra options_sol = { - "state_space": state_space_options["solution"]["state_space"], + "state_space": state_space_options["solution"], "model_params": model_params, } @@ -68,4 +91,116 @@ def test_sim_and_sol_model(state_space_options, load_example_model): solve_func = get_solve_func_for_model(model_sol) value, policy, endog_grid = solve_func(params) - breakpoint() + + options_sim = { + "state_space": state_space_options["simulation"], + "model_params": model_params, + } + marriage_trans_mat = jnp.array([[0.3, 0.7], [0.1, 0.9]]) + options_sim["model_params"]["marriage_trans_mat"] = marriage_trans_mat + + model_sim = setup_model( + options=options_sim, + state_space_functions=model_funcs["state_space_functions"], + utility_functions=utility_functions, + utility_functions_final_period=model_funcs["final_period_utility_functions"], + budget_constraint=model_funcs["budget_constraint"], + ) + + n_agents = 100_000 + initial_marriage_dist = np.array([0.5, 0.5]) + single_states = np.zeros(int(n_agents / 2), dtype=int) + married_states = np.ones(int(n_agents / 2), dtype=int) + initial_marriage_states = np.concatenate([single_states, married_states]) + + states_initial = { + "period": np.zeros(n_agents, dtype=int), + "lagged_choice": np.zeros(n_agents, dtype=int), + "married": initial_marriage_states, + } + n_periods = options_sim["state_space"]["n_periods"] + + sim_dict = simulate_all_periods( + states_initial=states_initial, + wealth_initial=np.ones(n_agents, dtype=float) * 10, + n_periods=n_periods, + params=params, + seed=123, + endog_grid_solved=endog_grid, + policy_solved=policy, + value_solved=value, + model=model_sol, + model_sim=model_sim, + ) + df = create_simulation_df(sim_dict) + + ########################################### + # Compare marriage shares as they must be governed + # by the transition matrix in the simulation + ########################################### + + marriage_shares_sim = df.groupby("period")["married"].value_counts(normalize=True) + + atol_marriage = 1e-2 + # We compare married shares, as single shares are just 1 - married shares + np.testing.assert_allclose( + marriage_shares_sim.loc[(0, 1)], + initial_marriage_dist[1], + atol=atol_marriage, + ) + + for period in range(1, n_periods): + last_period_marriage_shares = marriage_shares_sim.loc[ + (period - 1, [0, 1]) + ].values + predicted_shares = last_period_marriage_shares @ marriage_trans_mat + np.testing.assert_allclose( + marriage_shares_sim.loc[(period, 1)], + predicted_shares[1], + atol=atol_marriage, + ) + + ########################################### + # Compare values of the never married and all time married + # with the values from the solution + ########################################### + + _cond = [df["choice"] == 0, df["choice"] == 1] + _val = [df["taste_shocks_0"], df["taste_shocks_1"]] + df["taste_shock_realized_of_expected"] = np.select(_cond, _val) + + df["discount_factors"] = params["beta"] ** df.index.get_level_values("period") + df["disc_expected_utility"] = df["discount_factors"] * ( + df["taste_shock_realized_of_expected"] + df["utility"] + ) + # Finally discounted utility sum by agent + disc_util_sums = df.groupby("agent")["disc_expected_utility"].sum() + # Create sum of married variable to select individuals who where always married + df["married_sum"] = df.groupby("agent")["married"].transform("sum") + + for married_sum in [0, 5]: + df_always = df[df["married_sum"] == married_sum] + + # Now compare value of always married individuals + for choice in [0, 1]: + # Select all individuals who made the choice in the first period + # Their expected and realized values of the choice should be the same + df_always_period_0 = df_always.loc[(0, slice(None))] + df_always_period_0_choice = df_always_period_0[ + df_always_period_0["choice"] == choice + ] + if df_always_period_0_choice.shape[0] > 0: + relevant_agents = df_always_period_0_choice.index.get_level_values( + "agent" + ) + realized_value = disc_util_sums[relevant_agents].mean() + # In their expected value, we also have the realization of the first taste shock, + # but as they choose 0 this is also the realized taste shock used in the realized value + expected_value = df_always.loc[ + (0, relevant_agents), f"value_choice_{choice}" + ].mean() + np.testing.assert_allclose( + realized_value, + expected_value, + atol=1e-1, + ) diff --git a/tests/utils/markov_simulator.py b/tests/utils/markov_simulator.py new file mode 100644 index 00000000..522415ec --- /dev/null +++ b/tests/utils/markov_simulator.py @@ -0,0 +1,17 @@ +import numpy as np + + +def markov_simulator(n_periods_to_sim, initial_dist, trans_probs): + """Simulate a Markov process.""" + n_states = initial_dist.shape[0] + final_dist = np.zeros((n_periods_to_sim, n_states)) + final_dist[0, :] = initial_dist + + for t in range(n_periods_to_sim - 1): + current_dist = final_dist[t, :] + for state in range(n_states - 1): + final_dist[t + 1, state] = current_dist @ trans_probs[:, state] + + final_dist[t + 1, -1] = 1 - final_dist[t + 1, :-1].sum() + + return final_dist From 2f73ac92420dd4ddcda154d03e2ffb703150c8ae Mon Sep 17 00:00:00 2001 From: MaxBlesch Date: Mon, 25 Nov 2024 17:31:07 +0100 Subject: [PATCH 3/5] Compared numerical error for numpy and jax numpy. --- tests/sandbox/time_functions_jax.ipynb | 122 +++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 6 deletions(-) diff --git a/tests/sandbox/time_functions_jax.ipynb b/tests/sandbox/time_functions_jax.ipynb index 4c8b0a66..73244a84 100644 --- a/tests/sandbox/time_functions_jax.ipynb +++ b/tests/sandbox/time_functions_jax.ipynb @@ -2,15 +2,13 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, "id": "35ab80e3", "metadata": { "ExecuteTime": { - "end_time": "2024-06-20T14:03:27.083891148Z", - "start_time": "2024-06-20T14:03:26.534171812Z" + "end_time": "2024-11-25T15:44:09.704943Z", + "start_time": "2024-11-25T15:44:09.292524Z" } }, - "outputs": [], "source": [ "from jax import vmap, jit\n", "import pickle\n", @@ -19,8 +17,120 @@ "import yaml\n", "from functools import partial\n", "import jax.numpy as jnp\n", - "import numpy as np" - ] + "import numpy as np\n", + "from tests.utils.markov_simulator import markov_simulator" + ], + "outputs": [], + "execution_count": 1 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-11-25T16:03:54.707014Z", + "start_time": "2024-11-25T16:03:54.700726Z" + } + }, + "cell_type": "code", + "source": [ + "n_periods = 10\n", + "init_dist = np.array([0.5, 0.5])\n", + "trans_mat = np.array([[0.8, 0.2], [0.1, 0.9]])\n", + "\n", + "markov_simulator(n_periods, init_dist, trans_mat)" + ], + "id": "c2b7c16010b9ba85", + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0.5 , 0.5 ],\n", + " [0.45 , 0.55 ],\n", + " [0.415 , 0.585 ],\n", + " [0.3905 , 0.6095 ],\n", + " [0.37335 , 0.62665 ],\n", + " [0.361345 , 0.638655 ],\n", + " [0.3529415 , 0.6470585 ],\n", + " [0.34705905, 0.65294095],\n", + " [0.34294134, 0.65705866],\n", + " [0.34005893, 0.65994107]])" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 34 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-11-25T16:08:11.928721Z", + "start_time": "2024-11-25T16:08:11.908425Z" + } + }, + "cell_type": "code", + "source": [ + "n_agents = 100_000\n", + "current_agents_in_states = (np.ones(2) * n_agents / 2).astype(int)\n", + "for period in range(n_periods):\n", + " print(current_agents_in_states / n_agents)\n", + " next_period_agents_states = np.zeros(2, dtype=int)\n", + " for state in range(2):\n", + " agents_in_state = current_agents_in_states[state]\n", + " transition_draws = np.random.choice(\n", + " a=[0, 1], size=agents_in_state, p=trans_mat[state, :]\n", + " )\n", + " next_period_agents_states[1] += transition_draws.sum()\n", + " next_period_agents_states[0] += agents_in_state - transition_draws.sum()\n", + " current_agents_in_states = next_period_agents_states" + ], + "id": "ae676759dd2627d2", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.5 0.5]\n", + "[0.4502 0.5498]\n", + "[0.4189 0.5811]\n", + "[0.39164 0.60836]\n", + "[0.37405 0.62595]\n", + "[0.35994 0.64006]\n", + "[0.35166 0.64834]\n", + "[0.34544 0.65456]\n", + "[0.34263 0.65737]\n", + "[0.34015 0.65985]\n" + ] + } + ], + "execution_count": 47 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-11-25T16:02:05.105098Z", + "start_time": "2024-11-25T16:02:05.100262Z" + } + }, + "cell_type": "code", + "source": [ + "trans_mat[0, :]" + ], + "id": "28dac7ec90b5d015", + "outputs": [ + { + "data": { + "text/plain": [ + "Array([0.8, 0.2], dtype=float32)" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 29 }, { "cell_type": "code", From 47993f4abc0672d3967e72de841ed0ef92165015 Mon Sep 17 00:00:00 2001 From: MaxBlesch Date: Wed, 27 Nov 2024 15:11:04 +0100 Subject: [PATCH 4/5] Little sim fix. --- src/dcegm/simulation/simulate.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dcegm/simulation/simulate.py b/src/dcegm/simulation/simulate.py index da539389..5a82f950 100644 --- a/src/dcegm/simulation/simulate.py +++ b/src/dcegm/simulation/simulate.py @@ -129,8 +129,9 @@ def simulate_all_periods( key: np.vstack([sim_dict[key], final_period_dict[key]]) for key in sim_dict.keys() } - if "dummy_exog" not in model_sim["model_structure"]["exog_states_names"]: - result.pop("dummy_exog") + if "dummy_exog" in model_structure_solution["exog_states_names"]: + if "dummy_exog" not in model_sim["model_structure"]["exog_states_names"]: + result.pop("dummy_exog") return result From 743382bae50b85ebae5a0efcfc67c0f5d7a9a932 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:59:27 +0100 Subject: [PATCH 5/5] [pre-commit.ci] pre-commit autoupdate (#137) Co-authored-by: Sebastian Gsell --- .pre-commit-config.yaml | 4 ++-- setup.cfg | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 76782a85..589fce05 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -55,7 +55,7 @@ repos: args: - --profile=black - repo: https://github.com/asottile/setup-cfg-fmt - rev: v2.5.0 + rev: v2.7.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/psf/black @@ -90,7 +90,7 @@ repos: - id: nbqa-ruff exclude: tests/sandbox/ - repo: https://github.com/executablebooks/mdformat - rev: 0.7.17 + rev: 0.7.18 hooks: - id: mdformat additional_dependencies: diff --git a/setup.cfg b/setup.cfg index 2c230485..52f86596 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,7 +25,7 @@ project_urls = [options] packages = find: -python_requires = >=3.8 +python_requires = >=3.9 include_package_data = True package_dir = =src