-
Notifications
You must be signed in to change notification settings - Fork 111
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 AImplicit 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.matrixfunction - 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]