This example shows how the FMS subroutines may be used to perform a sequence of solutions when some of the matrix terms are changing.
	   +-    +    -+ +-  -+   +-  -+
	   | A11 | A12 | | X1 |   | B1 |
	   +-----+-----+ +----+ = +----+
	   | A21 | A22 | | X2 |   | B2 |
	   +-    +    -+ +-  -+   +-  -+
The system of equations is partitioned as shown above. On the first solution, all terms are computed. On following solutions, only those terms which must be recomputed due to changes in the matrix elements are reevaluated. The main work is performed by subroutine RESOLV, which is designed to be cut and pasted into your application.

The following input is used to test subroutine RESOLV:

After solving the system, you are asked the following:

If you answer yes to any of these questions, the problem is solved again, recomputing only those terms that are necessary.

C	T E S T     R E S O L V
C
C	This program tests subroutine RESOLV.
C	The test matrix is of the form
C
C              [A]        {X}  =  {B}
C       +-            -+ +   +   +   +
C       | N -1 -1 -1 -1| | 1 |   | 1 |
C       |-1  1  0  0  0| | 1 |   | 0 |
C       |-1  0  1  0  0| | 1 | = | 0 |
C       |-1  0  0  1  0| | 1 |   | 0 |
C       |-1  0  0  0  1| | 1 |   | 0 |
C       +-            -+ +   +   +   +
C
C
C	Program name:
	CHARACTER*10 MYNAME
	PARAMETER (MYNAME='EXAMPLE_14')
C
C	FMS matrix and vector file attributes:
	INTEGER     LU_A11(25)
	INTEGER     LU_A12(25)
	INTEGER     LU_A21(25)
	INTEGER     LU_A22(25), LU_F22(25)
	INTEGER     LU_B1 (25),            LU_X1(25)
	INTEGER     LU_B2 (25), LU_S2(25), LU_X2(25)
C
C	FMS memory management requires the following arrays:
	POINTER   (CMD_PTR, CMD)
	POINTER   (RMD_PTR, RMD)
	POINTER   (IMD_PTR, IMD)
	COMPLEX*16 CMD(0:1)
	REAL*8     RMD(0:1)
	INTEGER    IMD(0:1)
C
C	Data Type:
	INTEGER    IDTYPE
	PARAMETER (IDTYPE=2)
C
C	Input Data:
	LOGICAL ASK
	INTEGER ASK_I
C
C	LOCAL VARIABLES:
C	Number of equations in [A11]:
	   INTEGER N1
C	Number of equations in [A22]:
	   INTEGER N2
C	Maximum of N1 and N2:
	   INTEGER NMAX
C	Number of solution vectors:
	   INTEGER NRHS
C	Form a new [A11] matrix:
	   LOGICAL NEWA11
C	Form a new [A12] matrix:
	   LOGICAL NEWA12
C	Form a new [A21] matrix:
	   LOGICAL NEWA21
C	Form a new [A22] matrix:
	   LOGICAL NEWA22
C	Form a new {B1}  matrix:
	   LOGICAL NEWB1
C	Form a new {B2}  matrix:
	   LOGICAL NEWB2
C	Check the values of {X2}:
	   LOGICAL ICK_X2
C	Error on current term:
	   REAL*8  EI
C	Maximum overall error:
	   REAL*8  E2MAX, ERROR
C	CMD Pointer to scratch vector:
	   INTEGER L_TEMP
C
C	Profile vector for a full matrix:
	INTEGER LOWEQ(1)
	DATA    LOWEQ/-1/
C
C	CONSTANTS:
	   COMPLEX*16 C_ONE
	   DATA C_ONE/(1.0D0,0.0D0)/
C
C (1)	Initialize FMS:
	CALL FMSINI
	CALL FMSPSH(MYNAME)
C
C	Use full column partial pivoting (SLAB format):
	CALL FMSIST ('MFMAT', 3)
C
C	Read in problem size parameters:
	N1   = ASK_I('Enter the number of equations in A11')
	N2   = ASK_I('Enter the number of equations in A22')
	NRHS = ASK_I('Enter the number of solution vectors')
	WRITE (6,*) 'You may now alter any FMS parameter.'
	WRITE (6,*) 'When you are finished, type the letters RETURN'
	CALL FMSSET
	CALL FMSIGT ('MEMPTR', IMD_PTR)
	CALL FMSIGT ('MEMPTR', RMD_PTR)
	CALL FMSIGT ('MEMPTR', CMD_PTR)
C
C	Get a temporary vector for generating columns and RHS's:
	NMAX = MAX0(N1,N2)
	CALL FMSCMG (CMD, L_TEMP, NMAX)
C
C (2)	Open FMS files:
	CALL CNDI  (LOWEQ, N1,           'LU_A11', LU_A11)
	CALL FMSOV (N1, IDTYPE, N2  , 'LU_A12', LU_A12)
	CALL FMSOV (N1, IDTYPE, N2  , 'LU_A21', LU_A21)
	CALL CNDI  (LOWEQ, N2,           'LU_A22', LU_A22)
	CALL FMSOM  (LU_A22, 'LU_F22', LU_F22)
	CALL FMSOV (N1, IDTYPE, NRHS, 'LU_B1' , LU_B1 )
	CALL FMSOV (N1, IDTYPE, NRHS, 'LU_X1' , LU_X1 )
	CALL FMSOV (N2, IDTYPE, NRHS, 'LU_B2' , LU_B2 )
	CALL FMSOV (N2, IDTYPE, NRHS, 'LU_S2' , LU_S2 )
	CALL FMSOV (N2, IDTYPE, NRHS, 'LU_X2' , LU_X2 )
C
C (3)	Write data to FMS files:
	NEWA11 = .TRUE.
	NEWA12 = .TRUE.
	NEWA21 = .TRUE.
	NEWA22 = .TRUE.
	NEWB1  = .TRUE.
	NEWB2  = .TRUE.
	ICK_X2 = .TRUE.
C
C	Branch back to here for refinement solutions:
   30	CONTINUE
C
C	Generate [A11]:
	IF(NEWA11) CALL A11GEN (CMD(L_TEMP), N1, N2,   LU_A11)
C
C	Generate [A12]:
	IF(NEWA12) CALL A12GEN (CMD(L_TEMP), N1, N2,   LU_A12)
C
C	Generate [A21]:
	IF(NEWA21) CALL A21GEN (CMD(L_TEMP), N1, N2,   LU_A21)
C
C	Generate [A22]:
	IF(NEWA22) CALL A22GEN (CMD(L_TEMP), N2,       LU_A22)
C
C	Generate {B1}:
	IF(NEWB1 ) CALL B1GEN  (CMD(L_TEMP), N1, NRHS, LU_B1 )
C
C	Generate {B2}:
	IF(NEWB2 ) CALL B2GEN  (CMD(L_TEMP), N2, NRHS, LU_B2 )
C
C (4)	Perform matrix algebra:
	CALL RESOLV
     1	(LU_A11, LU_A11,
     2	 LU_A12, LU_A12,
     3	 LU_A21,
     4	 LU_A22, LU_F22,
     5	 LU_B1,  LU_B1, LU_X1,
     6	 LU_B2,  LU_S2, LU_X2,
     7	 NEWA11, NEWA12,
     8	 NEWA21, NEWA22,
     9	 NEWB1,  NEWB2,
     1	 ICK_X2, E2MAX)
C
C (5)	Read data from FMS files:
C       Check the answer:
	ERROR  = E2MAX
C
C	Initialize FMSGET:
	CALL FMSGET (LU_X1, 0, 0, 0, 0, CMD, 0)
	DO 60 IRHS = 1,NRHS
C
C	   Check {X1}:
	   CALL FMSGET (LU_X1, N1, 1, 1, IRHS, CMD(L_TEMP), N1)
	   DO 51 I = 0,(N1-1)
	      EI = ABS(CMD(L_TEMP+I) - C_ONE)
	      IF(EI .GT. ERROR) ERROR = EI
   51      CONTINUE
   60   CONTINUE
C
C	End FMSGET:
	CALL FMSGET (LU_X1, 0, 0, N1+1, 1, CMD, 0)
	WRITE(6,*) 'MAXIMUM ERROR =', ERROR
C
C	Modify the matrix and solve it again:
	IF(.NOT. ASK('Do you want another solution?')) GO TO 100
	NEWA11 = ASK('Do you want a new A11?')
	NEWA12 = ASK('Do you want a new A12?')
	NEWA21 = ASK('Do you want a new A21?')
	NEWA22 = ASK('Do you want a new A22?')
	NEWB1  = ASK('Do you want a new B1?' )
	NEWB2  = ASK('Do you want a new B2?' )
C
C	We have chosen to overlay factored data on input matrices.
C	Therefore if new factors must be recomputed, the arrays must
C	be reset to the unfactored values.
C	Based on the options selected above, these conditions become:
	IF( NEWA11 ) THEN
	    NEWA12 = .TRUE.
	    NEWA22 = .TRUE.
	    NEWB1  = .TRUE.
	    NEWB2  = .TRUE.
	END IF
	IF( NEWA12 ) NEWA22 = .TRUE.
	IF( NEWB1  ) NEWB2  = .TRUE.
	IF( NEWA11 .OR.
     1	    NEWA12 .OR.
     2	    NEWA21 .OR.
     3	    NEWA22 .OR.
     4	    NEWB1  .OR.
     5	    NEWB2) GO TO 30
C
C (6)	Close FMS files:
  100	CONTINUE
	CALL FMSCM (LU_A11)
	CALL FMSCV (LU_A12)
	CALL FMSCV (LU_A21)
	CALL FMSCV (LU_A22)
	CALL FMSCM (LU_F22)
	CALL FMSCV (LU_B1 )
	CALL FMSCV (LU_X1 )
	CALL FMSCV (LU_B2 )
	CALL FMSCV (LU_S2 )
	CALL FMSCV (LU_X2 )
	CALL FMSCMR (CMD, L_TEMP, NMAX)
	CALL FMSPOP(MYNAME)
	CALL FMSEND
	END
C=======================================================================
	LOGICAL FUNCTION ASK(QUESTION)
C=======================================================================
	CHARACTER* (*) QUESTION
	CHARACTER*1 IYN
	WRITE(6,2000) QUESTION
	READ (5,1000) IYN
	IF( (IYN .EQ. 'Y') .OR. (IYN .EQ. 'y') ) THEN
	   ASK = .TRUE.
	ELSE
	   ASK = .FALSE.
	END IF
	RETURN
 1000	FORMAT (A)
 2000	FORMAT (1X,A,' (y,n)>')
	END
C=======================================================================
	INTEGER FUNCTION ASK_I(STRING)
C=======================================================================
	CHARACTER* (*) STRING
	WRITE(6,2000) STRING
	READ (5,*) ASK_I
	RETURN
 2000	FORMAT (1X,A,'>')
	END
C=======================================================================
	SUBROUTINE A11GEN (ACOL, N1, N2, LU_A11)
C=======================================================================
	COMPLEX*16 ACOL(N1)
	INTEGER    N1, N2
	INTEGER    LU_A11(25)
	CHARACTER*6 MYNAME
	PARAMETER (MYNAME='A11GEN')
	REAL*8     R_ZERO, A11_Re
	DATA       R_ZERO/0.0D0/
	COMPLEX*16 C_MONE, C_ZERO, C_ONE
	DATA       C_MONE/(-1.0D0,0.0D0)/
	DATA       C_ZERO/( 0.0D0,0.0D0)/
	DATA       C_ONE /( 1.0D0,0.0D0)/
C
	CALL FMSPSH(MYNAME)
	WRITE(6,2000)
C
C	Initialize FMSCOL
	CALL FMSCOL (0, ACOL, LU_A11)
C
C	Write first column
	DO 10 I = 2,N1
	   ACOL(I) = C_MONE
   10	CONTINUE
	A11_Re  = DFLOAT(N1+N2)
	ACOL(1) = DCMPLX(A11_Re,R_ZERO)
	CALL FMSCOL (1, ACOL, LU_A11)
C
C	Write remaining columns:
	DO 20 I = 2,N1
	   ACOL(I) = C_ZERO
   20	CONTINUE
	ACOL(1) = C_MONE
	DO 30 I = 2,N1
	   ACOL(I) = C_ONE
	   CALL FMSCOL (I, ACOL, LU_A11)
	   ACOL(I) = C_ZERO
   30	CONTINUE
C
C	End FMSCOL
	CALL FMSCOL (N1+1, ACOL, LU_A11)
	CALL FMSPOP(MYNAME)
	RETURN
 2000	FORMAT (' Populating [A11]:')
	END
C=======================================================================
	SUBROUTINE A12GEN (ACOL, N1, N2, LU_A12)
C=======================================================================
	COMPLEX*16 ACOL(N1)
	INTEGER    N1, N2
	INTEGER    LU_A12(25)
	CHARACTER*6 MYNAME
	PARAMETER (MYNAME='A12GEN')
	COMPLEX*16 C_MONE, C_ZERO
	DATA       C_MONE/(-1.0D0,0.0D0)/
	DATA       C_ZERO/( 0.0D0,0.0D0)/
C
	CALL FMSPSH(MYNAME)
	WRITE(6,2000)
C
	DO 10 I=2,N1
	   ACOL(I) = C_ZERO
   10	CONTINUE
	ACOL(1) = C_MONE
C
C	Initialize FMSPUT:
	CALL FMSPUT (LU_A12, 0, 0, 0, 0, ACOL, 0)
C
C	Write out columns of [A12]:
	DO 20 I = 1,N2
	   CALL FMSPUT (LU_A12, N1, 1, 1, I, ACOL, N1)
   20	CONTINUE
C
C	End FMSPUT:
	CALL FMSPUT (LU_A12, 0, 0, N1+1, 0, ACOL, 0)
C
C	Set status:
	LU_A12(7) = 0
	CALL FMSPOP(MYNAME)
	RETURN
 2000	FORMAT (' Populating [A12]:')
	END
C=======================================================================
	SUBROUTINE A21GEN (AROW, N1, N2, LU_A21)
C=======================================================================
	COMPLEX*16 AROW(N1)
	INTEGER    N1, N2
	INTEGER    LU_A21(25)
	CHARACTER*6 MYNAME
	PARAMETER (MYNAME='A21GEN')
	COMPLEX*16 C_MONE, C_ZERO
	DATA       C_MONE/(-1.0D0,0.0D0)/
	DATA       C_ZERO/( 0.0D0,0.0D0)/
C
	CALL FMSPSH(MYNAME)
	WRITE(6,2000)
C
	DO 10 I=2,N1
	   AROW(I) = C_ZERO
   10	CONTINUE
	AROW(1) = C_MONE
C
C	Initialize FMSPUT:
	CALL FMSPUT (LU_A21, 0, 0, 0, 0, AROW, 0)
C
C	Write out rows of [A21], which is stored transposed:
	DO 20 I = 1,N2
	   CALL FMSPUT (LU_A21, N1, 1, 1, I, AROW, N1)
   20	CONTINUE
C
C	End FMSPUT:
	CALL FMSPUT (LU_A21, 0, 0, N1+1, 0, AROW, 0)
C
C	Set status:
	LU_A21(7) = 0
	CALL FMSPOP(MYNAME)
	RETURN
 2000	FORMAT (' Populating [A21]:')
	END
C=======================================================================
	SUBROUTINE A22GEN (ACOL, N2, LU_A22)
C=======================================================================
	COMPLEX*16 ACOL(N2)
	INTEGER    N2
	INTEGER    LU_A22(25)
	CHARACTER*6 MYNAME
	PARAMETER (MYNAME='A22GEN')
	COMPLEX*16 C_ZERO, C_ONE
	DATA       C_ZERO/( 0.0D0,0.0D0)/
	DATA       C_ONE /( 1.0D0,0.0D0)/
C
	CALL FMSPSH(MYNAME)
	WRITE(6,2000)
C
C	Initialize FMSCOL
	CALL FMSCOL (0, ACOL, LU_A22)
C
	DO 10 I = 1,N2
	   ACOL(I) = C_ZERO
   10	CONTINUE
C
	DO 20 I = 1,N2
	   ACOL(I) = C_ONE
	   CALL FMSCOL (I, ACOL, LU_A22)
	   ACOL(I) = C_ZERO
   20	CONTINUE
C
C	End FMSCOL
	CALL FMSCOL (N2+1, ACOL, LU_A22)
C
C	Set status:
	LU_A22(7) = 0
	CALL FMSPOP(MYNAME)
	RETURN
 2000	FORMAT (' Populating [A22]:')
	END
C=======================================================================
	SUBROUTINE B1GEN (RHS, N1, NRHS, LU_B1)
C=======================================================================
	COMPLEX*16 RHS(N1)
	INTEGER    N1, NRHS
	INTEGER    LU_B1(25)
	CHARACTER*5 MYNAME
	PARAMETER (MYNAME='B1GEN')
	COMPLEX*16 C_ZERO, C_ONE
	DATA       C_ZERO/(0.0D0,0.0D0)/
	DATA       C_ONE /(1.0D0,0.0D0)/
C
	CALL FMSPSH(MYNAME)
	WRITE(6,2000)
C
	DO 10 I=2,N1
	  RHS(I) = C_ZERO
   10	CONTINUE
	RHS(1) = C_ONE
C
C	Initialize FMSPUT:
	CALL FMSPUT (LU_B1, 0, 0, 0, 0, RHS, 0)
C
C	Write out columns of {B1}:
	DO 20 I = 1,NRHS
	   CALL FMSPUT (LU_B1, N1, 1, 1, I, RHS, N1)
   20	CONTINUE
C
C	End FMSPUT:
	CALL FMSPUT (LU_B1, 0, 0, N1+1, 0, RHS, 0)
C
C	Set status:
	LU_B1(7) = 0
	CALL FMSPOP(MYNAME)
	RETURN
 2000	FORMAT (' Populating {B1}:')
	END
C=======================================================================
	SUBROUTINE B2GEN (RHS, N2, NRHS, LU_B2)
C=======================================================================
	COMPLEX*16 RHS(N2)
	INTEGER    N2, NRHS
	INTEGER    LU_B2(25)
	CHARACTER*5 MYNAME
	PARAMETER (MYNAME='B2GEN')
	COMPLEX*16 C_ZERO, C_ONE
	DATA       C_ZERO/(0.0D0,0.0D0)/
	DATA       C_ONE /(1.0D0,0.0D0)/
C
	CALL FMSPSH(MYNAME)
	WRITE(6,2000)
C
	DO 10 I=1,N2
	  RHS(I) = C_ZERO
   10	CONTINUE
C
C	Initialize FMSPUT:
	CALL FMSPUT (LU_B2, 0, 0, 0, 0, RHS, 0)
C
C	Write out columns of {B2}:
	DO 20 I = 1,NRHS
	   CALL FMSPUT (LU_B2, N2, 1, 1, I, RHS, N2)
   20	CONTINUE
C
C	End FMSPUT:
	CALL FMSPUT (LU_B2, 0, 0, N2+1, 0, RHS, 0)
C
C	Set status:
	LU_B2(7) = 0
	CALL FMSPOP(MYNAME)
	RETURN
 2000	FORMAT (' Populating {B2}:')
	END
C=======================================================================
	SUBROUTINE RESOLV
     1	(LU_A11, LU_F11,
     2	 LU_A12, LU_F12,
     2	 LU_A21,
     4	 LU_A22, LU_F22,
     3	 LU_B1,  LU_S1, LU_X1,
     4	 LU_B2,  LU_S2, LU_X2,
     5	 NEWA11, NEWA12,
     6	 NEWA21, NEWA22,
     7	 NEWB1,  NEWB2,
     6	 ICK_X2, E2MAX)
C=======================================================================
C
C	DESCRIPTION:
C	   This subroutine solves the linear system
C
C	   +-    +    -+ +-  -+   +-  -+
C	   | A11 | A12 | | X1 |   | B1 |
C	   +-----+-----+ +----+ = +----+
C	   | A21 | A22 | | X2 |   | B2 |
C	   +-    +    -+ +-  -+   +-  -+
C
C	   when all or only part of the matrix terms change.
C
C
C	   On input, the following matrix terms are specified:
C
C	   +-    +    -+ +-  -+   +-  -+
C	   | A11 | A12 | |    |   | B1 |
C	   +-----+-----+ +----+ = +----+
C	   | A21 | A22 | |    |   | B2 |
C	   +-    +    -+ +-  -+   +-  -+
C
C
C	   The following intermediate work arrays are used:
C
C	   +-    +    -+ +-  -+   +-  -+
C	   |     |     | | S1 |   |    |
C	   +-----+-----+ +----+ = +----+
C	   |     |     | | S2 |   |    |
C	   +-    +    -+ +-  -+   +-  -+
C
C
C	   On output, the following terms are returned:
C
C	   +-    +    -+ +-  -+   +-  -+
C	   | F11 | F12 | | X1 |   |    |
C	   +-----+-----+ +----+ = +----+
C	   |     | F22 | | X2 |   |    |
C	   +-    +    -+ +-  -+   +-  -+
C
C	You may overlay any of the corresponding input, intermediate
C	or output terms to save storage by specifying the same actual
C	parameter on the subroutine call.
C
C	Arrays containing input data may share storage with
C	intermediate and output arrays if these conditions are met:
C	1) If any value changes in the input array, all values in that
C	   input array are redefined.
C	2) In defining the new values for an array, the previous
C	   values are not required. (They are no longer available
C	   because they have been overwritten)
C	If these conditions are true, then the following arrays can
C	share the same storage:
C	   [A11] & [F11],
C	   [A12] & [F12],
C	   [A22] & [F22],
C	   {B1}  &  {S1},
C	   {B2}  &  {S2}.
C
C	Ths storage for {S1} and {S2} can be shared with {X1} and {X2}.
C	No additional computation is required if the following
C	conditions are met:
C	   {S1} & {X1} : if [A11]      or {B1}         change,
C	   {S2} & {X2} : if [A11], [A12], {B1} or {B2} change.
C	If these conditions are not met and the storage is shared, then
C	additional computation will be performed.
C
C	You may also overlay {B1},{S1},{X1} or {B2},{S2},{X2} if
C	all the above conditions are met.
C
C	FORMAL PARAMETERS:
C	   (R ) LU_A11(25)  = INTEGER ARRAY
C	                      FMS matrix file attributes for [A11]
C
C	   (R ) LU_F11(25)  = INTEGER ARRAY
C	                      FMS matrix file attributes for [F11]
C	                      May be the same as LU_A11.
C
C	   (R ) LU_A12(25)  = INTEGER ARRAY
C	                      FMS vector file attributes for [A12]
C
C	   (R ) LU_F12(25)  = INTEGER ARRAY
C	                      FMS vector file attributes for [F12]
C	                      May be the same as LU_A12.
C
C	   (R ) LU_A21(25)  = INTEGER ARRAY
C	                      FMS vector file attributes for [A21]
C	                      Data on this file is not changed.
C
C	   (R ) LU_A22(25)  = INTEGER ARRAY
C	                      FMS mtarix file attributes for [A22]
C
C	   (R ) LU_F22(25)  = INTEGER ARRAY
C	                      FMS matrix file attributes for [F22]
C
C	   (R ) LU_B1(25)   = INTEGER ARRAY
C	                      FMS vector file attributes for {B1}
C
C	   (R ) LU_S1(25)   = INTEGER ARRAY
C	                      FMS vector file attributes for {S1}.
C	                      This is an intermediate work array.
C	                      May be the same value as LU_B1.
C
C	   (R ) LU_X1(25)   = INTEGER ARRAY
C	                      FMS vector file attributes for {X1}.
C	                      May be the same as LU_S1.
C
C	   (R ) LU_B2(25)   = INTEGER ARRAY
C	                      FMS vector file attributes for {B2}
C
C	   (R ) LU_S2(25)   = INTEGER ARRAY
C	                      FMS vector file attributes for {S2}.
C	                      This is an intermediate work array.
C	                      May be the same value as LU_B2.
C
C	   (R ) LU_X2(25)   = INTEGER ARRAY
C	                      FMS vector file attributes for {X2}.
C	                      May be the same as LU_B2.
C
C	   (R ) NEWA11      = LOGICAL
C	                      Indicates that [A11] has changed.
C
C	   (R ) NEWA12      = LOGICAL
C	                      Indicated that [A12] has changed.
C
C	   (R ) NEWA21      = LOGICAL
C	                      Indicated that [A21] has changed.
C
C	   (R ) NEWA22      = LOGICAL
C	                      Indicated that [A22] has changed.
C
C	   (R ) NEWB1       = Logical
C	                      Indicates that {B1} has changed.
C
C	   (R ) NEWB2       = Logical
C	                      Indicates that {B2} has changed.
C
C	   (R ) ICK_X2      = Logical
C	                      Check the values in {X2}.
C	                      This requires access to [A22] and {B2}.
C	                      Requires the following:
C	                      LU_S2  or LU_X2 do not overlay LU_B2
C
C	   (R ) E2MAX       = REAL*8
C	                      Maximum error in {X2}.
C
C	FMSCOM PARAMETERS:
C	   (RW) IACCOM      = Multiply accumulate flag
C	   (R ) LUPR        = FORTRAN unit for printing
C
C	CALLED FROM:
C	   EXAMPLE_14
C
C	SUBPROGRAMS USED:
C	   CNDF
C	   CNDS
C	   FMSMM
C
C	ERROR CONDITIONS:
C	   None.
C
C	HISTORY:
C
C	NOTES:
C
C	Expanding the partitioned system gives:
C
C	[A11]{X1} + [A12]{X2} = {B1}      (1)
C	[A21]{X1} + [A22]{X2} = {B2}      (2)
C
C	Premultiplying (1) by inv[A11] gives
C
C	{X1} = {S1} - [F12]{X2}           (3)
C
C	where
C	   {S1}  = inv[A11]{B1}           (4)
C	   [F12] = inv[A11][A12]          (5)
C
C	Substituting (3) into (2) gives:
C
C	[F22]{X2} = {S2}                  (6)
C
C	where
C	   [F22] = [A22] - [A21][F12]     (7)
C	   {S2}  = {B2}  - [A21]{S1}      (8)
C
C
C	The error in {X2} may be computed from:
C
C	   E2MAX = | {B2} - [A21]{X1} - [A22]{X2} |
C
C	The algorithm consists of the following 8 steps:
C
C	Solve large system:
C	1. Factor   [A11] into [F11]=[L11][U11]
C	2. Solve    [F11][F12] = [A12]            (eq. 5)
C	3. Solve    [F11]{S1}  = {B1}             (eq. 4)
C
C	Project to small system:
C	4. Multiply [F22'] = [A22] - [A21][F12]   (eq. 7)
C	5. Factor   [F22'] into [F22]=[L22][U22]
C	6. Multiply {S2}   = {B2}  - [A21]{S1}    (eq. 8)
C
C	Solve small system:
C	7. Solve    [F22]{X2} = {S2}              (eq. 6)
C
C	Project back to large system:
C	8. Multiply {X1} = {S1} - [F12]*{X2}      (eq. 3)
C
C	Check {X2}: (optional)
C	9. Multiply {ERR} = {B2} - [A21]{X1} - [A22]{X2}
C	   Then compute the maximum absolute value in {ERR}.
C
C	Summary of arrays used:
C
C	STEP  A11 F11 A12 F12 A21 A22 F22  B1  S1  X1  B2  S2  X2
C	====  ======= ======= === ======= =========== ===========
C	  1    R-->W
C	  2        R   R-->W
C	  3        R                       R-->W
C	  4                R   R   R-->W
C	  5                            RW
C	  6                    R               R       R-->W
C	  7                            R                   R-->W
C	  8                R                   R-->W           R
C
C	Steps required:
C
C	STEP1 = (NEWA11                  )
C	STEP2 = (NEWA12 | STEP1          )
C	STEP3 = (NEWB1  | STEP1          )
C	STEP4 = (NEWA22 | NEWA21 | STEP2 )
C	STEP5 = (STEP4                   )
C	STEP6 = (NEWB2  | NEWA21 | STEP3 )
C	STEP7 = (STEP5  | STEP6          )
C	STEP8 = (STEP3  | STEP2  | STEP7 )
C
C	or, substituting,
C
C	STEP1 = (NEWA11                                            )
C	STEP2 = (NEWA11 | NEWA12                                   )
C	STEP3 = (NEWA11 |                            NEWB1         )
C	STEP4 = (NEWA11 | NEWA12 | NEWA21 | NEWA22                 )
C	STEP5 = (NEWA11 | NEWA12 | NEWA21 | NEWA22                 )
C	STEP6 = (NEWA11 |          NEWA21 |          NEWB1 | NEWB2 )
C	STEP7 = (NEWA11 | NEWA12 | NEWA21 | NEWA22 | NEWB1 | NEWB2 )
C	STEP8 = (NEWA11 | NEWA12 | NEWA21 | NEWA22 | NEWB1 | NEWB2 )
C
C	Also if the intermediate vector storage is overlaid on the
C	storage for the solution vectors, it is assumed that it no
C	longer contains the intermediate arrays.  Therefore,
C	STEP3 = (STEP3  | (LU_S1 = LU_X1) )
C	STEP6 = (STEP6  | (LU_S2 = LU_X2) )
C-----------------------------------------------------------------------
C	FORMAL PARAMETERS
C-----------------------------------------------------------------------
	INTEGER    LU_A11(25)
	INTEGER    LU_F11(25)
C
	INTEGER    LU_A12(25)
	INTEGER    LU_F12(25)
C
	INTEGER    LU_A21(25)
C
	INTEGER    LU_A22(25)
C
	INTEGER    LU_F22(25)
C
	INTEGER    LU_B1 (25)
	INTEGER    LU_S1 (25)
	INTEGER    LU_X1 (25)
C
	INTEGER    LU_B2 (25)
	INTEGER    LU_S2 (25)
	INTEGER    LU_X2 (25)
C
	LOGICAL    NEWA11
	LOGICAL    NEWA12
	LOGICAL    NEWA21
	LOGICAL    NEWA22
	LOGICAL    NEWB1
	LOGICAL    NEWB2
	LOGICAL    ICK_X2
	REAL*8     E2MAX
C-----------------------------------------------------------------------
C	LOCAL VARIABLES
C-----------------------------------------------------------------------
C
	CHARACTER*6 MYNAME
	PARAMETER (MYNAME='RESOLV')
C
C	FMS Memory management:
	POINTER   (CMD_PTR, CMD)
	POINTER   (RMD_PTR, RMD)
	POINTER   (IMD_PTR, IMD)
	COMPLEX*16 CMD(0:1)
	REAL*8     RMD(0:1)
	INTEGER    IMD(0:1)
C
	COMMON /MYFMS/ L_A22, LDA22
C
C	Data type = complex:
	INTEGER    IDTYPE
	PARAMETER (IDTYPE = 2)
C
C	Skip operations during solving (no):
	INTEGER    ISKIP
	PARAMETER (ISKIP=0)
C
C	Constants:
	COMPLEX*16 C_ONE(1)
	DATA       C_ONE  /(1.0D0,0.0D0)/
	REAL*8     R_ZERO
	DATA       R_ZERO / 0.0D0/
	REAL*8     R_ONE
	DATA       R_ONE  / 1.0D0/
	REAL*8     R_THREE
	DATA       R_THREE/ 3.0D0/
	REAL*8     R_EIGHT
	DATA       R_EIGHT/ 8.0D0/
C
C	FMS Parameters:
	INTEGER    LUPR
C
C	Matrix dimensions:
	INTEGER    N1
	INTEGER    N2
	INTEGER    NRHS
	REAL*8     RN1
	REAL*8     RN2
	REAL*8     RNRHS
C
C	Temporary file:
	INTEGER    LU_ERR(25)
	INTEGER     LUA0  (25)
	DATA        LUA0(1)/0/
	INTEGER     LUX0  (25)
	INTEGER     LUS0  (25)
C
C	CPU, Wall and I/O time:
	REAL*8     TCPU(10)
	REAL*8     TWALL(10)
	REAL*8     TIO(10)
	REAL*8     T1, T2, T3
C
C	Steps to perform:
	LOGICAL    STEP1
	LOGICAL    STEP2
	LOGICAL    STEP3
	LOGICAL    STEP4
	LOGICAL    STEP5
	LOGICAL    STEP6
	LOGICAL    STEP7
	LOGICAL    STEP8
	LOGICAL    STEP9
C
C	Floating point operations:
	REAL*8     OPS(9), TOPS
C-----------------------------------------------------------------------
C	FORTRAN PROCEDURE
C-----------------------------------------------------------------------
	CALL FMSPSH(MYNAME)
C
C	Get the FORTRAN unit for printng:
	CALL FMSIGT ('LUPR', LUPR)
C
C	Get the memory pointer for arrays IMD, RMD and CMD:
	CALL FMSIGT ('MEMPTR', IMD_PTR)
	CALL FMSIGT ('MEMPTR', RMD_PTR)
	CALL FMSIGT ('MEMPTR', CMD_PTR)
C
C	Determine the size of the matrices:
	N1    = LU_A11(8)
	N2    = LU_A22(8)
	NRHS  = LU_B1 (6)
	NUMEQ = N1 + N2
	RN1   = DFLOAT(N1)
	RN2   = DFLOAT(N2)
	RNRHS = DFLOAT(NRHS)
	WRITE(LUPR,2000) NUMEQ, N1, N2, NRHS
C
C	Determine which steps to do:
	STEP1 = (NEWA11                        )
	STEP2 = (NEWA12 .OR. STEP1             )
	STEP3 = (NEWB1  .OR. STEP1             )
	STEP4 = (NEWA22 .OR. NEWA21 .OR. STEP2 )
	STEP5 = (STEP4                         )
	STEP6 = (NEWB2  .OR. NEWA21 .OR. STEP3 )
	STEP7 = (STEP5  .OR. STEP6             )
	STEP8 = (STEP2  .OR. STEP3  .OR. STEP7 )
	STEP9 = (ICK_X2                        )
C
C	Check overlaid storage:
	STEP3 = (STEP3  .OR. (LU_S1(1) .EQ. LU_X1(1)) )
	STEP6 = (STEP6  .OR. (LU_S2(2) .EQ. LU_X2(2)) )
	IF( (LU_B2(1)  .EQ. LU_S2(1) )   .OR.
     1	    (LU_B2(1)  .EQ. LU_X2(1) ) ) STEP9 = .FALSE.
C
C	Initialize operation counts for each step:
	OPS(1) = R_ZERO
	OPS(2) = R_ZERO
	OPS(3) = R_ZERO
	OPS(4) = R_ZERO
	OPS(5) = R_ZERO
	OPS(6) = R_ZERO
	OPS(7) = R_ZERO
	OPS(8) = R_ZERO
	OPS(9) = R_ZERO
C
C (1)	Factor [A11] into [L11][U11]:
	CALL FMSTIM (TCPU(1), TWALL(1), TIO(1))
	IF(STEP1) THEN
	   WRITE(LUPR,2001)
	   OPS(1) = R_EIGHT*RN1*RN1*RN1/R_THREE
	   CALL CNDAF (LU_A11, C_ONE, 1, LUS0, 0, LUA0, LU_F11,
     1	               LUX0, LUX0, 0)
	END IF
C
C (2)	Solve [F11][F12] = [A12]:
	CALL FMSTIM (TCPU(2), TWALL(2), TIO(2))
	IF(STEP2) THEN
	   WRITE(LUPR,2002)
	   OPS(2) = R_EIGHT*RN1*RN1*RN2
	   CALL CNDS (LU_F11, LU_A12, LU_F12, N2,   0)
	END IF
C
C (3)	Solve [F11]{S1}  = {B1}:
	CALL FMSTIM (TCPU(3), TWALL(3), TIO(3))
	IF(STEP3)  THEN
	   WRITE(LUPR,2003)
	   OPS(3) = R_EIGHT*RN1*RN1*RNRHS
	   CALL CNDS (LU_F11, LU_B1,  LU_S1,  NRHS, 0)
	END IF
C
C (4)	Multiply [F22'] = [A22] - [A21][F12]
	CALL FMSTIM (TCPU(4), TWALL(4), TIO(4))
	IF(STEP4)  THEN
	   WRITE(LUPR,2004)
	   OPS(4) = R_EIGHT*RN1*RN2*RN2
	   CALL FMSMM (LU_F22, LU_A22, -1, 'T', LU_A21, LU_F12)
	END IF
C
C (5)	Factor [F22'] into [F22]:
	CALL FMSTIM (TCPU(5), TWALL(5), TIO(5))
	IF(STEP5) THEN
	   WRITE(LUPR,2005)
	   OPS(5) = R_EIGHT*RN2*RN2*RN2/R_THREE
	   CALL CNDAF (LU_F22, C_ONE, 1, LUS0, 0, LUA0, LU_F22,
     1	               LUX0, LUX0, 0)
	END IF
C
C (6)	Multiply {S2}  = {B2}  - [A21]{S1}
	CALL FMSTIM (TCPU(6), TWALL(6), TIO(6))
	IF(STEP6) THEN
	   WRITE(LUPR,2006)
	   OPS(6) = R_EIGHT*RN2*RN1*RNRHS
	   CALL FMSMM (LU_S2, LU_B2, -1, 'T', LU_A21, LU_S1)
	END IF
C
C (7)	Solve [F22]{X2} = {S2}:
	CALL FMSTIM (TCPU(7), TWALL(7), TIO(7))
	IF(STEP7) THEN
	   WRITE(LUPR,2007)
	   OPS(7) = R_EIGHT*RN2*RN2*RNRHS
	   CALL CNDS  (LU_F22, LU_S2, LU_X2, NRHS, 0)
	END IF
C
C (8)	Multiply {X1} = {S1} - [F12]{X2}
	CALL FMSTIM (TCPU(8), TWALL(8), TIO(8))
	IF(STEP8) THEN
	   WRITE(LUPR,2008)
	   OPS(8) = R_EIGHT*RN1*RN2*RNRHS
	   CALL FMSMM ('N', -1, LU_F12, LU_X2, LU_S1, LU_X1)
	END IF
C
C (9)	Check {X2}: {ERR} = {B2} - [A21]{X1} - [A22]{X2}
	CALL FMSTIM (TCPU(9), TWALL(9), TIO(9))
	IF(STEP9) THEN
	   WRITE(LUPR,2009)
	   OPS(9) = R_EIGHT*(RN1+RN2)*RN2*RNRHS
C
C	   Open a vector file to store the error array ERR(N2,NRHS):
	CALL FMSOV (N2, IDTYPE, NRHS, 'LU_ERR' , LU_ERR)
C
C	   Multiply {ERR} = {B2} - [A21]{X1}
	   CALL FMSMM (LU_ERR, LU_B2, -1, 'T', LU_A21, LU_X1)
C
C	   Multiply {ERR} = {ERR} - [A22]{X2}:
	   CALL FMSMM (LU_ERR, LU_ERR, -1, 'N', LU_A22, LU_X2)
C
C	   Read LU_ERR and check the error:
C
C	   Allocate storage for one vector:
	   CALL FMSCMG (CMD, L_ERR, N2)
C
C	   Initialize FMSGET:
	   CALL FMSGET (LU_ERR, 0, 0, 0, 0, CMD, 0)
C
C	   Compute the maximum error:
	   E2MAX = R_ZERO
	   DO 95 N = 1,NRHS
C	      Read in next vector:
	      CALL FMSGET (LU_ERR, N2, 1, 1, N, CMD(L_ERR), N2)
	      L = L_ERR
	      DO 90 I = 1,N2
	         T1 = ABS(CMD(L))
	         IF(T1 .GT. E2MAX) E2MAX = T1
	         L = L + 1
   90	      CONTINUE
   95	   CONTINUE
C
C	   End FMSGET:
	   CALL FMSGET (LU_ERR, 0, 0, N2+1, 1, CMD, 0)
C
C	   Close the vector file LU_ERR:
	   CALL FMSCV  (LU_ERR)
C
C	   Delete the storage for {ERR}:
	   CALL FMSCMR (CMD, L_ERR, N2)
	END IF
C
C	Print timings:
	WRITE(LUPR,2010)
	CALL FMSTIM (TCPU(10), TWALL(10), TIO(10))
	TOPS = R_ZERO
	DO 100 ISTEP = 1,9
	   IF(OPS(ISTEP) .EQ. R_ZERO) THEN
C
C	      Operation skipped:
	      WRITE(LUPR,2012) ISTEP
	   ELSE
	      TOPS = TOPS + OPS(ISTEP)
C
C	      CPU time and Mflops:
	      T1 = TCPU(ISTEP+1)  - TCPU(ISTEP)
	      IF(T1 .GT. R_ZERO) THEN
	         MF1   = ((1.0D-6)*OPS(ISTEP)/T1)
	      ELSE
	         MF1   = 0
	      END IF
C
C	      Wall time, Mflops and ratio:
	      T2 = TWALL(ISTEP+1) - TWALL(ISTEP)
	      T3 = TIO(ISTEP+1)   - TIO(ISTEP)
	      IF((T2 .GT. R_ZERO) .AND.
     1	         (T2 .GT.  T3   ) ) THEN
	         MF2   = ((1.0D-6)*OPS(ISTEP)/T2)
	         RATIO = T1/(T2-T3)
	      ELSE
	         MF2   = 0
	         RATIO = R_ONE
	      END IF
	      WRITE(LUPR,2011) ISTEP, T1, T2, T3, MF1, MF2, RATIO
	   END IF
  100	CONTINUE
	T1 = TCPU(10)  - TCPU(1)
	T2 = TWALL(10) - TWALL(1)
	T3 = TIO(10)   - TIO(1)
	IF(T1 .GT. R_ZERO) THEN
	   MF1   = ((1.0D-6)*TOPS/T1)
	ELSE
	   MF1   = 0
	END IF
	IF(T2 .GT. R_ZERO) THEN
	   MF2   = ((1.0D-6)*TOPS/T2)
	   RATIO = T1/(T2-T3)
	ELSE
	   MF2   = 0
	   RATIO = R_ONE
	END IF
	WRITE(LUPR,2013) T1, T2, T3, MF1, MF2, RATIO
	CALL FMSPOP(MYNAME)
	RETURN
 2000	FORMAT (/
     1	' Start of Subroutine RESOLV',/
     2	' Rank of full matrix.....=',I6/
     3	' Rank of submatrix #1....=',I6/
     4	' Rank of submatrix #2....=',I6/
     5	' # of right-hand-sides...=',I6/)
 2001	FORMAT (/
     1	' STEP 1. Factor   [A11] into [F11]'/
     2	' =================================')
 2002	FORMAT (/
     1	' STEP 2. Solve    [F11][F12] = [A12]'/
     2	' ===================================')
 2003	FORMAT (/
     1	' STEP 3. Solve    [F11]{S1}  = {B1}'/
     2	' ==================================')
 2004	FORMAT (/
     1	' STEP 4. Multiply [F22] = [A22] - [A21][F12]'/
     2	' ===========================================')
 2005	FORMAT (/
     1	' STEP 5. Factor   [F22]'/
     2	' ======================')
 2006	FORMAT (/
     1	' STEP 6. Multiply {S2}  = {B2}  - [A21]{S1}'/
     2	' ==========================================')
 2007	FORMAT (/
     1	' STEP 7. Solve    [F22]{X2} = {S2}'/
     2	' =================================')
 2008	FORMAT (/
     1	' STEP 8. Multiply {X1} = {S1} - [A12]*{X2}'/
     2	' =========================================')
 2009	FORMAT (/
     1	' STEP 9. Checking values in {X2}'/
     2	' =========================================')
 2010	FORMAT (/
     1	' Summary of Subroutine RESOLV:'//
     2	'          <----------TIMES (Sec.)----------->'
     2	'    <--MFLOPS-->'/
     2	'  STEP          CPU         WALL          I/O     CPU    WALL',
     2	'    RATIO'/
     3	' =====    =========    =========    =========    ====    ====',
     3	'    =====')
 2011	FORMAT (I6,3F13.3,2I8,F9.3)
 2012	FORMAT (I6,6X,'Skipped')
 2013	FORMAT (' TOTAL',3F13.3,2I8,F9.3)
	END