SURFEX v7.3
General documentation of Surfex
|
00001 !----------------------------------------------------------------- 00002 !--------------- special set of characters for RCS information 00003 !----------------------------------------------------------------- 00004 ! $Source: /mesonh/MAKE/lib/COMPRESS/src/searchgrp.f90,v $ $Revision: 1.1 $ $Date: 2003/02/14 16:06:01 $ 00005 !----------------------------------------------------------------- 00006 !----------------------------------------------------------------- 00007 MODULE MODE_SEARCHGRP 00008 IMPLICIT NONE 00009 TYPE SOP_t 00010 INTEGER :: NBGRP 00011 INTEGER,DIMENSION(:),POINTER :: IBEG 00012 INTEGER,DIMENSION(:),POINTER :: IEND 00013 INTEGER,DIMENSION(:),POINTER :: VALMIN 00014 INTEGER,DIMENSION(:),POINTER :: VALMAX 00015 END TYPE SOP_t 00016 00017 INTEGER,EXTERNAL :: FMINBITS_IN_WORD 00018 00019 ! Private variables 00020 INTEGER,SAVE, PRIVATE :: IGRP 00021 INTEGER,DIMENSION(:),ALLOCATABLE,TARGET,PRIVATE :: IBEG,IEND,VALMAX,VALMIN 00022 INTEGER,PARAMETER, PRIVATE :: MAINSEUIL=8 00023 INTEGER,SAVE, PRIVATE :: IGRPMAX 00024 INTEGER,SAVE, PRIVATE :: ICOUNT 00025 INTEGER,DIMENSION(16),PARAMETER, PRIVATE :: MINELT=(/4,4,4,4,5,5,6,6,7,8,9,11,13,17,26,51/) 00026 00027 ! Private routines 00028 PRIVATE :: RECSEARCH_GRP 00029 00030 CONTAINS 00031 SUBROUTINE INI_SOPDATA(SOPDATA) 00032 TYPE(SOP_t), INTENT(OUT) :: SOPDATA 00033 00034 SOPDATA%NBGRP = 0 00035 NULLIFY(SOPDATA%IBEG) 00036 NULLIFY(SOPDATA%IEND) 00037 NULLIFY(SOPDATA%VALMIN) 00038 NULLIFY(SOPDATA%VALMAX) 00039 00040 END SUBROUTINE INI_SOPDATA 00041 00042 SUBROUTINE RECSEARCH(KTAB,SOPDATA) 00043 INTEGER,DIMENSION(:) :: KTAB 00044 TYPE(SOP_t), INTENT(OUT) :: SOPDATA 00045 00046 INTEGER :: NELT 00047 INTEGER :: GELT,BGELT 00048 00049 IF (ALLOCATED(IBEG)) THEN 00050 DEALLOCATE(IBEG,IEND,VALMAX,VALMIN) 00051 END IF 00052 00053 NELT=SIZE(KTAB) 00054 ALLOCATE(IBEG(NELT),IEND(NELT),VALMAX(NELT),VALMIN(NELT)) 00055 ICOUNT = 0 00056 IGRP = 0 00057 IGRPMAX = NELT 00058 CALL RECSEARCH_GRP(1,NELT,KTAB,MAINSEUIL) 00059 GELT = MAXVAL(IEND(1:IGRP)-IBEG(1:IGRP)+1) 00060 BGELT = FMINBITS_IN_WORD(GELT) 00061 00062 #ifdef DEBUG 00063 PRINT *,'Routine RECSEARCH_GRP appelee',ICOUNT,'fois.' 00064 PRINT *,'Nbre de groupes =',IGRP 00065 PRINT *,'Nbre maxi d''elements dans groupes',GELT 00066 PRINT *,'Nbre de bits pour coder le nombre d''elements:',BGELT 00067 #endif 00068 00069 SOPDATA%NBGRP=IGRP 00070 SOPDATA%IBEG=>IBEG 00071 SOPDATA%IEND=>IEND 00072 SOPDATA%VALMIN=>VALMIN 00073 SOPDATA%VALMAX=>VALMAX 00074 00075 END SUBROUTINE RECSEARCH 00076 00077 RECURSIVE SUBROUTINE RECSEARCH_GRP(IND1,IND2,ITAB,ISEUIL) 00078 INTEGER, INTENT(IN) :: IND1,IND2,ISEUIL 00079 INTEGER,DIMENSION(:),INTENT(IN) :: ITAB 00080 00081 INTEGER :: II 00082 INTEGER :: IMAX,IMIN 00083 INTEGER :: IVAL 00084 INTEGER :: nbitcod 00085 INTEGER :: tmpidx1,tmpidx2 00086 00087 ICOUNT=ICOUNT+1 00088 00089 IF (IGRP == 0) THEN 00090 IMIN = MINVAL(ITAB(IND1:IND2)) 00091 IMAX = MAXVAL(ITAB(IND1:IND2)) 00092 IGRP = 1 00093 VALMIN(IGRP) = IMIN 00094 VALMAX(IGRP) = IMAX 00095 IBEG(IGRP) = IND1 00096 IEND(IGRP) = IND2 00097 ELSE 00098 IMIN = VALMIN(IGRP) 00099 IMAX = VALMAX(IGRP) 00100 END IF 00101 00102 IF (IMAX > IMIN) THEN 00103 00104 IBEG(IGRP) = IND1 00105 IEND(IGRP) = IND1 00106 VALMIN(IGRP) = ITAB(IND1) 00107 VALMAX(IGRP) = ITAB(IND1) 00108 00109 DO II=IND1,IND2-1 00110 IVAL = ITAB(II+1) 00111 IMAX=MAX(VALMAX(IGRP),IVAL) 00112 IMIN=MIN(VALMIN(IGRP),IVAL) 00113 IF ((IMAX-IMIN)<(2**ISEUIL)) THEN 00114 ! II+1 belong to group IGRP 00115 IEND(IGRP) = II+1 00116 VALMIN(IGRP) = IMIN 00117 VALMAX(IGRP) = IMAX 00118 ELSE 00119 ! Search the created group 00120 nbitcod=FMINBITS_IN_WORD(VALMAX(IGRP)-VALMIN(IGRP)) 00121 #ifdef DEBUG 00122 PRINT *,'F:(IGRP,IBEG,IEND,MAX,MIN,nbitcod)=',IGRP,',',IBEG(IGRP),',',IEND(IGRP),',',VALMAX(IGRP),',',VALMIN(IGRP),',',nbitcod 00123 #endif 00124 IF (IEND(IGRP)-IBEG(IGRP)>MINELT(nbitcod+1)) THEN 00125 IF (nbitcod > 0) THEN 00126 tmpidx1=IBEG(IGRP) 00127 tmpidx2=IEND(IGRP) 00128 #ifdef DEBUG 00129 PRINT *,'Appel 1 RECSEARCH_GRP (first,last,seuil):',tmpidx1,tmpidx2,nbitcod/2 00130 #endif 00131 CALL RECSEARCH_GRP(tmpidx1,tmpidx2,ITAB,nbitcod/2) 00132 END IF 00133 ELSE 00134 IF (IGRP > 1) THEN 00135 nbitcod=FMINBITS_IN_WORD(VALMAX(IGRP-1)-VALMIN(IGRP-1)) 00136 IMIN=MIN(VALMIN(IGRP-1),VALMIN(IGRP)) 00137 IMAX=MAX(VALMAX(IGRP-1),VALMAX(IGRP)) 00138 IF (IEND(IGRP-1)-IBEG(IGRP-1)<=MINELT(nbitcod+1)) THEN 00139 IF ((IMAX-IMIN) < 2**15) THEN 00140 ! concat IGRP-1 and IGRP 00141 IEND(IGRP-1) = IEND(IGRP) 00142 VALMIN(IGRP-1) = IMIN 00143 VALMAX(IGRP-1) = IMAX 00144 IGRP = IGRP-1 00145 END IF 00146 ELSE 00147 IF (FMINBITS_IN_WORD(IMAX-IMIN) <= nbitcod) THEN 00148 ! concat IGRP-1 and IGRP 00149 IEND(IGRP-1) = IEND(IGRP) 00150 VALMIN(IGRP-1) = IMIN 00151 VALMAX(IGRP-1) = IMAX 00152 IGRP = IGRP-1 00153 END IF 00154 END IF 00155 END IF 00156 END IF 00157 ! New group is created 00158 IGRP = IGRP+1 00159 IF (IGRP>IGRPMAX) THEN 00160 PRINT *,'ERROR max number of group exceeded !' 00161 STOP 00162 END IF 00163 IBEG(IGRP) = II+1 00164 IEND(IGRP) = II+1 00165 VALMIN(IGRP) = IVAL 00166 VALMAX(IGRP) = IVAL 00167 END IF 00168 END DO 00169 #ifdef DEBUG 00170 PRINT *,'L:',IGRP,':',VALMAX(IGRP)-VALMIN(IGRP),FMINBITS_IN_WORD(VALMAX(IGRP)-VALMIN(IGRP)) 00171 #endif 00172 nbitcod = FMINBITS_IN_WORD(VALMAX(IGRP)-VALMIN(IGRP)) 00173 IF (IEND(IGRP)-IBEG(IGRP)>= MINELT(nbitcod+1)) THEN 00174 IF (nbitcod > 0) THEN 00175 tmpidx1=IBEG(IGRP) 00176 tmpidx2=IEND(IGRP) 00177 #ifdef DEBUG 00178 PRINT *,'Appel 2 RECSEARCH_GRP (first,last,seuil):',tmpidx1,tmpidx2,nbitcod/2 00179 #endif 00180 CALL RECSEARCH_GRP(tmpidx1,tmpidx2,ITAB,nbitcod/2) 00181 END IF 00182 END IF 00183 END IF 00184 00185 END SUBROUTINE RECSEARCH_GRP 00186 00187 SUBROUTINE INVERTCOL(ITAB,KX,KY) 00188 IMPLICIT NONE 00189 INTEGER, INTENT(IN) :: KX,KY 00190 INTEGER,DIMENSION(KX,KY), INTENT(INOUT)::ITAB 00191 00192 ITAB(:,2:KY:2) = ITAB(KX:1:-1,2:KY:2) 00193 00194 END SUBROUTINE INVERTCOL 00195 00196 END MODULE MODE_SEARCHGRP