Seven sins of numerical linear algebra
nhigham.com
nhigham.com
MIT has a course called The Missing Semester of Your CS Education [1]. It tells you about practical stuff that you need to know but isn't really taught in classes (shells, version control, build systems, package managers, VM's).
There needs to be something similar for linear algebra, it seems like there's a lot of folk knowledge and a big gap between what typical undergrad courses train you to do and what you encounter in actual practical problems.
(And don't get me started on all the weird linear algebra stuff they have going on in e.g. quantum physics.)
[1] https://stanford.edu/class/engr108/
[2] https://web.stanford.edu/~boyd/vmls/
[3] https://www.youtube.com/watch?v=oR6G1MUMveE
[4] https://ee263.stanford.edu/
[5] https://www.youtube.com/playlist?list=PL06960BA52D0DB32B
I’ve also recently noticed that programs and students outside North America seem to take the content much more seriously.
That was in Germany in the early 2000s.
I do know that this course is still offered widely across the US, but maybe not within CS, and maybe not as a mandatory course.
But, bottom line: if you're interested, it's very likely you can take it - you may have to check your school of engineering or applied math department.
http://www.ma.man.ac.uk/~higham/papers/bibbase.php
including a brief note on the comparing "Top 10 Algorithms in Applied Mathematics" between 2000 and 2016 that may interest some:
https://nhigham.com/2016/03/29/the-top-10-algorithms-in-appl...
It'd be nice to see some meat on the bones and a few ripping yarns about the application end of applied math techniques .. eg: forming an enhanced image from tens (or hundreds) of thousands of multichannel spectral samples using a sensitivity adjusted SVD, and then removing the most common expected background to highlight the anomalies.
It's dry stuff in Linear Algebra, somewhat more exciting when searching for nuclear weapons in a forest or gold in a desert.
When people do have ways to go around this problem, they do use Newton's method for large scale problems.
One of Newton's method major selling points is that once it's close to a local minimum, under the right smoothness assumptions it essentially converges faster and faster to an exact optimizer - in practice you get "one more correct significant digit each iteration" once you are close enough. It's called Newton's method region of quadratic convergence, see [0] Theorem 14.1, p.3
[0] https://www.stat.cmu.edu/~ryantibs/convexopt-F16/scribes/new...
There is the seminal paper "Deep Learning via Hessian-free Optimization" [1] that applies Newton's method (Hessian free because of a clever trick of solving Hx=-g iteratively without explicitly constructing the Hessian, and getting an approximation without full O(n^3)) - but n^2 or n^3 is just too large in practice when the diagonal approximations work just fine.
[1] https://www.cs.toronto.edu/~jmartens/docs/Deep_HessianFree.p...
http://gregorygundersen.com/blog/2020/12/09/matrix-inversion...
E.g. Goodfellow et al did even worse than this sin in the Deep Learning book when they claimed the condition number for a square (but not necessarily normal) matrix is defined in terms of eigenvalues. This is false, but nevertheless see 4.2 in https://www.deeplearningbook.org/contents/numerical.html . When I've raised this with people in real life, I typically get some reflexive response that it should be a useful approximation, but as this blog points out, that isn't true either.
[1]: https://www.math.purdue.edu/~yipn/543/matrixExp19-I.pdf
Possibly only a partial sin since I use Moore-Penrose pseudo inverse and L2 ridge regularization. This sin is being commit as a consequence of committing next sin.
> 2. Forming the Cross-Product Matrix A^TA
Yes yes this is potential numerically bad. However in practice as long as you are careful with scaling it’s perfectly fine and enable better parallel computations.
> 7. Using Eigenvalues to Estimate Conditioning
This sin is the only way I actually know so after reading this I realized I need to read more on this.
The last of the 4, which obviously is an avoidable sin.
> 3. Evaluating Matrix Products in an Inefficient Order
I definitely have code that should he changed. It’s also on my todo list now to audit a specific routine that I suspect can be fixed. This one is just stupid it can be avoided.
Putting this out to invoke Cunningham's Law... my intuition says that while the article may be right about matrices in the real numbers, using the eigenvalues to check for closeness to singularity may be more valid on the floats, because probably what you're testing for isn't "closeness to singularity" but how close you are to having floating point failures, and that seems at least likely to be heavily correlated.
I now sit back and wait for someone to explain why this is wrong while I act like this was an entirely unanticipated result of my post.
Thanks for this excellent link.
8. [edit: oops that's already no 5] Not taking advantage of matrix structure (symmetric, sparse, banded, Toeplitz, ...)
9. Transposing a matrix (Like the inverse A^{-1}, the explicit transpose A^t is often not needed)
If someone is writing a higher level object-oriented linear algebra environment, having the matrices carry around a "transposed" flag that they can pass to BLAS seems like a reasonable thing to do. Since, other than in Julia and Matlab, matrix stuff is usually an add-on, we can't really blame the language for this decision IMO.
A downside could be -- usually your underlying tuned library will be BLAS and LAPACK, which don't accept a 'transposed' flag for every single operation. So, from the user point of view, it could be kind of confusing -- "when I transpose a matrix and then go on to multiply, the transpose is free. But if I transpose a matrix and then go on to hit it with QR, it for some reason incurs this weird extra cost -- not where I do the operation, but later, in the QR."
... if you only use the transpose once. If instead it is going to be used multiple times, explicitly computing the transpose can be a huge performance boost.
For dense matrices, it is typically used to exploit memory locality (i.e. to be prefetch- and cache-friendly).
For sparse matrices (your point 8), the advantage can be even more pronounced, sometimes the difference between being able to exploit sparsity, or not.
This is the sin no 5 of the article: "5. Not Exploiting Structure in the Matrix"
Most matrix libraries should make transpose, conjugate, and conjugate transpose just twiddling a bit on its internal representation--BLAS routines should have a parameter on them saying if the input matrix needs to be transposed and/or conjugated before doing an operation.
People who say "transpose is an O(1) operation because it just creates a view" aren't including the important detail of caches and access patterns impact on performance.
In computer graphics, the situation is often different. Usually, you have small matrices (kxk for k=2,3,4); a huge number of vectors; and you want to apply your matrix to all of those vectors. Very often, these matrices have very well known forms and also known well behaved inverses. There isn't really a significant computational cost in computing the inverse (you'll very often write down its formula by hand), and conditioning is usually not an issue (consider a rotation matrix for example or undoing translations with homogeneous coordinates).
Since transformation matrices have simple structure, you can invert them much much faster.
Ex: inverse(R, u) is (R^T, -R^T * u)
I remember learning in algebra to solve this equation exactly the way he described and said we don't use. You multiply both sides by 1 / 7 which cancels the 7 on the left side, because 1 / 7 is the inverse of 7.
Now I just implicitly divide both sides by 7, but I'm still solving the equation by using the inverse of 7...
The cheap way is to compute 21/7.
The hard way is to compute 1/7 (one floating point operation), and then multiply it by 21 (another floating point operation).
With matrices, the discrepancy in work and possibly precision between "solve Ax=b" and "compute x = A^-1 b" can be very large.
well you just 1/sqrt(7) * sqrt(7)x = 1/sqrt(7) * 21
so x = sqrt(7)^2 * 3 / sqrt(7) = sqrt(7) * 3
but you didn't compute the inverse did you, and neither did i. you factored 21 and used the cancellation law (ax = ay => x = y)
Most of the industries are dominated by subject matter experts who write code.
- For intuition: https://www.youtube.com/watch?v=fNk_zzaMoSs
- For rigor: https://ocw.mit.edu/courses/18-06-linear-algebra-spring-2010...
- For code: https://codingthematrix.com/
- For numerical/algorithmic details: https://people.maths.ox.ac.uk/trefethen/text.html
It's been a long time since I've taken linear algebra but if you can find an OCW course, or a really good book I'd start there. You'll want some rigor under your belt. Once you do that, any good numerical analysis text will usually cover the basics (you'll need them) before going into the fascinating world of algorithms as they relate to linear algebra.
their treatment of numerical linear algebra is not as comprehensive as say the one you'd find in Watkins' Fundamentals of Matrix Computations but it's free