{"id":20689966,"url":"https://github.com/woodward/integrator","last_synced_at":"2025-08-20T16:30:54.927Z","repository":{"id":149898936,"uuid":"622369877","full_name":"woodward/integrator","owner":"woodward","description":"A numerical integrator written in Elixir for the solution of sets of non-stiff ordinary differential equations (ODEs).","archived":false,"fork":false,"pushed_at":"2024-12-05T02:44:55.000Z","size":908,"stargazers_count":33,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-12-12T12:25:49.280Z","etag":null,"topics":["adaptive-stepsize","bogacki-shampine","dormand-prince","elixir","elixir-nx","numerical","nx","ode-solver","odes","ordinary-differential-equations","runge-kutta","runge-kutta-adaptive-step-size","runge-kutta-methods"],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/woodward.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2023-04-01T22:46:26.000Z","updated_at":"2024-12-05T02:45:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"5a226aae-cd32-40ac-bfa3-8de63b13978d","html_url":"https://github.com/woodward/integrator","commit_stats":{"total_commits":400,"total_committers":1,"mean_commits":400.0,"dds":0.0,"last_synced_commit":"e169000d767aa1bdaa09cf0f6dc256a7af2dd7e8"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodward%2Fintegrator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodward%2Fintegrator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodward%2Fintegrator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodward%2Fintegrator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/woodward","download_url":"https://codeload.github.com/woodward/integrator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230438185,"owners_count":18225870,"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":["adaptive-stepsize","bogacki-shampine","dormand-prince","elixir","elixir-nx","numerical","nx","ode-solver","odes","ordinary-differential-equations","runge-kutta","runge-kutta-adaptive-step-size","runge-kutta-methods"],"created_at":"2024-11-16T23:11:27.292Z","updated_at":"2025-08-20T16:30:54.912Z","avatar_url":"https://github.com/woodward.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Integrator\n\nA numerical integrator written in Elixir for the solution of sets of non-stiff ordinary differential\nequations (ODEs). \n\n## Installation\n\nThe package can be installed by adding `integrator` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:integrator, \"~\u003e 0.1\"},\n  ]\nend\n```\n\nThe docs can be found at \u003chttps://hexdocs.pm/integrator\u003e.\n\n\n## Description\n\nTwo integrator options are available; the first, `Integrator.RungeKutta.DormandPrince45`, is an \nadaptation of the [Octave ode45](https://octave.sourceforge.io/octave/function/ode45.html) and [Matlab\node45](https://www.mathworks.com/help/matlab/ref/ode45.html). The `DormandPrince45` integrator utilizes the\n[Dormand-Prince](https://en.wikipedia.org/wiki/Dormand%E2%80%93Prince_method) 4th/5th order Runge\nKutta algorithm.\n\nThe 2nd available integrator, `Integrator.RungeKutta.BogackiShampine23`, is an adaptation of the [Octave\node23](https://octave.sourceforge.io/octave/function/ode23.html) and [Matlab\node23](https://www.mathworks.com/help/matlab/ref/ode23.html) The `BogackiShampine23` integrator uses the\n[Bogacki-Shampine](https://en.wikipedia.org/wiki/Bogacki%E2%80%93Shampine_method) 3rd order Runge\nKutta algorithm.\n\nBoth `DormandPrince45` (which is the default integrator option) and `BogackiShampine23` utilize an \nadaptive stepsize algorithm for computing the integration time step.  The time step is computed based \non the satisfaction of a required error tolerance; that is, the time step is reduced as necessary in \norder to satisfy the error criteria.\n\nThis library heavily leverages [Elixir Nx](https://github.com/elixir-nx/nx); many thanks to the\n[creators of `Nx`](https://github.com/elixir-nx/nx/graphs/contributors), as without it this library\nwould not have been possible. The [GNU Octave code](https://github.com/gnu-octave/octave) was also\nused heavily for inspiration and was used to generate dozens of numerical test cases for the Elixir \nimplementations of the algorithms.  Many thanks to [John W. Eaton](https://jweaton.org/) for his tremendous \nwork on Octave. `Integrator` has been tested extensively during its development, and has a large and \ngrowing test suite (currently 180+ tests).\n\n\n## Usage\n\nSee the [Livebook guides](https://github.com/woodward/integrator/tree/main/guides) for detailed \nexamples of usage. As a simple example, you can integrate the Van der Pol equation as defined in \n`Integrator.SampleEqns.van_der_pol_fn/2` from time 0 to 20 with an intial x value of `[0, 1]` via:\n\n```elixir\nt_initial = 0.0\nt_final = 20.0\nx_initial = Nx.tensor([0.0, 1.0])\nsolution = Integrator.integrate(\u0026SampleEqns.van_der_pol_fn/2, t_initial, t_final, x_initial)\n```\n\nYou'll also probably want to capture the data output via an output function; see the Livebook guides for \ndetails.\n\n![images/van_der_pol](images/van_der_pol.png)\n\nOptions exist for:\n- outputting simulation results dynamically via an output function (for applications\nsuch as plotting dynamically, or for animating while the simulation is underway)\n- generating simulation output at fixed times (such as at `t = 0.1, 0.2, 0.3`, etc.)\n- interpolating intermediate points via quartic Hermite interpolation (for `DormandPrince45`) or via cubic\nHermite interpolation (for `BogackiShampine23`) \n- detecting termination events (such as collisions); see the Livebook guides for details.\n- increasing the simulation fidelity (at the expense of simulation time) via absolute tolerance and\n  relative tolerance settings\n- running the integration as a GenServer (via `Integrator.Integration`)  \n\n\n## Nx Backends\n\n`Integrator` has been verified to work with the [Nx binary backend](https://hexdocs.pm/nx/Nx.BinaryBackend.html), \n[EXLA](https://github.com/elixir-nx/nx/tree/main/exla), [EMLX](https://github.com/elixir-nx/emlx), \nand [TorchX](https://github.com/elixir-nx/nx/tree/main/torchx).  See the \n[guide for event functions](guides/event_functions.livemd) for examples of how to configure these backends.\n\n\n## So why should I care? A tool to solve ODEs? Why would I need this?\n\nThe basic gist of this project is that it is a tool in Elixir (that leverages [Nx](https://github.com/elixir-nx)) \nto numerically solve sets of ordinary differential equations (ODEs).  Science and engineering \nproblems typically generate either sets of ODEs or partial differential equations (PDEs). So basically \n`integrator` lets you solve any scientific or engineering problem which generates ODEs, which is an\nextremely large class of problems (finite element methods are frequently used to solve sets of PDEs).\n\nHundreds (or perhaps even thousands) of scientific problems had been formulated in the form of ODEs \nsince the time that Isaac Newton first invented calculus in the 1600's, but these problems remained \nintractable \u0026 unsolvable for over three centuries, other than a very small set of problems that were \namenable to closed form solutions; that is, the ODEs could be solved analytically via mathematical \nmanipulation. So there was this tragic dilemma; we could formulate the problems mathematically since\nthe 1600's through the early 1900's, but couldn't actually solve the problems, not until the advent \nof the digital computer.\n\nSo one of the primary drivers to create the first digital computers in the 1940's through the 1960's \nwas to solve these intractable and unsolvable ODEs that had been around for centuries. The space program, \nfor example, would have been impossible without the numerical solution of ODEs which represented the \nspace flight trajectories, spacecraft attitude, \u0026 control, etc. And before the first digital computers, \nanalog computers were used in some cases to solve ODEs back in the 1920's - 1940's.\n\nSo believe it or not, the first computers were initially developed and used to solve ODEs, not play \nLeague of Legends. :wink:\n\nThe algorithms to solve these ODEs are battle-tested and in some cases have been around for decades; \nMatlab and Octave are just relatively clean implementations of these algorithms that are used as the \nbasis for the Elixir implentations (primarily so that test cases can be generated).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoodward%2Fintegrator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwoodward%2Fintegrator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoodward%2Fintegrator/lists"}