aboutsummaryrefslogtreecommitdiff
path: root/math/deboor/slvblk.f
diff options
context:
space:
mode:
Diffstat (limited to 'math/deboor/slvblk.f')
-rw-r--r--math/deboor/slvblk.f127
1 files changed, 127 insertions, 0 deletions
diff --git a/math/deboor/slvblk.f b/math/deboor/slvblk.f
new file mode 100644
index 00000000..80be1302
--- /dev/null
+++ b/math/deboor/slvblk.f
@@ -0,0 +1,127 @@
+ subroutine slvblk ( bloks, integs, nbloks, b, ipivot, x, iflag )
+c this program solves the linear system a*x = b where a is an
+c almost block diagonal matrix. such almost block diagonal matrices
+c arise naturally in piecewise polynomial interpolation or approx-
+c imation and in finite element methods for two-point boundary value
+c problems. the plu factorization method is implemented here to take
+c advantage of the special structure of such systems for savings in
+c computing time and storage requirements.
+c
+c parameters
+c bloks a one-dimenional array, of length
+c sum( integs(1,i)*integs(2,i) ; i = 1,nbloks )
+c on input, contains the blocks of the almost block diagonal
+c matrix a . the array integs (see below and the example)
+c describes the block structure.
+c on output, contains correspondingly the plu factorization
+c of a (if iflag .ne. 0). certain of the entries into bloks
+c are arbitrary (where the blocks overlap).
+c integs integer array description of the block structure of a .
+c integs(1,i) = no. of rows of block i = nrow
+c integs(2,i) = no. of colums of block i = ncol
+c integs(3,i) = no. of elim. steps in block i = last
+c i = 1,2,...,nbloks
+c the linear system is of order
+c n = sum ( integs(3,i) , i=1,...,nbloks ),
+c but the total number of rows in the blocks is
+c nbrows = sum( integs(1,i) ; i = 1,...,nbloks)
+c nbloks number of blocks
+c b right side of the linear system, array of length nbrows.
+c certain of the entries are arbitrary, corresponding to
+c rows of the blocks which overlap (see block structure and
+c the example below).
+c ipivot on output, integer array containing the pivoting sequence
+c used. length is nbrows
+c x on output, contains the computed solution (if iflag .ne. 0)
+c length is n.
+c iflag on output, integer
+c = (-1)**(no. of interchanges during factorization)
+c if a is invertible
+c = 0 if a is singular
+c
+c auxiliary programs
+c fcblok (bloks,integs,nbloks,ipivot,scrtch,iflag) factors the matrix
+c a , and is used for this purpose in slvblk. its arguments
+c are as in slvblk, except for
+c scrtch = a work array of length max(integs(1,i)).
+c
+c sbblok (bloks,integs,nbloks,ipivot,b,x) solves the system a*x = b
+c once a is factored. this is done automatically by slvblk
+c for one right side b, but subsequent solutions may be
+c obtained for additional b-vectors. the arguments are all
+c as in slvblk.
+c
+c dtblok (bloks,integs,nbloks,ipivot,iflag,detsgn,detlog) computes the
+c determinant of a once slvblk or fcblok has done the fact-
+c orization.the first five arguments are as in slvblk.
+c detsgn = sign of the determinant
+c detlog = natural log of the determinant
+c
+c ------ block structure of a ------
+c the nbloks blocks are stored consecutively in the array bloks .
+c the first block has its (1,1)-entry at bloks(1), and, if the i-th
+c block has its (1,1)-entry at bloks(index(i)), then
+c index(i+1) = index(i) + nrow(i)*ncol(i) .
+c the blocks are pieced together to give the interesting part of a
+c as follows. for i = 1,2,...,nbloks-1, the (1,1)-entry of the next
+c block (the (i+1)st block ) corresponds to the (last+1,last+1)-entry
+c of the current i-th block. recall last = integs(3,i) and note that
+c this means that
+c a. every block starts on the diagonal of a .
+c b. the blocks overlap (usually). the rows of the (i+1)st block
+c which are overlapped by the i-th block may be arbitrarily de-
+c fined initially. they are overwritten during elimination.
+c the right side for the equations in the i-th block are stored cor-
+c respondingly as the last entries of a piece of b of length nrow
+c (= integs(1,i)) and following immediately in b the corresponding
+c piece for the right side of the preceding block, with the right side
+c for the first block starting at b(1) . in this, the right side for
+c an equation need only be specified once on input, in the first block
+c in which the equation appears.
+c
+c ------ example and test driver ------
+c the test driver for this package contains an example, a linear
+c system of order 11, whose nonzero entries are indicated in the fol-
+c lowing schema by their row and column index modulo 10. next to it
+c are the contents of the integs arrray when the matrix is taken to
+c be almost block diagonal with nbloks = 5, and below it are the five
+c blocks.
+c
+c nrow1 = 3, ncol1 = 4
+c 11 12 13 14
+c 21 22 23 24 nrow2 = 3, ncol2 = 3
+c 31 32 33 34
+c last1 = 2 43 44 45
+c 53 54 55 nrow3 = 3, ncol3 = 4
+c last2 = 3 66 67 68 69 nrow4 = 3, ncol4 = 4
+c 76 77 78 79 nrow5 = 4, ncol5 = 4
+c 86 87 88 89
+c last3 = 1 97 98 99 90
+c last4 = 1 08 09 00 01
+c 18 19 10 11
+c last5 = 4
+c
+c actual input to bloks shown by rows of blocks of a .
+c (the ** items are arbitrary, this storage is used by slvblk)
+c
+c 11 12 13 14 / ** ** ** / 66 67 68 69 / ** ** ** ** / ** ** ** **
+c 21 22 23 24 / 43 44 45 / 76 77 78 79 / ** ** ** ** / ** ** ** **
+c 31 32 33 34/ 53 54 55/ 86 87 88 89/ 97 98 99 90/ 08 09 00 01
+c 18 19 10 11
+c
+c index = 1 index = 13 index = 22 index = 34 index = 46
+c
+c actual right side values with ** for arbitrary values
+c b1 b2 b3 ** b4 b5 b6 b7 b8 ** ** b9 ** ** b10 b11
+c
+c (it would have been more efficient to combine block 3 with block 4)
+c
+ integer nbloks
+ integer integs(3,nbloks),ipivot(1),iflag
+ real bloks(1),b(1),x(1)
+c in the call to fcblok, x is used for temporary storage.
+ call fcblok(bloks,integs,nbloks,ipivot,x,iflag)
+ if (iflag .eq. 0) return
+ call sbblok(bloks,integs,nbloks,ipivot,b,x)
+ return
+ end