ConsAggIndMarkovModel#

General-purpose consumer type with combined aggregate and idiosyncratic discrete Markov states - the “hierarchical Markov” pattern.

Both Krusell-Smith (1998) and the HAFiscal aggregate-demand model share a common structure: agents face discrete macro (aggregate) states that are common to the whole economy, plus discrete micro (idiosyncratic) states whose transition probabilities depend on the current macro state. The full state space is the Cartesian product of the two, encoded as a single integer index:

combined = num_micro_states * macro_state + micro_state

This module provides:

  • make_hierarchical_mrkv_array - builds the full (M*N) x (M*N) Markov transition matrix from an M x M aggregate matrix and either M conditional N x N micro matrices (destination-conditioned) or, in the general format, M x M of them keyed by source and destination macro state.

  • AggIndMrkvConsumerType - a MarkovConsumerType subclass that implements two-step Markov draws (macro from economy, micro per-agent) each period.

Design note#

This class was created in response to the prompt:

“Create a comprehensive, self-contained prompt document that will guide creation of a new general-purpose HARK class (AggIndMrkvConsumerType) and companion AggIndMarkovEconomy that unify the patterns currently implemented ad-hoc in HARK’s KrusellSmithType and HAFiscal’s AggFiscalType.”

The prompt was executed by Claude Opus 4.6 (Anthropic, 2025).

HARK.ConsumptionSaving.ConsAggIndMarkovModel.make_hierarchical_mrkv_array(MacroMrkvArray, CondMrkvArrays)#

Build a full (M*N) x (M*N) Markov transition matrix.

Parameters:
  • MacroMrkvArray (np.ndarray, shape (M, M)) – Aggregate Markov transition matrix.

  • CondMrkvArrays (list of np.ndarray or list of list of np.ndarray) – Conditional micro transition matrices, auto-detected between two formats. Simple: a flat list of M arrays, each (N, N), where CondMrkvArrays[j][mi, mj] is Pr(micro'=mj | micro=mi, macro'=j) (micro transitions depend only on the destination macro state). General: a nested M x M list of (N, N) arrays, where CondMrkvArrays[i][j] conditions on both the source and destination macro state (Krusell-Smith style). Detection: if CondMrkvArrays[0] is a 2-D ndarray, the simple format is used.

Returns:

Full transition matrix with combined-state indexing combined = N * macro + micro.

Return type:

np.ndarray, shape (M*N, M*N)

HARK.ConsumptionSaving.ConsAggIndMarkovModel.extract_cond_mrkv_arrays(MrkvIndArray, MacroMrkvArray, N)#

Extract conditional micro transition arrays in the general [i][j] format from a combined (M*N) x (M*N) transition matrix.

Each (N x N) block MrkvIndArray[N*i:N*(i+1), N*j:N*(j+1)] equals MacroMrkvArray[i,j] * CondMrkvArrays[i][j]. This function recovers CondMrkvArrays[i][j] by dividing each block by the corresponding macro probability.

Parameters:
  • MrkvIndArray (np.ndarray, shape (M*N, M*N)) – Full combined Markov transition matrix.

  • MacroMrkvArray (np.ndarray, shape (M, M)) – Aggregate Markov transition matrix.

  • N (int) – Number of micro states.

Returns:

result[i][j] is an (N, N) conditional micro transition matrix. Blocks whose macro probability is zero come back as zero matrices.

Return type:

list of list of np.ndarray

Raises:

ValueError – If MrkvIndArray is not (M*N) x (M*N), or if any block is not MacroMrkvArray[i,j] times a row-stochastic matrix. The latter condition is necessary and sufficient for the extracted arrays to be valid transition matrices, so an unchecked input would return rows that silently fail to sum to one.

class HARK.ConsumptionSaving.ConsAggIndMarkovModel.AggIndMrkvConsumerType(num_macro_states=None, num_micro_states=None, **kwds)#

Bases: MarkovConsumerType

A MarkovConsumerType with built-in hierarchical macro+micro Markov decomposition. Inherits all of MarkovConsumerType’s functionality (income shocks, state-dependent parameters, solver, simulation) and adds a two-step Markov draw:

  1. get_macro_markov_states() - reads aggregate state

  2. get_micro_markov_states() - draws idiosyncratic states

  3. Combines: shocks["Mrkv"] = num_micro_states * MacroMrkv + MicroMrkv

When num_macro_states / num_micro_states are not set, the class falls back to standard MarkovConsumerType behavior (pure clone).

Models that don’t need MarkovConsumerType’s income-shock / lifecycle infrastructure (e.g. Krusell-Smith) should pass construct=False and supply their own solver via default_["solver"].

Subclasses override:

  • get_macro_markov_states - how to read macro state (economy sow, etc.)

  • get_micro_markov_states - how to draw micro states (searchsorted, etc.)

initialize_sim()#

Prepares this AgentType for a new simulation. Resets the internal random number generator, makes initial states for all agents (using sim_birth), clears histories of tracked variables.

Parameters:

None

Return type:

None

get_markov_states()#

Two-step hierarchical draw when configured; otherwise parent draw.

get_macro_markov_states()#

Read the aggregate Markov state. Override in subclasses.

Reads self.shocks["MrkvAgg"] when the economy sows it, and otherwise recovers the macro state from the combined index.

get_micro_markov_states()#

Draw micro states from CondMrkvArrays.

When markov_shuffle is True, uses MarkovProcess with shuffle=True per cell - analogous to get_markov_states on a flat Markov chain; with balanced_transitions, systematic sampling by pLvl within each cell. Default remains iid RNG.choice per cell.

What counts as a cell depends on the CondMrkvArrays format. The simple format conditions only on the destination macro state, giving (destination-macro, source-micro) cells; the general format also conditions on the source, giving the finer partition (source-macro, destination-macro, source-micro).

Override entirely for custom logic (e.g. Krusell-Smith exact-match employment permutations).

Raises:

ValueError – If agents are assigned a macro transition whose conditional row sums to zero. extract_cond_mrkv_arrays returns a zero matrix where the macro probability is zero, so this means the macro states supplied to the agent contradict the conditional arrays it was given; there is no distribution to draw from.

macro_from_combined(mrkv)#

Extract the macro state index from a combined Markov index.

Parameters:

mrkv (int or np.ndarray) – Combined Markov state index (= N * macro + micro).

Returns:

Macro state index.

Return type:

int or np.ndarray

micro_from_combined(mrkv)#

Extract the micro state index from a combined Markov index.

Parameters:

mrkv (int or np.ndarray) – Combined Markov state index (= N * macro + micro).

Returns:

Micro state index.

Return type:

int or np.ndarray