File:  [CSRG BSD Unix] / 41BSD / cmd / efl / efltest / Band.e
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:12:53 2018 UTC (8 years, 1 month ago) by root
Branches: MAIN, BSD
CVS tags: HEAD, BSD41
BSD 4.1

  procedure bnds(n,ml,m,g,nb,b)
 
# to solve a*x = b, where a is a banded matrix, using gaussian
# elimination with partial pivoting.
 
# mnemonic - double precision band solution of a system of
#            linear algebraic equations.
 
# input -
 
#   n  - the order of the system.
#   ml - the number of nonzero elements of a on and below the diagonal.
#   m  - the total number of nonzero elements in each row of a.
#   g  - the matrix a, with g(i,j) = a(i,i+j-ml).
#   nb - the number of right-hand-sides b.
#   b  - the right-hand-sides.
 
# output -
 
#   g - has been clobbered.
#   b - the solution vectors, x.
 
# scratch space allocated - n*( (ml-1)*mu + 1 ) words.
 
# error states -
 
#   1 - n.lt.1.
#   2 - ml.lt.1.
#   3 - ml.gt.m.
#   4 - nb.lt.1.
#   5 - singular matrix. (recoverable)
  
  real g(n,m),b(n,nb)
  integer n,ml,m,nb
  
  include rstack
  
  integer il,iint,istkgt,nerror,nerr
  
# check the input for errors.
 
  if ( n < 1 ) { seterr(" bnds - n.lt.1",14,1,2) }
  if ( ml < 1 ) { seterr(" bnds - ml.lt.1",16,2,2) }
  if ( ml > m ) { seterr(" bnds - ml.gt.m",15,3,2) }
  if ( nb < 1 ) { seterr(" bnds - nb.lt.1",15,4,2) }
 
  enter(1)
  
  il = istkgt(max0(n*(ml-1),1),3) ; iint = istkgt(n,2)
  
  bndlu(n,ml,m,g,ws(il),is(iint))
  
  if ( nerror(nerr) == 0 ) { bndfb(n,ml,m,ws(il),g,is(iint),nb,b) }
 
  else { erroff() ; seterr(" bnds - singular matrix",23,5,1) }
  
  leave()
  
  return
  
  end
  procedure bndlu(n,ml,m,g,l,int)
 
# to obtain the lu decomposition of a banded matrix,
# using gaussian elimination with partial pivoting.
 
# mnemonic - double precision band lu decomposition.
 
# input -
 
#   n   - the order of the matrix.
#   ml  - the number of nonzero elements of a on and below the diagonal.
#   m   - the number of nonzero elements in each row of a.
#   g   - the matrix a, with g(i,j) = a(i,i+j-ml).
 
# output -
 
#   l   - the lower triangular banded factor of a.
#   g   - the upper triangular banded factor of a.
#   int - the row pivoting used.
 
# scratch storage allocated - none.
 
# error states -
 
#   1 - n.lt.1.
#   2 - ml.lt.1.
#   3 - m.lt.ml.
#   4 - singular matrix. (recoverable)
  
  real g(n,m),l(n,ml)    # l(n,ml-1).
  integer n,ml,m,int(n)
  
  real x,norm,eps,r1mach
  integer i,j,k,ll,m1,m2
  logical sing
  
# check the input for errors.
 
  if ( n < 1 ) { seterr(" bndlu - n.lt.1",15,1,2) }
  if ( ml < 1 ) { seterr(" bndlu - ml.lt.1",16,2,2) }
  if ( m < ml ) { seterr(" bndlu - m.lt.ml",16,3,2) }
 
  entsrc(i,0)    # protect against an existing error state.
 
  sing = .false. ; eps = r1mach(4)
  m1 = ml-1 ; m2 = m-ml
  
  ll = m1
  for ( i = 1 , i <= min0(m1,n) , i += 1 )    # set to 0 those elements
    {                                         # of g which are undefined.
    do j = ml+1-i , m 
		 { g(i,j-ll) = g(i,j) }
    ll = ll-1
    do j = m-ll , m 
		 { g(i,j) = 0.0e0 }
    }
  
  for ( i = 1 , i <= min0(m2,n) , i += 1 )    # zero out lower rhs wart.
    {
    do j = ml+i , m 
		 { g(n+1-i,j) = 0.0e0 }
    }
 
  norm = 0.0e0    # get || a || sub infinity.
  do i = 1 , n 
		
    {
    int(i) = i
    x = 0.0e0 ; do j = 1 , m 
		 { x += abs(g(i,j)) }
    norm = amax1(norm,x)
    }
  
  do k = 1 , n 
		
    {
    x = g(k,1) ; i = k
    
    ll = min0(m1+k,n)
    
    if ( k < ll )
      {
      do j = k+1 , ll 
		    # get the pivot row.
        { if ( abs(g(j,1)) > abs(x) ) { x = g(j,1) ; i = j } }
      }
    
    int(k) = i
    
    if ( x == 0.0e0 ) { sing = .true. ; g(k,1) = norm*eps }
 
    if ( ml == 1 | k == n ) { next }
    
    if ( i ~= k )    # need to interchange the rows.
      {
      do j = 1 , m 
		 { x = g(k,j) ; g(k,j) = g(i,j) ; g(i,j) = x }
      }
    
    if ( k >= ll ) { next }
    do i = k+1 , ll 
		
      {
      x = g(i,1)/g(k,1)
      l(k,i-k) = x
      
      do j = 2 , m 
		 { g(i,j-1) = g(i,j)-x*g(k,j) }
 
      g(i,m) = 0.0e0
      }
    }
  
  if ( sing ) { seterr(" bndlu - singular matrix",24,4,1) }
  
  return
  
  end
  procedure bndfb(n,ml,m,l,u,int,nb,b)
 
# to solve l*u*x = b, where l and u result from a call to bnds.
 
# mnemonic - double precision band forward elimination and
#            back-solve.
 
# input -
 
#   n   - the order of the system.
#   ml  - the number of nonzero entries of l on and below
#         the diagonal.
#   m   - the number of nonzero elements of u on and above
#         the diagonal.
#   l   - the lower triangular banded factor.
#   u   - the upper triangular banded factor.
#   int - the ordering of the rows of the system, due to pivoting.
#   nb  - the number of right-hand-sides.
#   b   - the right-hand-sides.
 
# output -
 
#   b - the solution vectors.
 
# scratch space allocated - none.
 
# error states -
 
#   1 - n.lt.1.
#   2 - ml.lt.1.
#   3 - m.lt.ml.
#   4 - nb.lt.1.
 
  real l(n,ml),u(n,m),b(n,nb)    # l(n,ml-1).
  integer n,ml,m,int(n),nb
 
  integer nerror,nerr
 
# check the input for errors.
 
  if ( n < 1 ) { seterr(" bndfb - n.lt.1",15,1,2) }
  if ( ml < 1 ) { seterr(" bndfb - ml.lt.1",16,2,2) }
  if ( m < ml ) { seterr(" bndfb - m.lt.ml",16,3,2) }
  if ( nb < 1 ) { seterr(" bndfb - nb.lt.1",16,4,2) }
  
  entsrc(nerr,0)    # protect against an existing error state.
  
  bndfe(n,ml,l,int,nb,b)
		    # do the forward-elimination.
 
  bndbs(n,m,u,nb,b)
		    # do the back-substitution.
  
  return
  
  end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.