Registered Member
|
Hello Eigen community!
I am currently working on a piece of code that somebody else has written, and I have recently found a major bug in it. The code can be found here: https://github.com/alkamid/QCLD/blob/ma ... ce/QCL.cpp I think I found the place where the bug occurs and it's line #619:
If I print POISSON_M.inverse() and DENSITY_VECTOR separately, their values seem to be okay (I can check the order of magnitude if you want), but POISSON_M.inverse()*DENSITY_VECTOR just goes crazy -- its values are >10e80, when they should be more like 10e15. This completely destroys further calculations. The strange thing is, it works just fine on Windows, and the program gives reasonable results. The problem occurs on Linux using gcc 4.8.1, as opposed to gcc 4.4.1 via MinGW on Windows. In both cases I used the latest stable Eigen, 3.2.0. Also, the multiplication in the first iteration of the main loop (the one starting at #228) seems to work fine on Linux. I would be very, very grateful if you could point me into the right direction with this bug, as I have already spent a few days locating it. If there is anything else I can provide you with, please let me know!
Last edited by alkamid on Tue Oct 29, 2013 10:22 am, edited 1 time in total.
|
Moderator
|
I would recommend you to run your program under valgrind to detect the real memory error.
Then, if POISSON_M is not very small (>4), then doing POISSON_M.lu().solve(DENSITY_VECTOR) will be both faster and numerically more accurate than explicitly computing the inverse. |
Registered Member
|
Thanks ggael. Although the program runs much faster (the matrix is >500x500), the error persists. I will try valgrind.
EDIT: valgrind gives me so many warnings that it will take at least a few days before I sort them out. EDIT2: Okay, could you please help me start with valgrind? The very first warning I get is:
Line 247 is:
and because valgrind is complaining about a Matrix object, I suspect something is wrong with H initialisation:
Is it not how I am supposed to initialise it? Can you see what is wrong here? |
Moderator
|
hm, could you show more code... What solve_eigen is? When you do EigenSolver<MatrixXd> H (Eigen_dim);, this creates an eigenvalue solveur and preallocate memory for matrices of size Eigen_dim x Eigen_dim. However, before using it, you must call H.compute(A); with some matrix A.
|
Registered Member
|
The whole code is here: https://github.com/alkamid/QCLD/blob/ma ... ce/QCL.cpp |
Moderator
|
instead of:
H = EigenSolver<MatrixXd> ( H_INITIALISE ,true ) you should do: H.compute( H_INITIALISE ,true ); maybe there are more issues though... Also make sure solve_eigen is not inlined to help debugging with valgrind. |
Registered Member
|
It seems to work now, thanks. But what was the issue, what I was doing wrong?
|
Moderator
|
Good question actually. Maybe this is hiding another memory issue (is valgrind completely green now?) or maybe your using an old version of Eigen which had and issue regarding that? The following example is running fine with valgrind:
|
Moderator
|
hm wait, the problem is that not all entries in H_INITIALISE are set. You should call:
H_INITIALISE.setZero(); before starting filling it. By default Eigen's matrices are not intialized to zero, they are not initialized at all. |
Registered Member
|
No, valgrind is far from being green, but at least it got a few more iterations right.
The first valgrind error (warning?) looks exactly the same to the one I posted in my second post, but I have no idea what is wrong there. I am compiling with -O2 flag, so all should be inline. |
Registered Member
|
Then the program slows down very significantly, but I understand what you mean. It is a tridiagonal matrix -- is there any way that Eigen can solve it faster? |
Moderator
|
adding .setZero() should not be slower since you are using a dense matrix anyway ! Is your matrix symmetric? If so you could EigenSelfadjointSolver and call computeFromTridiagonal(...).
|
Registered Member
|
Oh, I just panicked about the execution time -- it is in fact valgrind that takes so long, not the program itself. Actually, you solved two major issues with my program, thanks a lot for that! Now it seems to run just fine.
The matrix is not symmetric, unfortunately, so I guess I have to use dense matrices. Now when I run valgrind the first error is:
Line #246 is:
|
Moderator
|
It's probably the same. You should check that you're not assuming a matrix is automatically initialized by zero.
We plane to add a computeFromHessenberg shortcut in EigenSolver. That should save you some times. |
Registered Member
|
Maybe the problem is in "H"? This is how I initialise it: (line 177)
But is this the right way? |
Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]