INTELLIGENT WORK FORUMS FOR COMPUTER PROFESSIONALS
Come Join Us!
Are you a Computer / IT professional? Join Tek-Tips now!
- Talk With Other Members
- Be Notified Of Responses
To Your Posts
- Keyword Search
- One-Click Access To Your
Favorite Forums
- Automated Signatures
On Your Posts
- Best Of All, It's Free!
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.
Partner With Us!
"Best Of Breed" Forums Add Stickiness To Your Site

(Download This Button Today!)
Feedback
"...These forums are an excellent source and example of the way people can help each other..."
Geography
Where in the world do Tek-Tips members come from?
|
solving linear system with zero rows(picking rows and columns) (3)
|
|
|
dibas (Programmer) |
23 Apr 12 5:37 |
I'm trying to solve the following linear (6x6) system that contains a row of zeros in it using LU decomposition and LU back substitution. coefficient matrix = 0.07192 -0.05664 -0.22443 -159.36051 0.00000 -0.01644 0.00000 -0.00000 -0.00000 -0.00000 0.00000 -0.00000 -0.14818 0.11671 0.46242 328.35612 0.00000 0.03387 0.02470 -0.01945 -0.07708 -54.73203 0.00000 -0.00565 -0.00002 0.00002 0.00007 0.04627 0.00000 0.00000 -0.00012 0.00009 0.00037 0.26397 1.00000 0.00003 right hand side vector = -0.04441696 0.00000000 0.08007247 -0.00272736 -0.00002423 -0.00008325 My idea is to "eliminate" the zero-row together with the corresponding column and then solve the "reduced" system. My problem is that I do manage to pick out the non-zero row(s), but I cannot pick the corresponding column(s). This my piece of code. CODEprogram driver_lusolver use nrtype use nrutil, only : ludcmp, lubksb
implicit none integer, parameter :: mrows = 6, ncols = 6 ! rows & columns integer :: mlog, nlog ! log dimemsions of matrix to be 4md from a real(sp) :: a(mrows, ncols), b(mrows) integer, dimension(mrows) :: zero_row_indx integer :: i, j, kk, zeros_in_row, jj, ll logical :: any_nonzero real(sp) :: d integer(i4b) :: indx(mrows)
real(sp), allocatable :: a_prime(:, :) , b_prime(:)
! matrix A open(unit=7, file='matrix.dat', status = 'old', action='read') read(7,*) ((a(i,j), j=1,ncols), i=1,mrows) close(7)
! matrix b open(unit=11, file='bb.dat', status = 'old', action='read') read(11,*) (b(i), i=1,mrows) close(11)
zero_row_indx = 0 ! array for storing zero-row indices do i = 1 , mrows if ( all(abs(a(i,:)) < 1.0e-12) ) then zero_row_indx(i) = i end if end do
kk = count( mask= zero_row_indx > 0 ) ! write(*,*) "there are", kk, "zero rows" ! write(*,"(i2)") zero_row_indx
mlog = mrows - kk ! compute logical dimensions of new arrays nlog = ncols - kk
allocate(a_prime(mlog, nlog), b_prime(mlog)) !create storage for new arrays
a_prime = 0.000 ; b_prime = 0.00 !initialize new matrix & vector jj = 1 ! initialize row counter of new matrix & vecor do i = 1, mrows if ( any(abs(a(i,:)) > 1.0e-12) ) then a_prime(jj,:) = a(i,:) ! picking row b_prime(jj) = b(i) jj = jj + 1 end if end do
! Initialise 'indx' ( a vector of length mrows) ! containing row permutations indx(1:mrows) = 0 ; d = -1.0_sp
! Solve by lu decomposition call ludcmp(a_prime, indx, d) call lubksb(a_prime, indx, b)
! print solutions x(n) ! write (*,203) ! write (*,201) (b(i),i=1,mlog)
! expected soln: b = [3.000000 1.000000 -2.000000 1.000000]^T
200 format (' LUdecomp and LUbksb: Matrix A and vector') 201 format (6f13.5) 202 format (/,' Matrix A after decomposition') 203 format (/,' Solutions x(n)')
end program driver_lusolver I don't know if there is an algorithm or implementable method that can handle this case of a linear system. I would appreciate any suggestions. Thank you. |
|
|
ArkM (IS/IT--Management) |
23 Apr 12 5:51 |
Are you sure that you have "a row of zeroes"? If so, no solution of such a system. Look at minus sign in some -0.00000s: it's a very small negative value!.. |
|
|
dibas (Programmer) |
23 Apr 12 8:16 |
Those numbers are practically zeros, even when printed to 16 decimal places. They are just floating point artifacts. |
|
Think about your system as linear equations. Then you have one trivial equation that says 0 = 0 for every row of zeroes. If you have kk of these trivial equations, then you have (6 - kk) equations to define the 6 unknown entities --> no unambiguous solution. If you had the same number of zero columns, then you once again have a solvable system. But why bother to code a new solver of linear equations ? As this is a standard problem there are a lot of libraries around. Even if I did not use it as yet, I heard a lot about LAPACK. See this link: http://www.netlib.org/lapack/Norbert The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true. |
|
|
ArkM (IS/IT--Management) |
23 Apr 12 11:04 |
That's a problem: no zero columns in the matrix - no solution... |
|
|
dibas (Programmer) |
23 Apr 12 16:43 |
Yes gummibaer, I have tried a countless number of times to get LAPACK onto my system but failed. My PC is running on Linux Ubuntu 11.10 & uses the Gnome desktop (&terminal). My compiler is "gfortran". Even though my professors don not fully approve of using "black-box" solvers, I always wish to compare my results with what LAPACK would give. Starting from having the "lapack-3.4.1.tgz" file, is it possible for you to provide me with practical steps of installing the package? In one of my attempts, I did some steps to "build" and "test" but the package was not properly installed such that I could use it. So I then deleted everything. |
|
mikrom (Programmer) |
23 Apr 12 17:37 |
|
It's good to want to compare the results from your own fortran programs with algorithms implemented by you to the results from third party libraries or programs; but LAPACK is proving difficult to install, you can always compare to results from other programs like octave, freemat, python/numpy/scipy, etc...all which, I believe are available for installation to your Ubuntu with a single click.
|
|
|
dibas (Programmer) |
24 Apr 12 4:01 |
mikrom,I'm sorry the example program you gave me ( http://www.tek-tips.com/viewthread.cfm?qid=1678628 ) couldn't work because I had failed to properly install LAPACK on my system. These were the error messages from the two options you gave me: (1) /tmp/cczJi5YX.o: In function `MAIN__': example.f95:(.text+0xe1): undefined reference to `dgesv_' collect2: ld returned 1 exit status (2) /tmp/ccKYV7Q0.o: In function `MAIN__': example.f95:(.text+0xe1): undefined reference to `dgesv_' collect2: ld returned 1 exit status But I think the liblapack.dll is a Windows-based library. Anyway, I tried to define a lower-order square matrix with from the main one such that the zero row and the corresponding columns were left out. The decision to do that does not conflict with the theoretical background of my problem. I'm modifying the solving steps to see if the solving part works fine. |
|
|
mikrom (Programmer) |
24 Apr 12 5:38 |
Quote (dibas): But I think the liblapack.dll is a Windows-based library.
Yes, I tried it only at windows, because I'm not experienced Ubuntu-Linux user and I don't have it installed now. But it seems, that there is Lapack package for Ubuntu available: http://packages.ubuntu.com/precise/liblapack-devThe Ubuntu's APT packages could be installed simply using the command apt-get. Because it seems that liblapack-dev is dependent on other packages libblas-dev and liblapack3gf I would try something like this to install them all: CODEsudo apt-get install liblapack-dev libblas-dev liblapack3gf |
|
Quote: one such that the zero row and the corresponding columns were left out.
What would be the corresponding column ? I do not know of any relationship of rows to columns. Imagine your problem as a system of linear equations again. Then the rows correspond to the sequence how you noted the equations one after the other. So it is clear you could exchange any to rows - together with the vector of course - without any significant change to the equations and their solutions. Similar with the columns. They correspond to the sequence in which the parts of the equations are written down. Without any significant change to the system you can exchange any two columns. So it should be clear that you cannot lay your hand on a column and say this corresponds in any conceivable way to any row. Hope I could clarify this. You can do whatever you want with your system of equations, with five valid equations your system of six unknown variables does not have a solution. Howgh. The thing you can do is to ignore that one of the variables is unknown, say you assume x(1) as known. Solving the remaining 5 by 5 system gives you a set of five equations of the form x(n) = a(n) * x(1) + b(n) to define x(2) to x(6) when you know a value of x(1). Only this and nothing more. Norbert The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true. |
|
Somehow your equations intrigue me. For certain, having five equations for six unknown entities is not sufficient for an unambiguous solution and that is a fact. Buuuut.... Looking at your matrix one can see that all the values in the fifth column have a completely different magnitude then the rest. Roughly there is a factor of about 1000 or more between the coefficients in the fith column and the others and the vector elements of your right hand side(well except the last one, but still...). So I would assume that x(5) is smaller than the other x(n) by the factor of 1000 or more. So maybe you could get an estimate of x(1) to x(4) and x(6) if you approximate x(5) to be zero and thus ignore the fifth column. But, mind you, this is not because this column corresponds to the zero-row in any way but because of the numeric properties of these values. And this solution can only be an approximation to the full solution. Norbert. The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true. |
|
I wonder where these variables come from.
Allow me to play Devil's Advocate here, for a moment, and challenge the validity of the choice of variables....is it 100% certain that these variables are true state variables? Or could it be that one of them was mistaken by one and included in the equations when if should have been left out?
Other than that, there is nothing wrong in multiplying one of the rows by 100, or 1000 or whatever in order for it to have similar order of magnitude as the rest in order to make it easy on the solver...otherwise, it may declare it singular or something.
Yet, I don't know, of top of my head, what to do about the very small column.
|
|
|
dibas (Programmer) |
25 Apr 12 13:16 |
Yes, looking at the coefficient matrix, there equations are intriguing for sure. Just some brief background of the problem. This is part of an evolution problem which uses implicit time-stepping (integrator). So this involves a Newton-Raphson step at some point. It is in this step that we then encounter this "linear" system - actually the system is solved at each iteration for "Newton corrections(dx)" to the state variables, not the state variables themselves.
According to the theory of the problem, the state variable x2 should not evolve, which means the Jacobian matrix will have zeros in row2 (hence we can also set dx ~ 0). It is only included for generalization purposes - should it be allowed in some instance to evolve?
Also, the last two state variables are special in the sense that x5 is zero on initially (at t=0) but will then build up in future times. So to avoid some of the Jacobian elements being undefined because of this, I set them to zero and gave the value 1 to the diagonal elements so that the Jacobian matrix (in J.dx = -F) could be 'invertible'. So this brings in the different orders of magnitude. I'm yet to experiment with this and see if the one or some other number will be an appropriate choice. |
|
What? ... Hold on a second! After reading what you have said above, I am getting impression that you are confusing variable values with variable coefficients. I mean, a system of equations should look something like: a11x1 + a12x2 + a13x3 + a14x4 + a15x5 + a16x6 = b1 . . . a61x1 + a62x2 + a63x3 + a64x4 + a65x5 + a66x6 = b6 So, just because x5 is initially zero, that does not meant that you need to set a15, a25, a35, a45, a55 and a56 to zeroes in your coefficient matrix...the product of ai5x5 will zero out naturally if x5 is zero, YOU do not need to worry about that...a45 or a55 or whatever, could take on any values...you know what I am saying? So, where do the coefficients in your matrix (that you show in the original posting) come from? Do they have a genuine origin, or did you make some of them up like the zeroes and the 1 that you talked about? Then again, if you know that x2 is not going to evolve and if your matrix is actually solving for dx's and not x's and, hence, you know that dx2 is zero, THEN, you can actually take the second column out of the picture. I don't remember why the second row is full of zeroes, but if it is like for some reason and taking second column out brings you back a square system...go for it  That is, of course, if those zeroes truly represent the matrix coefficient and NOT the variable values!!! Hope it is me who is confused about this and not you |
|
... so line 2 and column 5 are added to the set artificially so to speak ? Then, if you leave them off, it would be a 5 by 5 system ? Norbert The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true. |
|
|
dibas (Programmer) |
26 Apr 12 3:34 |
"...I am getting impression that you are confusing variable values with variable coefficients." Oh, I agree salgerman. My language use was very sloppy (or even inaccurate) and hence the confusion between matrix coefficients and variable. Also, the coefficient matrix I printed out in my original post should have been:
0.07192 -0.05664 -0.22443 -159.36051 -0.01644 0.00000 0.00000 -0.00000 -0.00000 -0.00000 -0.00000 0.00000 -0.14818 0.11671 0.46242 328.35612 0.03387 0.00000 0.02470 -0.01945 -0.07708 -54.73203 -0.00565 0.00000 -0.00002 0.00002 0.00007 0.04627 0.00000 0.00000 -0.00012 0.00009 0.00037 0.26397 0.00003 1.00000
I'm sorry for that. So when referring to x5 (or ai5), it should have been x6 (and ai6). I picked this up because I know it is the sixth variable in my problem that behaves the way I was describing. I think I mixed up my printing statements from the code. Yes gummibaer, I want to then reduce the system to a 5x5 because of the zero row (row2).
Will follow the rest of your details salgerman. It looks I'll get something from there. |
|
|
mikrom (Programmer) |
26 Apr 12 7:30 |
Maybe I missed something, but IMHO: If you have given 5 equations of 6 variables, how want you to reduce it to 5 equations of 5 variables? It's simply undedetermined system and you cannot solve it using Gauss Elimination Method or derived methods like LU decomposition, because of singularity of the matrix. But you can use an approximation method, for example least-norm method. Because you suggested me to install Lapack I tried to use the subroutine DGELS to solve your system and got this result: CODE$ dibas lwork = 198 info = 0 Solution was succesfully computed: x[1]= -33964.12600132240913808300 x[2]= -0.00000000000000000000 x[3]= -12768.14057842434522172000 x[4]= 4.57661538381135368780 x[5]= -18639.50908847808022983400 x[6]= -0.00041115380137691132 Here is the source code: CODEProgram LinearEquations ! solving the matrix equation A*x=b using LAPACK Implicit none
! declarations integer :: i, m, n, lda, ldb, lwork, lwmax, info parameter(m = 6, n = 6, lwmax = 300) ! lda = max(1, m) ! ldb = max(1, m, n) parameter(lda = 6, ldb = 6) double precision :: A(lda,n), b(ldb), work(lwmax) ! matrix A A(1,:)=(/0.07192,-0.05664,-0.22443,-159.36051,-0.01644,0.00000/) A(2,:)=(/0.00000,-0.00000,-0.00000,-0.00000,-0.00000,0.00000/) A(2,:)=(/-0.14818,0.11671,0.46242,328.35612,0.03387,0.00000/) A(3,:)=(/0.02470,-0.01945,-0.07708,-54.73203,-0.00565,0.00000/) A(4,:)=(/-0.00002,0.00002,0.00007,0.04627,0.00000,0.00000/) A(5,:)=(/-0.00012,0.00009,0.00037,0.26397,0.00003,1.00000/)
! vector b
b(:)=(/-0.04441696,0.00000000,0.08007247,-0.00272736,-0.00002423,-0.00008325/)
! workspace query: calculates the optimal size of the WORK array lwork = -1 call DGELS( 'No transpose', m, n, 1, A, lda, b, ldb, work, lwork, info) ! compute workspace size lwork = min(lwmax, int(work(1))) write(*,*) 'lwork = ', lwork
! solve call DGELS('No transpose', m, n, 1, A, lda, b, ldb, work, lwork, info)
write(*,*) 'info = ', info if (info .eq. 0) then write(*,*) 'Solution was succesfully computed:' ! print the solution x do i=1, 6 write(*,9) i, b(i) end do else write(*,*) '* Error computing solution!' end if 9 format('x[', i1, ']= ', f27.20) end program LinearEquations |
|
|
 |
|