Broadcasting - mikera/core.matrix GitHub Wiki
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](/mikera/core.matrix/wiki/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](/mikera/core.matrix/wiki/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](/mikera/core.matrix/wiki/1-2]-[3-4) 1.5)
; => [2.5 3.5] [4.5 5.5](/mikera/core.matrix/wiki/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]