Smart questions
Smart people
 Find A ForumFind An Expert
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Remember Me

Are you a
Computer / IT professional?
Join Tek-Tips now!
• Talk With Other Members
• Be Notified Of Responses
• Keyword Search
Favorite Forums
• Automated Signatures
• 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.

Just copy and paste the

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)

 Forum Search FAQs Links Jobs Whitepapers MVPs
 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.

CODE

program 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')
close(7)

! matrix b
open(unit=11, file='bb.dat', status = 'old', action='read')
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.
 gummibaer (Programmer) 23 Apr 12 8:23
 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 notproperly installed such that I could use it. So I then deleted everything.
 mikrom (Programmer) 23 Apr 12 17:37

Quote (dibas):

is it possible for you to provide me with practical steps of installing the package?
 salgerman (Programmer) 24 Apr 12 0:19
 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 statusBut I think the liblapack.dll is a Windows-based library.Anyway, I tried to define a lower-order square matrix with from the mainone 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-dev
The 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:

CODE

sudo apt-get install liblapack-dev libblas-dev liblapack3gf
 gummibaer (Programmer) 24 Apr 12 6:18

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.

 gummibaer (Programmer) 25 Apr 12 10:48
 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.
 salgerman (Programmer) 25 Apr 12 11:04
 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 thisinvolves a Newton-Raphson step at some point. It is in this step that wethen 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 zeroon initially (at t=0) but will then build up in future times. So to avoidsome of the Jacobian elements being undefined because of this, I set themto 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 ifthe one or some other number will be an appropriate choice.
 salgerman (Programmer) 25 Apr 12 14:04
 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 = b6So, 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
 gummibaer (Programmer) 25 Apr 12 14:06
 ... 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 verysloppy (or even inaccurate) and hence the confusion between matrixcoefficients 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.00000I'm sorry for that. So when referring to x5 (or ai5), it shouldhave been x6 (and ai6). I picked this up because I know it is thesixth 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 thezero 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:

CODE

Program 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

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

• Talk To Other Members
• Notification Of Responses To Questions
• Favorite Forums One Click Access
• Keyword Search Of All Posts, And More...

Register now while it's still free!