Solving normal equation system in C++
Asked Answered
R

5

7

I would like to solve the system of linear equations:

 Ax = b

A is a n x m matrix (not square), b and x are both n x 1 vectors. Where A and b are known, n is from the order of 50-100 and m is about 2 (in other words, A could be maximum [100x2]).

I know the solution of x: $x = \inv(A^T A) A^T b$

I found few ways to solve it: uBLAS (Boost), Lapack, Eigen and etc. but i dont know how fast are the CPU computation time of 'x' using those packages. I also don't know if this numerically a fast why to solve 'x'

What is for my important is that the CPU computation time would be short as possible and good documentation since i am newbie.

After solving the normal equation Ax = b i would like to improve my approximation using regressive and maybe later applying Kalman Filter.

My question is which C++ library is the robuster and faster for the needs i describe above?

Ruddock answered 3/1, 2011 at 13:38 Comment(4)
How do you multiple an n x m matrix by an n dimensional column vector? Presumably x is actually m dimensional.Antedate
Also, have you got some requirement that states a minimum amount of buzzword compliance?Antedate
@Ruddock I don't think the Boost uBLAS library implements this but please correct me if I'm wrong. It rather seems that uBLAS provides you with vectors, matrices and basic operations (multiplication, addition) but nothing like LU, QR, SVD or matrix inversion, let alone OLS implementation. However it's probably a good library to implement such algorithms. Again, please tell me if I'm wrong or if you find a good Boost uBLAS OLS implementation...Hash
i was wrong, there is LU decomposition in lu.hpp. Along with the included triangular solver it lets you do some stuffsHash
I
7

This is a least squares solution, because you have more unknowns than equations. If m is indeed equal to 2, that tells me that a simple linear least squares will be sufficient for you. The formulas can be written out in closed form. You don't need a library.

If m is in single digits, I'd still say that you can easily solve this using A(transpose)*A*X = A(transpose)*b. A simple LU decomposition to solve for the coefficients would be sufficient. It should be a much more straightforward problem than you're making it out to be.

Integrator answered 3/1, 2011 at 14:17 Comment(9)
He talks about Kalman filter. I presume he is comfortable with linear algebra and OLS in particular. He wants optimized library.Lukasz
@duffymo, you are right, for now the solution of $x = \inv(A^T A) A^T b$ is what i am searching. The Kalman Filter is maybe for future development. What was importent to me is which wich libary (that support inverse, transpose, matrix multiplication and etc.) should i work with (Boost, Eigen, Lapack or etc.)Ruddock
I don't believe you need any of those right now. Kalman filter would be a different matter, but it's a future consideration.Integrator
@duffymo, i thought i need Eigen or Boost for matrix transpose, inverse and multiplication. If i dont need those things right now, then what do i need?Ruddock
@Ruddock you don't need to calculate the inverse.Antedate
Eigenvalue problems are different from solving systems of equations. I'll have to go back and review what I know about Kalman filtering to recall if eigenvalues are central to its implementation. (Sorry, my books are at home.)Integrator
At present i just want to solve $Ax = b$ (Kalman filtering is not for now). Nether the less, for finding LU or eigenvalues i would still need to use Eigen or Boost... Which one should i use?Ruddock
If it's really just two coefficients, I'd use the closed form solution and be done with it. It's easy to derive.Integrator
"Which one should I use?" - the one you know best. If you've never used either, then pick one and try it. Or, try both. Your problem is pretty simple. I'd suggest setting up a bake off, pick a measure, and see which one wins.Integrator
L
7

uBlas is not optimized unless you use it with optimized BLAS bindings.

The following are optimized for multi-threading and SIMD:

  1. Intel MKL. FORTRAN library with C interface. Not free but very good.
  2. Eigen. True C++ library. Free and open source. Easy to use and good.
  3. Atlas. FORTRAN and C. Free and open source. Not Windows friendly, but otherwise good.

Btw, I don't know exactly what are you doing, but as a rule normal equations are not a proper way to do linear regression. Unless your matrix is well conditioned, QR or SVD should be preferred.

Lukasz answered 3/1, 2011 at 14:4 Comment(11)
Also ACML for AMD chips. This one is free I believe.Rummer
I'm not sure the optimised mult-threaded versions would be that much of a benefit for matrices as miniscule as this.Antedate
would boost::numeric::ublas be consider as "optimized BLAS bindings"?Ruddock
@David Heffernan. 100x100 isn't that small.Lukasz
I wrote a simulator (master thesis) which generate some values. It could be a jump in the data and i am trying to detect it in real-time using statistical tests and updating my Normal equation estimation. I know that there are other ways, but this is what i am usingRuddock
@watson: it's 100x2. It is small.Tussle
@Eagle: So check @duffymo's solution. You need to compute A * A^t and A^tb and perform a LU decomposition on a small matrix. All this is cheap and stable (cheaper and much stabler than solving a 100x100 system)Tussle
@watson @Alexandre I'd be happy for my phone to do this in real time, but I presume the OP is using a real computer!Antedate
Ah... it is 100x2. Maybe too small for OpenMP. Nevertheless, I didn't say to use multithreading :).Lukasz
@watson 100x100 is tiny too, unless I'm missing somethingAntedate
@David Heffernan. 100x100 is big enough for QR. SVD is even more expensive. Plenty opportunity for multithreading. 100x100 doubles won't fit into L1 cache. More reasons to use optimized implementation.Lukasz
I
7

This is a least squares solution, because you have more unknowns than equations. If m is indeed equal to 2, that tells me that a simple linear least squares will be sufficient for you. The formulas can be written out in closed form. You don't need a library.

If m is in single digits, I'd still say that you can easily solve this using A(transpose)*A*X = A(transpose)*b. A simple LU decomposition to solve for the coefficients would be sufficient. It should be a much more straightforward problem than you're making it out to be.

Integrator answered 3/1, 2011 at 14:17 Comment(9)
He talks about Kalman filter. I presume he is comfortable with linear algebra and OLS in particular. He wants optimized library.Lukasz
@duffymo, you are right, for now the solution of $x = \inv(A^T A) A^T b$ is what i am searching. The Kalman Filter is maybe for future development. What was importent to me is which wich libary (that support inverse, transpose, matrix multiplication and etc.) should i work with (Boost, Eigen, Lapack or etc.)Ruddock
I don't believe you need any of those right now. Kalman filter would be a different matter, but it's a future consideration.Integrator
@duffymo, i thought i need Eigen or Boost for matrix transpose, inverse and multiplication. If i dont need those things right now, then what do i need?Ruddock
@Ruddock you don't need to calculate the inverse.Antedate
Eigenvalue problems are different from solving systems of equations. I'll have to go back and review what I know about Kalman filtering to recall if eigenvalues are central to its implementation. (Sorry, my books are at home.)Integrator
At present i just want to solve $Ax = b$ (Kalman filtering is not for now). Nether the less, for finding LU or eigenvalues i would still need to use Eigen or Boost... Which one should i use?Ruddock
If it's really just two coefficients, I'd use the closed form solution and be done with it. It's easy to derive.Integrator
"Which one should I use?" - the one you know best. If you've never used either, then pick one and try it. Or, try both. Your problem is pretty simple. I'd suggest setting up a bake off, pick a measure, and see which one wins.Integrator
R
2

If liscencing is not a problem, you might try the gnu scientific library

http://www.gnu.org/software/gsl/

It comes with a blas library that you can swap for an optimised library if you need to later (for example the intel, ATLAS, or ACML (AMD chip) library.

Rummer answered 3/1, 2011 at 14:14 Comment(4)
GSL linear algebra routines aren't optimized.Lukasz
@watson so what, you don't need fancy optimisation for 100x2?Antedate
@watson It provides an interface to the underlying BLAS library however? You can exchange for your favourate BLAS library in linking rather than in code if you find you really need to optimiseRummer
@David Heffernan. Cache is no problem, because 100x2 fits into L1, but with SSE it can be up to 4-8 times faster than uBLAS (if done in single precision). Download Eigen and see for yourself.Lukasz
H
1

If you have access to MATLAB, I would recommend using its C libraries.

Hereford answered 3/1, 2011 at 13:42 Comment(6)
hmm, rather a brutal solution to a trivial problem!Antedate
AFAIK, Matlab C library (at least linear algebra routines) use/based some of the well known publicly available libraries (LAPACK).Lukasz
@watson all the linear algebra libraries are essentially the same and derived from the HandbookAntedate
@David Heffernan. Hope your are joking. MKL, Eigen, ATLAS are optimized to exploit cache memory more efficiently. Stock LAPACK (r u referring to LAPACK handbook?) provides only (un-optimized) reference implementation and high level routines.Lukasz
@watson the algorithms are essentially the sameAntedate
@David Heffernan. Math formulas are the same, but implementations are different. Tuning to memory hierarchy is done differently. LAPACK and uBLAS don't do any tuning.Lukasz
R
-1

If you really need to specialize, you can approximate matrix inversion (to arbitrary precision) using the Skilling method. It uses order (N^2) operations only (rather than the order N^3 of usual matrix inversion - LU decomposition etc).

Its described in the thesis of Gibbs linked to here (around page 27):

http://www.inference.phy.cam.ac.uk/mng10/GP/thesis.ps.gz

Rummer answered 3/1, 2011 at 14:24 Comment(3)
Never use matrix inversion to solve linear systems. Solving linear systems is by essence a O(n^2) problem.Tussle
@Alexandre Really? - I would be interested in your solution. LU decomposition, for example is Order N^3 (according to the thesis I cite, anyway).Rummer
@David I agree entirely, but the question wants as "fast as possible" so I offer this as a future specialisation if they really need it.Rummer

© 2022 - 2024 — McMap. All rights reserved.