subroutine aptsorm (atab, nrows, ncols, nrowmx, ncord, ncords, & mods, nsave, ngroup, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTSORM c c call aptsorm (atab, nrows, ncols, nrowmx, ncord, ncords, c & mods, nsave, ngroup, nerr) c c Version: aptsorm Updated 1991 December 29 11:20. c aptsorm Originated 1990 July 25 13:00. c c Author: Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123. c c c Purpose: To sort columns ncord(n), n = 1, ncords, of the 2-D array atab, c which has nrows rows and ncols columns, each in ascending c (ncord positive) or descending (ncord negative) order, in c alphanumeric (mods = 0), integer (mods = 1), or floating point c (mods = 2) mode. Each sequential sort only reorders the rows c within groups of rows for which the column values of the c previously sorted column are the same. The first row of each c such group of rows is flagged with the sorting level, ngroup. c The first nsave sorting levels from previous calls to aptsorm c may be retained, allowing columns of different mode to be c sequentially sorted. c Flag nerr indicates any input errors. c c Note: Subroutine aptsort may be used for single-column sorting. c c Input: atab, nrows, ncols, nrowmx, ncord, ncords, mods, nsave, ngroup. c c Output: atab, nsave, ngroup, nerr. c c Glossary: c c atab In/Out A two-dimensional array, with nrows rows and ncols c columns. Memory size is atab(nrowmx,ncolmx), where c nrowmx is no less than nrows, and ncolmx is no less c than ncols. c c mods Input Mode of columns to be sorted: c 0 = alphanumeric or character. c 1 = integer. c 2 = floating point. c For sequential sorting of columns with different c modes, make more than one call to aptsorm. c c ncols Input Number of columns actually used in atab, to be c reordered by the sorting. c Must be at least 1. c c ncord Input Indices of columns to be sorted. Size ncords. c Positive for sorting in increasing order. c Negative for sorting in decreasing order. c The magnitude must be in the range from 1 to ncols. c c ncords Input The number of columns to be sequentially sorted. c Size of array ncord. Each sort will not change any c of the nsave columns previously sorted. c c nerr Output Indicates an input error, if not 0: c 1 if nrows is less than 2, or more than nrowmx. c 2 if ncols is less than 1. c 3 if mods is less than 0 or more than 2. c 4 if any ncord has a magnitude greater than ncols, c or equal to zero. c 5 if nsave is less than 0. c c ngroup In/Out Sequential number of a preceding sort, for which the c row is the first of a group of rows with the same c value in the column sorted. Size nrows. c Should be initialized to zero before the first sort, c unless the first call to aptsorm is with nsave = 0. c May be an otherwise unused table column larger than c ncols. c c nrowmx Input First dimension in size specification of array atab. c c nrows Input Number of rows in atab. Size of array ngroup. c Must be in the range from 2 to nrowmx. c c nsave In/Out Number of saved sorts to retain, up to a maximum c of the sum of nsave and ncords on the preceding c call to aptsorm. Should be zero for the first c call to aptsorm. Refers to the first of the c saved sorts, not the last. c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccend. c.... Dimensioned arguments. c---- Table to be sorted. dimension atab (nrowmx,ncols) character*8 atab c---- Index of column to be sorted. dimension ncord (1) c---- Sorting group flag for row. dimension ngroup (1) c.... Local variables. c---- Difference between row values. common /laptsorm/ diff c---- Floating point sorting direction. common /laptsorm/ esign c---- Difference between row values. common /laptsorm/ ldiff c---- Current extreme value in column nsort. common /laptsorm/ lext c---- ASCII string form of lext. character*8 aext c---- ASCII string form of lext. equivalence (lext, aext) c---- Floating point form of lext. equivalence (lext, eext) c---- Integer sorting direction, -1 or 1. common /laptsorm/ lsign c---- Temporary atab value. common /laptsorm/ atemp character*8 atemp c---- Value to be compared with lext. common /laptsorm/ ltry c---- ASCII string form of ltry. character*8 atry c---- ASCII string form of ltry. equivalence (ltry, atry) c---- Floating point form of ltry. equivalence (ltry, etry) c---- Index of an atab column. common /laptsorm/ ncol c---- Index in array ncord. common /laptsorm/ nord c---- Index of an atab row. common /laptsorm/ nrow c---- Equal to nrows - 1. common /laptsorm/ nrowm c---- Index of an atab row, nrow + 1. common /laptsorm/ next c---- Index of an atab row. common /laptsorm/ nn c---- Index of column being sorted. common /laptsorm/ nsort c---- Index of row to exchange with nrow. common /laptsorm/ nrowx cbugc***DEBUG begins. cbug common /ltsor/ aformr(10) cbug 9901 format (/ 'aptsorm sorting table.' / cbug & ' nrows=',i5,' ncols=',i3,' nrowmx=',i5,' mods=',i3, cbug & ' nsave=',i3) cbug 9902 format (' ncord=',20i3) cbug 9903 format ('----------nrow=',i5,' ngroup=',i3,'----------') cbug write ( 3, 9901) nrows, ncols, nrowmx, mods, nsave cbug write ( 3, 9902) (ncord(nord), nord = 1, ncords) cbug do 981 nrow = 1, nrows cbug if ((ngroup(nrow) .ge. 1) .and. cbug & (ngroup(nrow) .le. nsave)) then cbug write ( 3, 9903) nrow, ngroup(nrow) cbug endif cbug write ( 3, aformr) (atab(nrow,ncol), ncol = 1, ncols) cbug 981 continue cbugc***DEBUG ends. c.... Test for input errors. nerr = 0 if ((nrows .lt. 2) .or. (nrows .gt. nrowmx)) then nerr = 1 go to 210 endif if (ncols .lt. 1) then nerr = 2 go to 210 endif if ((mods .lt. 0) .or. (mods .gt. 2)) then nerr = 3 go to 210 endif do 110 nord = 1, ncords nsort = iabs (ncord(nord)) if ((nsort .gt. ncols) .or. (nsort .eq. 0)) then nerr = 4 go to 210 endif 110 continue if (nsave .lt. 0) then nerr = 5 go to 210 endif c.... Initialize the row group flags. c---- Loop over atab rows. do 120 nrow = 1, nrows if (ngroup(nrow) .gt. nsave) then ngroup(nrow) = 0 endif c---- End of loop over atab rows. 120 continue ngroup(1) = 1 c.... Sort table atab. c---- Loop over columns to be sorted. do 180 nord = 1, ncords nsave = nsave + 1 c.... Find the direction of sorting. if (ncord(nord) .lt. 0) then nsort = -ncord(nord) lsign = -1 esign = -1.0 else nsort = ncord(nord) lsign = 1 esign = 1.0 endif c.... Sort within each fixed group of rows in atab. nrowm = nrows - 1 c---- Loop over atab rows. do 170 nrow = 1, nrowm nrowx = nrow next = nrow + 1 aext = atab(nrow,nsort) c.... Search for a more extreme value in same group of rows. c---- Loop over rest of group rows. do 140 nn = next, nrows if ((ngroup(nn) .ge. 1) .and. & (ngroup(nn) .lt. nsave)) then c---- Starting a new group. go to 150 endif atry = atab(nn,nsort) c.... Select the mode of column to be sorted, make comparison. c=============================================================================== c---- Alphanumeric comparison. if (mods .eq. 0) then if (lsign .eq. -1) then if (atry .gt. aext) then go to 130 else go to 140 endif else if (atry .lt. aext) then go to 130 else go to 140 endif endif c---- End of alphanumeric comparison. endif c=============================================================================== c---- Integer comparison. if (mods .eq. 1) then ldiff = lsign * (ltry - lext) if (ldiff .lt. 0) then go to 130 else go to 140 endif c---- End of integer comparison. endif c=============================================================================== c---- Floating point comparison. if (mods .eq. 2) then diff = esign * (etry - eext) if (diff .lt. 0.0) then go to 130 else go to 140 endif c---- End of floating point comparison. endif c=============================================================================== c.... A more extreme value has been found. Reset lext, save index. 130 aext = atry nrowx = nn c---- End of loop over rest of group rows. 140 continue c---- Reached end of group. 150 continue c.... End of search. See if row nrow should be replaced. c---- Exchange rows nrow and nrowx. if (nrowx .ne. nrow) then c---- Loop over atab columns. do 160 ncol = 1, ncols atemp = atab(nrow,ncol) atab(nrow,ncol) = atab(nrowx,ncol) atab(nrowx,ncol) = atemp c---- End of loop over atab columns. 160 continue c---- Exchanged rows. endif c.... See if this row is the beginning of a new group. if (nrow .eq. 1) then go to 170 endif c++++ A new group. if (atab(nrow,nsort) .ne. atab(nrow-1,nsort)) then if ((ngroup(nrow) .eq. 0) .or. & (ngroup(nrow) .gt. nsave)) then ngroup(nrow) = nsave endif c---- Started a new group. endif c---- End of loop over atab rows. 170 continue c.... See if final row is the beginning of a new group. c++++ A new group. if (atab(nrows,nsort) .ne. atab(nrowm,nsort)) then if ((ngroup(nrows) .eq. 0) .or. & (ngroup(nrows) .gt. nsave)) then ngroup(nrows) = nsave endif c---- Started a new group. endif c---- End of loop over columns to be sorted. 180 continue cbugc***DEBUG begins. cbug 9904 format (/ 'aptsorm results:') cbug write ( 3, 9904) cbug do 982 nrow = 1, nrows cbug if ((ngroup(nrow) .ge. 1) .and. cbug & (ngroup(nrow) .le. nsave)) then cbug write ( 3, 9903) nrow, ngroup(nrow) cbug endif cbug write ( 3, aformr) (atab(nrow,ncol), ncol = 1, ncols) cbug 982 continue cbugc***DEBUG ends. 210 return c.... End of subroutine aptsorm. (+1 line.) end UCRL-WEB-209832