Live data from Hacker News

A Programmer’s Intuition for Matrix Multiplication

betterexplained.com

71–80 of 95 posts

Re: A Programmer’s Intuition for Matrix Multiplication

#71
post #56

What is some good intuition around matrix inverses?

The matrix inverse “undoes whatever the matrix did” is pretty much the most straightforward interpretation, if you’re thinking of a matrix as performing some kind of rotation/shear/scaling of space.

There are some other interpretations, for example if you think of a linear system Ax=b as a kind of “checking machine” (does x satisfy Ax=b? Yes/no, try again), then the inverse of A can produce solutions, since x=(A inverse)b.

Re: A Programmer’s Intuition for Matrix Multiplication

#72
post #14
post #3

Earlier quoted context omitted.

Purist test: aren't vectors just Nx1 matrices? Joking aside, matrices are linear maps in the context of multiplication. They can absolutely have meanings assigned outside the usual "when multiplied by a vector" type of calculations. For example the "adjacency matrix" representation of a graph is very often never multiplied by a vector even in academic algorithm descriptions. YMMV if you call it a (lookup) table in th…

> aren't vectors just Nx1 matrices? It's been a while since I formally studied maths, but - can you describe a situation in which this is _not_ true? (modulo transposition)

It’s more of a perspective and opinion thing. For example I would not say that an integer is its twos-complement representation, but I am very happy to hold onto that representation as a kind of key for the “real thing”.

Similarly, in a vector space there can be abstract vectors, which exist no matter of what basis you choose to write them down. (Choosing a basis = choosing a way to encode them as a 1xN or Nx1 matrix).

Often in the theory, general theorems can be proven very efficiently using these abstract vectors, but most of the time when one wants to actually do things to those vectors, picking a convenient basis and working with N coordinates is the best choice.

Re: A Programmer’s Intuition for Matrix Multiplication

#73

If we're talking about 3D rendering then a matrix multiplication with a vector are just projections: A 3x3 matrix that transforms a vector is nothing else than that vector being projected onto the 3 axis which are inside the 3x3 matrix. This is very easy to see visually. A matrix times matrix multiplication (eg 3x3 times 3x3) is just projecting the axis of one matrix onto the other: expressing the coordinate system i…

Sure - remember those noisy dot matrix printers?..

Re: A Programmer’s Intuition for Matrix Multiplication

#74

Earlier quoted context omitted.

> Purist test The short answer is. Yes, but if your PL treats it that way you will wind up in trouble [0]. The long answer is: https://www.youtube.com/watch?v=C2RO34b_oPM (but seriously take the time to watch this, it's fantastic). [0] Separately C- and often C-derived languages/frameworks like numpy also treat them as 1xN matrices, but that's a nearly tabs-vs-spaces level religious war, with actual consequences. I t…

> numpy also treat them [vectors] as 1xN matrices I may be misunderstanding something, but in numpy at least a vector, a 1×N array ("row vector"), and a N×1 array ("column vector") behave differently. vec = numpy.array([1,2,3]) assert vec.shape == (3,) assert vec.ndim == 1 row = np.array([[1,2,3]]) assert row.shape == (1,3) assert row.ndim == 2 col = np.array([[1], [2], [3]]) assert col.shape == (3,1) assert col.ndim…

I just tried this, I stand corrected, but I remember this (the last clause) not working in numpy. It's possible my memory is flawed:

    >>> import numpy as np
    >>> vec = np.array([1, 2, 3])
    >>> mtx = np.eye(3)
    >>> np.dot(vec, mtx)
    array([1., 2., 3.])
    >>> np.dot(mtx, vec)
    array([1., 2., 3.])
It's possible though that I was remembering not that it doesn't execute, but rather that if you do mess up the multiplication order and do it in the wrong direction with anything besides trivial diagonal matrices, you won't get a type error, you will get an incorrect but valid result, which is arguably worse than a type error, and way more frustrating, especially if start by testing eye, which is the easiest thing to do.

Re: A Programmer’s Intuition for Matrix Multiplication

#75
post #3

I'd prefer stating that matrices actually don't mean anything in isolation. They are simply representations of linear maps. What happens to the elements of a matrix before the elements are formed is irrelevant to the matrix itself. ..And to be clear, I am not a purist.

Purist test: aren't vectors just Nx1 matrices? Joking aside, matrices are linear maps in the context of multiplication. They can absolutely have meanings assigned outside the usual "when multiplied by a vector" type of calculations. For example the "adjacency matrix" representation of a graph is very often never multiplied by a vector even in academic algorithm descriptions. YMMV if you call it a (lookup) table in th…

The nth power of an adjacency matrix yields the number of length-n walks from any vertex to any other vertex.

Re: A Programmer’s Intuition for Matrix Multiplication

#76
When I took a course in linear algebra, we learned about linear transformations and vector spaces in the abstract first. Then when we got to matrices it was viewed as a way to represent linear transformations. Also it led to a natural derivation for matrix multiplication.

Re: A Programmer’s Intuition for Matrix Multiplication

#77
post #22

Earlier quoted context omitted.

That is genuinely a really fun way to look at it, thank you for linking this! Especially this fits nicely with Markov matrices where you have N input nodes and N output nodes and the sum of all of the probabilities coming out of one of the nodes needs to equal 1. What I might find a little more difficult to teach to people through this lens is the phenomenon of eigenvectors, but I suppose that's to be expected—nothin…

>What I might find a little more difficult to teach to people through this lens is the phenomenon of eigenvectors Why? Eigenvectors are simply inputs to the network where the output keeps its shape, that is, at most it gets rescaled, as if you had applied a uniform gain to the components, but otherwise it will be the same as the input.

So for example let me ask for your knee-jerk opinions based on this idea:

- does a matrix have the same left-eigenvectors as its right-eigenvectors?

- what is the relationship between the left-eigenvalues and right-eigenvalues?

- is there always an eigenvector? when is there a complete set? how do you generalize your notion of eigenvectors so that matrices always have a complete set of them?

I am not sure any of these are intuitive here.

Re: A Programmer’s Intuition for Matrix Multiplication

#78
post #77

Earlier quoted context omitted.

>What I might find a little more difficult to teach to people through this lens is the phenomenon of eigenvectors Why? Eigenvectors are simply inputs to the network where the output keeps its shape, that is, at most it gets rescaled, as if you had applied a uniform gain to the components, but otherwise it will be the same as the input.

So for example let me ask for your knee-jerk opinions based on this idea: - does a matrix have the same left-eigenvectors as its right-eigenvectors? - what is the relationship between the left-eigenvalues and right-eigenvalues? - is there always an eigenvector? when is there a complete set? how do you generalize your notion of eigenvectors so that matrices always have a complete set of them? I am not sure any of thes…

If A is a square matrix, then a left eigenvector v is a vector such that vA = \lambda_v v for some \lambda_v. Likewise, if u is a right eigenvector of A, Au = \lambda_u u.

Notice that u and v cannot be equal, because they are not the same shape. However, if v is a right eigenvector with eigenvalue \lambda, then v^T is a left eigenvector with eigenvalue \lambda, as well. More or less what this means is that we tend to just ignore left eigenvalues and only use the right eigenvalues, because the math is exactly the same up to a transpose operation.

A matrix does not necessarily have nontrivial eigenvectors. Think about the 0 matrix here. But, if A is nonzero, then it must have at least one nonzero eigenvalue, hence one nontrivial eigenvector. This is because a nonzero matrix must have at least one nonzero row and column; however, if you construct the other rows (columns) to be multiples of the first column, you end up with a matrix with only one nontrivial eigenvalue. This also illustrates the conditions necessary for an nxn matrix A to have n linearly independent eigenvectors: the rows of A must be linearly independent.

All of this is covered in a decent undergrad linear algebra course. I would suggest either finding a video course, or getting a good book and working through it, if you want to understand these things better.

Re: A Programmer’s Intuition for Matrix Multiplication

#79

Earlier quoted context omitted.

> numpy also treat them [vectors] as 1xN matrices I may be misunderstanding something, but in numpy at least a vector, a 1×N array ("row vector"), and a N×1 array ("column vector") behave differently. vec = numpy.array([1,2,3]) assert vec.shape == (3,) assert vec.ndim == 1 row = np.array([[1,2,3]]) assert row.shape == (1,3) assert row.ndim == 2 col = np.array([[1], [2], [3]]) assert col.shape == (3,1) assert col.ndim…

I just tried this, I stand corrected, but I remember this (the last clause) not working in numpy. It's possible my memory is flawed: >>> import numpy as np >>> vec = np.array([1, 2, 3]) >>> mtx = np.eye(3) >>> np.dot(vec, mtx) array([1., 2., 3.]) >>> np.dot(mtx, vec) array([1., 2., 3.]) It's possible though that I was remembering not that it doesn't execute, but rather that if you do mess up the multiplication order…

I remember a problem similar to the one you describe when using a dot product both to substitute for a fast loop and for its normal mathematical purpose, in the same operation:

  points = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]])
  M = np.array([[0.866, 0.5, 0], [-0.5, 0.866, 0], [0, 0, 1]])  # rotation
  points @ M  # works
  M @ points  # raises ValueError, also a different transform
Regarding messing up the multiplication order, numpy by itself doesn't have the information to raise a relevant type error, sadly. As you probably know, based on your other comments, the important thing is whether the adjacent basis vectors (dimensions) match, not how they are written. That is, given M = M_ij (a_i ⊗ b_j), a vector v_i a_i must be multiplied on the left, a vector v_i b_i must be multiplied on the right, and a vector v_i c_i (with basis vector c) shouldn't be used at all. Numpy just does array math; it doesn't keep track of dimensions. Hopefully the code has accurate comments, or you're using a language with a decent type checker.

However, I think you can track dimensional compatibility using xarray:

  import xarray as xr
  import numpy as np
  points = xr.DataArray([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]], dims=("idx", "a"))
  M = xr.DataArray([[0.154, 0.988, 0], [-0.988, 0.154, 0], [0, 0, 1]], dims=("a", "b"))  # rotation
  points.dot(M)  # works
  M.dot(points)  # also works
  # M's a-dim is matched to point's a-dim, so both
  # results have same values regardless of
  # multiplication order, just transposed.
  assert np.all(points.dot(M).T == points.dot(M))
I only just tried xarray in response to your post, so not sure if there are pitfalls in practice, or if this is the best way to use it.
Post reply on HN