-
Notifications
You must be signed in to change notification settings - Fork 0
Project outline
-
Simulations for expository purposes (journal papers, etc.) on a web page, across a wide range of modern platforms.
-
Simulation building and applied math by students in a classroom setting for educational purposes.
-
Quick prototyping by researchers.
- Current versions of the major web browsers (Safari, Firefox, IE, Chrome).
- New portable electronics platforms (iOS, Android).
- Command line/server side frameworks (Node.js, Rhino, etc.)
It's probably not worth trying to support older platforms. It's also probably not worth writing and maintaining platform specific code paths unless they provide significant performance improvements.
- It should be easy to use the library and easy to read code written using the library, even if that costs some performance. In general, programming time will be valued more than CPU time. This includes the following:
-
Parameter checking with readable error messages, rather than obscure crashes deep within the code. (If this is expensive, we might want to have fast "unchecked" versions that the expert user can easy switch to once the code is working if they need to speed things up, e.g. "findRoot.brentq.unchecked", or "findRoot(..., 'noInputCheck')").
-
Consistent function names, e.g. starting with a verb of what you want to do. This rule might be broken for a few very common cases (e.g. reading an array element).
-
Function names that focus on what you want to do, rather than how the library should do it. In Mathematica it was easy to choose the "FindRoot" function, vs. in scipy it was a pain to figure out whether I should use bisect, brentq, brentq2, newton, etc.. The library should have a good default method that works most of the time. Other methods might be useful for experts, but they should be buried in the options (e.g. "findRoot(myFunc, lbound, ubound, { method = 'brentq' })" or "findRoot.brentq(myFunc, lbound, ubound)")
-
Clear documentation that includes a tutorial for people new to the library. The documentation for a given function may be generated by comments in the code.
-
It should be trustworthy, so that when the simulation doesn't work you know you should start looking for errors in your own code, not the library. From my perspective, this suggests fast unit tests with 100% coverage along with some slower integration tests to check the numerics. Tests are released as part of the library, and should be usable by the user.
-
When it doesn't violate the previous two goals, the code should run as quickly as possible. At a basic level, this should mean a simulation written with the library is faster than a simulation written in the same amount of time without the library. This should generally come from good algorithms, rather than low level code tweaks. For example, for an ode based simulation, a good adaptive step size integrator should be able to outperform an quickly constructed Euler integrator. More ambitiously, this could apply to using things like WebCL. This will require a benchmarking tool we can trust, so we know which code really is fastest under which conditions. Packages such as BLAS and ATLAS may be valuable as references for good approaches.
-
When consistent with the previous three goals, the library code should be easy to read and maintain (which supports the previous three goals). Probably this means having a rule that readability is more important than a theoretical performance gain; things should be written the simple way first, and then if they're performance sensitive a benchmark should be written and ugly parts added only if they provide a measurable performance increase. Benchmarks should reflect real-world usage of the library. Code should pass JSLint, although individual warnings can be turned off by comments.
- A few basic tools need to be set up:
-
A central repository [done: github]
-
A testing framework or frameworks [done: homebrew]
-
Bug/Issue tracking [done: github]
-
Wiki [done: github]
-
Validation tests for numerics [done: homebrew]
-
A benchmark runner that records benchmark changes over time, and can run on multiple platforms.
-
Continuous integration system (Jeves, Hudson, etc.) to run benchmarks and tests on each new commit.
- Basic array tools tools:
-
N-dimensional arrays, with functions for taking hyperslabs, length, dimensions, etc.. [done]
-
Data types?
-
reshaping, transposes, etc. [done]
-
element-wise operations (add, multiply, etc.) with shape extension [done]
-
Axis-wise and array-wise operations (sum, product, min, max, mean, etc.) [partial]
-
vectorizing or matrixizing common functions (e.g. min, max, etc.), generic wrapper for other functions (like Thread from Mathematica) (jsn.apply?)
-
Matrix multiplication [done]
-
Common matrix operations, e.g. inverse, SVD, solving linear systems of equations, etc. [partial]
-
WebCL detection and usage when present. Note that it would be neat to make it simple for the user to create matrix-like objects with different storage mechanisms, e.g. band or sparse matrices.
- ODE integration tools
-
Basic Euler integrator
-
Fixed and adaptive step size Runge-Kutta (8th order Dormand-Prince?).
-
Support for events
-
Implicit integrators for stiff systems
-
SDE integrators with strong and weak convergence
- Basic Graphics and UI (perhaps as a extension library?)
-
2D scatter plots, lines, axes, etc.
-
Zooming and panning functionality
-
3D Scatter plots, lines, surfaces, etc. using WebGL?
-
Sliders for parameters, with text entry fields, range checking, and good error messages. Support callbacks, dynamic updating.
-
Interactive graphics to adjust parameters on graph?
-
Some sort of framework to make it quick and easy to create a simulation with controls for parameters, a graph or two, and a run button (or perhaps continuously updating).
- Other ideas
-
Random variables with common distributions (gaussian, poisson, etc.)
-
Interpolation functions (cubic splines, etc.)
-
basic statistics (mean, sd, etc.)
-
convolutions/filtering
-
special functions (Error function, Bessel, Airy, etc.)
-
FFT, wavelets, etc.