Saturday, 15 September 2012

MathP Examples

MathP is my Maths DSL for Common Lisp. Here are some examples of it in use. If you want to run these examples, don't forget to either use MathP (use-package '#:mathp), or qualify uses of fn as mathp:fn. Here we go:

In simple calculations. The REPL becomes a very powerful calculator:
#M dt=6 v=9 nl=2 v/dt*3600d0/nl
I appreciate brackets, but I also find it a lot quicker to write these kind of expressions at the REPL.

Here's the choose function:
#M(defun choose (n k)
   {assert(integerp(n) && integerp(k) && n >= k >= 0)
    result = 1
    #L(loop for i from 1 to k do #M result *= (n-k+i) / i)

Note the use of logical and (&&) as well as chained comparisons in the assert expression. I've also used the mutating assignment operator *=. MathP also contains +=, -=, /=, ^=, &= and |= (the last two perform logical and/or, not bitwise and/or).

To calculate normal distributions with closures:
#M e = exp(1d0)  scale = 1/sqrt(2*pi) #L
(defun normal-distribution (mean stdev)
    #M fn(x) scale/stdev * e^-(0.5d0*(x-mean)^2/stdev^2))
In the above, we use #L to read in a lisp form from within the MathP form. The top level of the MathP form with the #L would normally stop reading at the end of the line, but the lisp reader invoked by #L conveniently consumes it for us.

And to test the above normal distribution calculator:
(loop with dist = (normal-distribution 0 1)
      for x from -3 to 3.1 by 0.2
    do (format t "~&~4,1F ~A~%" x
               (make-string (round #M 40 * #!dist(x))
                            :initial-element #\=)))

The #! above is a syntax for funcall, where the actual function call looks like a normal function call in MathP.

And one last one, the binomial probability mass function:
#M defun binomial (p n k) choose(n k) * p^k * (1-p)^(n-k)

No comments:

Post a Comment