├── tests ├── __init__.py ├── dtraj │ ├── __init__.py │ ├── testfiles │ │ └── dtraj.npy │ └── test_trajectory.py ├── flux │ ├── __init__.py │ └── impl │ │ ├── __init__.py │ │ ├── dense │ │ ├── __init__.py │ │ └── tpt_test.py │ │ └── sparse │ │ ├── __init__.py │ │ ├── pathways_test.py │ │ └── tpt_test.py ├── util │ ├── __init__.py │ └── testfiles │ │ ├── matrix_int.dat │ │ ├── matrix_int.npy │ │ ├── matrix_float.npy │ │ ├── matrix_complex.npy │ │ ├── spmatrix_float.coo.npy │ │ ├── spmatrix_int.coo.npy │ │ ├── spmatrix_complex.coo.npy │ │ ├── matrix_float.dat │ │ ├── spmatrix_int_reference.dat │ │ ├── spmatrix_int.coo.dat │ │ ├── matrix_complex.dat │ │ ├── spmatrix_float.coo.dat │ │ ├── spmatrix_float_reference.dat │ │ └── spmatrix_complex.coo.dat ├── analysis │ ├── __init__.py │ ├── impl │ │ ├── __init__.py │ │ ├── dense │ │ │ ├── __init__.py │ │ │ ├── committor_test.py │ │ │ ├── stationary_vector_test.py │ │ │ ├── assessment_test.py │ │ │ ├── hitting_probability_test.py │ │ │ └── mean_first_passage_time_test.py │ │ └── sparse │ │ │ ├── __init__.py │ │ │ ├── committor_test.py │ │ │ ├── stationary_vector_test.py │ │ │ └── mean_first_passage_time_test.py │ └── test_committor.py ├── estimation │ ├── __init__.py │ ├── impl │ │ ├── __init__.py │ │ ├── dense │ │ │ ├── __init__.py │ │ │ └── tmatrix_sampler_test.py │ │ └── sparse │ │ │ ├── __init__.py │ │ │ ├── newton │ │ │ ├── __init__.py │ │ │ └── mle_rev_test.py │ │ │ ├── likelihood_test.py │ │ │ ├── transition_matrix_test.py │ │ │ └── prior_test.py │ └── tests │ │ ├── __init__.py │ │ ├── testfiles │ │ ├── dwell.npz │ │ ├── pi.dat │ │ ├── C_13_lag.dat │ │ ├── C_7_lag.dat │ │ ├── C_1_lag.dat │ │ ├── C_13_sliding.dat │ │ ├── C_1_sliding.dat │ │ └── C_7_sliding.dat │ │ ├── test_likelihood.py │ │ ├── test_bootstrapping.py │ │ └── test_prior.py ├── generation │ ├── __init__.py │ └── test_generation.py ├── conftest.py └── numeric.py ├── doc ├── requirements.txt ├── .gitignore ├── source │ ├── api │ │ ├── dtraj.rst │ │ ├── flux.rst │ │ ├── analysis.rst │ │ ├── estimation.rst │ │ ├── generation.rst │ │ └── index.rst │ ├── index.rst │ └── CHANGELOG.rst └── Makefile ├── msmtools ├── estimation │ ├── dense │ │ ├── mle │ │ │ ├── __init__.py │ │ │ ├── .gitignore │ │ │ ├── setup.py │ │ │ ├── src │ │ │ │ ├── _mle_trev_given_pi.h │ │ │ │ ├── _mle_trev.h │ │ │ │ ├── sigint_handler.h │ │ │ │ ├── _mle_trev_given_pi.c │ │ │ │ └── _mle_trev.c │ │ │ ├── mle_trev_given_pi.pyx │ │ │ └── mle_trev.pyx │ │ ├── tmat_sampling │ │ │ ├── __init__.py │ │ │ ├── .gitignore │ │ │ ├── setup.py │ │ │ ├── src │ │ │ │ ├── rnglib │ │ │ │ │ ├── rnglib.h │ │ │ │ │ └── ranlib.h │ │ │ │ ├── sample_revpi.h │ │ │ │ ├── util.h │ │ │ │ └── sample_rev.h │ │ │ ├── sampler_nrev.py │ │ │ └── tmatrix_sampler.py │ │ ├── setup.py │ │ ├── __init__.py │ │ └── transition_matrix.py │ ├── sparse │ │ ├── mle │ │ │ ├── __init__.py │ │ │ ├── newton │ │ │ │ ├── .gitignore │ │ │ │ └── __init__.py │ │ │ ├── .gitignore │ │ │ ├── src │ │ │ │ ├── _mle_trev_given_pi.h │ │ │ │ ├── _mle_trev.h │ │ │ │ ├── _mle_trev_given_pi.c │ │ │ │ └── _mle_trev.c │ │ │ ├── setup.py │ │ │ └── mle_trev.pyx │ │ ├── .gitignore │ │ ├── setup.py │ │ ├── __init__.py │ │ ├── likelihood.py │ │ ├── count_matrix.py │ │ ├── prior.py │ │ └── transition_matrix.py │ ├── setup.py │ └── __init__.py ├── util │ ├── kahandot_src │ │ ├── .gitignore │ │ ├── _kahandot.h │ │ ├── kahandot.pyx │ │ └── _kahandot.c │ ├── setup.py │ ├── __init__.py │ ├── numeric.py │ ├── include │ │ └── sigint_handler.h │ └── exceptions.py ├── flux │ ├── dense │ │ └── __init__.py │ ├── sparse │ │ └── __init__.py │ └── __init__.py ├── setup.py ├── analysis │ ├── sparse │ │ ├── __init__.py │ │ └── expectations.py │ ├── dense │ │ ├── __init__.py │ │ ├── hitting_probability.py │ │ └── assessment.py │ └── __init__.py ├── generation │ └── __init__.py ├── __init__.py └── dtraj │ └── __init__.py ├── .gitattributes ├── pyproject.toml ├── setup.cfg ├── MANIFEST.in ├── .travis.yml ├── appveyor.yml ├── tools ├── ci │ └── travis │ │ ├── install_miniconda.sh │ │ └── make_docs.sh └── conda-recipe │ ├── run_test.py │ └── meta.yaml ├── .gitignore ├── README.rst ├── dev_readme.rst └── setup_util.py /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dtraj/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/flux/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/util/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/analysis/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/estimation/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/flux/impl/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/generation/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | mock 2 | -------------------------------------------------------------------------------- /tests/analysis/impl/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/estimation/impl/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/flux/impl/dense/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | source/generated 2 | -------------------------------------------------------------------------------- /tests/analysis/impl/dense/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/analysis/impl/sparse/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/estimation/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/flux/impl/sparse/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/mle/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/mle/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/estimation/impl/dense/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/estimation/impl/sparse/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/estimation/impl/sparse/newton/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | msmtools/_version.py export-subst 2 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /msmtools/util/kahandot_src/.gitignore: -------------------------------------------------------------------------------- 1 | kahandot.c 2 | -------------------------------------------------------------------------------- /tests/util/testfiles/matrix_int.dat: -------------------------------------------------------------------------------- 1 | 0 1 2 2 | 3 4 5 3 | 6 7 8 4 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/mle/newton/.gitignore: -------------------------------------------------------------------------------- 1 | objective_sparse.c 2 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/.gitignore: -------------------------------------------------------------------------------- 1 | mle_trev.c 2 | mle_trev_given_pi.c 3 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/mle/.gitignore: -------------------------------------------------------------------------------- 1 | mle_trev.c 2 | mle_trev_given_pi.c 3 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/mle/.gitignore: -------------------------------------------------------------------------------- 1 | mle_trev.c 2 | mle_trev_given_pi.c 3 | *.so 4 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/.gitignore: -------------------------------------------------------------------------------- 1 | sampler_rev.c 2 | sampler_revpi.c 3 | -------------------------------------------------------------------------------- /doc/source/api/dtraj.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: msmtools.dtraj 2 | 3 | .. toctree:: 4 | :maxdepth: 1 5 | -------------------------------------------------------------------------------- /doc/source/api/flux.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: msmtools.flux 2 | 3 | .. toctree:: 4 | :maxdepth: 1 5 | -------------------------------------------------------------------------------- /doc/source/api/analysis.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: msmtools.analysis 2 | 3 | .. toctree:: 4 | :maxdepth: 1 5 | -------------------------------------------------------------------------------- /doc/source/api/estimation.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: msmtools.estimation 2 | 3 | .. toctree:: 4 | :maxdepth: 1 5 | -------------------------------------------------------------------------------- /doc/source/api/generation.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: msmtools.generation 2 | 3 | .. toctree:: 4 | :maxdepth: 1 5 | -------------------------------------------------------------------------------- /tests/dtraj/testfiles/dtraj.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markovmodel/msmtools/devel/tests/dtraj/testfiles/dtraj.npy -------------------------------------------------------------------------------- /tests/util/testfiles/matrix_int.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markovmodel/msmtools/devel/tests/util/testfiles/matrix_int.npy -------------------------------------------------------------------------------- /tests/util/testfiles/matrix_float.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markovmodel/msmtools/devel/tests/util/testfiles/matrix_float.npy -------------------------------------------------------------------------------- /tests/util/testfiles/matrix_complex.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markovmodel/msmtools/devel/tests/util/testfiles/matrix_complex.npy -------------------------------------------------------------------------------- /tests/estimation/tests/testfiles/dwell.npz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markovmodel/msmtools/devel/tests/estimation/tests/testfiles/dwell.npz -------------------------------------------------------------------------------- /tests/util/testfiles/spmatrix_float.coo.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markovmodel/msmtools/devel/tests/util/testfiles/spmatrix_float.coo.npy -------------------------------------------------------------------------------- /tests/util/testfiles/spmatrix_int.coo.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markovmodel/msmtools/devel/tests/util/testfiles/spmatrix_int.coo.npy -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "setuptools", 4 | "wheel", 5 | "numpy>=1.10", 6 | "Cython>=0.22", 7 | "scipy", 8 | ] 9 | -------------------------------------------------------------------------------- /tests/util/testfiles/spmatrix_complex.coo.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markovmodel/msmtools/devel/tests/util/testfiles/spmatrix_complex.coo.npy -------------------------------------------------------------------------------- /msmtools/util/kahandot_src/_kahandot.h: -------------------------------------------------------------------------------- 1 | #ifndef KAHANDOT_H 2 | #define KAHANDOT_H 3 | #include 4 | void _kdot(double *A, double *B, double *C, size_t n, size_t m, size_t l); 5 | double _ksum(double *X, size_t n, size_t m); 6 | #endif 7 | -------------------------------------------------------------------------------- /tests/util/testfiles/matrix_float.dat: -------------------------------------------------------------------------------- 1 | 0.000000000000000000e+00 1.000000000000000000e+00 2.000000000000000000e+00 2 | 3.000000000000000000e+00 4.000000000000000000e+00 5.000000000000000000e+00 3 | 6.000000000000000000e+00 7.000000000000000000e+00 8.000000000000000000e+00 4 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | import pytest 3 | 4 | 5 | @pytest.fixture(scope='session', autouse=True) 6 | def session_setup(): 7 | warnings.filterwarnings('once', category=DeprecationWarning) 8 | warnings.filterwarnings('once', category=PendingDeprecationWarning) 9 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/setup.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def configuration(parent_package='', top_path=None): 4 | from numpy.distutils.misc_util import Configuration 5 | config = Configuration('sparse', parent_package, top_path) 6 | config.add_subpackage('mle') 7 | 8 | return config 9 | -------------------------------------------------------------------------------- /tests/util/testfiles/spmatrix_int_reference.dat: -------------------------------------------------------------------------------- 1 | 0 10 0 0 0 0 0 0 0 0 2 | 20 1 11 0 0 0 0 0 0 0 3 | 0 21 2 12 0 0 0 0 0 0 4 | 0 0 22 3 13 0 0 0 0 0 5 | 0 0 0 23 4 14 0 0 0 0 6 | 0 0 0 0 24 5 15 0 0 0 7 | 0 0 0 0 0 25 6 16 0 0 8 | 0 0 0 0 0 0 26 7 17 0 9 | 0 0 0 0 0 0 0 27 8 18 10 | 0 0 0 0 0 0 0 0 28 9 11 | -------------------------------------------------------------------------------- /msmtools/estimation/setup.py: -------------------------------------------------------------------------------- 1 | 2 | def configuration(parent_package='', top_path=None): 3 | from numpy.distutils.misc_util import Configuration 4 | config = Configuration('estimation', parent_package, top_path) 5 | config.add_subpackage('dense') 6 | config.add_subpackage('sparse') 7 | 8 | return config 9 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/setup.py: -------------------------------------------------------------------------------- 1 | 2 | def configuration(parent_package='', top_path=None): 3 | from numpy.distutils.misc_util import Configuration 4 | config = Configuration('dense', parent_package, top_path) 5 | 6 | config.add_subpackage('mle') 7 | config.add_subpackage('tmat_sampling') 8 | return config 9 | -------------------------------------------------------------------------------- /doc/source/api/index.rst: -------------------------------------------------------------------------------- 1 | .. _ref_api: 2 | 3 | ============= 4 | Documentation 5 | ============= 6 | 7 | msmtools provides these packages to perform estimation and further analysis of Markov models. 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | estimation 13 | analysis 14 | flux 15 | dtraj 16 | generation 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/util/testfiles/spmatrix_int.coo.dat: -------------------------------------------------------------------------------- 1 | 1 1 1 2 | 2 2 2 3 | 3 3 3 4 | 4 4 4 5 | 5 5 5 6 | 6 6 6 7 | 7 7 7 8 | 8 8 8 9 | 9 9 9 10 | 0 1 10 11 | 1 2 11 12 | 2 3 12 13 | 3 4 13 14 | 4 5 14 15 | 5 6 15 16 | 6 7 16 17 | 7 8 17 18 | 8 9 18 19 | 1 0 20 20 | 2 1 21 21 | 3 2 22 22 | 4 3 23 23 | 5 4 24 24 | 6 5 25 25 | 7 6 26 26 | 8 7 27 27 | 9 8 28 28 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | 2 | # See the docstring in versioneer.py for instructions. Note that you must 3 | # re-run 'versioneer.py setup' after changing this section, and commit the 4 | # resulting files. 5 | 6 | [versioneer] 7 | VCS = git 8 | style = pep440 9 | versionfile_source = msmtools/_version.py 10 | #versionfile_build = 11 | tag_prefix = v 12 | parentdir_prefix = msmtools 13 | 14 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # versioneer 2 | include versioneer.py 3 | include msmtools/_version.py 4 | 5 | recursive-include msmtools testfiles/* tests/* 6 | 7 | # setup stuff 8 | include setup_util.py 9 | 10 | #include cython files and sources of extensions (incl. cython) 11 | recursive-include msmtools *.pyx *.c *.h 12 | 13 | 14 | include README* 15 | include LICENSE* 16 | 17 | include pyproject.toml 18 | 19 | -------------------------------------------------------------------------------- /msmtools/util/setup.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def configuration(parent_package='', top_path=None): 5 | from numpy.distutils.misc_util import Configuration 6 | config = Configuration('util', parent_package, top_path) 7 | 8 | config.add_extension('kahandot', 9 | sources=['kahandot_src/_kahandot.c', 'kahandot_src/kahandot.pyx'], 10 | include_dirs=['kahandot_src/', np.get_include()]) 11 | return config 12 | -------------------------------------------------------------------------------- /tests/util/testfiles/matrix_complex.dat: -------------------------------------------------------------------------------- 1 | (0.000000000000000000e+00+9.000000000000000000e+00j) (1.000000000000000000e+00+1.000000000000000000e+01j) (2.000000000000000000e+00+1.100000000000000000e+01j) 2 | (3.000000000000000000e+00+1.200000000000000000e+01j) (4.000000000000000000e+00+1.300000000000000000e+01j) (5.000000000000000000e+00+1.400000000000000000e+01j) 3 | (6.000000000000000000e+00+1.500000000000000000e+01j) (7.000000000000000000e+00+1.600000000000000000e+01j) (8.000000000000000000e+00+1.700000000000000000e+01j) 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: false 3 | 4 | env: 5 | global: 6 | - PATH=$HOME/miniconda/bin:$PATH 7 | matrix: 8 | - python=3.6 CONDA_PY=36 CONDA_NPY=111 9 | - python=3.7 CONDA_PY=37 CONDA_NPY=115 10 | 11 | before_install: 12 | - tools/ci/travis/install_miniconda.sh 13 | - conda install mamba boa 14 | - conda install conda-build conda-verify 15 | 16 | script: 17 | - conda mambabuild tools/conda-recipe --numpy=$CONDA_NPY -c conda-forge 18 | 19 | after_script: 20 | - bash <(curl -s https://codecov.io/bash) -f $HOME/coverage.xml -e CONDA_PY 21 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | global: 3 | DISTUTILS_USE_SDK: "1" 4 | ARCH: "64" 5 | PYTHON: "C:\\Miniconda3-x64" 6 | 7 | matrix: 8 | - CONDA_PY: "36" 9 | - CONDA_PY: "39" 10 | 11 | install: 12 | - CALL "%PYTHON%\\Scripts\\activate.bat" 13 | - conda config --set always_yes true 14 | - conda config --set quiet true 15 | - conda config --add channels conda-forge 16 | - conda install boa 17 | # Build the compiled extension and run the project tests 18 | - conda mambabuild tools/conda-recipe --numpy=%CONDA_NUMPY% 19 | 20 | build: false 21 | -------------------------------------------------------------------------------- /tests/estimation/tests/testfiles/pi.dat: -------------------------------------------------------------------------------- 1 | 1.309084620877833983e-02 2 | 4.432716193209394057e-02 3 | 1.775417542549480310e-02 4 | 2.441019178064034179e-02 5 | 2.530656386660943419e-02 6 | 6.404563693463498353e-02 7 | 6.666577071224019657e-02 8 | 3.063973994471656456e-02 9 | 6.368339064430164620e-02 10 | 4.081734064420747266e-02 11 | 9.043502073336052993e-02 12 | 4.625079583690042823e-02 13 | 9.028254601575017024e-02 14 | 6.879060775435444364e-02 15 | 5.978624278507334300e-02 16 | 1.688698762144261525e-02 17 | 7.208399400928119927e-02 18 | 8.850171712926394041e-02 19 | 6.874102679603207033e-02 20 | 7.500243224823542783e-03 21 | -------------------------------------------------------------------------------- /tools/ci/travis/install_miniconda.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # make TARGET overrideable with env 4 | : ${TARGET:=$HOME/miniconda} 5 | 6 | function install_miniconda { 7 | echo "installing miniconda to $TARGET" 8 | wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O mc.sh -o /dev/null 9 | bash mc.sh -b -f -p $TARGET 10 | # taken from conda-smithy 11 | conda config --remove channels defaults 12 | conda config --set always_yes true 13 | conda config --set quiet true 14 | conda config --add channels defaults 15 | conda config --add channels conda-forge 16 | conda config --set show_channel_urls true 17 | } 18 | 19 | install_miniconda 20 | export PATH=$TARGET/bin:$PATH 21 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/mle/setup.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def configuration(parent_package='', top_path=None): 5 | from numpy.distutils.misc_util import Configuration 6 | config = Configuration('mle', parent_package, top_path) 7 | 8 | config.add_extension('mle_trev', 9 | sources=['mle_trev.pyx', 10 | 'src/_mle_trev.c', 11 | ], 12 | include_dirs=['src/', np.get_include()] 13 | ) 14 | 15 | config.add_extension('mle_trev_given_pi', 16 | sources=['mle_trev_given_pi.pyx', 17 | 'src/_mle_trev_given_pi.c'], 18 | include_dirs=['src/', np.get_include()]) 19 | 20 | return config 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # compilation / build files 2 | *.orig 3 | *.bak 4 | build* 5 | *.log 6 | *.egg 7 | /.eggs 8 | /.settings 9 | /.tox 10 | *.pyc 11 | *.egg-info 12 | *.so 13 | /temp 14 | /target 15 | __pycache__ 16 | /pylint/pylint_*.txt 17 | /dist 18 | .externalToolBuilders 19 | 20 | # ignore untitled ipython notebooks 21 | Untitled*.ipynb 22 | 23 | # ignore c-files generated by cython 24 | /*/estimation/dense/mle_trev.c 25 | /*/estimation/dense/mle_trev_given_pi.c 26 | /*/estimation/sparse/mle_trev.c 27 | /*/estimation/sparse/mle_trev_given_pi.c 28 | /*/estimation/dense/sampler_rev.c 29 | /*/estimation/dense/sampler_revpi.c 30 | /*/estimation/sparse/newton/objective_sparse.c 31 | 32 | # generated from MANIFEST.in 33 | MANIFEST 34 | doc/source/api/generated/ 35 | .ipynb_checkpoints 36 | .project 37 | .pydevproject 38 | 39 | # project files 40 | .idea 41 | 42 | -------------------------------------------------------------------------------- /tools/conda-recipe/run_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | test_pkg = 'msmtools' 5 | cover_pkg = test_pkg 6 | 7 | junit_xml = os.path.join(os.getenv('CIRCLE_TEST_REPORTS', '.'), 'junit.xml') 8 | 9 | pytest_args = ("-v --pyargs {test_pkg} " 10 | "--cov={cover_pkg} " 11 | "--cov-report=xml:{dest_report} " 12 | #"--doctest-modules " 13 | "--junit-xml={junit_xml} " 14 | .format(test_pkg=test_pkg, cover_pkg=cover_pkg, 15 | junit_xml=junit_xml, 16 | dest_report=os.path.join(os.path.expanduser('~/'), 'coverage.xml'), 17 | ) 18 | .split(' ')) 19 | 20 | if __name__ == '__main__': 21 | print("args:", pytest_args) 22 | import pytest 23 | res = pytest.main(pytest_args) 24 | sys.exit(res) 25 | -------------------------------------------------------------------------------- /msmtools/util/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | -------------------------------------------------------------------------------- /tools/conda-recipe/meta.yaml: -------------------------------------------------------------------------------- 1 | package: 2 | name: msmtools 3 | version: 0 4 | 5 | source: 6 | path: ../.. 7 | 8 | build: 9 | # this method tests the "installability" of the source distribution 10 | script: python setup.py sdist; pip install --no-deps --ignore-installed -v dist/* # [linux] 11 | script: python setup.py install # [win] 12 | 13 | requirements: 14 | build: 15 | - {{ compiler('c') }} 16 | 17 | host: 18 | - cython 19 | - {{ pin_compatible('numpy') }} 20 | - python 21 | - setuptools 22 | - pip 23 | 24 | run: 25 | - decorator 26 | - numpy 27 | - python 28 | - scipy 29 | - setuptools 30 | 31 | test: 32 | source_files: 33 | - tests/ 34 | requires: 35 | - pytest 36 | - pytest-cov 37 | 38 | about: 39 | home: http://github.com/markovmodel/msmtools 40 | license: LGPLv3+ 41 | summary: "MSMTools" 42 | -------------------------------------------------------------------------------- /msmtools/flux/dense/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | from . import tpt 20 | -------------------------------------------------------------------------------- /tests/estimation/tests/testfiles/C_13_lag.dat: -------------------------------------------------------------------------------- 1 | 2 0 0 1 2 4 1 1 2 4 2 2 3 1 3 2 2 2 2 4 2 | 5 4 3 4 3 3 1 2 1 3 2 1 1 5 1 1 3 1 1 1 3 | 2 2 3 2 1 2 0 4 3 2 1 2 2 1 2 1 1 3 1 2 4 | 1 6 1 3 4 4 1 3 1 3 1 1 1 3 1 0 2 1 0 4 5 | 3 1 1 1 1 2 1 0 1 4 2 2 2 3 5 3 2 1 0 1 6 | 2 2 2 2 3 1 0 2 1 1 1 1 2 3 2 1 2 4 3 5 7 | 4 0 1 2 1 1 2 2 1 3 2 2 1 3 3 0 1 0 2 0 8 | 1 1 1 3 1 0 3 4 3 7 2 1 2 1 1 3 1 2 2 2 9 | 3 2 0 3 1 0 0 1 2 0 1 1 3 2 4 1 3 0 1 5 10 | 0 2 2 4 0 2 4 2 3 0 4 2 4 3 2 3 0 3 3 1 11 | 2 3 2 2 3 1 3 2 1 3 3 2 2 2 2 1 1 2 3 1 12 | 1 0 5 2 2 2 0 3 0 2 2 4 1 2 1 2 3 2 3 1 13 | 0 5 2 3 2 3 1 1 3 1 1 1 2 1 2 1 0 3 0 6 14 | 4 5 4 0 3 1 4 0 1 0 4 1 0 3 4 0 2 5 4 0 15 | 5 1 1 2 0 2 1 2 0 4 0 3 2 2 2 6 3 3 3 0 16 | 0 1 4 1 1 2 2 3 2 1 2 3 3 1 0 0 1 1 0 1 17 | 0 1 1 2 2 0 2 3 0 1 3 4 2 2 0 2 0 1 4 1 18 | 2 4 2 4 2 3 0 3 2 3 3 4 1 2 1 0 1 2 0 1 19 | 1 2 1 0 3 3 3 2 2 1 3 0 1 1 6 1 1 0 2 2 20 | 2 4 1 0 1 4 2 1 4 1 2 1 3 3 1 1 2 4 1 3 21 | -------------------------------------------------------------------------------- /tests/estimation/tests/testfiles/C_7_lag.dat: -------------------------------------------------------------------------------- 1 | 2 5 2 3 4 2 3 6 3 4 5 2 4 7 4 4 7 2 2 4 2 | 7 2 4 1 4 3 3 3 7 4 3 5 4 6 4 5 1 4 4 3 3 | 4 2 1 3 1 6 5 3 2 4 7 6 3 3 3 5 2 1 4 1 4 | 2 5 4 4 7 5 5 1 4 4 1 3 1 0 4 7 2 5 0 1 5 | 2 4 2 5 3 8 4 3 5 4 7 2 2 2 4 5 3 5 4 1 6 | 3 2 3 9 5 3 4 0 3 4 1 3 4 3 6 3 9 7 5 5 7 | 3 2 4 4 5 1 3 5 4 3 3 3 5 5 5 4 0 1 2 7 8 | 2 6 3 1 7 1 2 1 3 6 6 2 3 2 1 5 1 4 1 2 9 | 3 3 3 2 4 5 3 5 2 3 3 9 3 3 3 4 2 8 5 2 10 | 5 5 1 7 2 5 5 1 4 3 7 3 2 6 5 3 3 4 1 8 11 | 9 2 6 1 4 1 1 2 5 4 2 6 1 5 7 5 3 4 5 0 12 | 3 0 4 7 4 9 2 3 2 7 3 6 3 4 1 2 5 1 7 2 13 | 2 5 4 1 4 3 3 1 4 9 2 3 1 1 6 1 1 2 4 3 14 | 2 3 3 4 3 5 4 3 6 5 2 2 3 4 4 2 0 3 6 3 15 | 4 6 3 5 4 4 6 4 6 4 4 1 6 0 8 3 4 5 6 4 16 | 6 6 6 1 1 3 3 5 0 6 4 4 2 4 5 2 2 4 5 5 17 | 6 5 2 4 1 3 4 3 4 2 3 2 3 2 2 1 1 4 4 2 18 | 5 6 4 1 4 4 3 4 6 1 3 6 5 3 3 5 4 2 3 4 19 | 3 2 5 0 6 6 4 6 2 1 5 3 2 4 5 7 2 5 3 3 20 | 2 6 2 2 2 6 2 0 3 2 2 4 3 2 7 1 6 5 3 1 21 | -------------------------------------------------------------------------------- /msmtools/flux/sparse/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | from . import tpt 21 | from . import pathways 22 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/setup.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def configuration(parent_package='', top_path=None): 5 | from numpy.distutils.misc_util import Configuration 6 | config = Configuration('tmat_sampling', parent_package, top_path) 7 | 8 | config.add_library('rnglib', sources=['src/rnglib/rnglib.c', 'src/rnglib/ranlib.c']) 9 | 10 | config.add_extension('sampler_rev', 11 | sources=['sampler_rev.pyx', 12 | 'src/sample_rev.c'], 13 | include_dirs=['src/', np.get_include()], 14 | libraries=['rnglib']) 15 | 16 | config.add_extension('sampler_revpi', 17 | sources=['sampler_revpi.pyx', 18 | 'src/sample_revpi.c'], 19 | include_dirs=['src/', np.get_include()], 20 | libraries=['rnglib']) 21 | 22 | return config 23 | -------------------------------------------------------------------------------- /msmtools/setup.py: -------------------------------------------------------------------------------- 1 | 2 | def configuration(parent_package='', top_path=None): 3 | from numpy.distutils.misc_util import Configuration 4 | 5 | config = Configuration('msmtools', parent_package, top_path) 6 | 7 | config.add_subpackage('analysis') 8 | config.add_subpackage('analysis.dense') 9 | config.add_subpackage('analysis.sparse') 10 | 11 | config.add_subpackage('dtraj') 12 | config.add_subpackage('estimation') 13 | 14 | config.add_subpackage('flux') 15 | config.add_subpackage('flux.dense') 16 | config.add_subpackage('flux.sparse') 17 | 18 | config.add_subpackage('generation') 19 | config.add_subpackage('util') 20 | 21 | from Cython.Build import cythonize 22 | config.ext_modules = cythonize( 23 | config.ext_modules, 24 | compiler_directives={'language_level': '3'}) 25 | 26 | return config 27 | 28 | 29 | if __name__ == '__main__': 30 | from numpy.distutils.core import setup 31 | setup(**configuration(top_path='').todict()) 32 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/mle/newton/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2016, 2015, 2014 Computational Molecular Biology Group, 5 | # Freie Universitaet Berlin (GER) 6 | # 7 | # MSMTools is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | 20 | r""" 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/mle/src/_mle_trev_given_pi.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | int _mle_trev_given_pi_dense(double * const T, const double * const C, const double * const mu, const int n, const double maxerr, const int maxiter); 20 | 21 | -------------------------------------------------------------------------------- /msmtools/analysis/sparse/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | from . import assessment 21 | from . import committor 22 | from . import decomposition 23 | from . import expectations 24 | from . import fingerprints 25 | from . import mean_first_passage_time 26 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | from . import bootstrapping 21 | from . import transition_matrix 22 | from . import covariance 23 | 24 | from .mle import mle_trev, mle_trev_given_pi 25 | from .tmat_sampling import tmatrix_sampler 26 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | **This package will soon be no longer or only very sparsely maintained in favor of** `deeptime `__. 2 | 3 | 4 | 5 | MSMTools 6 | ======== 7 | 8 | What is it? 9 | ----------- 10 | msmtools is an open source collection of algorithms for the estimation 11 | and analysis of discrete state space Markov chains via Markov state 12 | models (MSM). 13 | 14 | The algorithms are implemented using `NumPy `_ 15 | and `SciPy `_. 16 | 17 | Installation 18 | ------------ 19 | With pip:: 20 | 21 | pip install msmtools 22 | 23 | with conda:: 24 | 25 | conda install -c conda-forge msmtools 26 | 27 | 28 | or install latest devel branch with pip:: 29 | 30 | pip install git+https://github.com/markovmodel/msmtools.git@devel 31 | 32 | 33 | Support and development 34 | ----------------------- 35 | For bug reports/suggestions/complains please file an issue on 36 | `GitHub `__. 37 | 38 | Or start a discussion on our mailing list: pyemma-users@lists.fu-berlin.de 39 | -------------------------------------------------------------------------------- /tools/ci/travis/make_docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | function install_deps { 3 | wget https://github.com/jgm/pandoc/releases/download/1.13.2/pandoc-1.13.2-1-amd64.deb \ 4 | -O pandoc.deb 5 | dpkg -x pandoc.deb $HOME 6 | 7 | export PATH=$PATH:$HOME/usr/bin 8 | # try to execute pandoc 9 | pandoc --version 10 | 11 | conda install -q --yes $doc_deps 12 | pip install -r requirements-build-doc.txt wheel 13 | } 14 | 15 | function build_doc { 16 | pushd doc; make ipython-rst html 17 | # workaround for docs dir => move doc to build/docs afterwards 18 | # travis (currently )expects docs in build/docs (should contain index.html?) 19 | mv build/html ../build/docs 20 | popd 21 | } 22 | 23 | function deploy_doc { 24 | echo "[distutils] 25 | index-servers = pypi 26 | 27 | [pypi] 28 | username:marscher 29 | password:${pypi_pass}" > ~/.pypirc 30 | 31 | python setup.py upload_docs 32 | } 33 | 34 | # build docs only for python 2.7 and for normal commits (not pull requests) 35 | if [[ $TRAVIS_PYTHON_VERSION = "2.7" ]] && [[ "${TRAVIS_PULL_REQUEST}" = "false" ]]; then 36 | install_deps 37 | build_doc 38 | deploy_doc 39 | fi 40 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/mle/src/_mle_trev_given_pi.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | int _mle_trev_given_pi_sparse(double * const T_unnormalized_data, const double * const CCt_data, const int * const i_indices, const int * const j_indices, const int len_CCt, const double * const mu, const int len_mu, const double maxerr, const int maxiter); 20 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/mle/src/_mle_trev.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | int _mle_trev_dense(double * const T, const double * const CCt, 20 | const double * const sum_C, const int dim, 21 | const double maxerr, const int maxiter, 22 | double * const mu, 23 | double eps_mu); 24 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/mle/src/_mle_trev.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | int _mle_trev_sparse(double * const T_data, const double * const CCt_data, 20 | const int * const i_indices, const int * const j_indices, 21 | const int len_CCt, const double * const sum_C, const int dim, 22 | const double maxerr, const int maxiter, 23 | double * const mu, 24 | double mu_eps); 25 | -------------------------------------------------------------------------------- /msmtools/analysis/dense/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | from . import assessment 21 | from . import committor 22 | from . import correlations 23 | from . import decomposition 24 | from . import expectations 25 | from . import fingerprints 26 | from . import hitting_probability 27 | from . import mean_first_passage_time 28 | from . import sensitivity 29 | from . import pcca 30 | -------------------------------------------------------------------------------- /dev_readme.rst: -------------------------------------------------------------------------------- 1 | ------------------------- 2 | How to make a new release 3 | ------------------------- 4 | 5 | Checklist 6 | --------- 7 | 8 | * Do all tests pass? 9 | * Are the changes tested in the upstream/dependent software? 10 | 11 | 12 | Steps 13 | ----- 14 | 1. Create a new tag with git on your local working copy:: 15 | 16 | git tag v1.1 -m "Release message" 17 | 18 | 2. Push the tag to origin:: 19 | 20 | git push --tags 21 | 22 | 3. Create a source distribution to upload on PyPI:: 23 | 24 | python setup.py sdist 25 | 26 | This will create a $name-$version.tar.gz file in the dist directory. 27 | 28 | 4. Upload on PyPI with twine (you need to have an account on PyPI for that):: 29 | 30 | pip install twine 31 | twine upload dist/$name-$version.tar.gz --user $user --password $pass 32 | 33 | 5. Update the conda recipe for Omnia channel 34 | a. Create a fork of https://github.com/omnia-md/conda-recipes 35 | b. Edit the recipe (meta.yml) to match the new dependencies and version numbers. 36 | c. Create a pull request on https://github.com/omnia-md/conda-recipes/pulls to 37 | have your changes tested and merged. 38 | d. Sit back and wait for the packages being build. 39 | -------------------------------------------------------------------------------- /msmtools/util/kahandot_src/kahandot.pyx: -------------------------------------------------------------------------------- 1 | # TODO: - matrix sum along one axis 2 | # - vector-vector dot product 3 | 4 | import numpy as np 5 | cimport numpy as np 6 | 7 | cdef extern from "_kahandot.h": 8 | void _kdot( 9 | double *A, 10 | double *B, 11 | double *C, 12 | size_t n, 13 | size_t m, 14 | size_t l 15 | ) 16 | double _ksum( 17 | double *X, 18 | size_t n, 19 | size_t m 20 | ) 21 | 22 | def kdot(np.ndarray[double, ndim=2, mode="c"] A not None, 23 | np.ndarray[double, ndim=2, mode="c"] B not None): 24 | 25 | assert A.shape[1] == B.shape[0] 26 | 27 | C = np.zeros((A.shape[0],B.shape[1]),dtype=np.float64) 28 | _kdot( 29 | np.PyArray_DATA( A ), 30 | np.PyArray_DATA( B ), 31 | np.PyArray_DATA( C ), 32 | A.shape[0], 33 | A.shape[1], 34 | B.shape[1] 35 | ) 36 | return C 37 | 38 | def ksum(np.ndarray[double, ndim=2, mode="c"] X not None): 39 | return _ksum( 40 | np.PyArray_DATA( X ), 41 | X.shape[0], 42 | X.shape[1] 43 | ) 44 | 45 | -------------------------------------------------------------------------------- /msmtools/util/kahandot_src/_kahandot.c: -------------------------------------------------------------------------------- 1 | #include "_kahandot.h" 2 | #include 3 | #include 4 | 5 | #define A(i,j) (A[(i)*m+(j)]) 6 | #define B(i,j) (B[(i)*l+(j)]) 7 | #define C(i,j) (C[(i)*l+(j)]) 8 | 9 | void _kdot(double *A, double *B, double *C, size_t n, size_t m, size_t l) 10 | { 11 | size_t i,j,k; 12 | double err, sum, t, y; 13 | 14 | for(i=0; i. 18 | 19 | r"""This module provides implementations for the estimation package 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | from . import count_matrix 26 | from . import connectivity 27 | from . import effective_counts 28 | from . import likelihood 29 | from . import transition_matrix 30 | from . import prior 31 | 32 | from .mle import mle_trev, mle_trev_given_pi 33 | -------------------------------------------------------------------------------- /msmtools/util/numeric.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def allclose_sparse(A, B, rtol=1e-5, atol=1e-8): 5 | """ 6 | Compares two sparse matrices in the same matter like numpy.allclose() 7 | Parameters 8 | ---------- 9 | A : scipy.sparse matrix 10 | first matrix to compare 11 | B : scipy.sparse matrix 12 | second matrix to compare 13 | rtol : float 14 | relative tolerance 15 | atol : float 16 | absolute tolerance 17 | 18 | Returns 19 | ------- 20 | True, if given matrices are equal in bounds of rtol and atol 21 | False, otherwise 22 | 23 | Notes 24 | ----- 25 | If the following equation is element-wise True, then allclose returns 26 | True. 27 | 28 | absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`)) 29 | 30 | The above equation is not symmetric in `a` and `b`, so that 31 | `allclose(a, b)` might be different from `allclose(b, a)` in 32 | some rare cases. 33 | """ 34 | A = A.tocsr() 35 | B = B.tocsr() 36 | 37 | """Shape""" 38 | same_shape = (A.shape == B.shape) 39 | 40 | """Data""" 41 | if same_shape: 42 | diff = (A - B).data 43 | same_data = np.allclose(diff, 0.0, rtol=rtol, atol=atol) 44 | 45 | return same_data 46 | else: 47 | return False 48 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/likelihood.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | """This module implements the transition matrix functionality""" 20 | 21 | import numpy as np 22 | import scipy 23 | 24 | 25 | def log_likelihood(C, T): 26 | """ 27 | implementation of likelihood of C given T 28 | """ 29 | C = C.tocsr() 30 | T = T.tocsr() 31 | ind = scipy.nonzero(C) 32 | relT = np.array(T[ind])[0, :] 33 | relT = np.log(relT) 34 | relC = np.array(C[ind])[0, :] 35 | 36 | return relT.dot(relC) 37 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | 2 | ======================================= 3 | MSMTools 4 | ======================================= 5 | 6 | MSMTools is a Python library for the estimation, validation and analysis Markov state models. 7 | 8 | It supports the following main features: 9 | 10 | * Markov state model (MSM) estimation and validation. 11 | * Computing Metastable states and structures with Perron-cluster cluster analysis (PCCA). 12 | * Systematic coarse-graining of MSMs to transition models with few states. 13 | * Extensive analysis options for MSMs, e.g. calculation of committors, mean first passage times, 14 | transition rates, experimental expectation values and time-correlation functions, etc. 15 | * Transition Path Theory (TPT). 16 | 17 | For a high-level interface to these functionalities, we encourage you to use PyEMMA. 18 | 19 | 20 | Technical features: 21 | 22 | * Code is implemented in Python (supports 2.7, 3.3/3.4) and C. 23 | * Runs on Linux (64 bit), Windows (32 or 64 bit) or MacOS (64 bit). 24 | 25 | 26 | Documentation 27 | ============= 28 | 29 | .. toctree:: 30 | :maxdepth: 2 31 | 32 | INSTALL 33 | api/index 34 | 35 | 36 | Development 37 | =========== 38 | .. toctree:: 39 | :maxdepth: 2 40 | 41 | CHANGELOG 42 | DEVELOPMENT 43 | 44 | 45 | Indices and tables 46 | ================== 47 | 48 | * :ref:`genindex` 49 | * :ref:`modindex` 50 | * :ref:`search` 51 | 52 | -------------------------------------------------------------------------------- /msmtools/generation/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r""" 20 | 21 | ================================================================ 22 | generation - MSM generation tools (:mod:`msmtools.generation`) 23 | ================================================================ 24 | 25 | .. currentmodule:: msmtools.generation 26 | 27 | This module contains function to generate simple MSMs. 28 | 29 | Metropolis-Hastings chain 30 | ========================= 31 | 32 | .. autosummary:: 33 | :toctree: generated/ 34 | 35 | transition_matrix_metropolis_1d 36 | generate_traj 37 | 38 | """ 39 | from .api import * 40 | -------------------------------------------------------------------------------- /msmtools/util/include/sigint_handler.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #ifndef SIGINT_HANDLER_H 20 | #define SIGINT_HANDLER_H 21 | 22 | #include 23 | 24 | static volatile sig_atomic_t interrupted; 25 | static void (*old_handler)(int); 26 | 27 | static void signal_handler(int signo) { 28 | interrupted = 1; 29 | } 30 | 31 | static void sigint_on(void) { 32 | interrupted = 0; 33 | old_handler = signal(SIGINT, signal_handler); 34 | } 35 | 36 | static void sigint_off(void) { 37 | if(old_handler != SIG_ERR) { 38 | signal(SIGINT, old_handler); 39 | if(interrupted) raise(SIGINT); 40 | } 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /msmtools/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r""" 20 | 21 | .. currentmodule:: msmtools 22 | 23 | 24 | MSM functions 25 | ============= 26 | Low-level functions for estimation and analysis of transition matrices and io. 27 | 28 | .. toctree:: 29 | :maxdepth: 1 30 | 31 | dtraj 32 | generation 33 | estimation 34 | analysis 35 | flux 36 | 37 | 38 | """ 39 | 40 | from . import analysis 41 | from . import estimation 42 | from . import generation 43 | from . import dtraj 44 | from . import flux 45 | 46 | from ._version import get_versions 47 | __version__ = get_versions()['version'] 48 | del get_versions 49 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/mle/src/sigint_handler.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #ifndef SIGINT_HANDLER_H 20 | #define SIGINT_HANDLER_H 21 | 22 | #include 23 | 24 | static volatile sig_atomic_t interrupted; 25 | static void (*old_handler)(int); 26 | 27 | static void signal_handler(int signo) { 28 | interrupted = 1; 29 | } 30 | 31 | static void sigint_on(void) { 32 | interrupted = 0; 33 | old_handler = signal(SIGINT, signal_handler); 34 | } 35 | 36 | static void sigint_off(void) { 37 | if(old_handler != SIG_ERR) { 38 | signal(SIGINT, old_handler); 39 | if(interrupted) raise(SIGINT); 40 | } 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /tests/numeric.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | ''' 20 | Created on 28.10.2013 21 | 22 | @author: marscher 23 | ''' 24 | from numpy.testing import assert_allclose as assert_allclose_np 25 | 26 | __all__ = ['assert_allclose', 27 | ] 28 | 29 | 30 | def assert_allclose(actual, desired, rtol=1.e-5, atol=1.e-8, 31 | err_msg='', verbose=True): 32 | r"""wrapper for numpy.testing.allclose with default tolerances of 33 | numpy.allclose. Needed since testing method has different values.""" 34 | return assert_allclose_np(actual, desired, rtol=rtol, atol=atol, 35 | err_msg=err_msg, verbose=True) 36 | 37 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/src/rnglib/rnglib.h: -------------------------------------------------------------------------------- 1 | #ifndef _RNGLIB_ 2 | #define _RNGLIB_ 3 | 4 | extern void advance_state ( int k ); 5 | extern int antithetic_get (void ); 6 | extern void antithetic_memory ( int i, int *value ); 7 | extern void antithetic_set ( int value ); 8 | extern void cg_get ( int g, int *cg1, int *cg2 ); 9 | extern void cg_memory ( int i, int g, int *cg1, int *cg2 ); 10 | extern void cg_set ( int g, int cg1, int cg2 ); 11 | extern int cgn_get (void); 12 | extern void cgn_memory ( int i, int *g ); 13 | extern void cgn_set ( int g ); 14 | extern void get_state ( int *cg1, int *cg2 ); 15 | extern int i4_uni (void); 16 | extern void ig_get ( int g, int *ig1, int *ig2 ); 17 | extern void ig_memory ( int i, int g, int *ig1, int *ig2 ); 18 | extern void ig_set ( int g, int ig1, int ig2 ); 19 | extern void init_generator ( int t ); 20 | extern void initialize (void); 21 | extern int initialized_get (void); 22 | extern void initialized_memory ( int i, int *initialized ); 23 | extern void initialized_set (void); 24 | extern void lg_get ( int g, int *lg1, int *lg2 ); 25 | extern void lg_memory ( int i, int g, int *lg1, int *lg2 ); 26 | extern void lg_set ( int g, int lg1, int lg2 ); 27 | extern int multmod ( int a, int s, int m ); 28 | extern float r4_uni_01 (void); 29 | extern double r8_uni_01 (void); 30 | extern void set_initial_seed ( int ig1, int ig2 ); 31 | extern void set_seed ( int cg1, int cg2 ); 32 | extern void timestamp (void); 33 | 34 | #endif /* _RNGLIB_ */ 35 | -------------------------------------------------------------------------------- /doc/source/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 1.2.6 (02-10-21) 5 | ---------------- 6 | 7 | **Fixes:** 8 | - Fixed transition matrix sampling drawing from wrong distribution. #125 9 | 10 | 11 | 1.2.5 (11-06-19) 12 | ---------------- 13 | 14 | [generation] replaced scipy.stats.rv_discrete by np.random.choice #123 15 | 16 | 17 | 1.2.4 (11-12-18) 18 | ---------------- 19 | 20 | **Fixes:** 21 | - Effective count matrix parallel evaluation fixes. #116, #117 22 | 23 | 1.2.3 (7-27-18) 24 | --------------- 25 | 26 | **New features** 27 | 28 | - Effective count matrix can be evaluated in parallel. #112 29 | 30 | 31 | 1.2.2 (6-25-18) 32 | --------------- 33 | 34 | **New features** 35 | 36 | - Added new transition matrix estimator which uses a primal-dual interior-point iteration scheme. #82 37 | 38 | **Fixes:** 39 | 40 | - Fixed a corner case, in which the pathway decomposition could fail (no more paths left). #107 41 | 42 | 43 | 1.2.1 (5-16-17) 44 | --------------- 45 | 46 | **New features** 47 | 48 | - Added fast reversible transition matrix estimation. #94 49 | 50 | **Fixes:** 51 | 52 | - Fixed some minor issues in rate matrix estimation. #97 #98 53 | 54 | 55 | 1.2 (10-24-16) 56 | -------------- 57 | 58 | **New features:** 59 | 60 | - Continous MSM (rate matrix) estimation 61 | 62 | 63 | 1.1.4 (9-23-16) 64 | --------------- 65 | 66 | **Fixes**: 67 | 68 | - Fixed sparsity pattern check in transition matrix sampler. #91, thanks @fabian-paul 69 | 70 | 1.1.3 (8-10-16) 71 | --------------- 72 | 73 | **New features**: 74 | 75 | - added documentation 76 | 77 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/src/sample_revpi.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | /* * moduleauthor:: B. Trendelkamp-Schroer 20 | * 21 | */ 22 | #ifndef _TMATRIX_SAMPLING_REVPI_ 23 | #define _TMATRIX_SAMPLING_REVPI_ 24 | 25 | extern double sample_quad(double xkl, double xkk, double xll, 26 | double ckl, double clk, double ckk, double cll, 27 | double bk, double bl); 28 | 29 | extern double sample_quad_rw(double xkl, double xkk, double xll, 30 | double ckl, double clk, double ckk, double cll, 31 | double bk, double bl); 32 | 33 | extern void update(double *X, double *C, double *b, size_t n); 34 | 35 | extern void update_sparse(double *X, double *C, double *b, size_t n, 36 | size_t * I, size_t * J, size_t n_idx); 37 | 38 | #endif /* _TMATRIX_SAMPLING_REVPI_ */ 39 | -------------------------------------------------------------------------------- /msmtools/util/exceptions.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | ''' 20 | Created on May 26, 2014 21 | 22 | @author: marscher 23 | ''' 24 | 25 | 26 | class SpectralWarning(RuntimeWarning): 27 | pass 28 | 29 | 30 | class ImaginaryEigenValueWarning(SpectralWarning): 31 | pass 32 | 33 | 34 | class PrecisionWarning(RuntimeWarning): 35 | r""" 36 | This warning indicates that some operation in your code leads 37 | to a conversion of datatypes, which involves a loss/gain in 38 | precision. 39 | 40 | """ 41 | pass 42 | 43 | 44 | class NotConvergedWarning(RuntimeWarning): 45 | r""" 46 | This warning indicates that some iterative procdure has not 47 | converged or reached the maximum number of iterations implemented 48 | as a safe guard to prevent arbitrary many iterations in loops with 49 | a conditional termination criterion. 50 | 51 | """ -------------------------------------------------------------------------------- /tests/estimation/tests/test_likelihood.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | import unittest 20 | 21 | import numpy as np 22 | from tests.numeric import assert_allclose 23 | import scipy.sparse 24 | 25 | from msmtools.estimation import log_likelihood 26 | 27 | """Unit tests for the transition_matrix module""" 28 | 29 | 30 | class TestTransitionMatrix(unittest.TestCase): 31 | def setUp(self): 32 | """Small test cases""" 33 | self.C1 = scipy.sparse.csr_matrix([[1, 3], [3, 1]]) 34 | 35 | self.T1 = scipy.sparse.csr_matrix([[0.8, 0.2], [0.9, 0.1]]) 36 | 37 | """Zero row sum throws an error""" 38 | self.T0 = scipy.sparse.csr_matrix([[0, 1], [0.9, 0.1]]) 39 | 40 | def tearDown(self): 41 | pass 42 | 43 | def test_count_matrix(self): 44 | """Small test cases""" 45 | log = log_likelihood(self.C1, self.T1) 46 | assert_allclose(log, np.log(0.8 * 0.2 ** 3 * 0.9 ** 3 * 0.1)) 47 | 48 | 49 | if __name__ == "__main__": 50 | unittest.main() 51 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/src/util.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #ifndef __util_h_ 20 | #define __util_h_ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | 28 | int my_isinf(double x) { 29 | #if _MSC_VER && !__INTEL_COMPILER 30 | return ! _finite(x); 31 | #else 32 | return isinf(x); 33 | #endif 34 | } 35 | 36 | int my_isnan(double x) { 37 | #if _MSC_VER && !__INTEL_COMPILER 38 | return _isnan(x); 39 | #else 40 | return isnan(x); 41 | #endif 42 | } 43 | 44 | /** 45 | Helper function, tests if x is numerically positive 46 | 47 | :param x: 48 | :return: 49 | */ 50 | int 51 | is_positive(double x) 52 | { 53 | double eps = 1e-15; 54 | if (x >= eps && !my_isinf(x) && !my_isnan(x)) 55 | return 1; 56 | else 57 | return 0; 58 | } 59 | 60 | double my_fmin(double a, double b) { 61 | #if _MSC_VER && !__INTEL_COMPILER 62 | return __min(a,b); 63 | #else 64 | return fmin(a,b); 65 | #endif 66 | } 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /tests/estimation/tests/test_bootstrapping.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | ''' 20 | Created on Jul 25, 2014 21 | 22 | @author: noe 23 | ''' 24 | import unittest 25 | import numpy as np 26 | import msmtools.estimation as msmest 27 | 28 | 29 | class TestBootstrapping(unittest.TestCase): 30 | 31 | def validate_counts(self, ntraj, length, n, tau): 32 | dtrajs = [] 33 | for i in range(ntraj): 34 | dtrajs.append(np.random.randint(0, n, size=length)) 35 | for i in range(10): 36 | C = msmest.bootstrap_counts(dtrajs, tau).toarray() 37 | assert(np.shape(C) == (n, n)) 38 | assert(np.sum(C) == (ntraj*length) / tau) 39 | 40 | def test_bootstrap_counts(self): 41 | self.validate_counts(1, 10000, 10, 10) 42 | self.validate_counts(1, 10000, 100, 1000) 43 | self.validate_counts(10, 100, 2, 10) 44 | self.validate_counts(10, 1000, 100, 100) 45 | self.validate_counts(1000, 10, 1000, 1) 46 | 47 | 48 | if __name__ == "__main__": 49 | unittest.main() 50 | -------------------------------------------------------------------------------- /tests/estimation/impl/sparse/likelihood_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | import unittest 20 | 21 | import numpy as np 22 | from tests.numeric import assert_allclose 23 | import scipy.sparse 24 | 25 | from msmtools.estimation.sparse import likelihood 26 | 27 | """Unit tests for the transition_matrix module""" 28 | 29 | 30 | class TestTransitionMatrix(unittest.TestCase): 31 | def setUp(self): 32 | """Small test cases""" 33 | self.C1 = scipy.sparse.csr_matrix([[1, 3], [3, 1]]) 34 | 35 | self.T1 = scipy.sparse.csr_matrix([[0.8, 0.2], [0.9, 0.1]]) 36 | 37 | """Zero row sum throws an error""" 38 | self.T0 = scipy.sparse.csr_matrix([[0, 1], [0.9, 0.1]]) 39 | 40 | def tearDown(self): 41 | pass 42 | 43 | def test_count_matrix(self): 44 | """Small test cases""" 45 | log = likelihood.log_likelihood(self.C1, self.T1) 46 | assert_allclose(log, np.log(0.8 * 0.2 ** 3 * 0.9 ** 3 * 0.1)) 47 | 48 | 49 | if __name__ == "__main__": 50 | unittest.main() 51 | -------------------------------------------------------------------------------- /tests/estimation/impl/sparse/newton/mle_rev_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit test for the reversible mle newton module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | import unittest 26 | 27 | from os.path import abspath, join 28 | from os import pardir 29 | 30 | import numpy as np 31 | from scipy.sparse import csr_matrix 32 | 33 | from tests.numeric import assert_allclose 34 | from msmtools.estimation.sparse.mle.newton.mle_rev import solve_mle_rev 35 | 36 | testpath = abspath(join(abspath(__file__), pardir)) + '/testfiles/' 37 | 38 | 39 | class TestReversibleEstimatorNewton(unittest.TestCase): 40 | def setUp(self): 41 | """Count matrix for bith-death chain with 100 states""" 42 | self.C = np.loadtxt(testpath + 'C.dat') 43 | self.P_ref = self.C/self.C.sum(axis=1)[:,np.newaxis] 44 | 45 | def test_estimator(self): 46 | P, pi = solve_mle_rev(csr_matrix(self.C)) 47 | assert_allclose(P.toarray(), self.P_ref) 48 | 49 | 50 | if __name__ == "__main__": 51 | unittest.main() 52 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | SHELL := /bin/bash 5 | PYVER = 2.7 6 | PYTHON = python$(PYVER) 7 | 8 | # You can set these variables from the command line. 9 | SPHINXOPTS = -j8 -v 10 | SPHINXBUILD = LANG=C sphinx-build 11 | PAPER = 12 | 13 | FILES= 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 19 | 20 | # ipython notebook index file 21 | NBCONVERT_CONFIG = $(realpath jupyter_nbconvert_config.py) 22 | NBCONVERT_CMD = jupyter nbconvert $(nbflags) --config $(NBCONVERT_CONFIG) 23 | 24 | .PHONY: help clean html ipython-rst 25 | 26 | #------------------------------------------------------------------------------ 27 | all: html 28 | help: 29 | @echo "Please use \`make ' where is one of" 30 | @echo " html to make standalone HTML files" 31 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 32 | 33 | clean: 34 | -rm -rf build/* source/generated source/api/generated 35 | 36 | html: 37 | mkdir -p build/html build/doctrees 38 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html $(FILES) 39 | @echo 40 | @echo "Build finished. The HTML pages are in build/html." 41 | 42 | source/generated: 43 | mkdir -p source/generated 44 | 45 | ipython-rst: source/generated 46 | @$(eval nb_names:= $$(shell grep generated source/ipython.rst | sed -re 's/\s+generated\/(.+)/\/\1.ipynb|/g')) 47 | @$(eval notebooks:= $$(shell find ../pyemma-ipython -name *.ipynb | grep -E "$(nb_names)" )) 48 | cd source/generated 49 | pwd 50 | set -x; for nb in $(notebooks); do $(NBCONVERT_CMD) $$nb || true; done 51 | @echo "Conversion finished." 52 | 53 | latex: 54 | mkdir -p build/latex build/doctrees 55 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex $(FILES) 56 | 57 | html_check: 58 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/html $(FILES) 59 | 60 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/src/sample_rev.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | /* * moduleauthor:: F. Noe 20 | */ 21 | 22 | #ifndef _sample_rev_h_ 23 | #define _sample_rev_h_ 24 | 25 | double _update_step(double v0, double v1, double v2, double c0, double c1, double c2, int random_walk_stepsize); 26 | double _sum_all(double* X, int n); 27 | void _normalize_all(double* X, int n); 28 | void _normalize_all_sparse(double* X, int* I, int* J, int n, int n_idx); 29 | double _sum_row(double* X, int n, int i); 30 | void _update(double* C, double* sumC, double* X, int n, int n_step); 31 | void _update_sparse_sparse(double* C, double* sumC, double* X, double* sumX, int* I, int* J, int n, int n_idx, int n_step); 32 | 33 | void _print_matrix(double* X, int n); 34 | void _update_sparse_speedtest(double* C, double* sumC, double* X, double* sumX, int* I, int* J, int n, int n_idx, int n_step); 35 | 36 | 37 | // declarations 38 | void _update_sparse(double* C, double* sumC, double* X, double* sumX, int* I, int* J, int n, int n_idx, int n_step); 39 | void _generate_row_indexes(int* I, int n, int n_idx, int* row_indexes); 40 | void _normalize_all(double* X, int n); 41 | 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /tests/analysis/impl/dense/committor_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit tests for the committor module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | import unittest 26 | import numpy as np 27 | from msmtools.util.birth_death_chain import BirthDeathChain 28 | from tests.numeric import assert_allclose 29 | 30 | from msmtools.analysis.dense import committor 31 | 32 | 33 | class TestCommittor(unittest.TestCase): 34 | def setUp(self): 35 | p = np.zeros(10) 36 | q = np.zeros(10) 37 | p[0:-1] = 0.5 38 | q[1:] = 0.5 39 | p[4] = 0.01 40 | q[6] = 0.1 41 | 42 | self.bdc = BirthDeathChain(q, p) 43 | 44 | def test_forward_comittor(self): 45 | P = self.bdc.transition_matrix() 46 | un = committor.forward_committor(P, [0, 1], [8, 9]) 47 | u = self.bdc.committor_forward(1, 8) 48 | assert_allclose(un, u) 49 | 50 | def test_backward_comittor(self): 51 | P = self.bdc.transition_matrix() 52 | un = committor.backward_committor(P, [0, 1], [8, 9]) 53 | u = self.bdc.committor_backward(1, 8) 54 | assert_allclose(un, u) 55 | 56 | 57 | if __name__ == "__main__": 58 | unittest.main() 59 | -------------------------------------------------------------------------------- /msmtools/flux/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r""" 20 | 21 | ==================================================================== 22 | flux - Reactive flux an transition pathways (:mod:`msmtools.flux`) 23 | ==================================================================== 24 | 25 | .. currentmodule:: msmtools.flux 26 | 27 | This module contains functions to compute reactive flux networks and 28 | find dominant reaction pathways in such networks. 29 | 30 | TPT-object 31 | ========== 32 | 33 | .. autosummary:: 34 | :toctree: generated/ 35 | 36 | tpt 37 | ReactiveFlux 38 | 39 | Reactive flux 40 | ============= 41 | 42 | .. autosummary:: 43 | :toctree: generated/ 44 | 45 | flux_matrix - TPT flux network 46 | to_netflux - Netflux from gross flux 47 | flux_production - Net flux-production for all states 48 | flux_producers 49 | flux_consumers 50 | coarsegrain 51 | 52 | Reaction rates and fluxes 53 | ========================= 54 | 55 | .. autosummary:: 56 | :toctree: generated/ 57 | 58 | total_flux 59 | rate 60 | mfpt 61 | 62 | 63 | Pathway decomposition 64 | ===================== 65 | 66 | .. autosummary:: 67 | :toctree: generated/ 68 | 69 | pathways 70 | 71 | """ 72 | 73 | from .api import * 74 | from .reactive_flux import * 75 | -------------------------------------------------------------------------------- /msmtools/dtraj/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r""" 20 | 21 | =============================================================== 22 | dtraj - Discrete trajectories functions (:mod:`msmtools.dtraj`) 23 | =============================================================== 24 | 25 | .. currentmodule:: msmtools.dtraj 26 | 27 | Discrete trajectory io 28 | ====================== 29 | 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | read_discrete_trajectory - read microstate trajectory from ascii file 34 | read_dtraj 35 | write_discrete_trajectory - write microstate trajectory to ascii file 36 | write_dtraj 37 | load_discrete_trajectory - read microstate trajectory from biqqnary file 38 | load_dtraj 39 | save_discrete_trajectory - write microstate trajectory to binary file 40 | save_dtraj 41 | 42 | Simple statistics 43 | ================= 44 | 45 | .. autosummary:: 46 | :toctree: generated/ 47 | 48 | count_states 49 | visited_set 50 | number_of_states 51 | index_states 52 | 53 | Sampling trajectory indexes 54 | =========================== 55 | 56 | .. autosummary:: 57 | :toctree: generated/ 58 | 59 | sample_indexes_by_distribution 60 | sample_indexes_by_state 61 | sample_indexes_by_sequence 62 | 63 | """ 64 | 65 | from .api import * 66 | -------------------------------------------------------------------------------- /tests/estimation/impl/sparse/transition_matrix_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | import unittest 20 | 21 | from tests.numeric import assert_allclose 22 | import scipy.sparse 23 | 24 | from msmtools.estimation.sparse import transition_matrix 25 | 26 | """Unit tests for the transition_matrix module""" 27 | 28 | 29 | class TestTransitionMatrixNonReversible(unittest.TestCase): 30 | def setUp(self): 31 | """Small test cases""" 32 | self.C1 = scipy.sparse.csr_matrix([[1, 3], [3, 1]]) 33 | self.C2 = scipy.sparse.csr_matrix([[0, 2], [1, 1]]) 34 | 35 | self.T1 = scipy.sparse.csr_matrix([[0.25, 0.75], [0.75, 0.25]]) 36 | self.T2 = scipy.sparse.csr_matrix([[0, 1], [0.5, 0.5]]) 37 | 38 | """Zero row sum throws an error""" 39 | self.C0 = scipy.sparse.csr_matrix([[0, 0], [3, 1]]) 40 | 41 | def tearDown(self): 42 | pass 43 | 44 | def test_count_matrix(self): 45 | """Small test cases""" 46 | T = transition_matrix.transition_matrix_non_reversible(self.C1).toarray() 47 | assert_allclose(T, self.T1.toarray()) 48 | 49 | T = transition_matrix.transition_matrix_non_reversible(self.C1).toarray() 50 | assert_allclose(T, self.T1.toarray()) 51 | 52 | 53 | if __name__ == "__main__": 54 | unittest.main() 55 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/sampler_nrev.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Transition matrix sampling for non-reversible stochastic matrices. 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | import numpy as np 26 | 27 | from ....analysis import stationary_distribution 28 | 29 | 30 | def update_nrev(alpha, P): 31 | N = alpha.shape[0] 32 | for i in range(N): 33 | # only pass positive alphas to dirichlet sampling. 34 | positive = alpha[i, :] > 0 35 | P[i, positive] = np.random.dirichlet(alpha[i, positive]) 36 | 37 | 38 | class SamplerNonRev(object): 39 | def __init__(self, Z): 40 | """Posterior counts""" 41 | self.Z = 1.0*Z 42 | """Alpha parameters for dirichlet sampling""" 43 | self.alpha = Z + 1.0 44 | """Initial state from single sample""" 45 | self.P = np.zeros_like(Z) 46 | self.update() 47 | 48 | def update(self, N=1): 49 | update_nrev(self.alpha, self.P) 50 | 51 | def sample(self, N=1, return_statdist=False): 52 | self.update(N=N) 53 | if return_statdist: 54 | pi = stationary_distribution(self.P) 55 | return self.P, pi 56 | else: 57 | return self.P 58 | -------------------------------------------------------------------------------- /tests/util/testfiles/spmatrix_float.coo.dat: -------------------------------------------------------------------------------- 1 | 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 2 | 2.000000000000000000e+00 2.000000000000000000e+00 2.000000000000000000e+00 3 | 3.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 4 | 4.000000000000000000e+00 4.000000000000000000e+00 4.000000000000000000e+00 5 | 5.000000000000000000e+00 5.000000000000000000e+00 5.000000000000000000e+00 6 | 6.000000000000000000e+00 6.000000000000000000e+00 6.000000000000000000e+00 7 | 7.000000000000000000e+00 7.000000000000000000e+00 7.000000000000000000e+00 8 | 8.000000000000000000e+00 8.000000000000000000e+00 8.000000000000000000e+00 9 | 9.000000000000000000e+00 9.000000000000000000e+00 9.000000000000000000e+00 10 | 0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+01 11 | 1.000000000000000000e+00 2.000000000000000000e+00 1.100000000000000000e+01 12 | 2.000000000000000000e+00 3.000000000000000000e+00 1.200000000000000000e+01 13 | 3.000000000000000000e+00 4.000000000000000000e+00 1.300000000000000000e+01 14 | 4.000000000000000000e+00 5.000000000000000000e+00 1.400000000000000000e+01 15 | 5.000000000000000000e+00 6.000000000000000000e+00 1.500000000000000000e+01 16 | 6.000000000000000000e+00 7.000000000000000000e+00 1.600000000000000000e+01 17 | 7.000000000000000000e+00 8.000000000000000000e+00 1.700000000000000000e+01 18 | 8.000000000000000000e+00 9.000000000000000000e+00 1.800000000000000000e+01 19 | 1.000000000000000000e+00 0.000000000000000000e+00 2.000000000000000000e+01 20 | 2.000000000000000000e+00 1.000000000000000000e+00 2.100000000000000000e+01 21 | 3.000000000000000000e+00 2.000000000000000000e+00 2.200000000000000000e+01 22 | 4.000000000000000000e+00 3.000000000000000000e+00 2.300000000000000000e+01 23 | 5.000000000000000000e+00 4.000000000000000000e+00 2.400000000000000000e+01 24 | 6.000000000000000000e+00 5.000000000000000000e+00 2.500000000000000000e+01 25 | 7.000000000000000000e+00 6.000000000000000000e+00 2.600000000000000000e+01 26 | 8.000000000000000000e+00 7.000000000000000000e+00 2.700000000000000000e+01 27 | 9.000000000000000000e+00 8.000000000000000000e+00 2.800000000000000000e+01 28 | -------------------------------------------------------------------------------- /tests/analysis/impl/sparse/committor_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit tests for the committor module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | import unittest 25 | import numpy as np 26 | from msmtools.util.birth_death_chain import BirthDeathChain 27 | from tests.numeric import assert_allclose 28 | 29 | from msmtools.analysis.sparse import committor 30 | 31 | 32 | class TestCommittor(unittest.TestCase): 33 | def setUp(self): 34 | p = np.zeros(100) 35 | q = np.zeros(100) 36 | p[0:-1] = 0.5 37 | q[1:] = 0.5 38 | p[49] = 0.01 39 | q[51] = 0.1 40 | 41 | self.bdc = BirthDeathChain(q, p) 42 | 43 | def tearDown(self): 44 | pass 45 | 46 | def test_forward_comittor(self): 47 | P = self.bdc.transition_matrix_sparse() 48 | un = committor.forward_committor(P, list(range(10)), list(range(90, 100))) 49 | u = self.bdc.committor_forward(9, 90) 50 | assert_allclose(un, u) 51 | 52 | def test_backward_comittor(self): 53 | P = self.bdc.transition_matrix_sparse() 54 | un = committor.backward_committor(P, list(range(10)), list(range(90, 100))) 55 | u = self.bdc.committor_backward(9, 90) 56 | assert_allclose(un, u) 57 | 58 | 59 | if __name__ == "__main__": 60 | unittest.main() 61 | -------------------------------------------------------------------------------- /tests/analysis/impl/dense/stationary_vector_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | import unittest 21 | import numpy as np 22 | from msmtools.util.birth_death_chain import BirthDeathChain 23 | from tests.numeric import assert_allclose 24 | 25 | from msmtools.analysis.dense.stationary_vector import stationary_distribution_from_eigenvector 26 | from msmtools.analysis.dense.stationary_vector import stationary_distribution_from_backward_iteration 27 | 28 | 29 | class TestStationaryVector(unittest.TestCase): 30 | def setUp(self): 31 | self.dim = 100 32 | self.k = 10 33 | 34 | """Set up meta-stable birth-death chain""" 35 | p = np.zeros(self.dim) 36 | p[0:-1] = 0.5 37 | 38 | q = np.zeros(self.dim) 39 | q[1:] = 0.5 40 | 41 | p[self.dim // 2 - 1] = 0.001 42 | q[self.dim // 2 + 1] = 0.001 43 | 44 | self.bdc = BirthDeathChain(q, p) 45 | 46 | def test_statdist_decomposition(self): 47 | P = self.bdc.transition_matrix() 48 | mu = self.bdc.stationary_distribution() 49 | mun = stationary_distribution_from_eigenvector(P) 50 | assert_allclose(mu, mun) 51 | 52 | def test_statdist_iteration(self): 53 | P = self.bdc.transition_matrix() 54 | mu = self.bdc.stationary_distribution() 55 | mun = stationary_distribution_from_backward_iteration(P) 56 | assert_allclose(mu, mun) 57 | 58 | if __name__ == "__main__": 59 | unittest.main() 60 | -------------------------------------------------------------------------------- /tests/analysis/impl/dense/assessment_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | ''' 20 | Created on 07.10.2013 21 | 22 | @author: marscher 23 | ''' 24 | import unittest 25 | import numpy as np 26 | from msmtools.util.birth_death_chain import BirthDeathChain 27 | 28 | from msmtools.analysis.dense import assessment 29 | 30 | 31 | class RateMatrixTest(unittest.TestCase): 32 | 33 | def setUp(self): 34 | self.A = np.array( 35 | [[-3, 3, 0, 0], 36 | [3, -5, 2, 0], 37 | [0, 3, -5, 2], 38 | [0, 0, 3, -3]] 39 | ) 40 | 41 | def testIsRateMatrix(self): 42 | self.assertTrue(assessment.is_rate_matrix(self.A), 'A should be a rate matrix') 43 | 44 | # manipulate matrix so it isn't a rate matrix any more 45 | self.A[0][0] = 3 46 | self.assertFalse(assessment.is_rate_matrix(self.A), 'matrix is not a rate matrix') 47 | 48 | 49 | class ReversibleTest(unittest.TestCase): 50 | 51 | def setUp(self): 52 | p = np.zeros(10) 53 | q = np.zeros(10) 54 | p[0:-1] = 0.5 55 | q[1:] = 0.5 56 | p[4] = 0.01 57 | q[6] = 0.1 58 | 59 | self.bdc = BirthDeathChain(q, p) 60 | self.T = self.bdc.transition_matrix() 61 | self.mu = self.bdc.stationary_distribution() 62 | 63 | def testIsReversible(self): 64 | # create a reversible matrix 65 | self.assertTrue(assessment.is_reversible(self.T, self.mu), "T should be reversible") 66 | 67 | 68 | if __name__ == "__main__": 69 | unittest.main() 70 | -------------------------------------------------------------------------------- /msmtools/analysis/dense/hitting_probability.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Dense implementation of hitting probabilities 20 | 21 | .. moduleauthor:: F.Noe 22 | 23 | """ 24 | 25 | import numpy as np 26 | 27 | 28 | def hitting_probability(P, target): 29 | """ 30 | Computes the hitting probabilities for all states to the target states. 31 | 32 | The hitting probability of state i to set A is defined as the minimal, 33 | non-negative solution of: 34 | 35 | .. math:: 36 | h_i^A &= 1 \:\:\:\: i\in A \\ 37 | h_i^A &= \sum_j p_{ij} h_i^A \:\:\:\: i \notin A 38 | 39 | Returns 40 | ======= 41 | h : ndarray(n) 42 | a vector with hitting probabilities 43 | """ 44 | if hasattr(target, "__len__"): 45 | target = np.array(target) 46 | else: 47 | target = np.array([target]) 48 | # target size 49 | n = np.shape(P)[0] 50 | # nontarget 51 | nontarget = np.array(list(set(range(n)) - set(target)), dtype=int) 52 | # stable states 53 | stable = np.where(np.isclose(np.diag(P), 1) == True)[0] 54 | # everything else 55 | origin = np.array(list(set(nontarget) - set(stable)), dtype=int) 56 | # solve hitting probability problem (P-I)x = -b 57 | A = P[origin, :][:, origin] - np.eye((len(origin))) 58 | b = np.sum(-P[origin, :][:, target], axis=1) 59 | x = np.linalg.solve(A, b) 60 | # fill up full solution with 0's for stable states and 1's for target 61 | xfull = np.ones((n)) 62 | xfull[origin] = x 63 | xfull[target] = 1 64 | xfull[stable] = 0 65 | 66 | return xfull 67 | -------------------------------------------------------------------------------- /tests/analysis/impl/sparse/stationary_vector_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Test package for the decomposition module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | import unittest 25 | 26 | import numpy as np 27 | from msmtools.util.birth_death_chain import BirthDeathChain 28 | from tests.numeric import assert_allclose 29 | 30 | from msmtools.analysis.sparse.stationary_vector import stationary_distribution_from_eigenvector 31 | from msmtools.analysis.sparse.stationary_vector import stationary_distribution_from_backward_iteration 32 | 33 | 34 | class TestStationaryVector(unittest.TestCase): 35 | def setUp(self): 36 | self.dim = 100 37 | self.k = 10 38 | self.ncv = 40 39 | 40 | """Set up meta-stable birth-death chain""" 41 | p = np.zeros(self.dim) 42 | p[0:-1] = 0.5 43 | 44 | q = np.zeros(self.dim) 45 | q[1:] = 0.5 46 | 47 | p[self.dim // 2 - 1] = 0.001 48 | q[self.dim // 2 + 1] = 0.001 49 | 50 | self.bdc = BirthDeathChain(q, p) 51 | 52 | def test_statdist_decomposition(self): 53 | P = self.bdc.transition_matrix_sparse() 54 | mu = self.bdc.stationary_distribution() 55 | mun = stationary_distribution_from_eigenvector(P, ncv=self.ncv) 56 | assert_allclose(mu, mun) 57 | 58 | def test_statdist_iteration(self): 59 | P = self.bdc.transition_matrix_sparse() 60 | mu = self.bdc.stationary_distribution() 61 | mun = stationary_distribution_from_backward_iteration(P) 62 | assert_allclose(mu, mun) 63 | 64 | if __name__ == "__main__": 65 | unittest.main() 66 | -------------------------------------------------------------------------------- /msmtools/estimation/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r""" 20 | 21 | ==================================================================== 22 | estimation - MSM estimation from data (:mod:`msmtools.estimation`) 23 | ==================================================================== 24 | 25 | .. currentmodule:: msmtools.estimation 26 | 27 | Countmatrix 28 | =========== 29 | 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | count_matrix - estimate count matrix from discrete trajectories 34 | cmatrix - estimate count matrix from discrete trajectories 35 | 36 | Connectivity 37 | ============ 38 | 39 | .. autosummary:: 40 | :toctree: generated/ 41 | 42 | connected_sets - Find connected subsets 43 | largest_connected_set - Find largest connected set 44 | largest_connected_submatrix - Count matrix on largest connected set 45 | connected_cmatrix 46 | is_connected - Test count matrix connectivity 47 | 48 | Estimation 49 | ========== 50 | 51 | .. autosummary:: 52 | :toctree: generated/ 53 | 54 | transition_matrix - Estimate transition matrix 55 | tmatrix 56 | rate_matrix 57 | log_likelihood 58 | tmatrix_cov 59 | error_perturbation 60 | 61 | 62 | Sampling 63 | ======== 64 | 65 | .. autosummary:: 66 | :toctree: generated/ 67 | 68 | tmatrix_sampler - Random sample from transition matrix posterior 69 | 70 | Bootstrap 71 | ========= 72 | 73 | .. autosummary:: 74 | :toctree: generated/ 75 | 76 | bootstrap_counts 77 | bootstrap_trajectories 78 | 79 | Priors 80 | ====== 81 | 82 | .. autosummary:: 83 | :toctree: generated/ 84 | 85 | prior_neighbor 86 | prior_const 87 | prior_rev 88 | 89 | 90 | """ 91 | from .api import * 92 | -------------------------------------------------------------------------------- /tests/util/testfiles/spmatrix_float_reference.dat: -------------------------------------------------------------------------------- 1 | 0.000000000000000000e+00 1.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2 | 2.000000000000000000e+01 1.000000000000000000e+00 1.100000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 3 | 0.000000000000000000e+00 2.100000000000000000e+01 2.000000000000000000e+00 1.200000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 2.200000000000000000e+01 3.000000000000000000e+00 1.300000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 5 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.300000000000000000e+01 4.000000000000000000e+00 1.400000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 6 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.400000000000000000e+01 5.000000000000000000e+00 1.500000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 7 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.500000000000000000e+01 6.000000000000000000e+00 1.600000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 8 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.600000000000000000e+01 7.000000000000000000e+00 1.700000000000000000e+01 0.000000000000000000e+00 9 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.700000000000000000e+01 8.000000000000000000e+00 1.800000000000000000e+01 10 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.800000000000000000e+01 9.000000000000000000e+00 11 | -------------------------------------------------------------------------------- /tests/flux/impl/sparse/pathways_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit test for the pathways-module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | import unittest 26 | import numpy as np 27 | from scipy.sparse import csr_matrix 28 | 29 | from msmtools.flux.sparse.pathways import pathways 30 | from msmtools.flux.sparse.tpt import flux_matrix 31 | from msmtools.analysis import committor, statdist 32 | from tests.numeric import assert_allclose 33 | 34 | class TestPathways(unittest.TestCase): 35 | 36 | def setUp(self): 37 | P = np.array([[0.8, 0.15, 0.05, 0.0, 0.0], 38 | [0.1, 0.75, 0.05, 0.05, 0.05], 39 | [0.05, 0.1, 0.8, 0.0, 0.05], 40 | [0.0, 0.2, 0.0, 0.8, 0.0], 41 | [0.0, 0.02, 0.02, 0.0, 0.96]]) 42 | P = csr_matrix(P) 43 | A = [0] 44 | B = [4] 45 | mu = statdist(P) 46 | qminus = committor(P, A, B, forward=False, mu=mu) 47 | qplus = committor(P, A, B, forward=True, mu=mu) 48 | self.A = A 49 | self.B = B 50 | self.F = flux_matrix(P, mu, qminus, qplus, netflux=True) 51 | 52 | self.paths = [np.array([0, 1, 4]), np.array([0, 2, 4]), np.array([0, 1, 2, 4])] 53 | self.capacities = [0.0072033898305084252, 0.0030871670702178975, 0.00051452784503631509] 54 | def test_pathways(self): 55 | paths, capacities = pathways(self.F, self.A, self.B) 56 | assert_allclose(capacities, self.capacities) 57 | N = len(paths) 58 | for i in range(N): 59 | self.assertTrue(np.all(paths[i] == self.paths[i])) 60 | 61 | 62 | if __name__=="__main__": 63 | unittest.main() 64 | -------------------------------------------------------------------------------- /tests/analysis/impl/dense/hitting_probability_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit test, dense implementation of hitting probabilities 20 | 21 | .. moduleauthor:: F.Noe 22 | 23 | """ 24 | import unittest 25 | 26 | import numpy as np 27 | from tests.numeric import assert_allclose 28 | 29 | from msmtools.analysis.dense.hitting_probability import hitting_probability 30 | 31 | 32 | class TestHitting(unittest.TestCase): 33 | def setUp(self): 34 | pass 35 | 36 | def tearDown(self): 37 | pass 38 | 39 | def test_hitting1(self): 40 | P = np.array([[0., 1., 0.], 41 | [0., 1., 0.], 42 | [0., 0., 1.]]) 43 | sol = np.array([1, 0, 0]) 44 | assert_allclose(hitting_probability(P, 1), sol) 45 | assert_allclose(hitting_probability(P, [1, 2]), sol) 46 | 47 | def test_hitting2(self): 48 | P = np.array([[1.0, 0.0, 0.0, 0.0], 49 | [0.1, 0.8, 0.1, 0.0], 50 | [0.0, 0.0, 0.8, 0.2], 51 | [0.0, 0.0, 0.2, 0.8]]) 52 | sol = np.array([0., 0.5, 1., 1.]) 53 | assert_allclose(hitting_probability(P, [2, 3]), sol) 54 | 55 | def test_hitting3(self): 56 | P = np.array([[0.9, 0.1, 0.0, 0.0, 0.0], 57 | [0.1, 0.9, 0.0, 0.0, 0.0], 58 | [0.0, 0.1, 0.4, 0.5, 0.0], 59 | [0.0, 0.0, 0.0, 0.8, 0.2], 60 | [0.0, 0.0, 0.0, 0.2, 0.8]]) 61 | sol = np.array([0.0, 0.0, 8.33333333e-01, 1.0, 1.0]) 62 | assert_allclose(hitting_probability(P, 3), sol) 63 | assert_allclose(hitting_probability(P, [3, 4]), sol) 64 | 65 | 66 | if __name__ == "__main__": 67 | unittest.main() 68 | -------------------------------------------------------------------------------- /tests/estimation/impl/sparse/prior_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit test for the prior module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | import unittest 25 | 26 | import numpy as np 27 | from tests.numeric import assert_allclose 28 | 29 | from scipy.sparse import csr_matrix 30 | 31 | from msmtools.estimation.sparse import prior 32 | 33 | from msmtools.util.numeric import allclose_sparse 34 | 35 | 36 | class TestPrior(unittest.TestCase): 37 | def setUp(self): 38 | C = np.array([[4, 4, 0, 2], [4, 4, 1, 0], [0, 1, 4, 4], [0, 0, 4, 4]]) 39 | self.C = csr_matrix(C) 40 | 41 | self.alpha_def = 0.001 42 | self.alpha = -0.5 43 | 44 | B_neighbor = np.array([[1, 1, 0, 1], [1, 1, 1, 0], [0, 1, 1, 1], [1, 0, 1, 1]]) 45 | B_const = np.ones_like(C) 46 | B_rev = np.triu(B_const) 47 | 48 | self.B_neighbor = csr_matrix(B_neighbor) 49 | self.B_const = B_const 50 | self.B_rev = B_rev 51 | 52 | def tearDown(self): 53 | pass 54 | 55 | def test_prior_neighbor(self): 56 | Bn = prior.prior_neighbor(self.C) 57 | self.assertTrue(allclose_sparse(Bn, self.alpha_def * self.B_neighbor)) 58 | 59 | Bn = prior.prior_neighbor(self.C, alpha=self.alpha) 60 | self.assertTrue(allclose_sparse(Bn, self.alpha * self.B_neighbor)) 61 | 62 | def test_prior_const(self): 63 | Bn = prior.prior_const(self.C) 64 | assert_allclose(Bn, self.alpha_def * self.B_const) 65 | 66 | Bn = prior.prior_const(self.C, alpha=self.alpha) 67 | assert_allclose(Bn, self.alpha * self.B_const) 68 | 69 | def test_prior_rev(self): 70 | Bn = prior.prior_rev(self.C) 71 | assert_allclose(Bn, -1.0 * self.B_rev) 72 | 73 | Bn = prior.prior_rev(self.C, alpha=self.alpha) 74 | assert_allclose(Bn, self.alpha * self.B_rev) 75 | 76 | 77 | if __name__ == "__main__": 78 | unittest.main() 79 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/src/rnglib/ranlib.h: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #ifndef _RANLIB_ 20 | #define _RANLIB_ 21 | 22 | extern char ch_cap ( char ch ); 23 | extern float genbet ( float aa, float bb ); 24 | extern float genchi ( float df ); 25 | extern float genexp ( float av ); 26 | extern float genf ( float dfn, float dfd ); 27 | extern float gengam ( float a, float r ); 28 | extern float *genmn ( float parm[] ); 29 | extern int *genmul ( int n, float p[], int ncat ); 30 | extern float gennch ( float df, float xnonc ); 31 | extern float gennf ( float dfn, float dfd, float xnonc ); 32 | extern float gennor ( float av, float sd ); 33 | extern void genprm ( int iarray[], int n ); 34 | extern float genunf ( float low, float high ); 35 | extern int i4_max ( int i1, int i2 ); 36 | extern int i4_min ( int i1, int i2 ); 37 | extern int ignbin ( int n, float pp ); 38 | extern int ignnbn ( int n, float p ); 39 | extern int ignpoi ( float mu ); 40 | extern int ignuin ( int low, int high ); 41 | extern int lennob ( char *s ); 42 | extern void phrtsd ( char *phrase, int *seed1, int *seed2 ); 43 | extern void prcomp ( int maxobs, int p, float mean[], float xcovar[], float answer[] ); 44 | extern float r4_exp ( float x ); 45 | extern float r4_exponential_sample ( float lambda ); 46 | extern float r4_max ( float x, float y ); 47 | extern float r4_min ( float x, float y ); 48 | extern float r4vec_covar ( int n, float x[], float y[] ); 49 | extern int s_eqi ( char *s1, char *s2 ); 50 | extern float sdot ( int n, float dx[], int incx, float dy[], int incy ); 51 | extern float *setcov ( int p, float var[], float corr ); 52 | extern void setgmn ( float meanv[], float covm[], int p, float parm[] ); 53 | extern float sexpo (void); 54 | extern float sgamma ( float a ); 55 | extern float snorm (void); 56 | extern int spofa ( float a[], int lda, int n ); 57 | extern void stats ( float x[], int n, float *av, float *var, float *xmin, float *xmax ); 58 | extern void trstat ( char *pdf, float parin[], float *av, float *var ); 59 | 60 | #endif /* _RANLIB_ */ 61 | -------------------------------------------------------------------------------- /tests/flux/impl/dense/tpt_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit test for the TPT-module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | import unittest 26 | import numpy as np 27 | from msmtools.util.birth_death_chain import BirthDeathChain 28 | from tests.numeric import assert_allclose 29 | 30 | from msmtools.flux.dense import tpt 31 | 32 | 33 | class TestTPT(unittest.TestCase): 34 | def setUp(self): 35 | p = np.zeros(10) 36 | q = np.zeros(10) 37 | p[0:-1] = 0.5 38 | q[1:] = 0.5 39 | p[4] = 0.01 40 | q[6] = 0.1 41 | 42 | self.A = [0, 1] 43 | self.B = [8, 9] 44 | self.a = 1 45 | self.b = 8 46 | 47 | self.bdc = BirthDeathChain(q, p) 48 | self.T = self.bdc.transition_matrix() 49 | 50 | """Use precomputed mu, qminus, qplus""" 51 | self.mu = self.bdc.stationary_distribution() 52 | self.qplus = self.bdc.committor_forward(self.a, self.b) 53 | self.qminus = self.bdc.committor_backward(self.a, self.b) 54 | # self.qminus = committor.backward_committor(self.T, self.A, self.B, mu=self.mu) 55 | # self.qplus = committor.forward_committor(self.T, self.A, self.B) 56 | self.fluxn = tpt.flux_matrix(self.T, self.mu, self.qminus, self.qplus, netflux=False) 57 | self.netfluxn = tpt.to_netflux(self.fluxn) 58 | self.Fn = tpt.total_flux(self.fluxn, self.A) 59 | self.kn = tpt.rate(self.Fn, self.mu, self.qminus) 60 | 61 | def test_flux(self): 62 | flux = self.bdc.flux(self.a, self.b) 63 | assert_allclose(self.fluxn, flux) 64 | 65 | def test_netflux(self): 66 | netflux = self.bdc.netflux(self.a, self.b) 67 | assert_allclose(self.netfluxn, netflux) 68 | 69 | def test_totalflux(self): 70 | F = self.bdc.totalflux(self.a, self.b) 71 | assert_allclose(self.Fn, F) 72 | 73 | def test_rate(self): 74 | k = self.bdc.rate(self.a, self.b) 75 | assert_allclose(self.kn, k) 76 | 77 | 78 | if __name__ == "__main__": 79 | unittest.main() 80 | -------------------------------------------------------------------------------- /tests/analysis/test_committor.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit tests for the committor API-function 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | import unittest 26 | import numpy as np 27 | from tests.numeric import assert_allclose 28 | 29 | from msmtools.analysis import committor 30 | 31 | from msmtools.util.birth_death_chain import BirthDeathChain 32 | 33 | 34 | class TestCommittorDense(unittest.TestCase): 35 | def setUp(self): 36 | p = np.zeros(10) 37 | q = np.zeros(10) 38 | p[0:-1] = 0.5 39 | q[1:] = 0.5 40 | p[4] = 0.01 41 | q[6] = 0.1 42 | 43 | self.bdc = BirthDeathChain(q, p) 44 | 45 | def tearDown(self): 46 | pass 47 | 48 | def test_forward_comittor(self): 49 | P = self.bdc.transition_matrix() 50 | un = committor(P, [0, 1], [8, 9], forward=True) 51 | u = self.bdc.committor_forward(1, 8) 52 | assert_allclose(un, u) 53 | 54 | def test_backward_comittor(self): 55 | P = self.bdc.transition_matrix() 56 | un = committor(P, [0, 1], [8, 9], forward=False) 57 | u = self.bdc.committor_backward(1, 8) 58 | assert_allclose(un, u) 59 | 60 | 61 | class TestCommittorSparse(unittest.TestCase): 62 | def setUp(self): 63 | p = np.zeros(100) 64 | q = np.zeros(100) 65 | p[0:-1] = 0.5 66 | q[1:] = 0.5 67 | p[49] = 0.01 68 | q[51] = 0.1 69 | 70 | self.bdc = BirthDeathChain(q, p) 71 | 72 | def tearDown(self): 73 | pass 74 | 75 | def test_forward_comittor(self): 76 | P = self.bdc.transition_matrix_sparse() 77 | un = committor(P, list(range(10)), list(range(90, 100)), forward=True) 78 | u = self.bdc.committor_forward(9, 90) 79 | assert_allclose(un, u) 80 | 81 | def test_backward_comittor(self): 82 | P = self.bdc.transition_matrix_sparse() 83 | un = committor(P, list(range(10)), list(range(90, 100)), forward=False) 84 | u = self.bdc.committor_backward(9, 90) 85 | assert_allclose(un, u) 86 | 87 | if __name__ == "__main__": 88 | unittest.main() 89 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/transition_matrix.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | ''' 20 | Created on Jan 13, 2014 21 | 22 | @author: noe 23 | ''' 24 | 25 | import numpy as np 26 | 27 | 28 | def transition_matrix_non_reversible(C): 29 | r""" 30 | Estimates a non-reversible transition matrix from count matrix C 31 | 32 | T_ij = c_ij / c_i where c_i = sum_j c_ij 33 | 34 | Parameters 35 | ---------- 36 | C: ndarray, shape (n,n) 37 | count matrix 38 | 39 | Returns 40 | ------- 41 | T: Estimated transition matrix 42 | 43 | """ 44 | # multiply by 1.0 to make sure we're not doing integer division 45 | rowsums = 1.0 * np.sum(C, axis=1) 46 | if np.min(rowsums) <= 0: 47 | raise ValueError( 48 | "Transition matrix has row sum of " + str(np.min(rowsums)) + ". Must have strictly positive row sums.") 49 | return np.divide(C, rowsums[:, np.newaxis]) 50 | 51 | 52 | def transition_matrix_reversible_pisym(C, return_statdist=False, **kwargs): 53 | r""" 54 | Estimates reversible transition matrix as follows: 55 | 56 | ..:math: 57 | p_{ij} = c_{ij} / c_i where c_i = sum_j c_{ij} 58 | \pi_j = \sum_j \pi_i p_{ij} 59 | x_{ij} = \pi_i p_{ij} + \pi_j p_{ji} 60 | p^{rev}_{ij} = x_{ij} / x_i where x_i = sum_j x_{ij} 61 | 62 | In words: takes the nonreversible transition matrix estimate, uses its 63 | stationary distribution to compute an equilibrium correlation matrix, 64 | symmetrizes that correlation matrix and then normalizes to the reversible 65 | transition matrix estimate. 66 | 67 | Parameters 68 | ---------- 69 | C: ndarray, shape (n,n) 70 | count matrix 71 | 72 | Returns 73 | ------- 74 | T: Estimated transition matrix 75 | 76 | """ 77 | # nonreversible estimate 78 | T_nonrev = transition_matrix_non_reversible(C) 79 | from ...analysis import stationary_distribution 80 | pi = stationary_distribution(T_nonrev) 81 | # correlation matrix 82 | X = pi[:, None] * T_nonrev 83 | X = X.T + X 84 | # result 85 | T_rev = X / X.sum(axis=1)[:, None] 86 | if return_statdist: 87 | #np.testing.assert_allclose(pi, stationary_distribution(T_rev)) 88 | #np.testing.assert_allclose(T_rev.T.dot(pi), pi) 89 | return T_rev, pi 90 | return T_rev 91 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/mle/mle_trev_given_pi.pyx: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Cython implementation of iterative likelihood maximization. 20 | 21 | .. moduleauthor:: F. Paul 22 | 23 | """ 24 | 25 | import numpy 26 | cimport numpy 27 | import warnings 28 | 29 | from ....util.exceptions import NotConvergedWarning 30 | from ....analysis import is_connected 31 | 32 | 33 | cdef extern from "_mle_trev_given_pi.h": 34 | int _mle_trev_given_pi_dense(double * const T, const double * const C, const double * const mu, const int n, const double maxerr, const int maxiter) 35 | 36 | def mle_trev_given_pi( 37 | C, 38 | mu, 39 | double maxerr = 1.0E-12, 40 | int maxiter = 1000000, 41 | double eps = 0.0 42 | ): 43 | 44 | assert maxerr > 0, 'maxerr must be positive' 45 | assert maxiter > 0, 'maxiter must be positive' 46 | assert eps >= 0, 'eps must be non-negative' 47 | if eps>0: 48 | warnings.warn('A regularization parameter value eps!=0 is not necessary for convergence. The parameter will be removed in future versions.', DeprecationWarning) 49 | assert is_connected(C, directed=False), 'C must be (weakly) connected' 50 | 51 | cdef numpy.ndarray[double, ndim=2, mode="c"] c_C = C.astype(numpy.float64, order='C', copy=False) 52 | cdef numpy.ndarray[double, ndim=1, mode="c"] c_mu = mu.astype(numpy.float64, order='C', copy=False) 53 | 54 | assert c_C.shape[0]==c_C.shape[1]==c_mu.shape[0], 'Dimensions of C and mu don\'t agree.' 55 | 56 | cdef numpy.ndarray[double, ndim=2, mode="c"] T = numpy.zeros_like(c_C, dtype=numpy.float64, order='C') 57 | 58 | err = _mle_trev_given_pi_dense( 59 | numpy.PyArray_DATA(T), 60 | numpy.PyArray_DATA(c_C), 61 | numpy.PyArray_DATA(c_mu), 62 | c_C.shape[0], 63 | maxerr, 64 | maxiter) 65 | 66 | if err == -1: 67 | raise Exception('Out of memory.') 68 | elif err == -2: 69 | raise Exception('The update of the Lagrange multipliers produced NaN.') 70 | elif err == -3: 71 | raise Exception('Some row and corresponding column of C have zero counts.') 72 | elif err == -4: 73 | raise Exception('Some element of pi is zero.') 74 | elif err == -5: 75 | warnings.warn('Reversible transition matrix estimation with fixed stationary distribution didn\'t converge.', NotConvergedWarning) 76 | 77 | return T 78 | 79 | -------------------------------------------------------------------------------- /tests/dtraj/test_trajectory.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""This module contains unit tests for the trajectory module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | import os 25 | import unittest 26 | 27 | import numpy as np 28 | 29 | from os.path import abspath, join 30 | from os import pardir 31 | 32 | from msmtools.dtraj import read_discrete_trajectory, write_discrete_trajectory, \ 33 | load_discrete_trajectory, save_discrete_trajectory 34 | 35 | testpath = abspath(join(abspath(__file__), pardir)) + '/testfiles/' 36 | filename_csv = testpath + 'dtraj.dat' 37 | filename_npy = testpath + 'dtraj.npy' 38 | assert os.path.exists(filename_csv) 39 | assert os.path.exists(filename_npy) 40 | 41 | 42 | class TestReadDiscreteTrajectory(unittest.TestCase): 43 | 44 | def test_read_discrete_trajectory(self): 45 | dtraj_np = np.loadtxt(filename_csv, dtype=int) 46 | dtraj = read_discrete_trajectory(filename_csv) 47 | self.assertTrue(np.all(dtraj_np == dtraj)) 48 | 49 | 50 | class TestWriteDiscreteTrajectory(unittest.TestCase): 51 | def setUp(self): 52 | import tempfile 53 | self.filename = tempfile.mktemp(suffix='.dat') 54 | self.dtraj = np.arange(10000) 55 | 56 | def tearDown(self): 57 | os.remove(self.filename) 58 | 59 | def test_write_discrete_trajectory(self): 60 | write_discrete_trajectory(self.filename, self.dtraj) 61 | dtraj_n = np.loadtxt(self.filename) 62 | self.assertTrue(np.all(dtraj_n == self.dtraj)) 63 | 64 | 65 | class TestLoadDiscreteTrajectory(unittest.TestCase): 66 | def test_load_discrete_trajectory(self): 67 | dtraj_n = np.load(filename_npy) 68 | dtraj = load_discrete_trajectory(filename_npy) 69 | self.assertTrue(np.all(dtraj_n == dtraj)) 70 | 71 | 72 | class TestSaveDiscreteTrajectory(unittest.TestCase): 73 | def setUp(self): 74 | import tempfile 75 | self.filename = tempfile.mktemp(suffix='.npy') 76 | self.dtraj = np.arange(10000) 77 | 78 | def tearDown(self): 79 | os.remove(self.filename) 80 | 81 | def test_save_discrete_trajectory(self): 82 | save_discrete_trajectory(self.filename, self.dtraj) 83 | dtraj_n = np.load(self.filename) 84 | self.assertTrue(np.all(dtraj_n == self.dtraj)) 85 | 86 | 87 | if __name__ == "__main__": 88 | unittest.main() 89 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/count_matrix.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""This module implements the countmatrix estimation functionality 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | import numpy as np 26 | import scipy.sparse 27 | 28 | ################################################################################ 29 | # count_matrix 30 | ################################################################################ 31 | 32 | def count_matrix_coo2_mult(dtrajs, lag, sliding=True, sparse=True, nstates=None): 33 | r"""Generate a count matrix from a given list discrete trajectories. 34 | 35 | The generated count matrix is a sparse matrix in compressed 36 | sparse row (CSR) or numpy ndarray format. 37 | 38 | Parameters 39 | ---------- 40 | dtraj : list of ndarrays 41 | discrete trajectories 42 | lag : int 43 | Lagtime in trajectory steps 44 | sliding : bool, optional 45 | If true the sliding window approach 46 | is used for transition counting 47 | sparse : bool (optional) 48 | Whether to return a dense or a sparse matrix 49 | nstates : int, optional 50 | Enforce a count-matrix with shape=(nstates, nstates). If there are 51 | more states in the data, this will lead to an exception. 52 | 53 | Returns 54 | ------- 55 | C : scipy.sparse.csr_matrix or numpy.ndarray 56 | The countmatrix at given lag in scipy compressed sparse row 57 | or numpy ndarray format. 58 | 59 | """ 60 | # Determine number of states 61 | if nstates is None: 62 | from ...dtraj import number_of_states 63 | nstates = number_of_states(dtrajs) 64 | rows = [] 65 | cols = [] 66 | # collect transition index pairs 67 | for dtraj in dtrajs: 68 | if dtraj.size > lag: 69 | if (sliding): 70 | rows.append(dtraj[0:-lag]) 71 | cols.append(dtraj[lag:]) 72 | else: 73 | rows.append(dtraj[0:-lag:lag]) 74 | cols.append(dtraj[lag::lag]) 75 | # is there anything? 76 | if len(rows) == 0: 77 | raise ValueError('No counts found - lag ' + str(lag) + ' may exceed all trajectory lengths.') 78 | # feed into one COO matrix 79 | row = np.concatenate(rows) 80 | col = np.concatenate(cols) 81 | data = np.ones(row.size) 82 | C = scipy.sparse.coo_matrix((data, (row, col)), shape=(nstates, nstates)) 83 | # export to output format 84 | if sparse: 85 | return C.tocsr() 86 | else: 87 | return C.toarray() 88 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/mle/mle_trev.pyx: -------------------------------------------------------------------------------- 1 | # This file is part of MSMTools. 2 | # 3 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 4 | # 5 | # MSMTools is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | 18 | r"""Cython implementation of iterative likelihood maximization. 19 | 20 | .. moduleauthor:: F. Paul 21 | 22 | """ 23 | 24 | import numpy 25 | cimport numpy 26 | 27 | 28 | 29 | numpy.import_array() 30 | 31 | import warnings 32 | 33 | cdef extern from "_mle_trev.h": 34 | int _mle_trev_dense(double * const T, const double * const CCt, 35 | const double * const sum_C, const int dim, 36 | const double maxerr, const int maxiter, 37 | double * const mu, 38 | double eps_mu) 39 | 40 | 41 | def mle_trev(C, double maxerr=1.0E-12, int maxiter=int(1.0E6), 42 | warn_not_converged=True, return_statdist=False, 43 | eps_mu=1.0E-15): 44 | from ....analysis import is_connected 45 | from ....util.exceptions import NotConvergedWarning 46 | assert maxerr > 0, 'maxerr must be positive' 47 | assert maxiter > 0, 'maxiter must be positive' 48 | assert C.shape[0] == C.shape[1], 'C must be a square matrix.' 49 | assert is_connected(C, directed=True), 'C must be strongly connected' 50 | 51 | cdef numpy.ndarray[double, ndim=1, mode="c"] C_sum = C.sum(axis=1).astype(numpy.float64, order='C', copy=False) 52 | cdef numpy.ndarray[double, ndim=2, mode="c"] CCt = (C+C.T).astype(numpy.float64, order='C', copy=False) 53 | 54 | cdef numpy.ndarray[double, ndim=2, mode="c"] T = numpy.zeros(C.shape, dtype=numpy.float64, order='C') 55 | cdef numpy.ndarray[double, ndim=1, mode="c"] mu = numpy.zeros(C.shape[0], dtype=numpy.float64, order='C') 56 | err = _mle_trev_dense( 57 | numpy.PyArray_DATA(T), 58 | numpy.PyArray_DATA(CCt), 59 | numpy.PyArray_DATA(C_sum), 60 | CCt.shape[0], 61 | maxerr, 62 | maxiter, 63 | numpy.PyArray_DATA(mu), 64 | eps_mu) 65 | 66 | 67 | if err == -1: 68 | raise Exception('Out of memory.') 69 | elif err == -2: 70 | raise Exception('The update of the stationary distribution produced zero or NaN.') 71 | elif err == -3: 72 | raise Exception('Some row and corresponding column of C have zero counts.') 73 | elif err == -5 and warn_not_converged: 74 | warnings.warn('Reversible transition matrix estimation didn\'t converge.', 75 | NotConvergedWarning) 76 | elif err == -6: 77 | raise Exception("Stationary distribution contains entries smaller than %s during" 78 | " iteration" % eps_mu) 79 | 80 | if return_statdist: 81 | return T, mu 82 | else: 83 | return T 84 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/prior.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""This module provides functions for computation of prior count matrices 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | import numpy as np 26 | 27 | from scipy.sparse import coo_matrix 28 | 29 | 30 | def prior_neighbor(C, alpha=0.001): 31 | r"""Neighbor prior of strength alpha for the given count matrix. 32 | 33 | Prior is defined by 34 | b_ij = alpha if Z_ij+Z_ji > 0 35 | b_ij = 0 else 36 | 37 | Parameters 38 | ---------- 39 | C : (M, M) scipy.sparse matrix 40 | Count matrix 41 | alpha : float (optional) 42 | Value of prior counts 43 | 44 | Returns 45 | ------- 46 | B : (M, M) scipy.sparse matrix 47 | Prior count matrix 48 | 49 | """ 50 | C_sym = C + C.transpose() 51 | C_sym = C_sym.tocoo() 52 | data = C_sym.data 53 | row = C_sym.row 54 | col = C_sym.col 55 | 56 | data_B = alpha * np.ones_like(data) 57 | B = coo_matrix((data_B, (row, col))) 58 | return B 59 | 60 | 61 | def prior_const(C, alpha=0.001): 62 | """Constant prior of strength alpha. 63 | 64 | Prior is defined via 65 | 66 | b_ij=alpha for all i,j 67 | 68 | Parameters 69 | ---------- 70 | C : (M, M) ndarray or scipy.sparse matrix 71 | Count matrix 72 | alpha : float (optional) 73 | Value of prior counts 74 | 75 | Returns 76 | ------- 77 | B : (M, M) ndarray 78 | Prior count matrix 79 | 80 | """ 81 | B = alpha * np.ones(C.shape) 82 | return B 83 | 84 | 85 | def prior_rev(C, alpha=-1.0): 86 | r"""Prior counts for sampling of reversible transition 87 | matrices. 88 | 89 | Prior is defined as 90 | 91 | b_ij= alpha if i<=j 92 | b_ij=0 else 93 | 94 | The reversible prior adds -1 to the upper triagular part of 95 | the given count matrix. This prior respects the fact that 96 | for a reversible transition matrix the degrees of freedom 97 | correspond essentially to the upper, respectively the lower 98 | triangular part of the matrix. 99 | 100 | Parameters 101 | ---------- 102 | C : (M, M) ndarray or scipy.sparse matrix 103 | Count matrix 104 | alpha : float (optional) 105 | Value of prior counts 106 | 107 | Returns 108 | ------- 109 | B : (M, M) ndarray 110 | Matrix of prior counts 111 | 112 | """ 113 | ind = np.triu_indices(C.shape[0]) 114 | B = np.zeros(C.shape) 115 | B[ind] = alpha 116 | return B 117 | -------------------------------------------------------------------------------- /msmtools/analysis/dense/assessment.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | import numpy as np 20 | 21 | # import decomposition 22 | from .stationary_vector import stationary_distribution 23 | 24 | def is_transition_matrix(T, tol=1e-10): 25 | """ 26 | Tests whether T is a transition matrix 27 | 28 | Parameters 29 | ---------- 30 | T : ndarray shape=(n, n) 31 | matrix to test 32 | tol : float 33 | tolerance to check with 34 | 35 | Returns 36 | ------- 37 | Truth value : bool 38 | True, if all elements are in interval [0, 1] 39 | and each row of T sums up to 1. 40 | False, otherwise 41 | """ 42 | if T.ndim != 2: 43 | return False 44 | if T.shape[0] != T.shape[1]: 45 | return False 46 | dim = T.shape[0] 47 | X = np.abs(T) - T 48 | x = np.sum(T, axis=1) 49 | return np.abs(x - np.ones(dim)).max() < dim * tol and X.max() < 2.0 * tol 50 | 51 | 52 | def is_rate_matrix(K, tol=1e-10): 53 | """ 54 | True if K is a rate matrix 55 | Parameters 56 | ---------- 57 | K : numpy.ndarray matrix 58 | Matrix to check 59 | tol : float 60 | tolerance to check with 61 | 62 | Returns 63 | ------- 64 | Truth value : bool 65 | True, if K negated diagonal is positive and row sums up to zero. 66 | False, otherwise 67 | """ 68 | R = K - K.diagonal() 69 | off_diagonal_positive = np.allclose(R, abs(R), 0.0, atol=tol) 70 | 71 | row_sum = K.sum(axis=1) 72 | row_sum_eq_0 = np.allclose(row_sum, 0.0, atol=tol) 73 | 74 | return off_diagonal_positive and row_sum_eq_0 75 | 76 | 77 | def is_reversible(T, mu=None, tol=1e-10): 78 | r""" 79 | checks whether T is reversible in terms of given stationary distribution. 80 | If no distribution is given, it will be calculated out of T. 81 | 82 | It performs following check: 83 | :math:`\pi_i P_{ij} = \pi_j P_{ji}` 84 | 85 | Parameters 86 | ---------- 87 | T : numpy.ndarray matrix 88 | Transition matrix 89 | mu : numpy.ndarray vector 90 | stationary distribution 91 | tol : float 92 | tolerance to check with 93 | 94 | Returns 95 | ------- 96 | Truth value : bool 97 | True, if T is a reversible transitition matrix 98 | False, otherwise 99 | """ 100 | if is_transition_matrix(T, tol): 101 | if mu is None: 102 | mu = stationary_distribution(T) 103 | X = mu[:, np.newaxis] * T 104 | return np.allclose(X, np.transpose(X), atol=tol) 105 | else: 106 | raise ValueError("given matrix is not a valid transition matrix.") 107 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/mle/mle_trev.pyx: -------------------------------------------------------------------------------- 1 | r"""Cython implementation of iterative likelihood maximization. 2 | 3 | .. moduleauthor:: F. Paul 4 | 5 | """ 6 | 7 | import numpy 8 | import scipy 9 | import scipy.sparse 10 | cimport numpy 11 | numpy.import_array() 12 | 13 | import msmtools.estimation 14 | import warnings 15 | import msmtools.util.exceptions 16 | 17 | cdef extern from "_mle_trev.h": 18 | int _mle_trev_sparse(double * const T_data, const double * const CCt_data, 19 | const int * const i_indices, const int * const j_indices, 20 | const int len_CCt, const double * const sum_C, const int dim, 21 | const double maxerr, const int maxiter, 22 | double * const mu, 23 | double eps_mu) 24 | 25 | 26 | def mle_trev(C, double maxerr=1.0E-12, int maxiter=int(1.0E6), 27 | warn_not_converged=True, return_statdist=False, 28 | eps_mu=1.0E-15): 29 | 30 | assert maxerr > 0, 'maxerr must be positive' 31 | assert maxiter > 0, 'maxiter must be positive' 32 | assert C.shape[0] == C.shape[1], 'C must be a square matrix.' 33 | assert msmtools.estimation.is_connected(C, directed=True), 'C must be strongly connected' 34 | 35 | C_sum_py = C.sum(axis=1).A1 36 | cdef numpy.ndarray[double, ndim=1, mode="c"] C_sum = C_sum_py.astype(numpy.float64, order='C', copy=False) 37 | 38 | CCt = C+C.T 39 | # convert CCt to coo format 40 | CCt_coo = CCt.tocoo() 41 | n_data = CCt_coo.nnz 42 | cdef numpy.ndarray[double, ndim=1, mode="c"] CCt_data = CCt_coo.data.astype(numpy.float64, order='C', copy=False) 43 | cdef numpy.ndarray[int, ndim=1, mode="c"] i_indices = CCt_coo.row.astype(numpy.intc, order='C', copy=True) 44 | cdef numpy.ndarray[int, ndim=1, mode="c"] j_indices = CCt_coo.col.astype(numpy.intc, order='C', copy=True) 45 | 46 | # prepare data array of T in coo format 47 | cdef numpy.ndarray[double, ndim=1, mode="c"] T_data = numpy.zeros(n_data, dtype=numpy.float64, order='C') 48 | cdef numpy.ndarray[double, ndim=1, mode="c"] mu = numpy.zeros(C.shape[0], dtype=numpy.float64, order='C') 49 | err = _mle_trev_sparse( 50 | numpy.PyArray_DATA(T_data), 51 | numpy.PyArray_DATA(CCt_data), 52 | numpy.PyArray_DATA(i_indices), 53 | numpy.PyArray_DATA(j_indices), 54 | n_data, 55 | numpy.PyArray_DATA(C_sum), 56 | CCt.shape[0], 57 | maxerr, 58 | maxiter, 59 | numpy.PyArray_DATA(mu), 60 | eps_mu) 61 | 62 | 63 | if err == -1: 64 | raise Exception('Out of memory.') 65 | elif err == -2: 66 | raise Exception('The update of the stationary distribution produced zero or NaN.') 67 | elif err == -3: 68 | raise Exception('Some row and corresponding column of C have zero counts.') 69 | elif err == -5 and warn_not_converged: 70 | warnings.warn('Reversible transition matrix estimation didn\'t converge.', 71 | msmtools.util.exceptions.NotConvergedWarning) 72 | elif err == -6: 73 | raise Exception("Stationary distribution contains entries smaller than %s during" 74 | " iteration" % eps_mu) 75 | # T matrix has the same shape and positions of nonzero elements as CCt 76 | T = scipy.sparse.csr_matrix((T_data, (i_indices, j_indices)), shape=CCt.shape) 77 | T = msmtools.estimation.sparse.transition_matrix.correct_transition_matrix(T) 78 | if return_statdist: 79 | return T, mu 80 | else: 81 | return T 82 | -------------------------------------------------------------------------------- /msmtools/analysis/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r""" 20 | 21 | ============================================================== 22 | analysis - MSM analysis functions (:mod:`msmtools.analysis`) 23 | ============================================================== 24 | 25 | .. currentmodule:: msmtools.analysis 26 | 27 | This module contains functions to analyze a created Markov model, which is 28 | specified with a transition matrix T. 29 | 30 | Validation 31 | ========== 32 | 33 | .. autosummary:: 34 | :toctree: generated/ 35 | 36 | is_transition_matrix - Positive entries and rows sum to one 37 | is_tmatrix 38 | is_rate_matrix - Nonpositive off-diagonal entries and rows sum to zero 39 | is_connected - Irreducible matrix 40 | is_reversible - Symmetric with respect to some probability vector pi 41 | 42 | Decomposition 43 | ============= 44 | 45 | Decomposition routines use the scipy LAPACK bindings for dense 46 | numpy-arrays and the ARPACK bindings for scipy sparse matrices. 47 | 48 | .. autosummary:: 49 | :toctree: generated/ 50 | 51 | stationary_distribution - Invariant vector from eigendecomposition 52 | statdist 53 | eigenvalues - Spectrum via eigenvalue decomposition 54 | eigenvectors - Right or left eigenvectors 55 | rdl_decomposition - Full decomposition into eigenvalues and eigenvectors 56 | timescales - Implied timescales from eigenvalues 57 | 58 | Expected counts 59 | ================= 60 | 61 | .. autosummary:: 62 | :toctree: generated/ 63 | 64 | expected_counts - Count matrix expected for given initial distribution 65 | expected_counts_stationary - Count matrix expected for equilibrium distribution 66 | 67 | Passage times 68 | ============= 69 | 70 | .. autosummary:: 71 | :toctree: generated/ 72 | 73 | mfpt - Mean first-passage time 74 | 75 | Committors and PCCA 76 | =================== 77 | 78 | .. autosummary:: 79 | :toctree: generated/ 80 | 81 | committor - Forward and backward committor 82 | pcca - Perron cluster center analysis 83 | 84 | Fingerprints 85 | ============ 86 | 87 | .. autosummary:: 88 | :toctree: generated/ 89 | 90 | fingerprint_correlation 91 | fingerprint_relaxation 92 | expectation - Equilibrium expectation value of an observable 93 | correlation 94 | relaxation 95 | 96 | Sensitivity analysis 97 | ==================== 98 | 99 | .. autosummary:: 100 | :toctree: generated/ 101 | 102 | stationary_distribution_sensitivity 103 | eigenvalue_sensitivity 104 | timescale_sensitivity 105 | eigenvector_sensitivity 106 | mfpt_sensitivity 107 | committor_sensitivity 108 | expectation_sensitivity 109 | 110 | """ 111 | 112 | from .api import * 113 | -------------------------------------------------------------------------------- /tests/flux/impl/sparse/tpt_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit test for the TPT-module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | 25 | import unittest 26 | import numpy as np 27 | from msmtools.util.birth_death_chain import BirthDeathChain 28 | from tests.numeric import assert_allclose 29 | 30 | from scipy.sparse import csr_matrix 31 | 32 | from msmtools.flux.sparse import tpt 33 | 34 | 35 | class TestRemoveNegativeEntries(unittest.TestCase): 36 | def setUp(self): 37 | self.A = np.random.randn(10, 10) 38 | self.Aplus = 1.0 * self.A 39 | neg = (self.Aplus < 0.0) 40 | self.Aplus[neg] = 0.0 41 | 42 | def test_remove_negative_entries(self): 43 | A = csr_matrix(self.A) 44 | Aplus = self.Aplus 45 | 46 | Aplusn = tpt.remove_negative_entries(A) 47 | assert_allclose(Aplusn.toarray(), Aplus) 48 | 49 | 50 | class TestTPT(unittest.TestCase): 51 | def setUp(self): 52 | p = np.zeros(10) 53 | q = np.zeros(10) 54 | p[0:-1] = 0.5 55 | q[1:] = 0.5 56 | p[4] = 0.01 57 | q[6] = 0.1 58 | 59 | self.A = [0, 1] 60 | self.B = [8, 9] 61 | self.a = 1 62 | self.b = 8 63 | 64 | self.bdc = BirthDeathChain(q, p) 65 | T_dense = self.bdc.transition_matrix() 66 | T_sparse = csr_matrix(T_dense) 67 | self.T = T_sparse 68 | 69 | """Use precomputed mu, qminus, qplus""" 70 | self.mu = self.bdc.stationary_distribution() 71 | self.qplus = self.bdc.committor_forward(self.a, self.b) 72 | self.qminus = self.bdc.committor_backward(self.a, self.b) 73 | # self.qminus = committor.backward_committor(self.T, self.A, self.B, mu=self.mu) 74 | # self.qplus = committor.forward_committor(self.T, self.A, self.B) 75 | self.fluxn = tpt.flux_matrix(self.T, self.mu, self.qminus, self.qplus, netflux=False) 76 | self.netfluxn = tpt.to_netflux(self.fluxn) 77 | # self.Fn = tpt.totalflux(self.fluxn, self.A) 78 | # self.kn = tpt.rate(self.Fn, self.mu, self.qminus) 79 | 80 | def test_flux(self): 81 | flux = self.bdc.flux(self.a, self.b) 82 | assert_allclose(self.fluxn.toarray(), flux) 83 | 84 | def test_netflux(self): 85 | netflux = self.bdc.netflux(self.a, self.b) 86 | assert_allclose(self.netfluxn.toarray(), netflux) 87 | 88 | # def test_totalflux(self): 89 | # F=self.bdc.totalflux(self.a, self.b) 90 | # assert_allclose(self.Fn, F) 91 | 92 | # def test_rate(self): 93 | # k=self.bdc.rate(self.a, self.b) 94 | # assert_allclose(self.kn, k) 95 | 96 | 97 | if __name__ == "__main__": 98 | unittest.main() 99 | -------------------------------------------------------------------------------- /tests/generation/test_generation.py: -------------------------------------------------------------------------------- 1 | # This file is part of MSMTools. 2 | # 3 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | # 5 | # MSMTools is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | 18 | ''' 19 | @author: noe, trendelkampschroer 20 | ''' 21 | import unittest 22 | import numpy as np 23 | import msmtools.generation as msmgen 24 | import msmtools.estimation as msmest 25 | import msmtools.analysis as msmana 26 | 27 | 28 | class TestTrajGeneration(unittest.TestCase): 29 | 30 | @classmethod 31 | def setUpClass(cls): 32 | cls.P = np.array([[0.9, 0.1], 33 | [0.1, 0.9]]) 34 | 35 | def setUp(self): 36 | self.random_state = np.random.RandomState(42) 37 | 38 | def test_trajectory(self): 39 | N = 1000 40 | traj = msmgen.generate_traj(self.P, N, start=0, random_state=self.random_state) 41 | 42 | # test shapes and sizes 43 | assert traj.size == N 44 | assert traj.min() >= 0 45 | assert traj.max() <= 1 46 | 47 | # test statistics of transition matrix 48 | C = msmest.count_matrix(traj, 1) 49 | Pest = msmest.transition_matrix(C) 50 | assert np.max(np.abs(Pest - self.P)) < 0.025 51 | 52 | def test_trajectories(self): 53 | # test number of trajectories 54 | M = 10 55 | N = 10 56 | trajs = msmgen.generate_trajs(self.P, M, N, start=0, random_state=self.random_state) 57 | assert len(trajs) == M 58 | 59 | def test_stats(self): 60 | # test statistics of starting state 61 | N = 5000 62 | trajs = msmgen.generate_trajs(self.P, N, 1, random_state=self.random_state) 63 | ss = np.concatenate(trajs).astype(int) 64 | pi = msmana.stationary_distribution(self.P) 65 | piest = msmest.count_states(ss) / float(N) 66 | np.testing.assert_allclose(piest, pi, atol=0.025) 67 | 68 | def test_transitionmatrix(self): 69 | # test if transition matrix can be reconstructed 70 | N = 5000 71 | trajs = msmgen.generate_traj(self.P, N, random_state=self.random_state) 72 | C = msmest.count_matrix(trajs, 1, sparse_return=False) 73 | T = msmest.transition_matrix(C) 74 | np.testing.assert_allclose(T, self.P, atol=.01) 75 | 76 | def test_stop_eq_start(self): 77 | M = 10 78 | N = 10 79 | trajs = msmgen.generate_trajs(self.P, M, N, start=0, stop=0, random_state=self.random_state) 80 | for traj in trajs: 81 | assert traj.size == 1 82 | 83 | def test_stop(self): 84 | # test if we always stop at stopping state 85 | M = 100 86 | N = 10 87 | stop = 1 88 | trajs = msmgen.generate_trajs(self.P, M, N, start=0, stop=stop, random_state=self.random_state) 89 | for traj in trajs: 90 | assert traj.size == N or traj[-1] == stop 91 | assert stop not in traj[:-1] 92 | 93 | if __name__ == "__main__": 94 | unittest.main() 95 | -------------------------------------------------------------------------------- /msmtools/analysis/sparse/expectations.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""This module provides sparse implementations for the computation of 20 | expectation values for a given transition matrix. 21 | 22 | .. moduleauthor:: B.Trendelkamp-Schroer 23 | 24 | """ 25 | 26 | import numpy as np 27 | 28 | from scipy.sparse import coo_matrix 29 | from scipy.sparse import diags 30 | 31 | from .stationary_vector import stationary_distribution 32 | 33 | 34 | def expected_counts(p0, T, N): 35 | r"""Compute expected transition counts for Markov chain after N steps. 36 | 37 | Expected counts are computed according to ..math:: 38 | 39 | E[C_{ij}^{(n)}]=\sum_{k=0}^{N-1} (p_0^T T^{k})_{i} p_{ij} 40 | 41 | Parameters 42 | ---------- 43 | p0 : (M,) ndarray 44 | Starting (probability) vector of the chain. 45 | T : (M, M) sparse matrix 46 | Transition matrix of the chain. 47 | N : int 48 | Number of steps to take from initial state. 49 | 50 | Returns 51 | -------- 52 | EC : (M, M) sparse matrix 53 | Expected value for transition counts after N steps. 54 | 55 | """ 56 | if (N <= 0): 57 | EC = coo_matrix(T.shape, dtype=float) 58 | return EC 59 | else: 60 | """Probability vector after (k=0) propagations""" 61 | p_k = 1.0 * p0 62 | """Sum of vectors after (k=0) propagations""" 63 | p_sum = 1.0 * p_k 64 | """Transpose T to use sparse dot product""" 65 | Tt = T.transpose() 66 | for k in np.arange(N - 1): 67 | """Propagate one step p_{k} -> p_{k+1}""" 68 | p_k = Tt.dot(p_k) 69 | """Update sum""" 70 | p_sum += p_k 71 | D_psum = diags(p_sum, 0) 72 | EC = D_psum.dot(T) 73 | return EC 74 | 75 | 76 | def expected_counts_stationary(T, n, mu=None): 77 | r"""Expected transition counts for Markov chain in equilibrium. 78 | 79 | Since mu is stationary for T we have 80 | 81 | .. math:: 82 | 83 | E(C^{(n)})=n diag(mu)*T. 84 | 85 | Parameters 86 | ---------- 87 | T : (M, M) sparse matrix 88 | Transition matrix. 89 | n : int 90 | Number of steps for chain. 91 | mu : (M,) ndarray (optional) 92 | Stationary distribution for T. If mu is not specified it will be 93 | computed via diagonalization of T. 94 | 95 | Returns 96 | ------- 97 | EC : (M, M) sparse matrix 98 | Expected value for transition counts after N steps. 99 | 100 | """ 101 | if (n <= 0): 102 | EC = coo_matrix(T.shape, dtype=float) 103 | return EC 104 | else: 105 | if mu is None: 106 | mu = stationary_distribution(T) 107 | D_mu = diags(mu, 0) 108 | EC = n * D_mu.dot(T) 109 | return EC 110 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/transition_matrix.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | """This module implements the transition matrix functionality""" 20 | 21 | import numpy as np 22 | import scipy.sparse 23 | 24 | 25 | def transition_matrix_non_reversible(C): 26 | """implementation of transition_matrix""" 27 | if not scipy.sparse.issparse(C): 28 | C = scipy.sparse.csr_matrix(C) 29 | rowsum = C.tocsr().sum(axis=1) 30 | # catch div by zero 31 | if np.min(rowsum) == 0.0: 32 | raise ValueError("matrix C contains rows with sum zero.") 33 | rowsum = np.array(1. / rowsum).flatten() 34 | norm = scipy.sparse.diags(rowsum, 0) 35 | return norm * C 36 | 37 | def correct_transition_matrix(T, reversible=None): 38 | r"""Normalize transition matrix 39 | 40 | Fixes a the row normalization of a transition matrix. 41 | To be used with the reversible estimators to fix an almost coverged 42 | transition matrix. 43 | 44 | Parameters 45 | ---------- 46 | T : (M, M) ndarray 47 | matrix to correct 48 | reversible : boolean 49 | for future use 50 | 51 | Returns 52 | ------- 53 | (M, M) ndarray 54 | corrected transition matrix 55 | """ 56 | row_sums = T.sum(axis=1).A1 57 | max_sum = np.max(row_sums) 58 | if max_sum == 0.0: 59 | max_sum = 1.0 60 | return (T + scipy.sparse.diags(-row_sums+max_sum, 0)) / max_sum 61 | 62 | 63 | def transition_matrix_reversible_pisym(C, return_statdist=False, **kwargs): 64 | r""" 65 | Estimates reversible transition matrix as follows: 66 | 67 | ..:math: 68 | p_{ij} = c_{ij} / c_i where c_i = sum_j c_{ij} 69 | \pi_j = \sum_j \pi_i p_{ij} 70 | x_{ij} = \pi_i p_{ij} + \pi_j p_{ji} 71 | p^{rev}_{ij} = x_{ij} / x_i where x_i = sum_j x_{ij} 72 | 73 | In words: takes the nonreversible transition matrix estimate, uses its 74 | stationary distribution to compute an equilibrium correlation matrix, 75 | symmetrizes that correlation matrix and then normalizes to the reversible 76 | transition matrix estimate. 77 | 78 | Parameters 79 | ---------- 80 | C: ndarray, shape (n,n) 81 | count matrix 82 | 83 | Returns 84 | ------- 85 | T: Estimated transition matrix 86 | 87 | """ 88 | # nonreversible estimate 89 | T_nonrev = transition_matrix_non_reversible(C) 90 | from ...analysis import stationary_distribution 91 | pi = stationary_distribution(T_nonrev) 92 | # correlation matrix 93 | X = scipy.sparse.diags(pi).dot(T_nonrev) 94 | X = X.T + X 95 | # result 96 | pi_rev = np.array(X.sum(axis=1)).squeeze() 97 | T_rev = scipy.sparse.diags(1.0/pi_rev).dot(X) 98 | if return_statdist: 99 | #np.testing.assert_allclose(pi, stationary_distribution(T_rev)) 100 | #np.testing.assert_allclose(T_rev.T.dot(pi), pi) 101 | return T_rev, pi 102 | return T_rev 103 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/tmat_sampling/tmatrix_sampler.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Transition matrix sampling module. Provides a common class for sampling of 20 | 21 | i) non-reversible transition matrices 22 | ii) reverisble transition matrices 23 | iii) reversible transition matrices with fixed stationary vector 24 | 25 | from given data 26 | 27 | .. moduleauthor:: B.Trendelkamp-Schroer 28 | .. moduleauthor:: Frank Noe 29 | 30 | """ 31 | 32 | import math 33 | import numpy as np 34 | 35 | from . sampler_nrev import SamplerNonRev 36 | from . sampler_rev import SamplerRev 37 | from . sampler_revpi import SamplerRevPi 38 | 39 | 40 | class TransitionMatrixSampler(object): 41 | 42 | def __init__(self, C, reversible=False, mu=None, P0=None, nsteps=1, prior='sparse'): 43 | 44 | if not prior == 'sparse': 45 | raise ValueError("Only Sparse prior is currenty implemented") 46 | 47 | self.C = C 48 | 49 | # distinguish the sampling cases and initialize accordingly 50 | if reversible: 51 | if mu is None: 52 | if nsteps is None: 53 | # use sqrt(n) as a rough guess for the decorrelation time 54 | nsteps = math.sqrt(np.shape(C)[0]) 55 | self.sampler = SamplerRev(C, P0=P0) 56 | else: 57 | if nsteps is None: 58 | nsteps = 6 # because we have observed autocorrelation times of about 3. 59 | self.sampler = SamplerRevPi(C, mu, P0=P0) 60 | else: 61 | if mu is None: 62 | nsteps = 1 # just force to 1, because this is independent sampling 63 | self.sampler = SamplerNonRev(C-1.0) 64 | else: 65 | raise ValueError('Non reversible sampling with fixed stationary vector not implemented') 66 | 67 | # remember number of steps to decorrelate between samples 68 | self.nsteps = nsteps 69 | 70 | def sample(self, nsamples=1, return_statdist=False, call_back=None): 71 | if nsamples==1: 72 | return self.sampler.sample(N=self.nsteps, return_statdist=return_statdist) 73 | else: 74 | N = self.C.shape[0] 75 | P_samples = np.zeros((nsamples, N, N)) 76 | if return_statdist: 77 | pi_samples = np.zeros((nsamples, N)) 78 | for i in range(nsamples): 79 | P_samples[i, :, :], pi_samples[i, :] = self.sampler.sample(N=self.nsteps, return_statdist=True) 80 | if call_back is not None: 81 | call_back() 82 | return P_samples, pi_samples 83 | else: 84 | for i in range(nsamples): 85 | P_samples[i, :, :] = self.sampler.sample(N=self.nsteps, return_statdist=False) 86 | if call_back is not None: 87 | call_back() 88 | return P_samples 89 | -------------------------------------------------------------------------------- /msmtools/estimation/dense/mle/src/_mle_trev_given_pi.c: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | /* moduleauthor:: F. Paul */ 20 | #include 21 | #include 22 | 23 | #ifdef _MSC_VER 24 | #undef isnan 25 | int isnan(double var) 26 | { 27 | volatile double d = var; 28 | return d != d; 29 | } 30 | #endif 31 | 32 | #undef NDEBUG 33 | #include 34 | #include "sigint_handler.h" 35 | #include "_mle_trev_given_pi.h" 36 | 37 | static double distsq(const int n, const double *const a, const double *const b) 38 | { 39 | double d = 0.0; 40 | int i; 41 | #pragma omp parallel for reduction(+:d) 42 | for(i=0; i maxerr*maxerr && iteration < maxiter && !interrupted); 102 | 103 | /* calculate T */ 104 | for(i=0; i0.0){ 111 | T(i,j) = C_ij / (lam_new[i] + lam_new[j]*mu[i]/mu[j]); 112 | // printf("%f ", T(i, j)); 113 | norm += T(i,j); 114 | } 115 | else{ 116 | T(i,j) = 0.0; 117 | } 118 | } 119 | } 120 | // printf("\n"); 121 | if(norm>1.0) T(i,i) = 0.0; else T(i,i) = 1.0-norm; 122 | } 123 | 124 | if(iteration==maxiter) { err=5; goto error; } 125 | 126 | free(lam); 127 | free(lam_new); 128 | sigint_off(); 129 | return 0; 130 | 131 | error: 132 | free(lam); 133 | free(lam_new); 134 | sigint_off(); 135 | return -err; 136 | } 137 | -------------------------------------------------------------------------------- /tests/analysis/impl/dense/mean_first_passage_time_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit tests for the mean first passage time module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | .. moduleauthor:: C.Wehmeyer 23 | 24 | """ 25 | import unittest 26 | 27 | import numpy as np 28 | from tests.numeric import assert_allclose 29 | 30 | from msmtools.analysis.dense.mean_first_passage_time import mfpt, mfpt_between_sets 31 | 32 | 33 | class TestMfpt(unittest.TestCase): 34 | def setUp(self): 35 | p1 = 0.7 36 | p2 = 0.5 37 | q2 = 0.4 38 | q3 = 0.6 39 | """3x3 birth and death transition matrix""" 40 | self.P = np.array([[1.0 - p1, p1, 0.0], 41 | [q2, 1.0 - q2 - p2, p2], 42 | [0.0, q3, 1.0 - q3]]) 43 | """Vector of mean first passage times to target state t=0""" 44 | self.m0 = np.array([0.0, (p2 + q3) / (q2 * q3), (p2 + q2 + q3) / (q2 * q3)]) 45 | """Vector of mean first passage times to target state t=1""" 46 | self.m1 = np.array([1.0 / p1, 0.0, 1.0 / q3]) 47 | """Vector of mean first passage times to target state t=2""" 48 | self.m2 = np.array([(p2 + p1 + q2) / (p1 * p2), (p1 + q2) / (p1 * p2), 0.0]) 49 | """Vector of mean first passage times to target states t=(0,1)""" 50 | self.m01 = np.array([0.0, 0.0, 1.0 / q3]) 51 | """Vector of mean first passage times to target states t=(1,2)""" 52 | self.m12 = np.array([1.0 / p1, 0.0, 0.0]) 53 | """Vector of stationary weights""" 54 | self.mu = np.array([1.0, p1 / q2, p1 * p2 / q2 / q3]) 55 | """Mean first passage times from (0) to (1,2)""" 56 | self.o0t12 = 1.0 / p1 57 | """Mean first passage times from (2) to (0,1)""" 58 | self.o2t01 = 1.0 / q3 59 | """Mean first passage times from (0,1) to (2)""" 60 | self.o01t2 = (self.m2[0] * self.mu[0] + self.m2[1] * self.mu[1]) / (self.mu[0] + self.mu[1]) 61 | """Mean first passage times from (1,2) to (0)""" 62 | self.o12t0 = (self.m0[1] * self.mu[1] + self.m0[2] * self.mu[2]) / (self.mu[1] + self.mu[2]) 63 | 64 | def tearDown(self): 65 | pass 66 | 67 | def test_mfpt(self): 68 | x = mfpt(self.P, 0) 69 | assert_allclose(x, self.m0) 70 | 71 | x = mfpt(self.P, 1) 72 | assert_allclose(x, self.m1) 73 | 74 | x = mfpt(self.P, 2) 75 | assert_allclose(x, self.m2) 76 | 77 | x = mfpt(self.P, [0, 1]) 78 | assert_allclose(x, self.m01) 79 | 80 | x = mfpt(self.P, [1, 2]) 81 | assert_allclose(x, self.m12) 82 | 83 | def test_mfpt_between_sets(self): 84 | x = mfpt_between_sets(self.P, [1, 2], 0) 85 | assert_allclose(x, self.o0t12) 86 | 87 | x = mfpt_between_sets(self.P, [0, 1], 2) 88 | assert_allclose(x, self.o2t01) 89 | 90 | x = mfpt_between_sets(self.P, 2, [0, 1]) 91 | assert_allclose(x, self.o01t2) 92 | 93 | x = mfpt_between_sets(self.P, 0, [1, 2]) 94 | assert_allclose(x, self.o12t0) 95 | 96 | 97 | if __name__ == "__main__": 98 | unittest.main() 99 | -------------------------------------------------------------------------------- /setup_util.py: -------------------------------------------------------------------------------- 1 | # This file is part of MSMTools. 2 | # 3 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 4 | # 5 | # MSMTools is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | 18 | """ 19 | utility functions for python setup 20 | """ 21 | import contextlib 22 | import os 23 | import sys 24 | import tempfile 25 | from distutils.errors import LinkError, CompileError 26 | 27 | 28 | @contextlib.contextmanager 29 | def stdchannel_redirected(stdchannel, dest_filename, fake=False): 30 | """ 31 | A context manager to temporarily redirect stdout or stderr 32 | 33 | e.g.: 34 | 35 | with stdchannel_redirected(sys.stderr, os.devnull): 36 | if compiler.has_function('clock_gettime', libraries=['rt']): 37 | libraries.append('rt') 38 | """ 39 | if fake: 40 | yield 41 | return 42 | oldstdchannel = dest_file = None 43 | try: 44 | oldstdchannel = os.dup(stdchannel.fileno()) 45 | dest_file = open(dest_filename, 'w') 46 | os.dup2(dest_file.fileno(), stdchannel.fileno()) 47 | 48 | yield 49 | finally: 50 | if oldstdchannel is not None: 51 | os.dup2(oldstdchannel, stdchannel.fileno()) 52 | if dest_file is not None: 53 | dest_file.close() 54 | 55 | 56 | # From http://stackoverflow.com/questions/ 57 | # 7018879/disabling-output-when-compiling-with-distutils 58 | def has_function(compiler, funcname, headers): 59 | if not isinstance(headers, (tuple, list)): 60 | headers = [headers] 61 | with tempfile.TemporaryDirectory() as tmpdir, stdchannel_redirected(sys.stderr, os.devnull), \ 62 | stdchannel_redirected(sys.stdout, os.devnull): 63 | try: 64 | fname = os.path.join(tmpdir, 'funcname.c') 65 | f = open(fname, 'w') 66 | for h in headers: 67 | f.write('#include <%s>\n' % h) 68 | f.write('int main(void) {\n') 69 | f.write(' %s();\n' % funcname) 70 | f.write('return 0;}') 71 | f.close() 72 | objects = compiler.compile([fname], output_dir=tmpdir) 73 | compiler.link_executable(objects, os.path.join(tmpdir, 'a.out')) 74 | except (CompileError, LinkError): 75 | return False 76 | except: 77 | import traceback 78 | traceback.print_last() 79 | return False 80 | return True 81 | 82 | 83 | def detect_openmp(compiler): 84 | from distutils.log import debug 85 | from copy import deepcopy 86 | compiler = deepcopy(compiler) # avoid side-effects 87 | has_openmp = has_function(compiler, 'omp_get_num_threads', headers='omp.h') 88 | debug('[OpenMP] compiler %s has builtin support', compiler) 89 | additional_libs = [] 90 | if not has_openmp: 91 | debug('[OpenMP] compiler %s needs library support', compiler) 92 | if sys.platform == 'darwin': 93 | compiler.add_library('iomp5') 94 | elif sys.platform == 'linux': 95 | compiler.add_library('gomp') 96 | has_openmp = has_function(compiler, 'omp_get_num_threads', headers='omp.h') 97 | if has_openmp: 98 | additional_libs = [compiler.libraries[-1]] 99 | debug('[OpenMP] added library %s', additional_libs) 100 | return has_openmp, additional_libs 101 | -------------------------------------------------------------------------------- /tests/analysis/impl/sparse/mean_first_passage_time_test.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group, Freie Universitaet Berlin (GER) 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit tests for the mean first passage time module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | .. moduleauthor:: C.Wehmeyer 23 | 24 | """ 25 | import unittest 26 | 27 | import numpy as np 28 | from tests.numeric import assert_allclose 29 | import scipy.sparse 30 | 31 | from msmtools.analysis.sparse.mean_first_passage_time import mfpt, mfpt_between_sets 32 | 33 | 34 | class TestMfpt(unittest.TestCase): 35 | def setUp(self): 36 | p1 = 0.7 37 | p2 = 0.5 38 | q2 = 0.4 39 | q3 = 0.6 40 | """3x3 birth and death transition matrix""" 41 | P = np.array([[1.0 - p1, p1, 0.0], 42 | [q2, 1.0 - q2 - p2, p2], 43 | [0.0, q3, 1.0 - q3]]) 44 | self.P = scipy.sparse.coo_matrix(P) 45 | """Vector of mean first passage times to target state t=0""" 46 | self.m0 = np.array([0.0, (p2 + q3) / (q2 * q3), (p2 + q2 + q3) / (q2 * q3)]) 47 | """Vector of mean first passage times to target state t=1""" 48 | self.m1 = np.array([1.0 / p1, 0.0, 1.0 / q3]) 49 | """Vector of mean first passage times to target state t=2""" 50 | self.m2 = np.array([(p2 + p1 + q2) / (p1 * p2), (p1 + q2) / (p1 * p2), 0.0]) 51 | """Vector of mean first passage times to target states t=(0,1)""" 52 | self.m01 = np.array([0.0, 0.0, 1.0 / q3]) 53 | """Vector of mean first passage times to target states t=(1,2)""" 54 | self.m12 = np.array([1.0 / p1, 0.0, 0.0]) 55 | """Vector of stationary weights""" 56 | self.mu = np.array([1.0, p1 / q2, p1 * p2 / q2 / q3]) 57 | """Mean first passage times from (0) to (1,2)""" 58 | self.o0t12 = 1.0 / p1 59 | """Mean first passage times from (2) to (0,1)""" 60 | self.o2t01 = 1.0 / q3 61 | """Mean first passage times from (0,1) to (2)""" 62 | self.o01t2 = (self.m2[0] * self.mu[0] + self.m2[1] * self.mu[1]) / (self.mu[0] + self.mu[1]) 63 | """Mean first passage times from (1,2) to (0)""" 64 | self.o12t0 = (self.m0[1] * self.mu[1] + self.m0[2] * self.mu[2]) / (self.mu[1] + self.mu[2]) 65 | 66 | def tearDown(self): 67 | pass 68 | 69 | def test_mfpt(self): 70 | x = mfpt(self.P, 0) 71 | assert_allclose(x, self.m0) 72 | 73 | x = mfpt(self.P, 1) 74 | assert_allclose(x, self.m1) 75 | 76 | x = mfpt(self.P, 2) 77 | assert_allclose(x, self.m2) 78 | 79 | x = mfpt(self.P, [0, 1]) 80 | assert_allclose(x, self.m01) 81 | 82 | x = mfpt(self.P, [1, 2]) 83 | assert_allclose(x, self.m12) 84 | 85 | def test_mfpt_between_sets(self): 86 | x = mfpt_between_sets(self.P, [1, 2], 0) 87 | assert_allclose(x, self.o0t12) 88 | 89 | x = mfpt_between_sets(self.P, [0, 1], 2) 90 | assert_allclose(x, self.o2t01) 91 | 92 | x = mfpt_between_sets(self.P, 2, [0, 1]) 93 | assert_allclose(x, self.o01t2) 94 | 95 | x = mfpt_between_sets(self.P, 0, [1, 2]) 96 | assert_allclose(x, self.o12t0) 97 | 98 | 99 | if __name__ == "__main__": 100 | unittest.main() 101 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/mle/src/_mle_trev_given_pi.c: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | /* moduleauthor:: F. Paul */ 20 | #include 21 | #include 22 | 23 | #ifdef _MSC_VER 24 | #undef isnan 25 | int isnan(double var) 26 | { 27 | volatile double d = var; 28 | return d != d; 29 | } 30 | #endif 31 | 32 | #undef NDEBUG 33 | #include 34 | #include "sigint_handler.h" 35 | #include "_mle_trev_given_pi.h" 36 | 37 | static double distsq(const int n, const double *const a, const double *const b) 38 | { 39 | double d = 0.0; 40 | int i; 41 | #pragma omp parallel for reduction(+:d) 42 | for(i=0; i maxerr*maxerr && iteration < maxiter && !interrupted); 117 | 118 | /* calculate T */ 119 | for(t=0; t. 17 | */ 18 | 19 | /* moduleauthor:: F. Paul */ 20 | #include 21 | #include 22 | #include 23 | #ifdef _MSC_VER 24 | #undef isnan 25 | static int isnan(double var) 26 | { 27 | volatile double d = var; 28 | return d != d; 29 | } 30 | #endif 31 | 32 | #undef NDEBUG 33 | #include 34 | #include "sigint_handler.h" 35 | #include "_mle_trev.h" 36 | 37 | static double relative_error(const int n, const double *const a, const double *const b) 38 | { 39 | double sum; 40 | double d; 41 | double max = 0.0; 42 | int i; 43 | for(i=0; i0) { 46 | d = fabs((a[i]-b[i])/sum); 47 | if(d>max) max=d; 48 | } 49 | } 50 | return max; 51 | } 52 | 53 | #define CCt(i,j) (CCt[(i)*dim+(j)]) 54 | #define T(i,j) (T[(i)*dim+(j)]) 55 | 56 | int _mle_trev_dense(double * const T, const double * const CCt, 57 | const double * const sum_C, const int dim, 58 | const double maxerr, const int maxiter, 59 | double * const mu, 60 | double eps_mu) 61 | { 62 | double rel_err, x_norm; 63 | int i, j, err, iteration; 64 | double *sum_x, *sum_x_new, *temp; 65 | 66 | sigint_on(); 67 | 68 | sum_x= (double*)malloc(dim*sizeof(double)); 69 | sum_x_new= (double*)malloc(dim*sizeof(double)); 70 | if(!(sum_x && sum_x_new)) { err=1; goto error; } 71 | 72 | /* ckeck sum_C */ 73 | for(i = 0; i maxerr && iteration < maxiter && !interrupted); 113 | 114 | /* calculate T*/ 115 | for(i=0; i. 17 | 18 | r"""Unit tests for the covariance module 19 | 20 | .. moduleauthor:: B.Trendelkamp-Schroer 21 | 22 | """ 23 | 24 | import unittest 25 | import numpy as np 26 | 27 | from msmtools.estimation import tmatrix 28 | from msmtools.estimation.dense.tmat_sampling.tmatrix_sampler import TransitionMatrixSampler 29 | 30 | 31 | class TestSamplerNonReversible(unittest.TestCase): 32 | 33 | def setUp(self): 34 | """Store state of the rng""" 35 | self.state = np.random.mtrand.get_state() 36 | 37 | # Reseed the rng to enforce 'deterministic' behavior" 38 | np.random.mtrand.seed(42) 39 | 40 | self.C = 1.0 * np.array([[7048, 6, 2], [6, 2, 3], [2, 3, 2933]]) 41 | 42 | # Mean in the asymptotic limit, N_samples -> \infty 43 | alpha = self.C 44 | alpha0 = self.C.sum(axis=1) 45 | 46 | self.mean = alpha / alpha0[:, np.newaxis] 47 | self.var = alpha * (alpha0[:, np.newaxis] - alpha) / \ 48 | (alpha0 ** 2 * (alpha0 + 1.0))[:, np.newaxis] 49 | 50 | self.N = 1000 51 | 52 | def tearDown(self): 53 | """Revert the state of the rng""" 54 | np.random.mtrand.set_state(self.state) 55 | 56 | def test_mean(self): 57 | """Create sampler object""" 58 | sampler = TransitionMatrixSampler(self.C, reversible=False) 59 | 60 | # Compute sample mean 61 | mean = np.zeros_like(self.C) 62 | for i in range(self.N): 63 | mean += sampler.sample() 64 | mean *= 1.0 / self.N 65 | 66 | # Check if sample mean and true mean fall into the 2\sigma interval 67 | self.assertTrue(np.all(np.abs(mean - self.mean) <= 2.0 * np.sqrt(self.var / self.N))) 68 | 69 | 70 | class TestSamplerReversible(unittest.TestCase): 71 | 72 | def setUp(self): 73 | self.C = 1.0 * np.array([[7048, 6, 0], [6, 2, 3], [0, 3, 2933]]) 74 | self.P_mle = tmatrix(self.C, reversible=True) 75 | self.N = 1000 76 | 77 | def test_mean(self): 78 | """Create sampler object""" 79 | sampler = TransitionMatrixSampler(self.C, reversible=True) 80 | 81 | sample = np.zeros((self.N, 3, 3)) 82 | for i in range(self.N): 83 | sample[i, :, :] = sampler.sample() 84 | mean = np.mean(sample, axis=0) 85 | std = np.std(sample, axis=0) 86 | 87 | # Check if sample mean and MLE agree within the sample standard deviation 88 | self.assertTrue(np.all(np.abs(mean - self.P_mle) <= std)) 89 | 90 | 91 | class TestSamplerReversiblePi(unittest.TestCase): 92 | 93 | def setUp(self): 94 | self.C = 1.0 * np.array([[7048, 6, 0], [6, 2, 3], [0, 3, 2933]]) 95 | self.pi = np.array([0.70532947, 0.00109989, 0.29357064]) 96 | self.P_mle = tmatrix(self.C, reversible=True, mu=self.pi) 97 | 98 | self.N = 1000 99 | 100 | def tearDown(self): 101 | pass 102 | 103 | def test_mean(self): 104 | """Create sampler object""" 105 | sampler = TransitionMatrixSampler(self.C, reversible=True, mu=self.pi, nsteps=10) 106 | 107 | sample = np.zeros((self.N, 3, 3)) 108 | for i in range(self.N): 109 | sample[i, :, :] = sampler.sample() 110 | mean = np.mean(sample, axis=0) 111 | std = np.std(sample, axis=0) 112 | 113 | # Check if sample mean and MLE agree within the sample standard deviation 114 | self.assertTrue(np.all(np.abs(mean - self.P_mle) <= std)) 115 | 116 | 117 | if __name__ == "__main__": 118 | unittest.main() 119 | -------------------------------------------------------------------------------- /tests/estimation/tests/test_prior.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MSMTools. 3 | # 4 | # Copyright (c) 2015, 2014 Computational Molecular Biology Group 5 | # 6 | # MSMTools is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | r"""Unit test for the prior module 20 | 21 | .. moduleauthor:: B.Trendelkamp-Schroer 22 | 23 | """ 24 | import unittest 25 | import warnings 26 | 27 | import numpy as np 28 | from tests.numeric import assert_allclose 29 | 30 | from scipy.sparse import csr_matrix 31 | 32 | from msmtools.util.numeric import allclose_sparse 33 | from msmtools.estimation import prior_neighbor, prior_const, prior_rev 34 | 35 | 36 | class TestPriorDense(unittest.TestCase): 37 | def setUp(self): 38 | C = np.array([[4, 4, 0, 2], [4, 4, 1, 0], [0, 1, 4, 4], [0, 0, 4, 4]]) 39 | self.C = C 40 | 41 | self.alpha_def = 0.001 42 | self.alpha = -0.5 43 | 44 | B_neighbor = np.array([[1, 1, 0, 1], [1, 1, 1, 0], [0, 1, 1, 1], [1, 0, 1, 1]]) 45 | B_const = np.ones_like(C) 46 | B_rev = np.triu(B_const) 47 | 48 | self.B_neighbor = B_neighbor 49 | self.B_const = B_const 50 | self.B_rev = B_rev 51 | 52 | def tearDown(self): 53 | pass 54 | 55 | def test_prior_neighbor(self): 56 | Bn = prior_neighbor(self.C) 57 | assert_allclose(Bn, self.alpha_def * self.B_neighbor) 58 | 59 | Bn = prior_neighbor(self.C, alpha=self.alpha) 60 | assert_allclose(Bn, self.alpha * self.B_neighbor) 61 | 62 | def test_prior_const(self): 63 | Bn = prior_const(self.C) 64 | assert_allclose(Bn, self.alpha_def * self.B_const) 65 | 66 | Bn = prior_const(self.C, alpha=self.alpha) 67 | assert_allclose(Bn, self.alpha * self.B_const) 68 | 69 | def test_prior_rev(self): 70 | Bn = prior_rev(self.C) 71 | assert_allclose(Bn, -1.0 * self.B_rev) 72 | 73 | Bn = prior_rev(self.C, alpha=self.alpha) 74 | assert_allclose(Bn, self.alpha * self.B_rev) 75 | 76 | 77 | class TestPriorSparse(unittest.TestCase): 78 | def setUp(self): 79 | C = np.array([[4, 4, 0, 2], [4, 4, 1, 0], [0, 1, 4, 4], [0, 0, 4, 4]]) 80 | self.C = csr_matrix(C) 81 | 82 | self.alpha_def = 0.001 83 | self.alpha = -0.5 84 | 85 | B_neighbor = np.array([[1, 1, 0, 1], [1, 1, 1, 0], [0, 1, 1, 1], [1, 0, 1, 1]]) 86 | B_const = np.ones_like(C) 87 | B_rev = np.triu(B_const) 88 | 89 | self.B_neighbor = csr_matrix(B_neighbor) 90 | self.B_const = B_const 91 | self.B_rev = B_rev 92 | 93 | def tearDown(self): 94 | pass 95 | 96 | def test_prior_neighbor(self): 97 | Bn = prior_neighbor(self.C) 98 | self.assertTrue(allclose_sparse(Bn, self.alpha_def * self.B_neighbor)) 99 | 100 | Bn = prior_neighbor(self.C, alpha=self.alpha) 101 | self.assertTrue(allclose_sparse(Bn, self.alpha * self.B_neighbor)) 102 | 103 | def test_prior_const(self): 104 | with warnings.catch_warnings(record=True) as w: 105 | Bn = prior_const(self.C) 106 | assert_allclose(Bn, self.alpha_def * self.B_const) 107 | 108 | with warnings.catch_warnings(record=True) as w: 109 | Bn = prior_const(self.C, alpha=self.alpha) 110 | assert_allclose(Bn, self.alpha * self.B_const) 111 | 112 | def test_prior_rev(self): 113 | with warnings.catch_warnings(record=True) as w: 114 | Bn = prior_rev(self.C) 115 | assert_allclose(Bn, -1.0 * self.B_rev) 116 | 117 | with warnings.catch_warnings(record=True) as w: 118 | Bn = prior_rev(self.C, alpha=self.alpha) 119 | assert_allclose(Bn, self.alpha * self.B_rev) 120 | 121 | 122 | if __name__ == "__main__": 123 | unittest.main() 124 | -------------------------------------------------------------------------------- /msmtools/estimation/sparse/mle/src/_mle_trev.c: -------------------------------------------------------------------------------- 1 | /* * This file is part of MSMTools. 2 | * 3 | * Copyright (c) 2015, 2014 Computational Molecular Biology Group 4 | * 5 | * MSMTools is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | /* moduleauthor:: F. Paul */ 20 | #include 21 | #include 22 | #include 23 | #undef NDEBUG 24 | #include 25 | #include "sigint_handler.h" 26 | #include "_mle_trev.h" 27 | 28 | #ifdef _MSC_VER 29 | #undef isnan 30 | int isnan(double var) 31 | { 32 | volatile double d = var; 33 | return d != d; 34 | } 35 | #endif 36 | 37 | static double relative_error(const int n, const double *const a, const double *const b) 38 | { 39 | double sum; 40 | double d; 41 | double max = 0.0; 42 | int i; 43 | for(i=0; i0) { 46 | d = fabs((a[i]-b[i])/sum); 47 | if(d>max) max=d; 48 | } 49 | } 50 | return max; 51 | } 52 | 53 | int _mle_trev_sparse(double * const T_data, const double * const CCt_data, 54 | const int * const i_indices, const int * const j_indices, 55 | const int len_CCt, const double * const sum_C, 56 | const int dim, const double maxerr, const int maxiter, 57 | double * const mu, 58 | double eps_mu) 59 | { 60 | double rel_err; 61 | int i, j, t, err, iteration; 62 | double *sum_x, *sum_x_new, *temp; 63 | double CCt_ij, value; 64 | double x_norm; 65 | 66 | sigint_on(); 67 | 68 | err = 0; 69 | 70 | sum_x= (double*)malloc(dim*sizeof(double)); 71 | sum_x_new= (double*)malloc(dim*sizeof(double)); 72 | if(!(sum_x && sum_x_new)) { err=1; goto error; } 73 | 74 | /* ckeck sum_C */ 75 | for(i = 0; i maxerr && iteration < maxiter && !interrupted); 119 | 120 | /* calculate X */ 121 | for(i=0; i