[go: up one dir, main page]

Menu

[r1]: / idl_lib / comp2ds.pro  Maximize  Restore  History

Download this file

118 lines (109 with data), 4.3 kB

  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
;+*********************************************************************************************
; COMP2DS
;
;*********************************************************************************************
;
; usage: result=comp2ds(var1, var2, [tolerance], [/exact], [/int_exact],
; [location=name])
;
; purpose: Compares all the elements of two identical data structures of any
; arbitrary configuration (except for objects of course) and returns the
; locations of the elements which differ by more than a certain tolerance.
;
; output: Returns a string array describing the locations of elements which
; differ by more than a certain tolerance. At the end of each returned
; string element is appended the tolerance in brackets, or a note about how
; the two data elements differed. Strings are always assumed
; to be exact. If none of the elements differ, returns a null string.
;
; inputs: var1 The first data structure to compare.
;
; var2 The second data structure to compare. Must be structurally
; identical to var2.
;
; tolerace The desired tolerance. If not set, default is 1.e-5.
;
; keywords: /exact Equivalent to setting tolerance to 0.
;
; /int_exact Integers are assumed to be exactly identical.
;
; location Specifies the base name for describing the data structure. If
; not set, a default base name of 'variable' is supplied.
;
; history: Created Nov. 2001 by Peter Mills (peter.mills@nrl.navy.mil)
; -documented, 2001-11-14 PM
;
; bugs: If the data structures contain pointers with circular dependencies, the
; routine will run until it eats up all the stack space.
;
; planned improvements:
; Arrays of different sizes are always flagged, and the routine aborts.
; This could be changed so that the arrays are compared up to the last
; element of the smallest of the two arrays. For multi-dimensional arrays, if
; you want it done properly this could become (moderately) complicated.
;
; Also, fix the above bug....
;
;-**********************************************************************************************
;compares two data structures,
;looks for elements with less than a certain percentage difference (tol)
;/exact means they must be identical
;/int_exact means integers must be identical
function comp2ds, var1, var2, tol, exact=exact, int_exact=int_exact, $
location=location
result=''
if n_elements(tol) eq 0 then tol=10e-5
if keyword_set(exact) then tol=0
format='(i0)'
int_types=[1, 2, 3, 12, 13, 14, 15]
type=size(var1, /type)
type2=size(var2, /type)
n=n_elements(var1)
n2=n_elements(var2)
if n_elements(location) eq 0 then location='variable'
if type ne type2 then begin
return, location+" (*** incompatible data types ***)"
endif
if n ne n2 then begin
return, location+" (*** different array sizes:"+string(n)+","+string(n2)+" ***)"
endif
if n ne 1 then begin
for i=0L, n-1 do begin
location1=location+"["+string(i, format=format)+"]"
result1=comp2ds(var1[i], var2[i], tol, exact=exact, $
int_exact=int_exact, location=location1)
nres=n_elements(result1)
if result1[0] ne '' then result=[result, result1]
endfor
endif else if type eq 8 then begin
tagnames=tag_names(var1)
for i=0L, n_elements(tagnames)-1 do begin
location1=location+"."+tagnames[i]
result1=comp2ds(var1.(i), var2.(i), tol, exact=exact, $
int_exact=int_exact, location=location1)
if result1[0] ne '' then result=[result, result1]
endfor
endif else if type eq 10 then begin
location1="(*"+location+")"
result1=comp2ds((*var1), (*var2))
if result1[0] ne "" then begin
result=[result, result1]
endif
endif else if type eq 7 then begin
if var1 ne var2 then return, location+" (string: "+var1+", "+var2+")"
endif else if keyword_set(int_exact) then begin
if (where(type eq int_types))[0] ne -1 then begin
if var1 ne var2 then begin
return, location+" (integer:"+string(var1)+","+string(var2)+")"
endif
endif
endif else begin
err=2.*(var1-var2)/(var1+var2)
if abs(err) gt tol then begin
return, location+" ("+string(err)+")"
endif
endelse
nres=n_elements(result)
if nres gt 1 then result=result[1:nres-1]
return, result
end