-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic stochastic model #1417
Merged
Merged
Generic stochastic model #1417
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
4d4ef3c
Added generic + michaelis menten
phumtutum 556e560
jupyter notebook added (not fully working yet)
phumtutum 1e99263
change to ipynb
phumtutum 74c8b2e
removed tau-leaping for now, clarified notebook, minor refactoring
phumtutum 97d737d
added ipynb to readme
phumtutum 1850b2b
added small tests for coverage
phumtutum b080f09
Added degradation model(for testing) + tests
phumtutum 52835a3
small fixes
phumtutum 5098400
small test fix
phumtutum cfc6c2b
moved n_parameters to markovjumpmodel
phumtutum 6d3b874
partial change(for testing docs)
phumtutum acc6b9d
fix 1
phumtutum 24d1aa8
finished docs
phumtutum 0a1ffdd
fix for docs
phumtutum 14ed81a
final fix for docs
phumtutum 4122bcb
fix for run-tests.py
phumtutum f158670
more fixes for run-tests.py
phumtutum c4edd3f
more doc fixes
phumtutum 362567d
testing error source
phumtutum 4b12e0e
attempt to fix
phumtutum 5403208
attempt to fix run-tests
phumtutum 7f69fda
Apply suggestions from code review
MichaelClerx a0d4f24
addressed most comments, left some documentation
phumtutum 99a56b3
added explanation for markov jump model
phumtutum 7c4d14f
Merge branch 'i-1067-generic-stochastic-model' of https://github.com/…
phumtutum d14667d
license to 2022 + changelog
phumtutum 27453ef
Merge branch 'master' into i-1067-generic-stochastic-model
phumtutum File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
*********************** | ||
Stochastic Toy Problems | ||
*********************** | ||
|
||
The `stochastic` module provides toy :class:`models<pints.toy.stochastic.MarkovJumpModel>`, | ||
:class:`distributions<pints.LogPrior>` and | ||
:class:`error measures<pints.ErrorMeasure>` that can be used for tests and in | ||
examples. | ||
|
||
|
||
.. toctree:: | ||
|
||
markov_jump_model | ||
stochastic_degradation_model | ||
stochastic_michaelis_menten_model |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
***************** | ||
Markov Jump Model | ||
***************** | ||
|
||
.. currentmodule:: pints.toy.stochastic | ||
|
||
.. autoclass:: MarkovJumpModel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
docs/source/toy/stochastic/stochastic_michaelis_menten_model.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
********************************* | ||
Stochastic Michaelis Menten model | ||
********************************* | ||
|
||
.. currentmodule:: pints.toy.stochastic | ||
|
||
.. autoclass:: MichaelisMentenModel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#!/usr/bin/env python3 | ||
# | ||
# Tests if the markov jump model works. | ||
# | ||
# This file is part of PINTS (https://github.com/pints-team/pints/) which is | ||
# released under the BSD 3-clause license. See accompanying LICENSE.md for | ||
# copyright notice and full license details. | ||
# | ||
import unittest | ||
import numpy as np | ||
from pints.toy.stochastic import DegradationModel | ||
|
||
|
||
class TestMarkovJumpModel(unittest.TestCase): | ||
""" | ||
Tests if the markov jump model works using | ||
the degradation model. | ||
""" | ||
def test_start_with_zero(self): | ||
# Test the special case where the initial molecule count is zero | ||
model = DegradationModel(0) | ||
times = [0, 1, 2, 100, 1000] | ||
parameters = [0.1] | ||
values = model.simulate(parameters, times) | ||
self.assertEqual(len(values), len(times)) | ||
self.assertTrue(np.all(values == np.zeros(5))) | ||
|
||
def test_start_with_twenty(self): | ||
# Run small simulation | ||
model = DegradationModel(20) | ||
times = [0, 1, 2, 100, 1000] | ||
parameters = [0.1] | ||
values = model.simulate(parameters, times) | ||
self.assertEqual(len(values), len(times)) | ||
self.assertEqual(values[0], 20) | ||
self.assertEqual(values[-1], 0) | ||
self.assertTrue(np.all(values[1:] <= values[:-1])) | ||
|
||
def test_simulate(self): | ||
times = np.linspace(0, 100, 101) | ||
model = DegradationModel(20) | ||
time, mol_count = model.simulate_raw([0.1], 100) | ||
values = model.interpolate_mol_counts(time, mol_count, times) | ||
self.assertTrue(len(time), len(mol_count)) | ||
# Test output of Gillespie algorithm | ||
expected = np.array([[x] for x in range(20, -1, -1)]) | ||
self.assertTrue(np.all(mol_count == expected)) | ||
|
||
# Check simulate function returns expected values | ||
self.assertTrue(np.all(values[np.where(times < time[1])] == 20)) | ||
|
||
# Check interpolation function works as expected | ||
temp_time = np.array([np.random.uniform(time[0], time[1])]) | ||
self.assertEqual( | ||
model.interpolate_mol_counts(time, mol_count, temp_time)[0], | ||
20) | ||
temp_time = np.array([np.random.uniform(time[1], time[2])]) | ||
self.assertEqual( | ||
model.interpolate_mol_counts(time, mol_count, temp_time)[0], | ||
19) | ||
|
||
def test_errors(self): | ||
model = DegradationModel(20) | ||
# parameters, times cannot be negative | ||
times = np.linspace(0, 100, 101) | ||
parameters = [-0.1] | ||
self.assertRaises(ValueError, model.simulate, parameters, times) | ||
|
||
times_2 = np.linspace(-10, 10, 21) | ||
parameters_2 = [0.1] | ||
self.assertRaises(ValueError, model.simulate, parameters_2, times_2) | ||
|
||
# this model should have 1 parameter | ||
parameters_3 = [0.1, 1] | ||
self.assertRaises(ValueError, model.simulate, parameters_3, times) | ||
|
||
# Initial value can't be negative | ||
self.assertRaises(ValueError, DegradationModel, -1) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,116 +1,88 @@ | ||
#!/usr/bin/env python3 | ||
# | ||
# Tests if the stochastic degradation (toy) model works. | ||
# Tests if the degradation (toy) model works. | ||
# | ||
# This file is part of PINTS (https://github.com/pints-team/pints/) which is | ||
# released under the BSD 3-clause license. See accompanying LICENSE.md for | ||
# copyright notice and full license details. | ||
# | ||
import unittest | ||
import numpy as np | ||
import pints | ||
import pints.toy | ||
from pints.toy import StochasticDegradationModel | ||
from pints.toy.stochastic import DegradationModel | ||
|
||
|
||
class TestStochasticDegradationModel(unittest.TestCase): | ||
class TestDegradationModel(unittest.TestCase): | ||
""" | ||
Tests if the stochastic degradation (toy) model works. | ||
Tests if the degradation (toy) model works. | ||
""" | ||
def test_start_with_zero(self): | ||
# Test the special case where the initial molecule count is zero | ||
model = StochasticDegradationModel(0) | ||
times = [0, 1, 2, 100, 1000] | ||
parameters = [0.1] | ||
values = model.simulate(parameters, times) | ||
self.assertEqual(len(values), len(times)) | ||
self.assertTrue(np.all(values == np.zeros(5))) | ||
|
||
def test_start_with_twenty(self): | ||
# Run small simulation | ||
model = pints.toy.StochasticDegradationModel(20) | ||
times = [0, 1, 2, 100, 1000] | ||
parameters = [0.1] | ||
values = model.simulate(parameters, times) | ||
self.assertEqual(len(values), len(times)) | ||
self.assertEqual(values[0], 20) | ||
self.assertEqual(values[-1], 0) | ||
self.assertTrue(np.all(values[1:] <= values[:-1])) | ||
def test_n_parameters(self): | ||
x_0 = 20 | ||
model = DegradationModel(x_0) | ||
self.assertEqual(model.n_parameters(), 1) | ||
|
||
def test_simulation_length(self): | ||
x_0 = 20 | ||
model = DegradationModel(x_0) | ||
times = np.linspace(0, 1, 100) | ||
k = [0.1] | ||
values = model.simulate(k, times) | ||
self.assertEqual(len(values), 100) | ||
|
||
def test_propensities(self): | ||
x_0 = 20 | ||
k = [0.1] | ||
model = DegradationModel(x_0) | ||
self.assertTrue( | ||
np.allclose( | ||
model._propensities([x_0], k), | ||
np.array([2.0]))) | ||
|
||
def test_suggested(self): | ||
model = pints.toy.StochasticDegradationModel(20) | ||
model = DegradationModel(20) | ||
times = model.suggested_times() | ||
parameters = model.suggested_parameters() | ||
self.assertTrue(len(times) == 101) | ||
self.assertTrue(parameters > 0) | ||
|
||
def test_simulate(self): | ||
times = np.linspace(0, 100, 101) | ||
model = StochasticDegradationModel(20) | ||
time, mol_count = model.simulate_raw([0.1]) | ||
values = model.interpolate_mol_counts(time, mol_count, times) | ||
self.assertTrue(len(time), len(mol_count)) | ||
# Test output of Gillespie algorithm | ||
self.assertTrue(np.all(mol_count == np.array(range(20, -1, -1)))) | ||
|
||
# Check simulate function returns expected values | ||
self.assertTrue(np.all(values[np.where(times < time[1])] == 20)) | ||
|
||
# Check interpolation function works as expected | ||
temp_time = np.array([np.random.uniform(time[0], time[1])]) | ||
self.assertEqual( | ||
model.interpolate_mol_counts(time, mol_count, temp_time)[0], | ||
20) | ||
temp_time = np.array([np.random.uniform(time[1], time[2])]) | ||
self.assertEqual( | ||
model.interpolate_mol_counts(time, mol_count, temp_time)[0], | ||
19) | ||
|
||
def test_mean_variance(self): | ||
# test mean | ||
model = pints.toy.StochasticDegradationModel(10) | ||
model = DegradationModel(10) | ||
v_mean = model.mean([1], [5, 10]) | ||
self.assertEqual(v_mean[0], 10 * np.exp(-5)) | ||
self.assertEqual(v_mean[1], 10 * np.exp(-10)) | ||
|
||
model = pints.toy.StochasticDegradationModel(20) | ||
model = DegradationModel(20) | ||
v_mean = model.mean([5], [7.2]) | ||
self.assertEqual(v_mean[0], 20 * np.exp(-7.2 * 5)) | ||
|
||
# test variance | ||
model = pints.toy.StochasticDegradationModel(10) | ||
model = DegradationModel(10) | ||
v_var = model.variance([1], [5, 10]) | ||
self.assertEqual(v_var[0], 10 * (np.exp(5) - 1.0) / np.exp(10)) | ||
self.assertAlmostEqual(v_var[1], 10 * (np.exp(10) - 1.0) / np.exp(20)) | ||
|
||
model = pints.toy.StochasticDegradationModel(20) | ||
model = DegradationModel(20) | ||
v_var = model.variance([2.0], [2.0]) | ||
self.assertAlmostEqual(v_var[0], 20 * (np.exp(4) - 1.0) / np.exp(8)) | ||
|
||
def test_errors(self): | ||
model = pints.toy.StochasticDegradationModel(20) | ||
model = DegradationModel(20) | ||
# parameters, times cannot be negative | ||
times = np.linspace(0, 100, 101) | ||
parameters = [-0.1] | ||
self.assertRaises(ValueError, model.simulate, parameters, times) | ||
self.assertRaises(ValueError, model.mean, parameters, times) | ||
self.assertRaises(ValueError, model.variance, parameters, times) | ||
|
||
times_2 = np.linspace(-10, 10, 21) | ||
parameters_2 = [0.1] | ||
self.assertRaises(ValueError, model.simulate, parameters_2, times_2) | ||
self.assertRaises(ValueError, model.mean, parameters_2, times_2) | ||
self.assertRaises(ValueError, model.variance, parameters_2, times_2) | ||
|
||
# this model should have 1 parameter | ||
parameters_3 = [0.1, 1] | ||
self.assertRaises(ValueError, model.simulate, parameters_3, times) | ||
self.assertRaises(ValueError, model.mean, parameters_3, times) | ||
self.assertRaises(ValueError, model.variance, parameters_3, times) | ||
|
||
# Initial value can't be negative | ||
self.assertRaises(ValueError, pints.toy.StochasticDegradationModel, -1) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#!/usr/bin/env python3 | ||
# | ||
# Tests if the Michaelis Menten (toy) model works. | ||
# | ||
# This file is part of PINTS (https://github.com/pints-team/pints/) which is | ||
# released under the BSD 3-clause license. See accompanying LICENSE.md for | ||
# copyright notice and full license details. | ||
# | ||
import unittest | ||
import numpy as np | ||
from pints.toy.stochastic import MichaelisMentenModel | ||
|
||
|
||
class TestMichaelisMentenModel(unittest.TestCase): | ||
""" | ||
Tests if the Michaelis Menten (toy) model works. | ||
""" | ||
def test_n_parameters(self): | ||
x_0 = [1e4, 2e3, 2e4, 0] | ||
model = MichaelisMentenModel(x_0) | ||
self.assertEqual(model.n_parameters(), 3) | ||
|
||
def test_simulation_length(self): | ||
x_0 = [1e4, 2e3, 2e4, 0] | ||
model = MichaelisMentenModel(x_0) | ||
times = np.linspace(0, 1, 100) | ||
k = [1e-5, 0.2, 0.2] | ||
values = model.simulate(k, times) | ||
self.assertEqual(len(values), 100) | ||
|
||
def test_propensities(self): | ||
x_0 = [1e4, 2e3, 2e4, 0] | ||
k = [1e-5, 0.2, 0.2] | ||
model = MichaelisMentenModel(x_0) | ||
self.assertTrue( | ||
np.allclose( | ||
model._propensities(x_0, k), | ||
np.array([200.0, 4000.0, 4000.0]))) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess initially it's just models?