-
Notifications
You must be signed in to change notification settings - Fork 113
Broadcasting
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)
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 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]