astromax
astromax

Reputation: 6331

Numpy Matrix Subtraction Confusion

I have a question about the result of an operation I accidentally performed with two numpy matrices (and later fixed).

Let's say that I have a column vector, A = [1,2,3], and a row vector B = [1,1,1]. As far as I know there is no correct mathematical way to "subtract" these two vectors, i.e. this should be an undefined operation. And yet, when I do so, I get back:

>>> matrix([[0, 1, 2],
            [0, 1, 2],
            [0, 1, 2]])

I thought that this might be some sort of broadcasting operation, but this still troubles me a bit. Shouldn't numpy.matrix objects only contain mathematically valid matrix operations?

Any help is appreciated!

Thanks!

Upvotes: 10

Views: 12730

Answers (2)

askewchan
askewchan

Reputation: 46578

I cannot really explain the rationale, because I often use np.matrix instead of np.array to prevent this sort of thing. Thanks to @Jaime's link in the comments above, it's clear that np.matrix is simply a subclass from np.ndarray with redefined infix operations where there is an appropriate answer from linear algebra. Where there isn't, it falls back on the rules from np.ndarray with ndim = 2.

It seems that addition follows the matrix multiplication rules for which elements from A are paired with which elements from B:

In [1]: import numpy as np
In [2]: A = np.matrix([1,2,3]).T
In [3]: B = np.matrix([1,1,1])

In [4]: A
Out[4]: 
matrix([[1],
        [2],
        [3]])

In [5]: B
Out[5]: matrix([[1, 1, 1]])

In [6]: A+B
Out[6]: 
matrix([[2, 2, 2],
        [3, 3, 3],
        [4, 4, 4]])

In [7]: A*B
Out[7]: 
matrix([[1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]])

This is the same behavior you get with np.array:

In [9]: a = np.arange(3)[...,None]

In [10]: b = np.arange(3)

In [11]: a
Out[11]: 
array([[0],
       [1],
       [2]])

In [12]: b
Out[12]: array([0, 1, 2])

In [13]: a+b
Out[13]: 
array([[0, 1, 2],
       [1, 2, 3],
       [2, 3, 4]])

Upvotes: 1

kith
kith

Reputation: 5566

A and B are being broadcasted together:

A = np.matrix([[1],[2],[3]])
#a 3x1 vector
#1
#2
#3

B = np.matrix([[1,1,1]])
#a 1x3 vector
#1 1 1

A-B
#a 3x3 vector
#0 0 0
#1 1 1
#2 2 2

A gets broadcasted along its size 1 dimension(columns) into

#1 1 1
#2 2 2
#3 3 3

B get broadcasted along its size 1 dimension(rows) into

#1 1 1
#1 1 1
#1 1 1

Then A-B is computed as usual for two 3x3 matrices.

If you want to know why it does this instead of reporting an error it's because np.matrix inherits from np.array. np.matrix overrides multiplication, but not addition and subtraction, so it uses the operations based on the np.array, which broadcasts when the dimensions allow it.

Upvotes: 2

Related Questions