Mitch Richling: MJRCALC – LISP Mathematical Library
Author: | Mitch Richling |
Updated: | 2022-06-26 |
Table of Contents
- 1. What is it?
- 2. How do I use it?
- 3. Gallery
- 3.1. Theoretical Cloud/Grid/Cluster Computing (Rendered via VisIt)
- 3.2. Differential Equations (Rendered via GNUPlot & VisIt)
- 3.3. Optimization (Rendered via VisIt)
- 3.4. Ray Traced Visualization (Rendered via POV-Ray)
- 3.5. Mandelbrot Set Fractals (Rendered via direct image synthesis)
- 3.6. Newton Fractals (Rendered via direct image synthesis)
- 3.7. Mandelbrot Mountain Fractals (Rendered via VisIt or POV-Ray
- 3.8. Polynomial Interpolation (Rendered via GNUPlot)
- 3.9. Orthogonal Polynomials (Rendered via GNUPlot)
- 3.10. Random Stuff
- 4. Support
- 5. Loading and using the Code in your REPL
- 6. Interactive Use
- 7. Code Base
- 8. FAQ
1. What is it?
I have developed a great affinity for using LISP as an interactive mathematical problem solving tool and general algorithm development environment. This has resulted in the accumulation of a good deal of mathematically oriented LISP code over the years, and sharing that code is what this page is all about. So, if you are a mathematically inclined LISPer looking for a particular mathematical routine, then you may well be in the right place – assuming you have a high tolerance for ugly/buggy LISP and can forgive my unapologetic, raging case of NIH Syndrome!
2. How do I use it?
First and foremost, I keep a REPL up and running all the time with this code loaded – makes for a great alternative to those silly GUI calculator
applications! Please note the code really is designed for interactive use inside of a smart REPL. I use
SLIME+SBCL inside of GNU Emacs. *MJRCALC*
is in no way a
replacement for tools like Maple or Mathematica – I use them both. Instead of trying to do
everything with a single, powerful tool, I find my problem solving efficiency is much higher when I use a suite of specialized tools for tasks each is
particularly good at, and this is where *MJRCALC*
comes into play. I think of it as a bit of glue allowing me to more effectively weave such tools
together. In fact, I frequently have several mathematical tools running in the same Emacs session with *MJRCALC*
:
Octavestats Maximastats GAPstats
Macaulay2stats and R Speaking of weaving systems together, *MJRCALC*
can drive
GNUPlot through a pipe for simple, immediate visualization. For more sophisticated, interactive visualization, *MJRCALC*
can produce VTK files for tools like VisIt and Paraview – I really love VisIT. For less
immediate visualization needs, *MJRCALC*
can also generate files for POV-Ray.
What can all of this LISP code do? That's a hard question to answer directly, so I'll just list some of the things I have used it for over the years:
- Desktop calculator replacement. ;)
- Development and prototyping of deeply algorithmic and/or mathematical software
- Numerical analysis
- linear algebra
- integration
- ODEs
- PDEs
- Optimization
- Root finding
- Dynamical systems modeling and simulation (ODEs, PDEs, and algebraic equations)
- Efficient solutions to Kepler's equation
- High speed orbital dynamics (modeling the motion of thousands of solar system bodies)
- High accuracy integration of planetary systems
- Large scale particle simulation (Galactic dynamics, fungal growth, fountains, …)
- Diffusion simulations
- Mathematical Population dynamics
- Symbolic algebra
- Computational commutative algebra (solving polynomial systems, Grobner basis, etc…)
- Non-numeric root localization
- Rational and integer roots and critical points
- Combined symbolic and numerical algorithms
- Factorization of polynomials over the integers and prime order fields
- Symbolic differentiation of LISP forms
- Analytical solution of differential equations
- Combinatorial enumeration and counting algorithms
- Most of the 12-fold way
- Several combinatorial functions
- Generation of combinatorial objects (sets, cross products, permutations, combinations)
- Computational group theory
- Electron orbital mechanics
- Crystal lattice formation
- Probabilistic modeling and simulation (complex systems or statistical tests)
- Sophisticated data visualization problems
- Project Euler problems
3. Gallery
Instead of providing a few boring snips of code, here are some pretty pictures generated by this code base in conjunction with tools like GNUPlot, VisIt, and POV-Ray.
3.1. Theoretical Cloud/Grid/Cluster Computing (Rendered via VisIt)
3.3. Optimization (Rendered via VisIt)
3.4. Ray Traced Visualization (Rendered via POV-Ray)
3.8. Polynomial Interpolation (Rendered via GNUPlot)
3.9. Orthogonal Polynomials (Rendered via GNUPlot)
4. Support
Please feel free to contact me if you find a bug, have an idea for an improvement, or just want to chat about implementation details. I can't guarantee I'll be able to act on such feedback in a timely fashion, but I do try very hard to eventually read and respond to all of my mail.
4.1. Paid support
Sorry, I don't provide paid support for this product. I have previously accepted contracts for very specific enhancement requests; however, my acceptance has been most strongly influenced by just how interesting the project was and not the cash offer.
4.2. Contributed Patches
I hate to say it, but contributed patches are difficult to deal with because of the complexity of copyright and IP law. I would rather get a bug report or enhancement request in plain English than a patch file.
4.3. About Quality and Consistency
This code base is an organically growing and evolving project dynamically changing as my work and needs evolve. This has a couple implications. First, this code base will always contain various functions in the middle of being re-factored (i.e. broken) or in the process of being implemented. The second implication is that I freely change things as I recognize dumb API decisions and find opportunities to make the code work better. If you plan on including this code in a long term project, then my advice is to fork the code and then be very careful about updates.
5. Loading and using the Code in your REPL
The authoritative source for information regarding how to load the code into your LISP is found in the documentation string for the function MJR_META_HELP
found in the :MJR_META
package in the file lib-meta.lisp
.
What follows is a brief, perhaps out of date, account of what you can find documented that file.
lib-meta.lisp
.
5.1. The ASDF Way
If your LISP has a modern (post v3) version of ASDF installed and you have placed the source for *MJRCALC*
into one of the places your ASDF looks for
packages, then you can simply do the following:
(load "/full/path/to/where/you/put/*MJRCALC*/sup-lm-asdf.lisp")
Of course you can use the file name, not the full path, if your LISP is in the directory with the *MJRCALC*
source. The code in the
sup-lm-asdf.lisp
file is quite simple. In essence, it runs three functions:
(require :asdf) (asdf:load-system :mjrcalc) (mjr_meta::mjr_meta_use-packages :BASE-PATH "/full/path/to/where/you/put/*MJRCALC*/")
5.2. The Meta Way
While most users will make use of ASDF, this not a requirement. The :MJR_META
package can load the code (and do a whole lot more). If you just want to load
everything up and do a use-package
on everything, then the following will do the trick:
(load "/full/path/to/where/you/put/*MJRCALC*/lib-meta.lisp") (mjr_meta::mjr_meta_load-packages :BASE-PATH "/full/path/to/where/you/put/*MJRCALC*/") (mjr_meta::mjr_meta_use-packages :BASE-PATH "/full/path/to/where/you/put/*MJRCALC*/")
If your LISP is in the directory with the *MJRCALC*
code, then you can nix the :base-path
argument, and use just the file name in the load
call. In
fact, if you are in the directory with the *MJRCALC*
, then you could simply load up
sup-lm-meta.lisp
.
(load "sup-lm-meta.lisp")
This last method is most like the load system used by *MJRCALC*
before the conversion to ASDF. So if you have some old code looking for an equivalent to
the historical load method, this is where to start.
6. Interactive Use
All the functions are contained in packages. All package names begin with the string "MJR_
". Following this standard prefix is a tag describing the
category of functionality and an underscore. Immediately after this second underscore, is a descriptive name for the function. For example, "MJR_MAT_NORM
"
is a matrix function computing a norm while "mjr_nleq_root-newton
" is a function for "NonLinear EQuations" which finds roots via Newton's method.
Because of this naming structure, tab completion may be used to great advantage both as a way to save typing effort and a way to discover function names. SLIME shows the function argument names in the Emacs message window after the function name and a space are typed at the REPL prompt, so function arguments are somewhat systematically named across packages and are a bit more verbosely named than is usual for LISP code.
All the functions have a comment string, so you can use LISP's documentation system to learn about them. Most packages have a "help" function,
mjr_nleq_help
for example, which will dump its own documentation string when evaluated – this string generally contains a description of the package and
some information useful for understanding how to use the package. You can also take a look at the comment at the top of each file. The unit tests, linked in
the download section below, can be a great help in understanding what the functions are intended to do. Finally, several examples linked below may be helpful
in understanding how to use the library.
7. Code Base
The source is on github.
- exp-BoatGo.lisp
- Drug smuggler boat path
- exp-ClassicOptAckley.lisp
- Analysis of the classic Rosenbrock banana optimization test function.
- exp-ClassicOptBanana.lisp
- Analysis of the classic Rosenbrock banana optimization test function.
- exp-ClassicOptBeale.lisp
- Analysis of the classic Beale optimization test function.
- exp-ClassicOptFreudensteinRoth.lisp
- Analysis of the classic Freudenstein-Roth optimization test function.
- exp-CLT.lisp
- Theoretical family of probability distributions of sums of an input PDF represented as a historgram.
- exp-compareComplexFunction.lisp
- Compare the value of a function in Maxima vs on in MJRCALC.
- exp-ComplexFunctionViz.lisp
- Complex function visualization via VTK files.
- exp-dXXXX.lisp
- Example for :MJR_DQUAD.
- exp-Euler.lisp
- Solutions to Project Euler Problems.
- exp-FixedPointItr.lisp
- Some :MJR_NLEQ examples.
- exp-Gravity2D.lisp
- Demonstrate the danger of assuming everything is a sphere in gravity problems.
- exp-Gravity3D.lisp
- Difference between two gravitational systems with the same total mass.
- exp-IntFactors.lisp
- For the integers n in [1,72], list the first integer such that it has n unique divisors.
- exp-IntrpMitch.lisp
- Error Interpolating Runge's Function with Mitch Nodes of the First Kind vs Chebyshev Nodes.
- exp-IntrpRunge.lisp
- Demonstrate how adding more interpolation poitns may lead to worse fit.
- exp-Kepler.lisp
- Draw Newton-like fractal and output to a TGA file.
- exp-Life.lisp
- Read in a life RLE file, and iterate (dumping a TGA at each step) until the pattern cycles.
- exp-MandelbrotOrbit.lisp
- Compute Mandelbrot set, and dump it to a TGA file using unique coloring scheme.
- exp-MandelbrotPot.lisp
- Draw the potential of the mandelbrot set.
- exp-MandelbrotTGA.lisp
- Compute Mandelbrot set, and dump it to a TGA file using a nice pallet.
- exp-MandelbrotVTK.lisp
- Draw the Mandelbrot set, and save it as a VTK file.
- exp-marsden-ch3sec3ex17.lisp
- Solving a vector calculus problem.
- exp-Newton.lisp
- Draw Newton fractal and output to a TGA file.
- exp-Newton2.lisp
- Modified Newton's method fractals colored with the arg of the 20'th iterate.
- exp-ODEalgCmp.lisp
- Solve a simple ODE, and plot the results.
- exp-ODEcannon.lisp
- Cannon shot simulation.
- exp-ODEcircle.lisp
- Example of an ODE plot.
- exp-ODElorenzDEQ.lisp
- Compute (with :MJR_ODE) and draw the Lorenz strange attracter.
- exp-ODElorenzEuler.lisp
- Compute and draw the Lorenz strange attracter without :MJR_ODE..
- exp-ODEpopulationCompete.lisp
- Plot the direction field for an ODE of two competing populations.
- exp-ODErossler.lisp
- Compute the Rossler strange attracter.
- exp-ODEthreeBody.lisp
- A famous 3-body problem.
- exp-OrthoPolys.lisp
- Draw several sets of orthogonal polynomials.
- exp-PiPrime.lisp
- Find primes who's quotient approximates pi. We want the smallest primes for any given accuracy.
- exp-PiRandom.lisp
- Approximate pi with random numbrs.
- exp-PolyLegendreRoots.lisp
- Compute the nodes for Gauss-Legendre integration with high accuracy.
- exp-PovGraphs.lisp
- Some graphs with Povray – using general p.pov-like code.
- exp-PovMixRes.lisp
- How to draw a surface with a grid at one scale, and lines at another.
- exp-PovWaveGraph.lisp
- Generate a height field TGA and image map TGA file for a PovRay render.
- exp-PrimePairs.lisp
- Find composite numbers which are the product of two primes that are a distance of d apart where d in [1, 150].
- exp-PrimePi.lisp
- The prime counting function (pi) and a pair of bounding functions.
- exp-ProbNeedle.lisp
- Buffon's Needle Problem.
- exp-pursuit.lisp
- Drug smuggler boat path
- exp-qmci.lisp
- Benchmark and demonstrate basic mjr_qmci functionality.
- exp-ratTrig.lisp
- exp-sierpinski.lisp
- Draw a colorful Sierpinski gasket-like thingy, and output the drawing as an SVG file
- exp-svgCircles.lisp
- Generate some SVGs with mathematical art using thousands of circles.
- exp-svgDemo.lisp
- Demo of the SVG package.@EOF
- exp-SwirlyGraph.lisp
- Draw a nice and swirly image.
- exp-VTKcolorSpace.lisp
- Draw the RGB Cube and HSL sphere.
- pre-qmci.lisp
- Quasi-Monte Carlo Integration.
- lib-gfp.lisp
- Interactive GF(p) library – modular arithmatic.
- lib-gpoly.lisp
- Generate Polynomial Code For General Fields.
- lib-meta.lisp
- Meta package for working with MJRCALC packages.
- lib-sia.lisp
- Simple Interval Arithmetic (with guess).
- use-a.lisp
- Angle (and time-ish) utilities.
- use-annot.lisp
- Provide data annotation tools – DSIMP and DQUAD.
- use-arr.lisp
- Array utilities.
- use-cas.lisp
- Very basic computer algebra on :MJR_MXP objects.
- use-char.lisp
- Character (ASCII & EBCIDIC) tools.@EOL
- use-chem.lisp
- Chemical element data.
- use-chk.lisp
- Floating point comparison: disaster prevention.
- use-cmp.lisp
- Floating point comparison: best guess.
- use-color.lisp
- Color theory (color space conversions and computations).
- use-colorize.lisp
- Interface for :MJR_COLORIZED and :MJR_COLORIZER.
- use-colorized.lisp
- Colorization of discrete spaces (Z_n).
- use-colorizer.lisp
- Colorization of continuous spaces (R, C, R^2, R^3, C, I, I^2, and I^3).
- use-combc.lisp
- Constructive Combinatorics: Generating combinatorial objects.
- use-combe.lisp
- Enumerative Combinatorics: Counting combinatorial objects.
- use-const.lisp
- Physical constants – with units.
- use-date.lisp
- Handy date stuff.
- use-dft.lisp
- DFT and inverse DFT.
- use-dquad.lisp
- Data sets on QUADrilateral (rectilinear) grids.
- use-dsimp.lisp
- Data sets on SIMPlicial complexes.
- use-ee.lisp
- Electronics Engineering.
- use-eps.lisp
- Floating point comparison: within EPSilon.
- use-fsamp.lisp
- Sample mathematical functions and create DQUADs and DSIMPs.
- use-geo.lisp
- Geographic and cartographic computations.
- use-geom.lisp
- Computational Geometry.
- use-gnupl.lisp
- Plotting dquads with GNUPlot.
- use-ia.lisp
- User interface wrapper for :MJR_SIA.
- use-intg.lisp
- Numerical integration of univariate real functions.
- use-intrp.lisp
- Polynomial interpolation.
- use-intu.lisp
- Handy integer utilities.
- use-mat.lisp
- Matrix math library.
- use-matt.lisp
- Generate and compute with various test matrices.
- use-mxp.lisp
- Mathematical eXPressions library.
- use-ndiff.lisp
- Numerical differentiation.
- use-nleq.lisp
- Non-linear equation root finding.
- use-nleqm.lisp
- Multiple Non-linear EQuation root location.
- use-numu.lisp
- Numerical utilities.
- use-ode.lisp
- ODE (Ordinary Differential Equation) IVP (Initial Value Problem) solvers.
- use-opt.lisp
- Univariate function optimization.
- use-optm.lisp
- Multivariate function OPTimization.
- use-perm.lisp
- Permutation group computation.
- use-poly.lisp
- Polynomials over complex, real, rational, and integers.
- use-polygfp.lisp
- Univariate polynomials over prime order fields – i.e. GF(p)[x].
- use-pov.lisp
- Produce Povray files!
- use-prime.lisp
- Computational Number Theory.
- use-prng.lisp
- Uniform random deviate generators.
- use-prob.lisp
- Augments and supports :mjr_probau.
- use-probau.lisp
- Balls And Urns probability distributions.
- use-probe.lisp
- Empirical probability distriubtions.
- use-probu.lisp
- Computations on PDFs (Probability Distribution Functions).
- use-pwf.lisp
- piecewise function stuff.
- use-rtrig.lisp
- Rational Approximations For Irrational Functions.
- use-stats.lisp
- Statistics: Averages, histograms, sub-samples, simple linear regression.
- use-string.lisp
- String utilities.
- use-svg.lisp
- Simple API to create SVG files
- use-tga.lisp
- Raster image stuff.
- use-units.lisp
- Unit conversion tool.
- use-util.lisp
- Utilities.
- use-vec.lisp
- Mathematical vectors.
- use-vtk.lisp
- Write VTK files.
- use-vvec.lisp
- Virtual vectors.
8. FAQ
I went without a FAQ for *MJRCALC*
for a long time. Now that the user community has grown, it seems
the time has come to start one up.
- Do you really use this as your desktop calculator?
- Yes. LISP has great numeric support (one of the best numeric type hierarchies ever developed in any language). I'm an old RPN guy, so prefix notation is
very comfortable for me; however, I occasionally use the
:MJR_MXP
package to enter an expression using infix notation. - You have implemented several algorithms in
*MJRCALC*
for which better, or standard, implementations already exist. Why? - Any number of reasons.
- I may have been reading about an algorithm new to me, and wanted to try and implement it. The
:MJR_DEQ
package is a good example – the whole thing was written simply because I was reading some really good books on the numerical solution of differential equations! - I may have needed some kind of odd functionality not found in the standard algorithms. The
:MJR_MAT
package is a good example of this – you don't find many matrix elimination routines capable of using Givens, Householder, and Gauss steps on the same matrix! - It could have just been my raging case of NIH Syndrome I mentioned near the top of this page. ;)
- I may have been reading about an algorithm new to me, and wanted to try and implement it. The
- Could you integrate
*MJRCALC*
with MY-FAVORITE-PACKAGE? - I have a rule about strong coupling and dependencies on external code. I don't do it. This is mostly because of the level of effort required to keep up
with external libraries – I want
*MJRCALC*
to work any place I take it. I don't want to worry about trying to set up some complex environment just to get the code to run. On the other hand, loose coupling is very much a possibility. For example, the:MJR_PRNG
allows one to plug in external libraries like the most excellentmt19937
package available via Quicklisp. - Some of the numerical methods are strangely general or non-standard (even at the cost of speed)?
- This is very true. It is a feature!! One of the reasons I wrote this library was to provide a test bed for developing new algorithms in numerical analysis
– not just to implement well known algorithms. For example, the
:MJR_DEQ
library uses plugins for the step methods allowing one to easily test new RK methods. Another example is some of the generic code in:MJR_MAT
allowing matrix elimination using a mix of Givens, Householder, and Gauss steps. When I need a standard solver and I care about performance or size, then I generally use one of the many high quality libraries available (NetLib is your friend!) - Can I use
*MJRCALC*
in a commercial product? - Sure so long as you follow the license agreement That said, you should be careful. I don't manage
*MJRCALC*
like a commercial product with regard to backward compatibility. Note also I generally do not provide any form of commercial support. I have some advice about this in the section above about support - How is
*MJRCALC*
licensed? - I use a BSD-like license. You can find it in the licence file file in the distribution.