1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
;
; some tests on Modulo operations
;
; Alain Coulais, April 22, 2014
;
; Under GNU GPL v2 or later
;
; any suggestion welcome to enlarge the scope of these tests
;
pro MYMESS, errors, message
errors=errors+1
MESSAGE, /continue, message
end
;
function TMP_TYPENAME, input
;
typename_exist=0
;
DEFSYSV, '!gdl', exists=is_it_gdl
;
if (is_it_gdl) then begin
if (!gdl.EPOCH GT 1398200000) then typename_exist=1
;;
endif else begin
;;
;; we are in IDL, TYPENAME() was introduced in 8.0
;;
if !VERSION.RELEASE GE '8.0' then typename_exist=1
endelse
;
if (typename_exist) then begin
return, TYPENAME(input)
endif else begin
return, STRING(SIZE(input,/tname))
endelse
;
end
;
; ----------------------------
;
pro MODULO_ON_INTEGERS, nb_errors, type=type, verbose=verbose, test=test
;
if ~KEYWORD_SET(type) then begin
type=2
MESSAGE,/continue, 'input TYPE set to : INT'
endif
;
if ((type EQ 0) OR ((type GT 3 ) AND (type LT 12))) then begin
if (type EQ 10) OR (type EQ 11) then begin
MESSAGE, /continue, 'BAD input TYPE (pointer, struct)'
endif else begin
MESSAGE, /continue, 'BAD numerical input TYPE (not an Integer-like) ['+TMP_TYPENAME(INDGEN(1, type=type))+']'
endelse
return
endif
;
errors=0
;
nbps=123456
;
; special limits for Byte, Int, Uint ...
if (type EQ 1) then begin
nbps=30
half=0b
endif
if (type EQ 2) OR (type EQ 12) then nbps=4500 ; (~~ 32768 / 7)
if (type EQ 12) OR (type EQ 13) OR (type EQ 15) then half=0
;
if (type EQ 2) OR (type EQ 3) OR (type EQ 14) then half=nbps/2
;
input0=INDGEN(nbps, type=type)-half
;
if KEYWORD_SET(verbose) then begin
print, 'requested TYPE = ', type, ', Type Name = ', $
TMP_TYPENAME(INDGEN(1, type=type))
print, 'effective TYPE = ', SIZE(input0,/type), ', Type Name = ', $
TMP_TYPENAME(input0)
endif
;
input2=input0*2
input7=input0*7
;
type_info='(for TYPE == '+TMP_TYPENAME(input0)+')'
;
txt='Errors in MODULO_ON_INTEGERS '+type_info
;
res= input2 MOD 2
mini=MIN(res)
maxi=MAX(res)
if ((mini LT 0) OR (maxi GT 0)) then MYMESS, errors, txt+'(case MOD 2)'
;
res= input7 MOD 7
mini=MIN(res)
maxi=MAX(res)
if ((mini LT 0) OR (maxi GT 0)) then MYMESS, errors, txt+'(case MOD 7)'
;
mess='errors found in MODULO_ON_INTEGERS '
;
if (errors GT 0) then begin
MESSAGE, /cont, 'nb of '+mess+type_info+' : '+string(errors)
endif else begin
MESSAGE, /cont, 'NO '+mess+type_info+'.'
endelse
;
if (N_PARAMS() EQ 1) then nb_errors=nb_errors+errors
;
if KEYWORD_SET(test) then STOP
;
end
;
; ----------------------------
;
pro MODULO_ON_FLOAT, nb_errors, tolerance=tolerance, nbp=nbp, scale=scale, $
double=double, verbose=verbose, test=test
;
errors=0
;
if ~KEYWORD_SET(tolerance) then tolerance=0.0
if ~KEYWORD_SET(nbp) then nbp=100
if ~KEYWORD_SET(scale) then scale=.25
;
if KEYWORD_SET(double) then begin
two_pi=2.*!Dpi
four_pi=4.*!Dpi
input=scale*(DINDGEN(nbp)-nbp/2)
endif else begin
two_pi=2.*!pi
four_pi=4.*!pi
input=scale*(FINDGEN(nbp)-nbp/2)
endelse
;
res=(((four_pi+input) mod two_pi) - (input mod two_pi)) mod two_pi
abs_res=TOTAL(ABS(res))
if KEYWORD_SET(verbose) then print, 'Tolerance, Result :', tolerance, abs_res
;
if KEYWORD_SET(double) then txt='/Double ' else txt='/Float '
txt=txt+' and NBP= '+STRING(nbp)+', scale='+STRING(scale)
txt=txt+' and Tolerance='+STRING(Tolerance)
;
if (abs_res LE tolerance) then begin
txt='OK for '+txt
endif else begin
txt='ERROR for '+txt
errors++
endelse
MESSAGE,/continue, STRCOMPRESS(txt)
;
if (N_PARAMS() EQ 1) then nb_errors=nb_errors+errors
;
if KEYWORD_SET(test) then STOP
;
end
;
; ----------------------------------------------------------------
;
pro TEST_MODULO, help=help, short=short, verbose=verbose, no_exit=no_exit, test=test
;
if KEYWORD_SET(help) then begin
print, 'pro TEST_MODULO, help=help, short=short, verbose=verbose, $'
print, ' no_exit=no_exit, test=test'
return
endif
;
nb_errors=0
;
types_list=[1,2,3,12,13,14,15]
for ii=0, N_ELEMENTS(types_list)-1 do begin
MODULO_ON_INTEGERS, nb_errors, type=types_list[ii], verbose=verbose, test=test
endfor
;
; no tolerance on default
MODULO_ON_FLOAT, nb_errors, tol=3.5e-5, verbose=verbose, test=test
MODULO_ON_FLOAT, nb_errors, /double, verbose=verbose, test=test
;
MODULO_ON_FLOAT, nb_errors, tol=6.04, scale=11.12, nb=1230, $
verbose=verbose, test=test
MODULO_ON_FLOAT, nb_errors, tol=2.4e-10, scale=11.12, nb=1230, /double, $
verbose=verbose, test=test
;
MODULO_ON_FLOAT, nb_errors, tol=6.3, scale=1.12, nb=1230, $
verbose=verbose, test=test
MODULO_ON_FLOAT, nb_errors, tol=2.4e-11, scale=1.12, nb=1230, /double, $
verbose=verbose, test=test
;
BANNER_FOR_TESTSUITE, 'TEST_MODULO', nb_errors, short=short
;
if (nb_errors GT 0) AND ~KEYWORD_SET(no_exit) then EXIT, status=1
;
if KEYWORD_SET(test) then STOP
;
end
|