gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
cwidth.f
Go to the documentation of this file.
1  subroutine cwidth ( w,b,nequ,ncols,integs,nbloks, d, x,iflag )
2 
3 c*********************************************************************72
4 c
5 cc CWIDTH solves an almost block diagonal linear system.
6 c
7 c this program is a variation of the theme in the algorithm bandet1
8 c by martin and wilkinson (numer.math. 9(1976)279-307). it solves
9 c the linear system
10 c a*x = b
11 c of nequ equations in case a is almost block diagonal with all
12 c blocks having ncols columns using no more storage than it takes to
13 c store the interesting part of a . such systems occur in the determ-
14 c ination of the b-spline coefficients of a spline approximation.
15 c
16 c parameters
17 c w on input, a two-dimensional array of size (nequ,ncols) contain-
18 c ing the interesting part of the almost block diagonal coeffici-
19 c ent matrix a (see description and example below). the array
20 c integs describes the storage scheme.
21 c on output, w contains the upper triangular factor u of the
22 c lu factorization of a possibly permuted version of a . in par-
23 c ticular, the determinant of a could now be found as
24 c iflag*w(1,1)*w(2,1)* ... * w(nequ,1) .
25 c b on input, the right side of the linear system, of length nequ.
26 c the contents of b are changed during execution.
27 c nequ number of equations in system
28 c ncols block width, i.e., number of columns in each block.
29 c integs integer array, of size (2,nequ), describing the block struct-
30 c ure of a .
31 c integs(1,i) = no. of rows in block i = nrow
32 c integs(2,i) = no. of elimination steps in block i
33 c = overhang over next block = last
34 c nbloks number of blocks
35 c d work array, to contain row sizes . if storage is scarce, the
36 c array x could be used in the calling sequence for d .
37 c x on output, contains computed solution (if iflag .ne. 0), of
38 c length nequ .
39 c iflag on output, integer
40 c = (-1)**(no.of interchanges during elimination)
41 c if a is invertible
42 c = 0 if a is singular
43 c
44 c ------ block structure of a ------
45 c the interesting part of a is taken to consist of nbloks con-
46 c secutive blocks, with the i-th block made up of nrowi = integs(1,i)
47 c consecutive rows and ncols consecutive columns of a , and with
48 c the first lasti = integs(2,i) columns to the left of the next block.
49 c these blocks are stored consecutively in the workarray w .
50 c for example, here is an 11th order matrix and its arrangement in
51 c the workarray w . (the interesting entries of a are indicated by
52 c their row and column index modulo 10.)
53 c
54 c --- a --- --- w ---
55 c
56 c nrow1=3
57 c 11 12 13 14 11 12 13 14
58 c 21 22 23 24 21 22 23 24
59 c 31 32 33 34 nrow2=2 31 32 33 34
60 c last1=2 43 44 45 46 43 44 45 46
61 c 53 54 55 56 nrow3=3 53 54 55 56
62 c last2=3 66 67 68 69 66 67 68 69
63 c 76 77 78 79 76 77 78 79
64 c 86 87 88 89 nrow4=1 86 87 88 89
65 c last3=1 97 98 99 90 nrow5=2 97 98 99 90
66 c last4=1 08 09 00 01 08 09 00 01
67 c 18 19 10 11 18 19 10 11
68 c last5=4
69 c
70 c for this interpretation of a as an almost block diagonal matrix,
71 c we have nbloks = 5 , and the integs array is
72 c
73 c i= 1 2 3 4 5
74 c k=
75 c integs(k,i) = 1 3 2 3 1 2
76 c 2 2 3 1 1 4
77 c
78 c -------- method --------
79 c gauss elimination with scaled partial pivoting is used, but mult-
80 c ipliers are n o t s a v e d in order to save storage. rather, the
81 c right side is operated on during elimination.
82 c the two parameters
83 c i p v t e q and l a s t e q
84 c are used to keep track of the action. ipvteq is the index of the
85 c variable to be eliminated next, from equations ipvteq+1,...,lasteq,
86 c using equation ipvteq (possibly after an interchange) as the pivot
87 c equation. the entries in the pivot column are a l w a y s in column
88 c 1 of w . this is accomplished by putting the entries in rows
89 c ipvteq+1,...,lasteq revised by the elimination of the ipvteq-th
90 c variable one to the left in w . in this way, the columns of the
91 c equations in a given block (as stored in w ) will be aligned with
92 c those of the next block at the moment when these next equations be-
93 c come involved in the elimination process.
94 c thus, for the above example, the first elimination steps proceed
95 c as follows.
96 c
97 c *11 12 13 14 11 12 13 14 11 12 13 14 11 12 13 14
98 c *21 22 23 24 *22 23 24 22 23 24 22 23 24
99 c *31 32 33 34 *32 33 34 *33 34 33 34
100 c 43 44 45 46 43 44 45 46 *43 44 45 46 *44 45 46 etc.
101 c 53 54 55 56 53 54 55 56 *53 54 55 56 *54 55 56
102 c 66 67 68 69 66 67 68 69 66 67 68 69 66 67 68 69
103 c . . . .
104 c
105 c in all other respects, the procedure is standard, including the
106 c scaled partial pivoting.
107 c
108  implicit none
109 
110  integer nbloks
111 
112  integer iflag,integs(2,nbloks),ncols,nequ, i,ii,icount,ipvteq
113  & ,ipvtp1,istar,j,jmax,lastcl,lasteq,lasti,nexteq,nrowad
114  double precision b(nequ),d(nequ),w(nequ,ncols),x(nequ),
115  & awi1od,colmax,ratio,rowmax,sum,temp
116  iflag = 1
117  ipvteq = 0
118  lasteq = 0
119 c the i-loop runs over the blocks
120  do 50 i=1,nbloks
121 c
122 c the equations for the current block are added to those current-
123 c ly involved in the elimination process, by increasing lasteq
124 c by integs(1,i) after the rowsize of these equations has been
125 c recorded in the array d .
126 c
127  nrowad = integs(1,i)
128  do 10 icount=1,nrowad
129  nexteq = lasteq + icount
130  rowmax = 0.0d+00
131  do 5 j=1,ncols
132  5 rowmax = dmax1(rowmax,dabs(w(nexteq,j)))
133  if (rowmax .eq. 0.0d+00) go to 999
134  10 d(nexteq) = rowmax
135  lasteq = lasteq + nrowad
136 c
137 c there will be lasti = integs(2,i) elimination steps before
138 c the equations in the next block become involved. further,
139 c l a s t c l records the number of columns involved in the cur-
140 c rent elimination step. it starts equal to ncols when a block
141 c first becomes involved and then drops by one after each elim-
142 c ination step.
143 c
144  lastcl = ncols
145  lasti = integs(2,i)
146  do 30 icount=1,lasti
147  ipvteq = ipvteq + 1
148  if (ipvteq .lt. lasteq) go to 11
149  if ( dabs(w(ipvteq,1))+d(ipvteq) .gt. d(ipvteq) )
150  * go to 50
151  go to 999
152 c
153 c determine the smallest i s t a r in (ipvteq,lasteq) for
154 c which abs(w(istar,1))/d(istar) is as large as possible, and
155 c interchange equations ipvteq and istar in case ipvteq
156 c .lt. istar .
157 c
158  11 colmax = dabs(w(ipvteq,1))/d(ipvteq)
159  istar = ipvteq
160  ipvtp1 = ipvteq + 1
161  do 13 ii=ipvtp1,lasteq
162  awi1od = dabs(w(ii,1))/d(ii)
163  if (awi1od .le. colmax) go to 13
164  colmax = awi1od
165  istar = ii
166  13 continue
167  if ( dabs(w(istar,1))+d(istar) .eq. d(istar) )
168  & go to 999
169  if (istar .eq. ipvteq) go to 16
170  iflag = -iflag
171  temp = d(istar)
172  d(istar) = d(ipvteq)
173  d(ipvteq) = temp
174  temp = b(istar)
175  b(istar) = b(ipvteq)
176  b(ipvteq) = temp
177  do 14 j=1,lastcl
178  temp = w(istar,j)
179  w(istar,j) = w(ipvteq,j)
180  14 w(ipvteq,j) = temp
181 c
182 c subtract the appropriate multiple of equation ipvteq from
183 c equations ipvteq+1,...,lasteq to make the coefficient of the
184 c ipvteq-th unknown (presently in column 1 of w ) zero, but
185 c store the new coefficients in w one to the left from the old.
186 c
187  16 do 20 ii=ipvtp1,lasteq
188  ratio = w(ii,1)/w(ipvteq,1)
189  do 18 j=2,lastcl
190  18 w(ii,j-1) = w(ii,j) - ratio*w(ipvteq,j)
191  w(ii,lastcl) = 0.0d+00
192  20 b(ii) = b(ii) - ratio*b(ipvteq)
193  30 lastcl = lastcl - 1
194  50 continue
195 c
196 c at this point, w and b contain an upper triangular linear system
197 c equivalent to the original one, with w(i,j) containing entry
198 c (i, i-1+j ) of the coefficient matrix. solve this system by backsub-
199 c stitution, taking into account its block structure.
200 c
201 c i-loop over the blocks, in reverse order
202  i = nbloks
203  59 lasti = integs(2,i)
204  jmax = ncols - lasti
205  do 70 icount=1,lasti
206  sum = 0.0d+00
207  if (jmax .eq. 0) go to 61
208  do 60 j=1,jmax
209  60 sum = sum + x(ipvteq+j)*w(ipvteq,j+1)
210  61 x(ipvteq) = (b(ipvteq)-sum)/w(ipvteq,1)
211  jmax = jmax + 1
212  70 ipvteq = ipvteq - 1
213  i = i - 1
214  if (i .gt. 0) go to 59
215  return
216  999 iflag = 0
217  return
218  end
subroutine cwidth(w, b, nequ, ncols, integs, nbloks, d, x, iflag)
Definition: cwidth.f:2
gtkIOStream: /tmp/gtkiostream/src/deBoor/cwidth.f Source File
GTK+ IOStream  Beta