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)

result})

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