FirmsDecideDesiredProduction#

class bamengine.events.planning.FirmsDecideDesiredProduction[source]#

Bases: Event

Set production targets based on inventory levels and market position.

Firms adjust their production targets adaptively based on whether they have unsold inventory and how their prices compare to market average. This implements the adaptive production rule from Delli Gatti et al. (2011).

This event first zeroes out the current production field (preparing it for the new period), then uses production_prev (the previous period’s actual production) as the baseline signal for planning decisions.

Algorithm

For each firm i:

  1. Zero out current production: \(Y_i := 0\)

  2. Generate random shock: \(\varepsilon_i \sim U(0, h_\rho)\)

  3. Use previous production (production_prev) as baseline and apply rule:

    • If \(S_i = 0\) and \(P_i \geq \bar{P}\): \(Y^*_i = Y^{prev}_i \times (1 + \varepsilon_i)\) [increase]

    • If \(S_i > 0\) and \(P_i < \bar{P}\): \(Y^*_i = Y^{prev}_i \times (1 - \varepsilon_i)\) [decrease]

    • Otherwise: \(Y^*_i = Y^{prev}_i\) [maintain]

  4. Set desired_production = expected_demand = \(Y^*_i\)

Mathematical Notation

\[\begin{split}Y^*_{i,t} = \begin{cases} Y^{prev}_{i}(1 + \varepsilon_i) & \text{if } S_{i,t-1}=0 \land P_i \geq \bar{P} \\ Y^{prev}_{i}(1 - \varepsilon_i) & \text{if } S_{i,t-1}>0 \land P_i < \bar{P} \\ Y^{prev}_{i} & \text{otherwise} \end{cases}\end{split}\]

where:

  • \(Y^*\): desired production for next period

  • \(Y^{prev}\): actual production in previous period (production_prev)

  • \(S\): inventory (unsold goods from previous period)

  • \(P\): firm’s individual price

  • \(\bar{P}\): average market price across all firms

  • \(\varepsilon\): random shock \(\sim U(0, h_\rho)\)

  • \(h_\rho\): maximum production shock parameter (config)

Examples

Execute this event:

>>> import bamengine as be
>>> sim = be.Simulation.init(n_firms=100, seed=42)
>>> event = sim.get_event("firms_decide_desired_production")
>>> event.execute(sim)

Inspect production changes:

>>> prod = sim.prod
>>> firms_increasing = (prod.inventory == 0) & (prod.price >= sim.ec.avg_mkt_price)
>>> firms_increasing.sum()
45

Check desired production distribution:

>>> prod.desired_production.mean()
52.5
>>> prod.desired_production.std()
5.2

Notes

This event must execute early in the pipeline as desired production determines labor requirements (see FirmsDecideDesiredLabor).

The production shock introduces randomness that prevents firms from settling into static equilibria.

See also

FirmsDecideDesiredLabor

Calculate labor needs from production targets

Producer

Production and pricing state

bamengine.events._internal.planning.firms_decide_desired_production

Implementation

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:

None

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 = 'firms_decide_desired_production'#