TST: Cover the multi-distribution branch in test_left_eigen_vec - #962
TST: Cover the multi-distribution branch in test_left_eigen_vec#962techreign wants to merge 1 commit into
Conversation
Test_markovchain_stationary_distributions_KMRMarkovMatrix2 only ever used the irreducible KMR matrix (N=27), which has exactly one stationary distribution. As a result, test_left_eigen_vec's else branch (the multiple-stationary-distributions case) and the `if len(stat_shape) == 1` arm in setup_method were dead code never executed by the suite. Factor the shared test methods into a base class and add a new Test_markovchain_stationary_distributions_ReducibleMarkovMatrix subclass built on a reducible 4-state matrix with two absorbing states, giving n_stat_dists == 2 and exercising the else branch. stationary_distributions is documented as always ndim=2, so the dead `if len(stat_shape) == 1` arm is removed rather than duplicated. The existing KMR matrix test behavior and assertions are unchanged. Fixes QuantEcon#961 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Hi @techreign — a quick process note while this is in the review queue. QuantEcon's Code of AI Use (QEP-5, QuantEcon/qeps#13) doesn't restrict AI-assisted contributions, but it does ask that meaningful AI involvement be disclosed. We'd like it in two places: a trailer in the commit message, and a one-line note in the PR description. The commit here already carries a ( The intent is that reviewers know what to expect, and that a human has chosen the task, checked the result, and will own the follow-up discussion. Generated by Claude Code |
What was wrong
Test_markovchain_stationary_distributions_KMRMarkovMatrix2inquantecon/markov/tests/test_core.pyonly ever used the irreducible KMRsequential-move matrix (
N = 27), which has exactly one stationarydistribution. Because of that:
elsebranch oftest_left_eigen_vec(the multiple-stationary-distributions case) was never executed by the suite.
if len(stat_shape) == 1:arm insetup_methodwas similarly dead,since
MarkovChain.stationary_distributionsis documented as alwaysndim=2, sostat_shapealways has length 2.Both branches were correct code, just untested code masquerading as tested.
What changed
test_markov_matrix,test_sum_one,test_nonnegative,test_left_eigen_vec) out into ashared, non-collected base class
_Test_markovchain_stationary_distributions_Base.Test_markovchain_stationary_distributions_KMRMarkovMatrix2as asubclass with the exact same
N=27KMR matrix,setup_methodlogic, andassertions as before (only the dead
if len(stat_shape) == 1arm wasremoved, since it can never be reached).
Test_markovchain_stationary_distributions_ReducibleMarkovMatrix,built on a reducible 4-state matrix with two absorbing states (states 0
and 1) reached from two transient states (2 and 3). This gives
stationary_distributions.shape == (2, 4), son_stat_dists == 2and theelsebranch oftest_left_eigen_vecis now actually exercised andverified.
No production code in
quantecon/markov/core.pychanged; this is atest-only fix, matching the "TST:" convention used for the issue.
How it was verified
To prove the previously-dead
elsebranch is now hit, a temporary printwas added inside the
elsebranch oftest_left_eigen_vecand run withpytest -k test_left_eigen_vec -s:confirming the KMR case takes the
ifbranch (n_stat_dists == 1, noprint) and the new reducible-matrix case takes the
elsebranch withn_stat_dists == 2. The temporary print was removed before the finalcommit (
pytest-cov/coverage.pycould not be used for this in the localdev environment — both hit an unrelated
ImportError: cannot load module more than once per processfrom numpy 2.x's C-extension guard whencombined with coverage's import hooks on this machine).
Fixes #961