{"id":29165107,"url":"https://github.com/lrydin/kramersmoyal","last_synced_at":"2025-07-01T07:10:39.884Z","repository":{"id":36488518,"uuid":"183752905","full_name":"LRydin/KramersMoyal","owner":"LRydin","description":"kramersmoyal: Kramers-Moyal coefficients for stochastic data of any dimension, to any desired order","archived":false,"fork":false,"pushed_at":"2024-12-26T10:51:17.000Z","size":4915,"stargazers_count":74,"open_issues_count":0,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-06-27T01:07:57.807Z","etag":null,"topics":["diffusion","drift","drift-diffusion","kernel-density-estimation","nadaraya-watson","stochastic","stochastic-differential-equations","stochastic-process"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LRydin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-04-27T09:22:14.000Z","updated_at":"2025-06-12T12:44:31.000Z","dependencies_parsed_at":"2022-08-02T11:52:12.067Z","dependency_job_id":"285c67fe-3509-4bc1-b209-f53db9f9f96e","html_url":"https://github.com/LRydin/KramersMoyal","commit_stats":{"total_commits":168,"total_committers":6,"mean_commits":28.0,"dds":0.2142857142857143,"last_synced_commit":"7e9c37047211bda7bb9fd07134084795e45bc90a"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/LRydin/KramersMoyal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LRydin%2FKramersMoyal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LRydin%2FKramersMoyal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LRydin%2FKramersMoyal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LRydin%2FKramersMoyal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LRydin","download_url":"https://codeload.github.com/LRydin/KramersMoyal/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LRydin%2FKramersMoyal/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262916694,"owners_count":23383891,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diffusion","drift","drift-diffusion","kernel-density-estimation","nadaraya-watson","stochastic","stochastic-differential-equations","stochastic-process"],"created_at":"2025-07-01T07:10:38.779Z","updated_at":"2025-07-01T07:10:39.864Z","avatar_url":"https://github.com/LRydin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![DOI](https://joss.theoj.org/papers/10.21105/joss.01693/status.svg)](https://doi.org/10.21105/joss.01693)\n![PyPI - License](https://img.shields.io/pypi/l/kramersmoyal) ![PyPI](https://img.shields.io/pypi/v/kramersmoyal) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/kramersmoyal)\n[![Build Status](https://github.com/LRydin/KramersMoyal/actions/workflows/CI.yml/badge.svg)](https://github.com/LRydin/KramersMoyal/actions/workflows/CI.yml)\n[![codecov](https://codecov.io/gh/LRydin/KramersMoyal/branch/master/graph/badge.svg)](https://codecov.io/gh/LRydin/KramersMoyal) [![Documentation Status](https://readthedocs.org/projects/kramersmoyal/badge/?version=latest)](https://kramersmoyal.readthedocs.io/en/latest/?badge=latest)\n\n# KramersMoyal\n`kramersmoyal` is a python package designed to obtain the Kramers–Moyal coefficients, or conditional moments, from stochastic data of any dimension. It employs kernel density estimations, instead of a histogram approach, to ensure better results for low number of points as well as allowing better fitting of the results.\n\nThe [paper](https://doi.org/10.21105/joss.01693) is now officially published on [JOSS](https://joss.theoj.org/). The paper is also available [here](/paper/paper.pdf), or you can find it in the [ArXiv](https://arxiv.org/abs/1912.09737).\n\n# Installation\nTo install `kramersmoyal`, just use `pip`\n\n```\npip install kramersmoyal\n```\nThen on your favourite editor just use\n```python\nfrom kramersmoyal import km\n```\n\n## Dependencies\nThe library depends on `numpy` and `scipy`.\n\n# A one-dimensional stochastic process\n\nA Jupyter notebook with this example can be found [here](/examples/kmc.ipynb)\n\n## The theory\nTake, for example, the well-documented one-dimension Ornstein–Uhlenbeck process, also known as Va\u0026#353;\u0026#237;\u0026#269;ek process, see [here](https://en.wikipedia.org/wiki/Ornstein%E2%80%93Uhlenbeck_process). This process is governed by two main parameters: the mean-reverting parameter \u0026theta; and the diffusion parameter \u0026sigma;\n\n\u003cimg src=\"/other/OU_eq.png\" title=\"Ornstein–Uhlenbeck process\" height=\"25\"/\u003e\n\nwhich can be solved in various ways. For our purposes, recall that the drift coefficient, i.e., the first-order Kramers–Moyal coefficient, is given by ![](/other/inline_KM_1.png) and the second-order Kramers–Moyal coefficient is ![](/other/inline_KM_2.png), i.e., the diffusion.\n\nGenerate an exemplary Ornstein–Uhlenbeck process with your favourite integrator, e.g., the [Euler–Maruyama](https://en.wikipedia.org/wiki/Euler%E2%80%93Maruyama_method) or with a more powerful tool from [`JiTCSDE`](https://github.com/neurophysik/jitcsde) found on GitHub.\nFor this example let's take \u0026theta;=.3 and \u0026sigma;=.1, over a total time of 500 units, with a sampling of 1000 Hertz, and from the generated data series retrieve the two parameters, the drift -\u0026theta;y(t) and diffusion \u0026sigma;.\n\n## Integrating an Ornstein–Uhlenbeck process\nHere is a short code on generating a Ornstein–Uhlenbeck stochastic trajectory with a simple Euler–Maruyama integration method\n\n```python\n# integration time and time sampling\nt_final = 500\ndelta_t = 0.001\n\n# The parameters theta and sigma\ntheta = 0.3\nsigma = 0.1\n\n# The time array of the trajectory\ntime = np.arange(0, t_final, delta_t)\n\n# Initialise the array y\ny = np.zeros(time.size)\n\n# Generate a Wiener process\ndw = np.random.normal(loc=0, scale=np.sqrt(delta_t), size=time.size)\n\n# Integrate the process\nfor i in range(1,time.size):\n    y[i] = y[i-1] - theta*y[i-1]*delta_t + sigma*dw[i]\n```\n\nFrom here we have a plain example of an Ornstein–Uhlenbeck process, always drifting back to zero, due to the mean-reverting drift \u0026theta;. The effect of the noise can be seen across the whole trajectory.\n\n\u003cimg src=\"/other/fig1.png\" title=\"Ornstein–Uhlenbeck process\" height=\"200\"/\u003e\n\n## Using `kramersmoyal`\nTake the timeseries `y` and let's study the Kramers–Moyal coefficients. For this let's look at the drift and diffusion coefficients of the process, i.e., the first and second Kramers–Moyal coefficients, with an `epanechnikov` kernel\n```python\n\n# The kmc holds the results, where edges holds the binning space\nkmc, edges = km(y, powers=2)\n```\n\nThis results in\n\n\u003cimg src=\"/other/fig2.png\" title=\"Drift and diffusion terms of an Ornstein–Uhlenbeck process\" height=\"200\"/\u003e\n\nNotice here that to obtain the Kramers–Moyal coefficients you need to divide `kmc` by the timestep `delta_t`. This normalisation stems from the Taylor-like approximation, i.e., the Kramers–Moyal expansion (`delta t` \u0026rarr; 0).\n\n# A two-dimensional diffusion process\n\nA Jupyter notebook with this example can be found [here](/examples/kmc.ipynb)\n\n## Theory\n\nA two-dimensional diffusion process is a stochastic process that comprises two ![](/other/inline_W.png) and allows for a mixing of these noise terms across its two dimensions.\n\n\u003cimg src=\"/other/2D-diffusion.png\" alt=\"2D-diffusion\" title=\"A 2-dimensional diffusion process\" height=\"60\" /\u003e\n\nwhere we will select a set of state-dependent parameters obeying\n\n\u003cimg src=\"/other/parameters_2D-diffusion.png\" alt=\"2D-diffusion\" title=\"Specific parameters for the diffusion process\" height=\"70\" /\u003e\n\nwith ![](/other/inline_parameters_2D-diffusion_1.png) and ![](/other/inline_parameters_2D-diffusion_2.png).\n\n## Choice of parameters\nAs an example, let's take the following set of parameters for the drift vector and diffusion matrix\n\n```python\n# integration time and time sampling\nt_final = 2000\ndelta_t = 0.001\n\n# Define the drift vector N\nN = np.array([2.0, 1.0])\n\n# Define the diffusion matrix g\ng = np.array([[0.5, 0.0], [0.0, 0.5]])\n\n# The time array of the trajectory\ntime = np.arange(0, t_final, delta_t)\n```\n\n## Integrating a 2-dimensional process\nIntegrating the previous stochastic trajectory with a simple Euler–Maruyama integration method\n\n```python\n# Initialise the array y\ny = np.zeros([time.size, 2])\n\n# Generate two Wiener processes with a scale of np.sqrt(delta_t)\ndW = np.random.normal(loc=0, scale=np.sqrt(delta_t), size=[time.size, 2])\n\n# Integrate the process (takes about 20 secs)\nfor i in range(1, time.size):\n    y[i,0] = y[i-1,0]  -  N[0] * y[i-1,0] * delta_t + g[0,0]/(1 + np.exp(y[i-1,0]**2)) * dW[i,0]  +  g[0,1] * dW[i,1]\n    y[i,1] = y[i-1,1]  -  N[1] * y[i-1,1] * delta_t + g[1,0] * dW[i,0]  +  g[1,1]/(1 + np.exp(y[i-1,1]**2)) * dW[i,1]\n```\n\nThe stochastic trajectory in 2 dimensions for `10` time units (`10000` data points)\n\n\u003cimg src=\"/other/fig3.png\" alt=\"2D-diffusion\" title=\"2-dimensional trajectory\" height=\"280\" /\u003e\n\n## Back to `kramersmoyal` and the Kramers–Moyal coefficients\nFirst notice that all the results now will be two-dimensional surfaces, so we will need to plot them as such\n\n```python\n# Choose the size of your target space in two dimensions\nbins = [100, 100]\n\n# Introduce the desired orders to calculate, but in 2 dimensions\npowers = np.array([[0,0], [1,0], [0,1], [1,1], [2,0], [0,2], [2,2]])\n# insert into kmc:   0      1      2      3      4      5      6\n\n# Notice that the first entry in [,] is for the first dimension, the\n# second for the second dimension...\n\n# Choose a desired bandwidth bw\nbw = 0.1\n\n# Calculate the Kramers−Moyal coefficients\nkmc, edges = km(y, bw=bw, bins=bins, powers=powers)\n\n# The K−M coefficients are stacked along the first dim of the\n# kmc array, so kmc[1,...] is the first K−M coefficient, kmc[2,...]\n# is the second. These will be 2-dimensional matrices\n```\n\nNow one can visualise the Kramers–Moyal coefficients (surfaces) in green and the respective theoretical surfaces in black. (Don't forget to normalise: `kmc / delta_t`).\n\n\u003cimg src=\"/other/fig4.png\" alt=\"2D-diffusion\" title=\"2-dimensional Kramers–Moyal surfaces (green) and the theoretical surfaces (black)\" height=\"480\" /\u003e\n\n# Contributions\nWe welcome reviews and ideas from everyone. If you want to share your ideas or report a bug, open an [issue](https://github.com/LRydin/KramersMoyal/issues) here on GitHub, or contact us directly.\nIf you need help with the code, the theory, or the implementation, do not hesitate to contact us, we are here to help.\nWe abide to a [Conduct of Fairness](contributions.md).\n\n# TODOs\nNext on the list is\n- Include more kernels\n- Work through the documentation carefully\n\n# Changelog\n- Version 0.4.1 - Changing CI. Correcting `kmc[0,:]` normalisation. Various Simplifications. Bins as ints, powers as ints.\n- Version 0.4.0 - Added the documentation, first testers, and the Conduct of Fairness\n- Version 0.3.2 - Adding 2 kernels: `triagular` and `quartic` and extending the documentation and examples.\n- Version 0.3.1 - Corrections to the fft triming after convolution.\n- Version 0.3.0 - The major breakthrough: Calculates the Kramers–Moyal coefficients for data of any dimension.\n- Version 0.2.0 - Introducing convolutions and `gaussian` and `uniform` kernels. Major speed up in the calculations.\n- Version 0.1.0 - One and two dimensional Kramers–Moyal coefficients with an `epanechnikov` kernel.\n\n# Literature and Support\n\n### Literature\nThe study of stochastic processes from a data-driven approach is grounded in extensive mathematical work. From the applied perspective there are several references to understand stochastic processes, the Fokker–Planck equations, and the Kramers–Moyal expansion\n\n- Tabar, M. R. R. (2019). *Analysis and Data-Based Reconstruction of Complex Nonlinear Dynamical Systems.* Springer, International Publishing\n- Risken, H. (1989). *The Fokker–Planck equation.* Springer, Berlin, Heidelberg.\n- Gardiner, C.W. (1985). *Handbook of Stochastic Methods.* Springer, Berlin.\n\nYou can find and extensive review on the subject [here](http://sharif.edu/~rahimitabar/pdfs/80.pdf)\u003csup\u003e1\u003c/sup\u003e\n\n### History\nThis project was started in 2017 at the [neurophysik](https://www.researchgate.net/lab/Klaus-Lehnertz-Lab-2) by Leonardo Rydin Gorjão, Jan Heysel, Klaus Lehnertz, and M. Reza Rahimi Tabar. Francisco Meirinhos later devised the hard coding to python. The project has had many supporters, such as Dirk Witthaut at the [Institute of Climate and Energy Systems (ICE)- Energiesystemtechnik (ICE-1), FZJ](https://www.fz-juelich.de/profile/witthaut_d), Benjamin Schäfer [Institute for Automation and Applied Informatics, KIT](https://www.iai.kit.edu/english/2154_4101.php), and Niklas Boers at [Technical University of Munich](https://www.professoren.tum.de/en/boers-niklas) \u0026 [Potsdam Institute for Climate Impact Research](https://www.pik-potsdam.de/members/boers), along with many others. \n\n### Funding\nHelmholtz Association Initiative _Energy System 2050 - A Contribution of the Research Field Energy_ and the grant No. VH-NG-1025 and *STORM - Stochastics for Time-Space Risk Models* project of the Research Council of Norway (RCN) No. 274410.\n\n---\n\n\u003csup\u003e1\u003c/sup\u003e Friedrich, R., Peinke, J., Sahimi, M., Tabar, M. R. R. *Approaching complexity by stochastic methods: From biological systems to turbulence,* [Phys. Rep. 506, 87–162 (2011)](https://doi.org/10.1016/j.physrep.2011.05.003).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flrydin%2Fkramersmoyal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flrydin%2Fkramersmoyal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flrydin%2Fkramersmoyal/lists"}