econirl.RustBusEnvironment
- class econirl.RustBusEnvironment(operating_cost=0.001, replacement_cost=3.0, num_mileage_bins=90, mileage_transition_probs=(0.3919, 0.5953, 0.0128), discount_factor=0.9999, scale_parameter=1.0, seed=None, cost_type='linear', operating_cost_params=None)[source]
Bases:
DDCEnvironmentRust (1987) bus engine replacement environment.
Harold Zurcher’s decision problem: Each period, observe bus mileage and decide whether to keep the current engine or replace it.
- State space:
Mileage discretized into bins {0, 1, …, num_mileage_bins - 1} Each bin represents approximately 5,000 miles.
- Action space:
0 = Keep: Continue with current engine 1 = Replace: Install new engine (mileage resets to 0)
- Utility specification (depends on cost_type):
linear: U(s, keep) = -theta_1 * s quadratic: U(s, keep) = -theta_1 * s - theta_2 * s^2 cubic: U(s, keep) = -theta_1 * s - theta_2 * s^2 - theta_3 * s^3 sqrt: U(s, keep) = -theta_1 * sqrt(s) hyperbolic: U(s, keep) = -theta_1 / (N+1 - s)
U(s, replace) = -replacement_cost + ε_replace
where ε are i.i.d. Type I Extreme Value (Gumbel) shocks.
- Transition dynamics:
If keep: mileage increases by {0, 1, 2} with probabilities (θ_0, θ_1, θ_2) If replace: mileage resets to 0
Example
>>> env = RustBusEnvironment( ... operating_cost=0.001, ... replacement_cost=3.0, ... discount_factor=0.9999, ... ) >>> obs, info = env.reset() >>> print(f"Initial mileage bin: {obs}")
>>> env_quad = RustBusEnvironment( ... cost_type="quadratic", ... operating_cost_params=(0.001, 0.00001), ... replacement_cost=3.0, ... )
- Parameters:
- KEEP = 0
- REPLACE = 1
- __init__(operating_cost=0.001, replacement_cost=3.0, num_mileage_bins=90, mileage_transition_probs=(0.3919, 0.5953, 0.0128), discount_factor=0.9999, scale_parameter=1.0, seed=None, cost_type='linear', operating_cost_params=None)[source]
Initialize the Rust bus environment.
- Parameters:
operating_cost (float) – Cost per unit mileage for operating (θ_1 in Rust). Used as the single operating cost coefficient for linear, sqrt, and hyperbolic cost types. Ignored when operating_cost_params is provided for quadratic or cubic types.
replacement_cost (float) – Fixed cost of engine replacement (RC in Rust)
num_mileage_bins (int) – Number of mileage discretization bins (default 90)
mileage_transition_probs (tuple[float, float, float]) – Probabilities of mileage increase (0, 1, or 2 bins) Must sum to 1. Default from Rust (1987) estimates.
discount_factor (float) – Time discount factor β
scale_parameter (float) – Logit scale parameter σ
seed (int | None) – Random seed for reproducibility
cost_type (Literal['linear', 'quadratic', 'cubic', 'sqrt', 'hyperbolic']) – Functional form of operating cost. One of “linear”, “quadratic”, “cubic”, “sqrt”, “hyperbolic”.
operating_cost_params (tuple[float, ...] | None) – Tuple of operating cost coefficients for multi-parameter cost types (quadratic, cubic). For quadratic, provide (theta_1, theta_2). For cubic, provide (theta_1, theta_2, theta_3). If None, uses operating_cost as the single coefficient.
- property transition_matrices: Array
Return transition probability matrices.
- Returns:
Tensor of shape (num_actions, num_states, num_states) where result[a, s, s’] = P(s’ | s, a)
- property feature_matrix: Array
Return feature matrix for utility computation.
Features are the observable characteristics that enter the utility function: U(s,a;θ) = θ · φ(s,a)
- Returns:
Tensor of shape (num_states, num_actions, num_features)
- property true_parameters: dict[str, float]
Return the true utility parameters (for simulation studies).
- Returns:
Dictionary mapping parameter names to values
- compute_utility_matrix(parameters=None)
Compute the full utility matrix for all state-action pairs.
- Parameters:
parameters (Array | None) – Optional parameter vector. If None, uses true_parameters.
- Returns:
Tensor of shape (num_states, num_actions) with flow utilities
- Return type:
Array
- encode_states(states)
Encode flat state indices to continuous features.
Default: normalized scalar s/(S-1) with shape (batch, 1). Override for multi-dimensional environments.
- Parameters:
states (Array)
- Return type:
Array
- generate_panel(n_individuals=1000, n_periods=100, seed=42, as_dataframe=False)
Generate synthetic panel data from this environment.
Computes the optimal policy from the true parameters and simulates trajectories for multiple individuals.
- Parameters:
- Returns:
Panel object, or DataFrame if as_dataframe=True.
- Return type:
- get_true_parameter_vector()
Return true parameters as a tensor in canonical order.
- Return type:
Array
- classmethod info()
Return metadata about this environment.
Subclasses should override this to provide name, description, source, n_states, n_actions, parameter details, etc.
- Return type:
- property problem_spec: DDCProblem
Return the DDCProblem specification for this environment.