OpenLibm/slatec/dpchng.f
Viral B. Shah c977aa998f Add Makefile.extras to build libopenlibm-extras.
Replace amos with slatec
2012-12-31 16:37:05 -05:00

257 lines
7.3 KiB
Fortran

*DECK DPCHNG
SUBROUTINE DPCHNG (II, XVAL, IPLACE, SX, IX, IRCX)
C***BEGIN PROLOGUE DPCHNG
C***SUBSIDIARY
C***PURPOSE Subsidiary to DSPLP
C***LIBRARY SLATEC
C***TYPE DOUBLE PRECISION (PCHNGS-S, DPCHNG-D)
C***AUTHOR Hanson, R. J., (SNLA)
C Wisniewski, J. A., (SNLA)
C***DESCRIPTION
C
C SUBROUTINE DPCHNG CHANGES ELEMENT II IN VECTOR +/- IRCX TO THE
C VALUE XVAL.
C DPCHNG LIMITS THE TYPE OF STORAGE TO A SEQUENTIAL SCHEME.
C SPARSE MATRIX ELEMENT ALTERATION SUBROUTINE.
C
C II THE ABSOLUTE VALUE OF THIS INTEGER IS THE SUBSCRIPT FOR
C THE ELEMENT TO BE CHANGED.
C XVAL NEW VALUE OF THE MATRIX ELEMENT BEING CHANGED.
C IPLACE POINTER INFORMATION WHICH IS MAINTAINED BY THE PACKAGE.
C SX(*),IX(*) THE WORK ARRAYS WHICH ARE USED TO STORE THE SPARSE
C MATRIX. THESE ARRAYS ARE AUTOMATICALLY MAINTAINED BY THE
C PACKAGE FOR THE USER.
C IRCX POINTS TO THE VECTOR OF THE MATRIX BEING UPDATED.
C A NEGATIVE VALUE OF IRCX INDICATES THAT ROW -IRCX IS
C BEING UPDATED. A POSITIVE VALUE OF IRCX INDICATES THAT
C COLUMN IRCX IS BEING UPDATED. A ZERO VALUE OF IRCX IS
C AN ERROR.
C
C SINCE DATA ITEMS ARE KEPT SORTED IN THE SEQUENTIAL DATA STRUCTURE,
C CHANGING A MATRIX ELEMENT CAN REQUIRE THE MOVEMENT OF ALL THE DATA
C ITEMS IN THE MATRIX. FOR THIS REASON, IT IS SUGGESTED THAT DATA
C ITEMS BE ADDED A COL. AT A TIME, IN ASCENDING COL. SEQUENCE.
C FURTHERMORE, SINCE DELETING ITEMS FROM THE DATA STRUCTURE MAY ALSO
C REQUIRE MOVING LARGE AMOUNTS OF DATA, ZERO ELEMENTS ARE EXPLICITLY
C STORED IN THE MATRIX.
C
C THIS SUBROUTINE IS A MODIFICATION OF THE SUBROUTINE LCHNGS,
C SANDIA LABS. REPT. SAND78-0785.
C MODIFICATIONS BY K.L. HIEBERT AND R.J. HANSON
C REVISED 811130-1000
C REVISED YYMMDD-HHMM
C
C***SEE ALSO DSPLP
C***ROUTINES CALLED DPRWPG, IDLOC, XERMSG
C***REVISION HISTORY (YYMMDD)
C 811215 DATE WRITTEN
C 890531 Changed all specific intrinsics to generic. (WRB)
C 890606 Changed references from IPLOC to IDLOC. (WRB)
C 891214 Prologue converted to Version 4.0 format. (BAB)
C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
C 900328 Added TYPE section. (WRB)
C 910403 Updated AUTHOR and DESCRIPTION sections. (WRB)
C***END PROLOGUE DPCHNG
DIMENSION IX(*)
INTEGER IDLOC
DOUBLE PRECISION SX(*),XVAL,ZERO,ONE,SXLAST,SXVAL
SAVE ZERO, ONE
DATA ZERO,ONE /0.D0,1.D0/
C***FIRST EXECUTABLE STATEMENT DPCHNG
IOPT=1
C
C DETERMINE NULL-CASES..
IF(II.EQ.0) RETURN
C
C CHECK VALIDITY OF ROW/COL. INDEX.
C
IF (.NOT.(IRCX.EQ.0)) GO TO 20002
NERR=55
CALL XERMSG ('SLATEC', 'DPCHNG', 'IRCX=0', NERR, IOPT)
20002 LMX = IX(1)
C
C LMX IS THE LENGTH OF THE IN-MEMORY STORAGE AREA.
C
IF (.NOT.(IRCX.LT.0)) GO TO 20005
C
C CHECK SUBSCRIPTS OF THE ROW. THE ROW NUMBER MUST BE .LE. M AND
C THE INDEX MUST BE .LE. N.
C
IF (.NOT.(IX(2).LT.-IRCX .OR. IX(3).LT.ABS(II))) GO TO 20008
NERR=55
CALL XERMSG ('SLATEC', 'DPCHNG',
+ 'SUBSCRIPTS FOR ARRAY ELEMENT TO BE ACCESSED WERE OUT OF ' //
+ 'BOUNDS', NERR, IOPT)
20008 GO TO 20006
C
C CHECK SUBSCRIPTS OF THE COLUMN. THE COL. NUMBER MUST BE .LE. N AND
C THE INDEX MUST BE .LE. M.
C
20005 IF (.NOT.(IX(3).LT.IRCX .OR. IX(2).LT.ABS(II))) GO TO 20011
NERR=55
CALL XERMSG ('SLATEC', 'DPCHNG',
+ 'SUBSCRIPTS FOR ARRAY ELEMENT TO BE ACCESSED WERE OUT OF ' //
+ 'BOUNDS', NERR, IOPT)
20011 CONTINUE
C
C SET I TO BE THE ELEMENT OF ROW/COLUMN J TO BE CHANGED.
C
20006 IF (.NOT.(IRCX.GT.0)) GO TO 20014
I = ABS(II)
J = ABS(IRCX)
GO TO 20015
20014 I = ABS(IRCX)
J = ABS(II)
C
C THE INTEGER LL POINTS TO THE START OF THE MATRIX ELEMENT DATA.
C
20015 LL=IX(3)+4
II = ABS(II)
LPG = LMX - LL
C
C SET IPLACE TO START OUR SCAN FOR THE ELEMENT AT THE BEGINNING
C OF THE VECTOR.
C
IF (.NOT.(J.EQ.1)) GO TO 20017
IPLACE=LL+1
GO TO 20018
20017 IPLACE=IX(J+3)+1
C
C IEND POINTS TO THE LAST ELEMENT OF THE VECTOR TO BE SCANNED.
C
20018 IEND = IX(J+4)
C
C SCAN THROUGH SEVERAL PAGES, IF NECESSARY, TO FIND MATRIX ELEMENT.
C
IPL = IDLOC(IPLACE,SX,IX)
NP = ABS(IX(LMX-1))
GO TO 20021
20020 IF (ILAST.EQ.IEND) GO TO 20022
C
C THE VIRTUAL END OF DATA FOR THIS PAGE IS ILAST.
C
20021 ILAST = MIN(IEND,NP*LPG+LL-2)
C
C THE RELATIVE END OF DATA FOR THIS PAGE IS IL.
C SEARCH FOR A MATRIX VALUE WITH AN INDEX .GE. I ON THE PRESENT
C PAGE.
C
IL = IDLOC(ILAST,SX,IX)
IL = MIN(IL,LMX-2)
20023 IF (.NOT.(.NOT.(IPL.GE.IL .OR. IX(IPL).GE.I))) GO TO 20024
IPL=IPL+1
GO TO 20023
C
C SET IPLACE AND STORE DATA ITEM IF FOUND.
C
20024 IF (.NOT.(IX(IPL).EQ.I .AND. IPL.LE.IL)) GO TO 20025
SX(IPL) = XVAL
SX(LMX) = ONE
RETURN
C
C EXIT FROM LOOP IF ITEM WAS FOUND.
C
20025 IF(IX(IPL).GT.I .AND. IPL.LE.IL) ILAST = IEND
IF (.NOT.(ILAST.NE.IEND)) GO TO 20028
IPL = LL + 1
NP = NP + 1
20028 GO TO 20020
C
C INSERT NEW DATA ITEM INTO LOCATION AT IPLACE(IPL).
C
20022 IF (.NOT.(IPL.GT.IL.OR.(IPL.EQ.IL.AND.I.GT.IX(IPL)))) GO TO 20031
IPL = IL + 1
IF(IPL.EQ.LMX-1) IPL = IPL + 2
20031 IPLACE = (NP-1)*LPG + IPL
C
C GO TO A NEW PAGE, IF NECESSARY, TO INSERT THE ITEM.
C
IF (.NOT.(IPL.LE.LMX .OR. IX(LMX-1).GE.0)) GO TO 20034
IPL=IDLOC(IPLACE,SX,IX)
20034 IEND = IX(LL)
NP = ABS(IX(LMX-1))
SXVAL = XVAL
C
C LOOP THROUGH ALL SUBSEQUENT PAGES OF THE MATRIX MOVING DATA DOWN.
C THIS IS NECESSARY TO MAKE ROOM FOR THE NEW MATRIX ELEMENT AND
C KEEP THE ENTRIES SORTED.
C
GO TO 20038
20037 IF (IX(LMX-1).LE.0) GO TO 20039
20038 ILAST = MIN(IEND,NP*LPG+LL-2)
IL = IDLOC(ILAST,SX,IX)
IL = MIN(IL,LMX-2)
SXLAST = SX(IL)
IXLAST = IX(IL)
ISTART = IPL + 1
IF (.NOT.(ISTART.LE.IL)) GO TO 20040
K = ISTART + IL
DO 50 JJ=ISTART,IL
SX(K-JJ) = SX(K-JJ-1)
IX(K-JJ) = IX(K-JJ-1)
50 CONTINUE
SX(LMX) = ONE
20040 IF (.NOT.(IPL.LE.LMX)) GO TO 20043
SX(IPL) = SXVAL
IX(IPL) = I
SXVAL = SXLAST
I = IXLAST
SX(LMX) = ONE
IF (.NOT.(IX(LMX-1).GT.0)) GO TO 20046
IPL = LL + 1
NP = NP + 1
20046 CONTINUE
20043 GO TO 20037
20039 NP = ABS(IX(LMX-1))
C
C DETERMINE IF A NEW PAGE IS TO BE CREATED FOR THE LAST ELEMENT
C MOVED DOWN.
C
IL = IL + 1
IF (.NOT.(IL.EQ.LMX-1)) GO TO 20049
C
C CREATE A NEW PAGE.
C
IX(LMX-1) = NP
C
C WRITE THE OLD PAGE.
C
SX(LMX) = ZERO
KEY = 2
CALL DPRWPG(KEY,NP,LPG,SX,IX)
SX(LMX) = ONE
C
C STORE LAST ELEMENT MOVED DOWN IN A NEW PAGE.
C
IPL = LL + 1
NP = NP + 1
IX(LMX-1) = -NP
SX(IPL) = SXVAL
IX(IPL) = I
GO TO 20050
C
C LAST ELEMENT MOVED REMAINED ON THE OLD PAGE.
C
20049 IF (.NOT.(IPL.NE.IL)) GO TO 20052
SX(IL) = SXVAL
IX(IL) = I
SX(LMX) = ONE
20052 CONTINUE
C
C INCREMENT POINTERS TO LAST ELEMENT IN VECTORS J,J+1,... .
C
20050 JSTART = J + 4
JJ=JSTART
N20055=LL
GO TO 20056
20055 JJ=JJ+1
20056 IF ((N20055-JJ).LT.0) GO TO 20057
IX(JJ) = IX(JJ) + 1
IF(MOD(IX(JJ)-LL,LPG).EQ.LPG-1) IX(JJ) = IX(JJ) + 2
GO TO 20055
C
C IPLACE POINTS TO THE INSERTED DATA ITEM.
C
20057 IPL=IDLOC(IPLACE,SX,IX)
RETURN
END