WorkersUpdateContracts#
- class bamengine.events.production.WorkersUpdateContracts[source]#
Bases:
EventDecrement contract duration and handle expiration for employed workers.
Each employed worker’s contract duration (periods_left) decrements by 1. Contracts that reach 0 expire: workers become unemployed but remain loyal (can reapply to previous employer). Firm labor counts are recalculated to reflect expired contracts.
Algorithm
For each employed worker j:
Decrement contract: \(\text{periods\_left}_j \leftarrow \text{periods\_left}_j - 1\)
If \(\text{periods\_left}_j = 0\): - Set \(\text{contract\_expired}_j = \text{True}\) - Set \(\text{employer\_prev}_j = \text{employer}_j\) (store for loyalty) - Set \(\text{employer}_j = -1\) (unemployed) - Set \(w_j = 0\)
Recalculate firm labor counts: - For each firm i: \(L_i = |\{j : \text{employer}_j = i\}|\)
Mathematical Notation
For firm i after contract updates:
\[L_i = |\{j : \text{employer}_j = i\}|\]Examples
>>> import bamengine as be >>> sim = be.Simulation.init(n_households=500, seed=42) >>> event = sim.get_event("workers_update_contracts") >>> event.execute(sim)
Check contracts decremented:
>>> import numpy as np >>> # All employed workers should have periods_left >= 0 >>> employed_mask = sim.wrk.employed >>> (sim.wrk.periods_left[employed_mask] >= 0).all() True
Check expired contracts:
>>> expired_mask = sim.wrk.contract_expired >>> expired_mask.sum() 12
Verify expired workers are unemployed:
>>> (sim.wrk.employer[expired_mask] == -1).all() True
Verify labor counts match:
>>> worker_counts = np.bincount( ... sim.wrk.employer[sim.wrk.employed], minlength=sim.emp.current_labor.size ... ) >>> np.array_equal(worker_counts, sim.emp.current_labor) True
Notes
This event must execute after FirmsRunProduction (end of period).
Workers with expired contracts have contract_expired flag set, which triggers loyalty behavior in the next labor market phase (workers apply to previous employer first if not fired).
Firm labor counts are recalculated to reflect contract expirations. Wage bills are NOT recalculated here — they retain the values from when wages were actually paid (FirmsCalcWageBill), ensuring that revenue-phase gross_profit correctly reflects actual expenses.
See also
LaborMarketRoundSets initial contract duration
WorkersDecideFirmsToApplyUses contract_expired flag for loyalty
WorkerEmployment state with contract fields
EmployerLabor force state with current_labor
bamengine.events._internal.production.workers_update_contractsImplementation
- execute(sim)[source]#
Execute the event’s logic.
Mutates simulation state in-place. This method must be implemented by all Event subclasses.
- Parameters:
sim (
Simulation) – The simulation instance containing all state and configuration.- Returns:
All mutations are in-place.
- Return type:
Examples
Implement execute in a custom event:
>>> from bamengine import event, ops >>> >>> @event ... class CustomPricingEvent: ... def execute(self, sim): ... prod = sim.get_role("Producer") ... # Apply 10% markup to all prices ... new_prices = ops.multiply(prod.price, 1.1) ... ops.assign(prod.price, new_prices)
Access configuration and RNG:
>>> @event ... class StochasticEvent: ... def execute(self, sim): ... shock = sim.config.h_rho ... random_values = sim.rng.uniform(0, shock, size=sim.n_firms) ... # Use random_values in calculations
Notes
The execute method receives full Simulation access, including: - All roles: sim.get_role(“RoleName”) or sim.prod, sim.wrk, etc. - Configuration: sim.config - RNG: sim.rng - Economy state: sim.ec
- __init__()#
- name = 'workers_update_contracts'#