ConsumersCalcPropensity#

class bamengine.events.goods_market.ConsumersCalcPropensity[source]#

Bases: Event

Calculate marginal propensity to consume based on relative savings.

Households with below-average savings have higher propensity to consume (spend more), while those with above-average savings have lower propensity (save more). This implements consumption smoothing behavior.

Algorithm

For each consumer j:

  1. Calculate relative savings: \(r_j = SA_j / \overline{SA}\)

  2. Apply propensity function: \(c_j = 1 / (1 + \tanh(r_j)^\beta)\)

Mathematical Notation

\[c_j = \frac{1}{1 + \tanh\left(\frac{SA_j}{\overline{SA}}\right)^\beta}\]

where:

  • \(c_j\): propensity to consume (\(0 < c_j < 1\))

  • \(SA_j\): current savings of consumer j

  • \(\overline{SA}\): average savings across all consumers

  • \(\beta\): sensitivity parameter controlling consumption response (config)

Examples

>>> import bamengine as be
>>> sim = be.Simulation.init(n_households=500, seed=42)
>>> event = sim.get_event("consumers_calc_propensity")
>>> event.execute(sim)

Check propensity distribution:

>>> sim.con.propensity.mean()
0.65

Verify range:

>>> import numpy as np
>>> (sim.con.propensity > 0).all() and (sim.con.propensity < 1).all()
True

High-savers have lower propensity:

>>> high_savers = sim.con.savings > sim.con.savings.mean()
>>> low_savers = sim.con.savings < sim.con.savings.mean()
>>> sim.con.propensity[low_savers].mean() > sim.con.propensity[high_savers].mean()
True

Notes

This event must execute first in goods market phase.

Propensity is bounded: 0 < c < 1 (consumers always save something, always spend something).

Higher β increases sensitivity to relative savings position.

See also

ConsumersDecideIncomeToSpend

Uses propensity to allocate spending

bamengine.events._internal.goods_market.consumers_calc_propensity

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