diff --git a/.coverage b/.coverage index 5bef51b893ff7f1bc8ea1d4dbecf9ba0018b5b60..dc9fdfb14aa20e5b4806c9472467064144b816c4 100644 Binary files a/.coverage and b/.coverage differ diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f96626be90aa6698698c9c27fe74b330d53dd691..09fccc7b570a1a4427f31323602303e77c54a493 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,9 @@ +v0.3.3.1 (2018-02-10) +--------------------- + +* Fixed bug in which MarkovChain.steady_state might use the wrong eigenvector. +* Added warnings if transition probabilities are negative or don't sum to 1. + v0.3.3.0 (2018-02-08) --------------------- diff --git a/dist/prob140-0.3.3.1.tar.gz b/dist/prob140-0.3.3.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..ecb2d73816ac326c55e916588a38fc41974add44 Binary files /dev/null and b/dist/prob140-0.3.3.1.tar.gz differ diff --git a/prob140.egg-info/PKG-INFO b/prob140.egg-info/PKG-INFO index 835ad7a699160f74211b186ec53efca5a7dc8428..8ee928a446b51598892d031b8afed5adfed66510 100644 --- a/prob140.egg-info/PKG-INFO +++ b/prob140.egg-info/PKG-INFO @@ -1,12 +1,12 @@ Metadata-Version: 1.1 Name: prob140 -Version: 0.3.3.0 +Version: 0.3.3.1 Summary: A probability library for Berkeley's Prob140 course Home-page: http://prob140.org/ Author: Jason Zhang, Dibya Ghosh Author-email: zhang.j@berkeley.edu License: GPL -Download-URL: https://gitlab.com/probability/prob140/raw/master/dist/prob140-0.3.3.0.tar.gz +Download-URL: https://gitlab.com/probability/prob140/raw/master/dist/prob140-0.3.3.1.tar.gz Description-Content-Type: UNKNOWN Description: UNKNOWN Keywords: data,probability,berkeley,Prob140 diff --git a/prob140/markov_chains.py b/prob140/markov_chains.py index 9a00526d2414e2ef2d51733044e194c3d1da7891..679d061df489b50716070fa20e3f509633fadcba 100644 --- a/prob140/markov_chains.py +++ b/prob140/markov_chains.py @@ -1,4 +1,5 @@ from collections import OrderedDict +import warnings from datascience import Table import matplotlib.pyplot as plt @@ -13,6 +14,11 @@ class MarkovChain: """ def __init__(self, states, transition_matrix): + transition_matrix = np.array(transition_matrix) + if not np.all(transition_matrix >= 0): + warnings.warn('Transition matrix contains negative value(s).') + if not np.all(np.isclose(np.sum(transition_matrix, axis=1), 1.)): + warnings.warn('Transition probabilities don\'t sum to 1.') self.states = states self.matrix = transition_matrix @@ -287,7 +293,13 @@ class MarkovChain: A | 0.666667 B | 0.333333 """ - eigenvector = np.real(scipy.linalg.eig(self.matrix, left=True)[1][:, 0]) + # Steady state is the left eigenvector that corresponds to eigenvalue=1. + w, vl = scipy.linalg.eig(self.matrix, left=True, right=False) + + # Find index of eigenvalue = 1. + index = np.isclose(w, 1) + + eigenvector = np.real(vl[:, index])[:, 0] probabilities = eigenvector / sum(eigenvector) return Table().values(self.states).probability(probabilities) diff --git a/prob140/version.py b/prob140/version.py index 62d12492c18b168a8f807968384ffb68cba1b1c3..03bc7a0e6274b99eaf27ee5fbdf3e11b620adb30 100644 --- a/prob140/version.py +++ b/prob140/version.py @@ -1 +1 @@ -__version__ = '0.3.3.0' +__version__ = '0.3.3.1' diff --git a/tests/test_markov_chains.py b/tests/test_markov_chains.py index 41a4420f9cb30600f2898c8dddb9193048f3be75..dfff4d2c40d3cc0813b723b556e9ae13a6844722 100644 --- a/tests/test_markov_chains.py +++ b/tests/test_markov_chains.py @@ -78,6 +78,14 @@ def test_construction(): mc_from_matrix.get_transition_matrix() ) + # Negative probability. + with pytest.warns(UserWarning): + MarkovChain.from_matrix([1, 2], [[-1, 2], [0.5, 0.5]]) + # Transition probability doesn't sum to 1. + with pytest.warns(UserWarning): + MarkovChain.from_matrix([1, 2], [[0.2, 0.3], [1, 2]]) + + def test_distribution(): assert_dist_equal(MC_SIMPLE.distribution('A'), [0.1, 0.9]) diff --git a/tests/test_single_variable_plots.ipynb b/tests/test_single_variable_plots.ipynb index 33c27007823d67c204e74aaa8d56bc05680b3eb2..ede654f87c9e4931ff6d1c0395de266dfbbb674f 100644 --- a/tests/test_single_variable_plots.ipynb +++ b/tests/test_single_variable_plots.ipynb @@ -518,7 +518,7 @@ "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 3.0 }, "file_extension": ".py", "mimetype": "text/x-python", @@ -529,5 +529,5 @@ } }, "nbformat": 4, - "nbformat_minor": 1 -} + "nbformat_minor": 0 +} \ No newline at end of file