Skip to content
Mike Anderson edited this page Jul 23, 2013 · 4 revisions

core.matrix supports Broadcasting, which is a way of extending arrays to a higher dimensionality shape as needed in various operations.

There are two types of broadcasting:

  • Explicit broadcasting: You can tell core.matrix to broadcast any array to a higher dimensionality shape, and get back an array of the shape requested
  • Implicit broadcasting: Some core.matrix functions support automatic broadcasting, so that a lower-dimensional argument will be automatically broadcasted to match the shape of the other argument(s)

Explicit Broadcasting

The clojure.core.matrix/broadcast function can be used to explicitly broadcast an array (or scalar to a specific shape.

;; broadcasting a length 2 vector to a 3x2 matrix:
(broadcast [1 2] [3 2])
; => #<NDWrapper [[1 2] [1 2] [1 2]]>

;; Broadcasting a scalar value to a 3x2 matrix
(broadcast 1.0 [3 2])
; => #<NDWrapper [[1.0 1.0] [1.0 1.0] [1.0 1.0]]>

If a broadcast operations succeeds, you are guaranteed that the returned array has the exact shape requested.

The broadcasted array may or may not be a view: this depends on the underlying matrix implementation. In general, you should not attempt to mutate a broadcasted array. If you want to mutate the result of broadcasted matrix operation, you can use the mutable-matrix function:

(def M (mutable-matrix (broadcast A target-shape)))
;; M is now guaranteed to be a mutable matrix containing a copy of the broadcasted array A

Implicit Broadcasting

Implicit broadcasting works only with Elementwise operations. This allows you to use lower dimensional (or scalar) arguments which will automatically be broadcast to work with higher-dimensional arguments.

Examples:

;; Implicit broadcasting of a scalar to match a 2x2 matrix
(add [[1 2] [3 4]] 1.5)
; => [[2.5 3.5] [4.5 5.5]]

For implicit broadcasting to work, the following rules must all be followed:

  • The function must be an elementwise core.matrix function
  • The argument to be broadcasted must be compatible with the target shape (see below)
  • An argument which is the target of a mutable operation can never be broadcast. i.e. only argments that are being read from can be broadcast
  • The broadcasting must be possible purely by appending leading dimensions. Implicit broadcasting will not duplicate a length 1 dimension five times to produce a length 5 dimension, for example.

Two shapes are compatible for the purposes of implicit broadcasting if the larger shape can be constructed purely by adding additional leading dimensions.

;; compatible: the second can be created from the first by adding [2 3 ....] 
    [3 4]
[2 3 3 4]

;; not compatible: the last dimension does not match:
    [3 3]
[2 3 3 4]

;; not compatible: implicit broadcasting does not replicate the length 1 dimension
    [1 3]
[2 3 3 3]