Skip to content

core.matrix internals

Mike Anderson edited this page Jul 22, 2013 · 2 revisions

Here is what's going on when one is calling a function from clojure.core.matrix (let's assume it's mul and arguments are of type NDArray):

  • The public API functions are defined in clojure.core.matrix
  • These API functions calls an appropriate protocol function from clojure.core.matrix.protocols (in this case matrix-multiply). Arguments may possibly be re-arranged so that the argument used for type dispatch is passed as first one (because protocols are dispatched by first argument);
  • If there is an implementation of corresponding protocol for NDArray (clojure.core.matrix.impl.ndarray), it is called;
  • If there is no implementation, a default implementation for java.lang.Object (or java.lang.Number if appropriate) is called from clojure.core.matrix.impl.default; functions in this namespace often use functions from clojure.core.matrix.protocols that are related to mandatory protocols (for example, matrix-multiply uses get-2d, is-mutable?, get-shape, new-matrix and possibly set-2d!), this way all core.matrix operations work on all implementations that implement mandatory protocols.

All implementations should call clojure.core.matrix.implementations/register-implementation, providing a so-called "canonical object" to core.matrix that can be later retrieved by implementation-key from clojure.core.matrix.implementations/canonical-objects. This objects are used to trigger appropriate type dispatch for multimethods (so, for example, when new NDArray-based matrix is created, "canonical object" is used to dispatch to NDArray's implementation of new-matrix). canonical-objects is a dictionary stored in an atom and populated during code loading.