10

I am using ublas::Compressed Matrix to work with UMFPACK, a sparse linear solver. Since I am doing a simulation, so every time the linear system is constructed slightly differently that might involve enlarging/shrinking the coefficient matrix and some sparse matrix multiplications. The scale of the linear system is around 25k.

Even there is a binding patch for boost to work with UMFPACK, I still need to change the matrix from time to time, sometimes even figuring out the number of non-zero values would be time-consuming(ideally, I have to give the number of non-zero values when I initialize a matrix). Also, I use ublas::range to append columns/rows dynamically.

So my question is: is there any efficient way to do this? Right now it's too slow for me. Transposing a matrix with dimension like 15k costs nearly 6s and appending about 12k rows is fast(because I guess it's a row-major matrix), but appending the same number of columns to the matrix can cost up to 20s(i guess for the same reason as above, so even I used a column-major matrix the total time required would be the same).

Kinda getting desperate here. Any suggestion is welcome.

Cheers.

He01
  • 171
  • 1
  • 1
  • 6
  • Since I had nearly 30 views but no answers, I think maybe my question is not very clear. So here are some details. – He01 Nov 16 '10 at 10:59
  • Since I am doing simulation, for every time step, I have assemble a linear system and solve it which is basically just AX=B. However, the coefficient matrix A is usually composed by three matrices. A weight matrix, two coefficient matrices for soft constraints and hard constraints respectively that cannot be precomputed. (see next comment) – He01 Nov 16 '10 at 11:08
  • Because solving the linear system is the result of minimizing a quadratic function in a least square sense, I have to do a matrix-matrix multiplication to make a matrix T and a matrix-vector multiplication to make B for integrating the soft constraint matrix the linear system. Then I have to append the hard constraint matrix to the bottom and the right of T in order to make A. Finally, after A and B done, I can input them into UMFPack.(see next comment) – He01 Nov 16 '10 at 11:08
  • As you can imagine, there must be several operations involving data-copying, matrix transposing and resizing. But I just don't know how to make it faster. The code is too long to be put here. And thank you for your time. – He01 Nov 16 '10 at 11:12
  • Since there is still no answer, can anybody at least tell me which part of my question is not clear enough? Any comment is welcome! – He01 Nov 23 '10 at 16:38
  • the classic solution to these kinds of problems is to come up with a different solution.... – Dov Dec 18 '10 at 13:53
  • Providing some demo code could help. – Yakov Galka Dec 18 '10 at 17:58
  • What do you mean by "adding columns"? Does that mean appending a new sparse matrix on the right of the existing one? – Jeremiah Willcock Jan 23 '11 at 06:28

4 Answers4

1

I am not familiar with your packages, but why do you (ideally) have to specify the number of non-zero elements in your matrix? Can't you over-specify and then reduce in size?

I'm also confused by why adding columns should cost so much. A sparse format should be able to handle that. I would conclude that one of two things are happening. Either your matrix is somehow being converted to a non-sparse matrix before being converted back (seems horrible, and impossible in any decent sparse matrix package) or the code for insertion is quadratic, because it repeatedly inserts values, shifting over all the others each time.

The latter seems likely. I would try to roll my own "insert column" code which takes the current sparse matrix, figures out how many more entries there are, allocates a bigger block, and copies in sequentially, inserting the new columns as you go. This is linear, and should essentially be instantaneous. I don't know whether that's sufficient to solve the entire problem, but it should be a start.

Furthermore, if the matrix has on the order of 25k entries, there is no reasonable answer to why copying it or transposing it should take more than a couple of milliseconds. I think you need to benchmark individual pieces of this problem and really determine exactly where the time is going, unless the above solution for adding the columns solves your problem.

Dov
  • 6,731
  • 5
  • 35
  • 58
  • Thanks Dov, I have been very busy since then, let the problem hang on there for a while. I will try your suggestions, piece by piece. – He01 Jan 02 '11 at 18:00
  • Hi Dov, for the transposing part, I tried to transpose a row-major sparse matrix and assign it to a row-major sparse matrix, it is much slower than if I assign it to a column-major sparse matrix. i guess somehow maybe the internal representation is also changed when transposing. – He01 Feb 09 '11 at 15:11
0

How do you construct the matrix each time, are you interfacing from some kind of different software. In this case, time spent on interfacing is I guess is pretty low.

And you use -DNDEBUG flag, for uBlas, right?

I am not sure still what the problem is...

Best,Umut

Umut Tabak
  • 1,770
  • 3
  • 24
  • 39
  • Hi Umut, thanks for your attention, I will test it more and try to give a whole picture here. – He01 Jan 02 '11 at 18:01
0

Rather than constructing A by joining several different sets of values, have you considered keeping them in separate matrices and using the existing solver routines to construct your own overall solver? Basically, you would apply the appropriate decomposition (LU, QR, whatever) to one component matrix, run the corresponding update/transformation on the subsequent components, and repeat for each subsequent matrix. You would then use the factored component matrices to compute your solution. It's not clear whether the library you've been working with would support this directly, though, or whether you'd have to write some/all of the numerical routines yourself.

Phil Miller
  • 32,214
  • 11
  • 62
  • 86
0

Did you try Eigen for this kind of problem? Recently they completed sparse matrices support.

linello
  • 7,476
  • 14
  • 53
  • 98