How long are these lists going to be, and how many insertions/deletions will occur relative to the number of element lookups and in-place updates? Would it make sense to consider other random-access data structures (in particular, growable vectors) instead of lists?

-- Jeremiah Willcock

On Fri, 4 Jan 2013, Neil Toronto wrote:

My doctoral research is to beat the crap out of STAN, WinBUGS, etc., etc., by leveraging information you can only get by writing a compiler for a language with a formal definition.

There's no Bayesian DSL that can answer queries with arbitrary conditions like "X^2+Y^2 = 1.2". MCMC fails spectacularly. In fact, you can't even reason about those using Bayes' law for densities. But I've got a backend implementation based on a measure-theoretic semantics that can sample from distributions with conditions like that. :D

I needed a Typed Racket implementation of random-access lists to make it scale well for models with more than 20 random variables or so.

Neil ⊥

On 01/04/2013 05:50 PM, Ray Racine wrote:
MCMC with Gibbs Sampling and MH for straightforward stuff is
straightforward, but the subtitles of underflow, use log space or not
etc are something you guys know quite a bit more about than I do.

FWIW, a few months ago I was doing some custom Racket coded for
straightforward Gibbs (mainly) and MH in one case for customer related
data analysis, but the water gets deep quickly beyond the
straightforward, and one quickly questions the validity of their custom
sampler against  considerations of a proven MCMC library.  I did a brief
amount research on the current state of things with regards to WinBugs,
OpenBugs, Jags, ... After a quick overview, I sort of narrowed things
down to a relatively new arrival, STAN. https://code.google.com/p/stan/

It's a new rewrite, based on a new sampling algorithm variation
where existent libraries are getting long in the tooth.  It generates
the sampling code rather then interprets BUGS DSL code and claims to
take some pains to support FFI binding (R of course) and embedding.

Just wanted to mention STAN if you haven't run across it yet,  as
opposed to well know standby MCMC libs.

One day ... an FFI Racket <-> STAN would be very cool.


On Jan 4, 2013 4:47 PM, "Neil Toronto" <neil.toro...@gmail.com
<mailto:neil.toro...@gmail.com>> wrote:

    I get excited about applying statistics to programming. Here's
    something exciting I found today.

    I'm working on a Typed Racket implementation of Chris Okasaki's
    purely functional random-access lists, which are O(1) for `cons',
    `first' and `rest', and basically O(log(n)) for random access. I
    wanted solid randomized tests, and I figured the best way would be
    bisimulation: do exactly the same, random thing to a (Listof
    Integer) and an (RAList Integer), then ensure the lists are the
    same. Iterate N times, each time using the altered lists for the
    next bisimulation step.

    There's a problem with this, though: the test runtimes are all over
    the place for any fixed N, and are especially wild with large N.
    Sometimes it first does a bunch of `cons' operations in a row.
    Because each bisimulation step is O(n) in the list length (to check
    equality), this makes the remaining steps very slow. Sometimes it
    follows up with a bunch of `rest' operations, which makes the
    remaining steps very fast.

    More precisely, random bisimulation does a "simple random walk" over
    test list lengths, where `cons' is a step from n to n+1 and `rest'
    is a step from n to n-1. Unfortunately, the n's stepped on in a
    simple random walk have no fixed probability distribution, and thus
    no fixed average or variance. That means each bisimulation step has
no fixed average runtime or fixed variation in runtime. Wildness ensues.

    One possible solution is to generate fresh test lists from a fixed
    distribution, for each bisimulation step. This is a bad solution,
    though, because I want to see whether RAList instances behave
    correctly *over time* as they're operated on.

    The right solution is to use a Metropolis-Hastings random walk
    instead of a simple random walk, to sample list lengths from a fixed
    distribution. Then, the list lengths will have a fixed average,
    meaning that each bisimulation step will have a fixed average
    runtime, and my overall average test runtime will be O(N) instead of
    wild and crazy.

    First, I choose a distribution. The geometric family is good because
    list lengths are nonnegative. Geometric with p = 0.05 means list
    lengths should be (1-p)/p = 19 on average, but are empty with
    probability 0.05 and very large with very low probability.

    So I add these two lines:

       (require math/distributions)

       (define length-dist (geometric-dist 0.05))

    In a Metropolis-Hastings random walk, you step from n to n' with
    probability min(1,P(n')/P(n)); this is called "accepting" the step.
    Otherwise, you "reject" the step by staying in the same spot. Adding
    this new test takes only two defines and a `cond':

       (define r (random 5))  ; Randomly choose an operation
       (cond
         [(= r 0)
          ;; New! Only cons with probability P(n+1)/P(n)
          (define n (length lst))
          (define accept (/ (pdf length-dist (+ n 1))
                            (pdf length-dist n)))
          (cond [((random) . < . accept)
                 .... Accept: cons and ensure continued equality ....]
                [else
                 .... Reject: return the same lists ....])]
         [(= r 1)
          .... Accept: `rest' each list and ensure continued equality ....]
         .... Other random operations ....)

    I left off the acceptance test for `rest' because P(n-1) > P(n) ==>
    P(n-1)/P(n) > 1, so the test would always pass. (This is because the
    geometric distribution's pdf is monotone. If I had chosen a Poisson
    distribution, which has a bump in the middle, I'd have to do the
    acceptance test for both `cons' and `rest'.)

    I instrument the test loop to record list lengths, verify that their
    mean is about 19, and do some density plots vs. the geometric
    distribution. It all looks good: the randomized bisimulation test
    does indeed operate on lists whose length is distributed
    Geometric(0.05), so the overall average test runtime is O(N), and it
    still tests them as they're operated on over time.

    Neil ⊥
    ____________________
      Racket Users list:
    http://lists.racket-lang.org/__users
    <http://lists.racket-lang.org/users>


____________________
Racket Users list:
http://lists.racket-lang.org/users
____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to