Smart questions
Smart answers
Smart people
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Member Login

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!

Join Tek-Tips
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

LINK TO THIS FORUM!

Add Stickiness To Your Site By Linking To This Professionally Managed Technical Forum.
Just copy and paste the
code below into your site.

Partner With Us!

"Best Of Breed" Forums Add Stickiness To Your Site
Partner Button
(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)Helpful Member!(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.

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')
     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.
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 not
properly installed such that I could use it. So I then deleted everything.
Helpful Member!  mikrom (Programmer)
23 Apr 12 17:37

Quote (dibas):


is it possible for you to provide me with practical steps of installing the package?
Didn't this help you a little bit?
http://www.tek-tips.com/viewthread.cfm?qid=1678628
Helpful Member!  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 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-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
Helpful Member!  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 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.
 
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 = 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  smile

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  smile







 
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 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:

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
    

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Back To Forum

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:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close