• Stars
    star
    134
  • Rank 270,967 (Top 6 %)
  • Language
    Haskell
  • License
    BSD 3-Clause "New...
  • Created almost 8 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simulate physics on generalized coordinate systems using Hamiltonian Mechanics and automatic differentiation. Don't throw away your shot.

Hamilton

Build Status

Simulate physics on arbitrary coordinate systems using automatic differentiation and Hamiltonian mechanics. State only an arbitrary parameterization of your system and a potential energy function!

For example, a simulating a double pendulum system by simulating the progression of the angles of each bob:

My name is William Rowan Hamilton

You only need:

  1. Your generalized coordinates (in this case, θ1 and θ2), and equations to convert them to cartesian coordinates of your objects:

    x1 = sin θ1
    y1 = -cos θ1
    x2 = sin θ1 + sin θ2 / 2      -- second pendulum is half-length
    y2 = -cos θ1 - cos θ2 / 2
  2. The masses/inertias of each of those cartesian coordinates (m1 for x1 and y1, m2 for x2 and y2)

  3. A potential energy function for your objects:

    U = (m1 y1 + m2 y2) * g

And that's it! Hamiltonian mechanics steps your generalized coordinates (θ1 and θ2) through time, without needing to do any simulation involving x1/y1/x2/y2! And you don't need to worry about tension or any other stuff like that. All you need is a description of your coordinate system itself, and the potential energy!

doublePendulum :: System 4 2
doublePendulum =
    mkSystem' (vec4 m1 m1 m2 m2)            -- masses
              (\(V2 θ1 θ2)     -> V4 (sin θ1)            (-cos θ1)
                                     (sin θ1 + sin θ2/2) (-cos θ1 - cos θ2/2)
              )                             -- coordinates
              (\(V4 _ y1 _ y2) -> (m1 * y1 + m2 * y2) * g)
                                            -- potential

Thanks to Alexander William Rowan Hamilton, we can express our system parameterized by arbitrary coordinates and get back equations of motions as first-order differential equations. This library solves those first-order differential equations for you using automatic differentiation and some matrix manipulation.

See a blog post I wrote on this, and also the hackage documentation and the example runner user guide (and its source).

Full Example

Let's turn our double pendulum (with the second pendulum half as long) into an actual running program. Let's say that g = 5, m1 = 1, and m2 = 2.

First, the system:

import           Numeric.LinearAlgebra.Static
import qualified Data.Vector.Sized as V


doublePendulum :: System 4 2
doublePendulum = mkSystem' masses coordinates potential
  where
    masses :: R 4
    masses = vec4 1 1 2 2
    coordinates
        :: Floating a
        => V.Vector 2 a
        -> V.Vector 4 a
    coordinates (V2 θ1 θ2) = V4 (sin θ1)            (-cos θ1)
                                (sin θ1 + sin θ2/2) (-cos θ1 - cos θ2/2)
    potential
        :: Num a
        => V.Vector 4 a
        -> a
    potential (V4 _ y1 _ y2) = (y1 + 2 * y2) * 5


-- some helper patterns to pattern match on sized vectors
pattern V2 :: a -> a -> V.Vector 2 a
pattern V2 x y <- (V.toList->[x,y])
  where
    V2 x y = fromJust (V.fromList [x,y])

pattern V4 :: a -> a -> a -> a -> V.Vector 4 a
pattern V4 x y z a <- (V.toList->[x,y,z,a])
  where
    V4 x y z a = fromJust (V.fromList [x,y,z,a])

Neat! Easy, right?

Okay, now let's run it. Let's pick a starting configuration (state of the system) of θ1 and θ2:

config0 :: Config 2
config0 = Cfg (vec2 1 0  )  -- initial positions
              (vec2 0 0.5)  -- initial velocities

Configurations are nice, but Hamiltonian dynamics is all about motion through phase space, so let's convert this configuration-space representation of the state into a phase-space representation of the state:

phase0 :: Phase 2
phase0 = toPhase doublePendulum config0

And now we can ask for the state of our system at any amount of points in time!

ghci> evolveHam doublePendulum phase0 [0,0.1 .. 1]
-- result: state of the system at times 0, 0.1, 0.2, 0.3 ... etc.

Or, if you want to run the system step-by-step:

evolution :: [Phase 2]
evolution = iterate (stepHam 0.1 doublePendulum) phase0

And you can get the position of the coordinates as:

positions :: [R 2]
positions = phsPositions <$> evolution

And the position in the underlying cartesian space as:

positions' :: [R 4]
positions' = underlyingPos doublePendulum <$> positions

Example App runner

(Source)

Installation:

$ git clone https://github.com/mstksg/hamilton
$ cd hamilton
$ stack install

Usage:

$ hamilton-examples [EXAMPLE] (options)
$ hamilton-examples --help
$ hamilton-examples [EXAMPLE] --help

The example runner is a command line application that plots the progression of several example system through time.

Example Description Coordinates Options
doublepend Double pendulum, described above θ1, θ2 (angles of bobs) Masses of each bob
pend Single pendulum θ (angle of bob) Initial angle and velocity of bob
room Object bounding around walled room x, y Initial launch angle of object
twobody Two gravitationally attracted bodies, described below r, θ (distance between bodies, angle of rotation) Masses of bodies and initial angular veocity
spring Spring hanging from a block on a rail, holding up a weight r, x, θ (position of block, spring compression, spring angle) Masses of block, weight, spring constant, initial compression
bezier Bead sliding at constant velocity along bezier curve t (Bezier time parameter) Control points for arbitrary bezier curve

Call with --help (or [EXAMPLE] --help) for more information.

More examples

Two-body system under gravity

The two-body solution

  1. The generalized coordinates are just:

    • r, the distance between the two bodies
    • θ, the current angle of rotation
    x1 =  m2/(m1+m2) * r * sin θ        -- assuming (0,0) is the center of mass
    y1 =  m2/(m1+m2) * r * cos θ
    x2 = -m1/(m1+m2) * r * sin θ
    y2 = -m1/(m1+m2) * r * cos θ
  2. The masses/inertias are again m1 for x1 and y1, and m2 for x2 and y2

  3. The potential energy function is the classic gravitational potential:

    U = - m1 * m2 / r

And...that's all you need!

Here is the actual code for the two-body system, assuming m1 is 100 and m2 is 1:

twoBody :: System 4 2
twoBody = mkSystem masses coordinates potential
  where
    masses :: R 4
    masses = vec4 100 100 1 1
    coordinates
        :: Floating a
        => V.Vector 2 a
        -> V.Vector 4 a
    coordinates (V2 r θ) = V4 (r1 * cos θ) (r1 * sin θ)
                              (r2 * cos θ) (r2 * sin θ)
      where
        r1 =   r *   1 / 101
        r2 = - r * 100 / 101
    potential
        :: Num a
        => V.Vector 4 a
        -> a
    potential (V2 r _) = - 100 / r

Potential improvements

  • Time-dependent systems: Shouldn't be an problem in theory/math; just add a time parameter before all of the functions. This opens a lot of doors, like deriving inertial forces for free (like the famous Coriolis force and centrifugal force).

    The only thing is that it makes the API pretty inconvenient, because it'd require all of the functions to also take a time parameter. Of course, the easy way out/ugly solution would be to just offer two versions of the same function (one for time-independent systems and one for time-dependent systems. But this is un-ideal.

  • Velocity-dependent potentials: Would give us the ability to model systems with velocity-dependent Lagrangians like a charged particle in an electromagnetic field, and also dissipative systems, like systems with friction (dependent on signum v) and linear & quadratic wind resistance.

    This issue is much harder, theoretically. It involves inverting arbitrary functions forall a. RealFloat a => V.Vector n a -> V.Vector m a. It might be possible with the help of some bidirectionalization techniques, but I can't get the bff package to compile, and I'm not sure how to get bff-mono to work with numeric functions.

    If anyone is familiar with bidirectionalization techniques and is willing to help out, please send me a message or open an issue! :)

More Repositories

1

backprop

Heterogeneous automatic differentiation ("backpropagation") in Haskell
Haskell
180
star
2

auto

Haskell DSL and platform providing denotational, compositional api for discrete-step, locally stateful, interactive programs, games & automations. http://hackage.haskell.org/package/auto
Haskell
176
star
3

advent-of-code-2020

🎅🌟❄️☃️🎄🎁
Haskell
98
star
4

advent-of-code-2018

Advent of Code 2018 Solutions (Spoilers!)
Haskell
83
star
5

inCode

Source for personal blog.
Haskell
74
star
6

advent-of-code-2019

Advent of Code 2019 Solutions (Spoilers!)
Haskell
66
star
7

tensor-ops

Type-safe tensor manipulation operations in Haskell with tensorflow-style automatic differentiation
Haskell
60
star
8

advent-of-code-2017

Advent of Code 2017 (Warning: Spoilers)
Haskell
49
star
9

advent-of-code-2021

🎅🌟❄️☃️🎄🎁
Haskell
43
star
10

mutable

Automatic piecewise-mutable references for your types
Haskell
42
star
11

functor-combinators

Combine and enhance Functors
Haskell
38
star
12

backprop-learn

Combinators and types for easily building trainable neural networks using the backprop library
Haskell
33
star
13

servant-cli

Generate a command line client from a servant API
Haskell
29
star
14

uncertain

Manipulating numbers with inherent measurement/experimental uncertainty.
Haskell
25
star
15

setup-stack

Github action for setting up haskell stack
JavaScript
24
star
16

nonempty-containers

Efficient non-empty variants of containers data types, with full API
Haskell
23
star
17

advent-of-code-dev

Interactive development environment and runner for Advent of Code challenges
Haskell
23
star
18

ghcjs-websockets

GHCJS interface for the Javascript Websocket API (DEPRECATED: use ghcjs-base's native websockets!)
Haskell
22
star
19

corona-charts

Ultimate interactive COVID-19 data plotter
PureScript
21
star
20

typelits-printf

Type-safe printf from parsing GHC TypeLits Symbol
Haskell
20
star
21

auto-examples

Example projects using the auto library.
Haskell
19
star
22

lens-typelevel

Type-level lenses using singletons because why not
Haskell
15
star
23

opto

Numerical optimization with support for stochastic optimization, mostly for my own experimental usage
Haskell
14
star
24

advent-of-code-api

Haskell bindings to Advent of Code REST API
Haskell
14
star
25

interactive-plot

Quick interactive time series terminal plots usable in ghci
Haskell
14
star
26

hmatrix-backprop

backprop primitives for hmatrix
Haskell
13
star
27

advent-of-code-2022

🎅🌟❄️☃️🎄🎁
Haskell
12
star
28

prompt

Monad and transformer for deferred-effect pure prompt-response queries
Haskell
12
star
29

decidable

Combinators for manipulating dependently-typed predicates.
Haskell
12
star
30

servant-validate

Validate well-formed servant APIs at compile time
Haskell
10
star
31

typelits-witnesses

Existential witnesses, singletons, and classes for operations on GHC TypeLits
Haskell
9
star
32

hakyll-dhall

Dhall compiler for Hakyll
Haskell
8
star
33

conduino

Lightweight composable continuation-based stream processors
Haskell
8
star
34

tic-tac-typed

Exploring a "type-safe" Tic-Tac-Toe in Haskell
Haskell
8
star
35

emd

Hilbert-Huang Transform (Empirical Mode Decomposition) in pure Haskell
Haskell
7
star
36

blog

Source for blog engine/static website. Haskell Web Development learning project.
Haskell
7
star
37

talks

Collection of slides, notes, and posters for public talks I've given.
HTML
6
star
38

wavelets

wavelet decomposition in haskell
Haskell
6
star
39

bins

Aggregate continuous variables into discrete bins
Haskell
6
star
40

one-liner-instances

Default implementations for common typeclasses using one-liner
Haskell
6
star
41

get-package

Github action for installing packages from OS package managers
JavaScript
6
star
42

log.sh

Simple command line note/logging script for one-off notes
Shell
6
star
43

data-diff

Derivable diffing and patching on arbitrary data types using GHC Generics
Haskell
5
star
44

purdle

wordle clone in purescript for fun
JavaScript
5
star
45

advent-of-code-ocr

Parsing ASCII art word solutions for advent of code
Haskell
5
star
46

dhallscript

Embedded scripting language in dhall
Haskell
5
star
47

pandoc-sync

Automatic one- and two-way syncing of pandoc sources and renders
Haskell
5
star
48

tic-tac-miso

type-safe tic tac toe with Miso GUI
Haskell
4
star
49

santabot

Source for the freenode ##adventofcode irc bot monitoring Advent of Code
Haskell
4
star
50

type-combinators-singletons

Interop between type-combinators and singletons library
Haskell
4
star
51

dhall-typed

Manipulate typed dhall expressions
Haskell
4
star
52

otp-authenticator

OTP Authenticator (ala Google Authenticator) cli app
Haskell
4
star
53

cluster

Clustering algorithms for fun
Haskell
4
star
54

quotiented

Quotient types in Haskell using smart constructors, associated types, and MPTCs
Haskell
3
star
55

eggvisor

Finds optimal research path for a desired end goal, for the Auxbrain game Egg, Inc.
Haskell
3
star
56

tagged-binary

Provides tools for serializing data tagged with type information
Haskell
3
star
57

auto-chatbot

Chatbot framework over the auto library
Haskell
2
star
58

backpack-tensor

backpack signatures and implements for tensor operations
Haskell
2
star
59

generics-lift

GHC Generics for deriving numeric typeclasses, Monoid, and other similar classes.
Haskell
2
star
60

forms-applicative

playing around with free applicatives/alternatives for validated forms
Haskell
2
star
61

auto-frp

Implementation of the FRP programming model providing the ability to work with real-time semantics using tools from the auto library
Haskell
2
star
62

cv-static

Source for static CV
Dhall
2
star
63

jlebot2

General-purpose chatbot, re-written to use the "auto" library
Haskell
2
star
64

neural-tests

tests and benchmarks for experimental neural networks
Haskell
2
star
65

netwire-experiments

Experiments and learning with the Haskell FRP Library Netwire
Haskell
2
star
66

dashboard

Personal dashboard for my OSS projects
Dhall
2
star
67

advent-of-code-2016

Solutions for Advent of Code 2016 (Spoilers!)
Haskell
2
star
68

corona-analysis

Collection of some simple personal scripts for COVID-19 data analysis
Haskell
2
star
69

dhall-text-shell

dhall text but provide shell commands as function arguments
Haskell
2
star
70

functor-products

Generalized functor products based on lifted foldables
Haskell
2
star
71

memotag

Memoized function application tuples with convenient lens interface
Haskell
1
star
72

expr-gadt

Expression and Lambda Calc type experiments using GADTs for complete type safety
Haskell
1
star
73

typescript-json

Type-safe bidirectional serializers to and from typescript-compatible json
Haskell
1
star
74

jlscript

Object-oriented, statically & duck typed, mixed-purity interpreted scripting language.
Haskell
1
star
75

connection-logger.sh

Short bash script to monitor the host server's internet connection and log latencies/disconnections to stdout.
Shell
1
star
76

hmatrix-sized

hmatrix wrapper with GHC TypeLits-based length-encoded types
Haskell
1
star
77

dmats

Dependently typed compiled programming language for matrix manipulation
Haskell
1
star
78

jlebot

simple irc bot in haskell, for fun
Haskell
1
star
79

traversablet

Instant monad transformers for any Traversable
Haskell
1
star
80

phys108L

Source for "Electromagnetism Physics Labs" that can be done at home with household items
Haskell
1
star
81

vector-algorithms-sized

vector-sized wrapper for vector-algorithms
Haskell
1
star
82

jle-utils

Suite of general utility scripts I use to navigate life
Haskell
1
star
83

pi-monte-carlo

Path Integral Monte Carlo simulation pet project for learning Haskell
Haskell
1
star
84

hackerrank

Hackerrank Fun (for livestream)
Haskell
1
star
85

hmatrix-vector-sized

Conversion between hmatrix and vector-sized types
Haskell
1
star
86

aurum

Fast, lightweight, pull-based FRP
Haskell
1
star
87

Emerge

Project exploring emergent behavior in an environment governed run by natural selection and competition
Ruby
1
star
88

como

Numerical analysis and algorithm platform in Haskell powered by comonads and cokleisli composition.
Haskell
1
star
89

neural

Playing with neural networks in haskell just for fun
Haskell
1
star
90

bff-mono

Fork of https://bitbucket.org/kztk/bff-mono
Haskell
1
star
91

dhall-cv-latex

latex output for dhall-cv project
Dhall
1
star
92

list-witnesses

Inductive dependently-typed witnesses for working with type-level lists.
Haskell
1
star
93

slicer

Haskell
1
star
94

CPSC229-03-WI16-Course-Materials

Course materials (lecture slides, live code records, notes) for CPSC229-03 Functional Programming and Haskell at Chapman University
Haskell
1
star
95

configurator-export

Pretty printer and exporter for configurations from the 'configurator' library
Haskell
1
star
96

cm-dip

Some experiments with comonads for digital image processing. Warning: pretty messy, not really intended for presentation :)
Haskell
1
star