A Mathematical View on Broadcasting

The Broadcasting mechanism in NumPy is usually introduced by explaining the relevant rules.

Another perspective is to look at the topic from a mathematical viewpoint.

The initial example is the addition of a function and a constant.

The authors argue that this is not proper mathematical notation and resolve it by defining a broadcast function for the constant.

The result is the addition two functions.

Which could also be written as

It is not quite clear to me what the intention of the authors was to leave out the function parameters. I assume they were left out because they are not relevant to the argument.

The question wether a 1×1 matrix should be considered a scalar is a similar topic with regard to notation.

A perspective that tries to bring together rigour and practicality:

A 1×1 matrix is not a scalar–it is an element of a matrix algebra. However, there is sometimes a meaningful way of treating a 1×1 matrix as though it were a scalar, hence in many contexts it is useful to treat such matrices as being "functionally equivalent" to scalars. It might be a little sloppy to do so, but a little bit of sloppiness is forgivable if it introduces no confusion or ambiguity, and if it aids brevity or clarity of exposition.

With the objection:

We can cast any real 𝑥 to the constant function on ℝ whose value is always 𝑥, but are reals and constant functions "functionally equivalent"? Well... no, a function can be evaluated at a point, while a real has no such feature.

And the remark:

Okay I guess the added words "in the right context", in the right context, would evade my objection. Namely, if we interpret it to mean that scalars and 1-by-1 matrices, when used in certain specific ways, can be treated as functionally equivalent, then I agree. =)

Handling of a 1x1 array in NumPy:

>>> from numpy import array, reshape
>>> a = reshape(array(1), (1,1))
>>> a.shape
(1, 1)
>>> type(a)
<class 'numpy.ndarray'>
>>> type(a[0,0])
<class 'numpy.int64'>
>>> type(a.item())
<class 'int'>

Similar for a zero-dimensional array:

>>> a = array(1)
>>> type(a)
<class 'numpy.ndarray'>
>>> a.shape
()
>>> type(a[()])
<class 'numpy.int64'>
>>> type(a.item())
<class 'int'>

Interesting Stuff

Me writing about Tech stuff