Nice. I haven't been able yet to test any of these, anyone?

What is your opinion about physics in Reactive? Should we try to make an adapter to an optimized imperative physics engine, or should we write one in Haskell?



On Wed, Dec 3, 2008 at 10:38 PM, Creighton Hogg <wchogg@gmail.com> wrote:
So this is a bit of a brainstorming post.  I did a little thinking
earlier about different simple ODE solving techniques, and tried to
translate them fairly directly into Reactive.  The result isn't pretty
& I'd like to talk about that.

The naive definitions, to me, of the Euler, Euler-Cromer, and Midpoint
methods should look like the following.  Each takes in an Event (),
initial positions & velocities, and a Behavior (v -> v -> v) that is
the acceleration as a function of time.  We want to be general since
the acceleration may be an explicit function of time as well as as
position & velocity.

euler tau x0 v0 a = liftA2 (,) x v
  where x = accumB x0 (fmap (^+^) (liftA2 (^*) (prev vi) deltaTs))
        v = accumB v0 (fmap (^+^) (liftA2 (^*) ai deltaTs))
        ai = (snapshot_ tau a) <*> (prev xi) <*> (prev vi)
        xi = (snapshot_ tau x)
        vi = (snapshot_ tau v)
        deltaTs = diffE (tau `snapshot_` time)

eulerCromer tau x0 v0 a = liftA2 (,) x v
 where x = accumB x0 (fmap (^+^) (liftA2 (^*) vi deltaTs))
       v = accumB v0 (fmap (^+^) (liftA2 (^*) ai deltaTs))
       ai = (snapshot_ tau a) <*> (prev xi) <*> (prev vi)
       xi = snapshot_ tau x
       vi = snapshot_ tau v
       deltaTs = diffE (tau `snapshot_` time)

midpoint tau x0 v0 a = liftA2 (,) x v
 where x = accumB x0 (fmap (^+^) (liftA2 (^*) vavg deltaTs))
       v = accumB v0 (fmap (^+^) (liftA2 (^*) ai deltaTs))
       ai = (snapshot_ tau a) <*> (prev xi) <*> (prev vi)
       xi = snapshot_ tau x
       vi = snapshot_ tau v
       deltaTs = diffE (tau `snapshot_` time)
       vavg = fmap (^/2) $ liftA2 (^+^) vi (prev vi)

prev :: Event a -> Event a
prev = fmap snd . withPrevE

this code is fairly verbose, but that's because I'm trying to be very
explicit about the ordering of the sampling & how the new values at
each time step are created.  The problem is that I feel like I'm
wrestling very hard against Reactive rather than working with it.  I
was hoping that I could get some feedback on a way to write these very
simple algorithms that is more inline with the spirit of the API.