Commit 7fbd6c8d01a3d2a2833fc36a219749c18b2c40c5
1 parent
86f1665a
Exists in
master
added IDL lib files that may become obsolete or retired in future IDL releases
Showing
3 changed files
with
552 additions
and
0 deletions
Show diff stats
@@ -0,0 +1,171 @@ | @@ -0,0 +1,171 @@ | ||
1 | +; $Id: //depot/Release/ENVI52_IDL84/idl/idldir/lib/int_tabulated.pro#1 $ | ||
2 | +; | ||
3 | +; Copyright (c) 1995-2014, Exelis Visual Information Solutions, Inc. All | ||
4 | +; rights reserved. Unauthorized reproduction is prohibited. | ||
5 | +;+ | ||
6 | +; NAME: | ||
7 | +; INT_TABULATED | ||
8 | +; | ||
9 | +; PURPOSE: | ||
10 | +; This function integrates a tabulated set of data { x(i) , f(i) }, | ||
11 | +; on the closed interval [min(X) , max(X)]. | ||
12 | +; | ||
13 | +; CATEGORY: | ||
14 | +; Numerical Analysis. | ||
15 | +; | ||
16 | +; CALLING SEQUENCE: | ||
17 | +; Result = INT_TABULATED(X, F) | ||
18 | +; | ||
19 | +; INPUTS: | ||
20 | +; X: The tabulated X-value data. This data may be irregularly | ||
21 | +; gridded and in random order. If the data is randomly ordered | ||
22 | +; you must set the SORT keyword to a nonzero value. | ||
23 | +; Duplicate x values will result in a warning message. | ||
24 | +; F: The tabulated F-value data. Upon input to the function | ||
25 | +; X(i) and F(i) must have corresponding indices for all | ||
26 | +; values of i. If X is reordered, F is also reordered. | ||
27 | +; | ||
28 | +; X and F must be of floating point or double precision type. | ||
29 | +; | ||
30 | +; KEYWORD PARAMETERS: | ||
31 | +; SORT: A zero or non-zero scalar value. | ||
32 | +; SORT = 0 (the default) The tabulated x-value data is | ||
33 | +; already in ascending order. | ||
34 | +; SORT = 1 The tabulated x-value data is in random order | ||
35 | +; and requires sorting into ascending order. Both | ||
36 | +; input parameters X and F are returned sorted. | ||
37 | +; DOUBLE: If set to a non-zero value, computations are done in | ||
38 | +; double precision arithmetic. | ||
39 | +; | ||
40 | +; OUTPUTS: | ||
41 | +; This fuction returns the integral of F computed from the tabulated | ||
42 | +; data in the closed interval [min(X) , max(X)]. | ||
43 | +; | ||
44 | +; RESTRICTIONS: | ||
45 | +; Data that is highly oscillatory requires a sufficient number | ||
46 | +; of samples for an accurate integral approximation. | ||
47 | +; | ||
48 | +; PROCEDURE: | ||
49 | +; INT_TABULATED.PRO constructs a regularly gridded x-axis with a | ||
50 | +; number of segments as an integer multiple of four. Segments | ||
51 | +; are processed in groups of four using a 5-point Newton-Cotes | ||
52 | +; integration formula. | ||
53 | +; For 'sufficiently sampled' data, this algorithm is highly accurate. | ||
54 | +; | ||
55 | +; EXAMPLES: | ||
56 | +; Example 1: | ||
57 | +; Define 11 x-values on the closed interval [0.0 , 0.8]. | ||
58 | +; x = [0.0, .12, .22, .32, .36, .40, .44, .54, .64, .70, .80] | ||
59 | +; | ||
60 | +; Define 11 f-values corresponding to x(i). | ||
61 | +; f = [0.200000, 1.30973, 1.30524, 1.74339, 2.07490, 2.45600, $ | ||
62 | +; 2.84299, 3.50730, 3.18194, 2.36302, 0.231964] | ||
63 | +; | ||
64 | +; Compute the integral. | ||
65 | +; result = INT_TABULATED(x, f) | ||
66 | +; | ||
67 | +; In this example, the f-values are generated from a known function, | ||
68 | +; (f = .2 + 25*x - 200*x^2 + 675*x^3 - 900*x^4 + 400*x^5) | ||
69 | +; | ||
70 | +; The Multiple Application Trapazoid Method yields; result = 1.5648 | ||
71 | +; The Multiple Application Simpson's Method yields; result = 1.6036 | ||
72 | +; INT_TABULATED.PRO yields; result = 1.6232 | ||
73 | +; The Exact Solution (4 decimal accuracy) yields; result = 1.6405 | ||
74 | +; | ||
75 | +; Example 2: | ||
76 | +; Create 30 random points in the closed interval [-2 , 1]. | ||
77 | +; x = randomu(seed, 30) * 3.0 - 2.0 | ||
78 | +; | ||
79 | +; Explicitly define the interval's endpoints. | ||
80 | +; x(0) = -2.0 & x(29) = 1.0 | ||
81 | +; | ||
82 | +; Generate f(i) corresponding to x(i) from a given function. | ||
83 | +; f = sin(2*x) * exp(cos(2*x)) | ||
84 | +; | ||
85 | +; Call INT_TABULATED with the SORT keyword. | ||
86 | +; result = INT_TABULATED(x, f, /sort) | ||
87 | +; | ||
88 | +; In this example, the f-values are generated from the function, | ||
89 | +; f = sin(2*x) * exp(cos(2*x)) | ||
90 | +; | ||
91 | +; The result of this example will vary because the x(i) are random. | ||
92 | +; Executing this example three times gave the following results: | ||
93 | +; INT_TABULATED.PRO yields; result = -0.0702 | ||
94 | +; INT_TABULATED.PRO yields; result = -0.0731 | ||
95 | +; INT_TABULATED.PRO yields; result = -0.0698 | ||
96 | +; The Exact Solution (4 decimal accuracy) yields; result = -0.0697 | ||
97 | +; | ||
98 | +; MODIFICATION HISTORY: | ||
99 | +; Written by: GGS, RSI, September 1993 | ||
100 | +; Modified: GGS, RSI, November 1993 | ||
101 | +; Use Numerical Recipes cubic spline interpolation | ||
102 | +; function NR_SPLINE/NR_SPLINT. Execution time is | ||
103 | +; greatly reduced. Added DOUBLE keyword. The 'sigma' | ||
104 | +; keyword is no longer supported. | ||
105 | +; Modified: GGS, RSI, April 1995 | ||
106 | +; Changed cubic spline calls from NR_SPLINE/NR_SPLINT | ||
107 | +; to SPL_INIT/SPL_INTERP. Improved double-precision | ||
108 | +; accuracy. | ||
109 | +; Modified: GGS, RSI, April 1996 | ||
110 | +; Replaced WHILE loop with vector operations. | ||
111 | +; Check for duplicate points in x vector. | ||
112 | +; Modified keyword checking and use of double precision. | ||
113 | +;- | ||
114 | + | ||
115 | +FUNCTION Int_Tabulated, X, F, Double = Double, Sort = Sort | ||
116 | + | ||
117 | + ;Return to caller if an error occurs. | ||
118 | + ON_ERROR, 2 | ||
119 | + | ||
120 | + TypeX = SIZE(X) | ||
121 | + TypeF = SIZE(F) | ||
122 | + | ||
123 | + ;Check F data type. | ||
124 | + if TypeF[TypeF[0]+1] ne 4 and TypeF[TypeF[0]+1] ne 5 then $ | ||
125 | + MESSAGE, "F values must be float or double." | ||
126 | + | ||
127 | + ;Check length. | ||
128 | + if TypeX[TypeX[0]+2] ne TypeF[TypeF[0]+2] then $ | ||
129 | + MESSAGE, "X and F arrays must have the same number of elements." | ||
130 | + | ||
131 | + ;Check duplicate values. | ||
132 | + if TypeX[TypeX[0]+2] ne N_ELEMENTS(UNIQ(X[SORT(X)])) then $ | ||
133 | + MESSAGE, "X array contains duplicate points." | ||
134 | + | ||
135 | + ;If the DOUBLE keyword is not set then the internal precision and | ||
136 | + ;result are identical to the type of input. | ||
137 | + if N_ELEMENTS(Double) eq 0 then $ | ||
138 | + Double = (TypeX[TypeX[0]+1] eq 5 or TypeF[TypeF[0]+1] eq 5) | ||
139 | + | ||
140 | + Xsegments = TypeX[TypeX[0]+2] - 1L | ||
141 | + | ||
142 | + ;Sort vectors into ascending order. | ||
143 | + if KEYWORD_SET(Sort) ne 0 then begin | ||
144 | + ii = SORT(x) | ||
145 | + X = X[ii] | ||
146 | + F = F[ii] | ||
147 | + endif | ||
148 | + | ||
149 | + while (Xsegments MOD 4L) ne 0L do $ | ||
150 | + Xsegments = Xsegments + 1L | ||
151 | + | ||
152 | + Xmin = MIN(X) | ||
153 | + Xmax = MAX(X) | ||
154 | + | ||
155 | + ;Uniform step size. | ||
156 | + h = (Xmax+0.0 - Xmin) / Xsegments | ||
157 | + ;Compute the interpolates at Xgrid. | ||
158 | + ;x values of interpolates >> Xgrid = h * FINDGEN(Xsegments + 1L) + Xmin | ||
159 | + z = SPL_INTERP(X, F, SPL_INIT(X, F, Double = Double), $ | ||
160 | + h * FINDGEN(Xsegments + 1L) + Xmin, Double = Double) | ||
161 | + ;Compute the integral using the 5-point Newton-Cotes formula. | ||
162 | + ii = (LINDGEN((N_ELEMENTS(z) - 1L)/4L)+1) * 4 | ||
163 | + if Double eq 0 then $ | ||
164 | + RETURN, FLOAT(TOTAL(2.0 * h * (7.0 * (z[ii-4] + z[ii]) + $ | ||
165 | + 32.0 * (z[ii-3] + z[ii-1]) + 12.0 * z[ii-2]) / 45.0)) $ | ||
166 | + else $ | ||
167 | + RETURN, TOTAL(2D * h * (7D * (z[ii-4] + z[ii]) + $ | ||
168 | + 32D * (z[ii-3] + z[ii-1]) + 12D * z[ii-2]) / 45D, /DOUBLE) | ||
169 | + | ||
170 | +END | ||
171 | + |
@@ -0,0 +1,265 @@ | @@ -0,0 +1,265 @@ | ||
1 | +; $Id: //depot/Release/ENVI52_IDL84/idl/idldir/lib/interpol.pro#1 $ | ||
2 | +; | ||
3 | +; Copyright (c) 1982-2014, Exelis Visual Information Solutions, Inc. All | ||
4 | +; rights reserved. Unauthorized reproduction is prohibited. | ||
5 | + | ||
6 | +Function ls2fit, xx, y, xm | ||
7 | + | ||
8 | +COMPILE_OPT idl2, hidden | ||
9 | + | ||
10 | +x = xx - xx[0] ;Normalize to preserve significance. | ||
11 | +ndegree = 2L | ||
12 | +n = n_elements(xx) | ||
13 | + | ||
14 | +corrm = fltarr(ndegree+1, ndegree+1) ;Correlation matrix | ||
15 | +b = fltarr(ndegree+1) | ||
16 | + | ||
17 | +corrm[0,0] = n ;0 - Form the normal equations | ||
18 | +b[0] = total(y) | ||
19 | +z = x ;1 | ||
20 | +b[1] = total(y*z) | ||
21 | +corrm[[0,1],[1,0]] = total(z) | ||
22 | +z = z * x ;2 | ||
23 | +b[2] = total(y*z) | ||
24 | +corrm[[0,1,2], [2,1,0]] = total(z) | ||
25 | +z = z * x ;3 | ||
26 | +corrm[[1,2],[2,1]] = total(z) | ||
27 | +corrm[2,2] = total(z*x) ;4 | ||
28 | + | ||
29 | +c = b # invert(corrm) | ||
30 | +xm0 = xm - xx[0] | ||
31 | +return, c[0] + c[1] * xm0 + c[2] * xm0^2 | ||
32 | +end | ||
33 | + | ||
34 | + | ||
35 | + | ||
36 | +;+ | ||
37 | +; NAME: | ||
38 | +; INTERPOL | ||
39 | +; | ||
40 | +; PURPOSE: | ||
41 | +; Linearly interpolate vectors with a regular or irregular grid. | ||
42 | +; Quadratic or a 4 point least-square fit to a quadratic | ||
43 | +; interpolation may be used as an option. | ||
44 | +; | ||
45 | +; CATEGORY: | ||
46 | +; E1 - Interpolation | ||
47 | +; | ||
48 | +; CALLING SEQUENCE: | ||
49 | +; Result = INTERPOL(V, N) ;For regular grids. | ||
50 | +; | ||
51 | +; Result = INTERPOL(V, X, XOUT) ;For irregular grids. | ||
52 | +; | ||
53 | +; INPUTS: | ||
54 | +; V: The input vector can be any type except string. | ||
55 | +; | ||
56 | +; For regular grids: | ||
57 | +; N: The number of points in the result when both input and | ||
58 | +; output grids are regular. | ||
59 | +; | ||
60 | +; Irregular grids: | ||
61 | +; X: The absicissae values for V. This vector must have same # of | ||
62 | +; elements as V. The values MUST be monotonically ascending | ||
63 | +; or descending. | ||
64 | +; | ||
65 | +; XOUT: The absicissae values for the result. The result will have | ||
66 | +; the same number of elements as XOUT. XOUT does not need to be | ||
67 | +; monotonic. If XOUT is outside the range of X, then the | ||
68 | +; closest two endpoints of (X,V) are linearly extrapolated. | ||
69 | +; | ||
70 | +; Keyword Input Parameters: | ||
71 | +; NAN = if set, then filter out NaN values before interpolating. | ||
72 | +; The default behavior is to include the NaN values - by including NaN's | ||
73 | +; the output will contain NaN's in locations where the interpolation | ||
74 | +; result is undefined. | ||
75 | +; | ||
76 | +; LSQUADRATIC = if set, interpolate using a least squares | ||
77 | +; quadratic fit to the equation y = a + bx + cx^2, for each 4 | ||
78 | +; point neighborhood (x[i-1], x[i], x[i+1], x[i+2]) surrounding | ||
79 | +; the interval, x[i] <= XOUT < x[i+1]. | ||
80 | +; | ||
81 | +; QUADRATIC = if set, interpolate by fitting a quadratic | ||
82 | +; y = a + bx + cx^2, to the three point neighborhood (x[i-1], | ||
83 | +; x[i], x[i+1]) surrounding the interval x[i] <= XOUT < x[i+1]. | ||
84 | +; | ||
85 | +; SPLINE = if set, interpolate by fitting a cubic spline to the | ||
86 | +; 4 point neighborhood (x[i-1], x[i], x[i+1], x[i+2]) surrounding | ||
87 | +; the interval, x[i] <= XOUT < x[i+1]. | ||
88 | +; | ||
89 | +; Note: if LSQUADRATIC or QUADRATIC or SPLINE is not set, the | ||
90 | +; default linear interpolation is used. | ||
91 | +; | ||
92 | +; OUTPUTS: | ||
93 | +; INTERPOL returns a floating-point vector of N points determined | ||
94 | +; by interpolating the input vector by the specified method. | ||
95 | +; | ||
96 | +; If the input vector is double or complex, the result is double | ||
97 | +; or complex. | ||
98 | +; | ||
99 | +; COMMON BLOCKS: | ||
100 | +; None. | ||
101 | +; | ||
102 | +; SIDE EFFECTS: | ||
103 | +; None. | ||
104 | +; | ||
105 | +; RESTRICTIONS: | ||
106 | +; None. | ||
107 | +; | ||
108 | +; PROCEDURE: | ||
109 | +; For linear interpolation, | ||
110 | +; Result(i) = V(x) + (x - FIX(x)) * (V(x+1) - V(x)) | ||
111 | +; | ||
112 | +; where x = i*(m-1)/(N-1) for regular grids. | ||
113 | +; m = # of elements in V, i=0 to N-1. | ||
114 | +; | ||
115 | +; For irregular grids, x = XOUT(i). | ||
116 | +; m = number of points of input vector. | ||
117 | +; | ||
118 | +; For QUADRATIC interpolation, the equation y=a+bx+cx^2 is | ||
119 | +; solved explicitly for each three point interval, and is then | ||
120 | +; evaluated at the interpolate. | ||
121 | +; For LSQUADRATIC interpolation, the coefficients a, b, and c, | ||
122 | +; from the above equation are found, for the four point | ||
123 | +; interval surrounding the interpolate using a least square | ||
124 | +; fit. Then the equation is evaluated at the interpolate. | ||
125 | +; For SPLINE interpolation, a cubic spline is fit over the 4 | ||
126 | +; point interval surrounding each interpolate, using the routine | ||
127 | +; SPL_INTERP(). | ||
128 | +; | ||
129 | +; MODIFICATION HISTORY: | ||
130 | +; Written, DMS, October, 1982. | ||
131 | +; Modified, Rob at NCAR, February, 1991. Made larger arrays possible | ||
132 | +; and correct by using long indexes into the array instead of | ||
133 | +; integers. | ||
134 | +; Modified, DMS, August, 1998. Now use binary intervals which | ||
135 | +; speed things up considerably when XOUT is random. | ||
136 | +; DMS, May, 1999. Use new VALUE_LOCATE function to find intervals, | ||
137 | +; which speeds things up by a factor of around 100, when | ||
138 | +; interpolating from large arrays. Also added SPLINE, | ||
139 | +; QUADRATIC, and LSQUADRATIC keywords. | ||
140 | +; CT, VIS, Feb 2009: CR54942: Automatically filter out NaN values. | ||
141 | +; Clean up code. | ||
142 | +; CT, VIS, Feb 2010: CR57403: Back out previous change. | ||
143 | +; Add NAN keyword to control filtering out of NaN's | ||
144 | +;- | ||
145 | +; | ||
146 | +FUNCTION INTERPOL, VV, XX, XOUT, $ | ||
147 | + SPLINE=spline, LSQUADRATIC=ls2, QUADRATIC=quad, NAN=nan | ||
148 | + | ||
149 | + COMPILE_OPT idl2 | ||
150 | + | ||
151 | + on_error,2 ;Return to caller if an error occurs | ||
152 | + | ||
153 | + regular = n_params(0) eq 2 | ||
154 | + | ||
155 | + ; Make a copy so we don't overwrite the input arguments. | ||
156 | + v = vv | ||
157 | + x = xx | ||
158 | + m = N_elements(v) ;# of input pnts | ||
159 | + | ||
160 | + if (regular) then nOut = LONG(x) | ||
161 | + | ||
162 | + ; Filter out NaN values in both the V and X arguments. | ||
163 | + if (KEYWORD_SET(nan)) then begin | ||
164 | + isNAN = FINITE(v, /NAN) | ||
165 | + if (~regular) then isNAN or= FINITE(x, /NAN) | ||
166 | + | ||
167 | + if (~ARRAY_EQUAL(isNAN, 0)) then begin | ||
168 | + good = WHERE(~isNAN, ngood) | ||
169 | + if (ngood gt 0 && ngood lt m) then begin | ||
170 | + v = v[good] | ||
171 | + if (regular) then begin | ||
172 | + ; We supposedly had a regular grid, but some of the values | ||
173 | + ; were NaN (missing). So construct the irregular grid. | ||
174 | + regular = 0b | ||
175 | + x = LINDGEN(m) | ||
176 | + xout = FINDGEN(nOut) * ((m-1.0) / ((nOut-1.0) > 1.0)) ;Grid points | ||
177 | + endif | ||
178 | + x = x[good] | ||
179 | + endif | ||
180 | + endif | ||
181 | + endif | ||
182 | + | ||
183 | + ; get the number of input points again, in case some NaN's got filtered | ||
184 | + m = N_elements(v) | ||
185 | + type = SIZE(v, /TYPE) | ||
186 | + | ||
187 | + if regular && $ ;Simple regular case? | ||
188 | + ((keyword_set(ls2) || keyword_set(quad) || keyword_set(spline)) eq 0) $ | ||
189 | + then begin | ||
190 | + xout = findgen(nOut)*((m-1.0)/((nOut-1.0) > 1.0)) ;Grid points in V | ||
191 | + xoutInt = long(xout) ;Cvt to integer | ||
192 | + case (type) of | ||
193 | + 1: diff = v[1:*] - FIX(v) | ||
194 | + 12: diff = v[1:*] - LONG(v) | ||
195 | + 13: diff = v[1:*] - LONG64(v) | ||
196 | + 15: diff = LONG64(v[1:*]) - LONG64(v) | ||
197 | + else: diff = v[1:*] - v | ||
198 | + endcase | ||
199 | + return, V[xoutInt] + (xout-xoutInt)*diff[xoutInt] ;interpolate | ||
200 | + endif | ||
201 | + | ||
202 | + if regular then begin ;Regular intervals?? | ||
203 | + xout = findgen(nOut) * ((m-1.0) / ((nOut-1.0) > 1.0)) ;Grid points | ||
204 | + s = long(xout) ;Subscripts | ||
205 | + endif else begin ;Irregular | ||
206 | + if n_elements(x) ne m then $ | ||
207 | + message, 'V and X arrays must have same # of elements' | ||
208 | + s = VALUE_LOCATE(x, xout) > 0L < (m-2) ;Subscript intervals. | ||
209 | + endelse | ||
210 | + | ||
211 | + ; Clip interval, which forces extrapolation. | ||
212 | + ; XOUT[i] is between x[s[i]] and x[s[i]+1]. | ||
213 | + | ||
214 | + CASE (1) OF | ||
215 | + | ||
216 | + KEYWORD_SET(ls2): BEGIN ;Least square fit quadratic, 4 points | ||
217 | + s = s > 1L < (m-3) ;Make in range. | ||
218 | + p = replicate(v[0]*1.0, n_elements(s)) ;Result | ||
219 | + for i=0L, n_elements(s)-1 do begin | ||
220 | + s0 = s[i]-1 | ||
221 | + p[i] = ls2fit(regular ? s0+findgen(4) : x[s0:s0+3], v[s0:s0+3], xout[i]) | ||
222 | + endfor | ||
223 | + END | ||
224 | + | ||
225 | + KEYWORD_SET(quad): BEGIN ;Quadratic. | ||
226 | + s = s > 1L < (m-2) ;In range | ||
227 | + x1 = regular ? float(s) : x[s] | ||
228 | + x0 = regular ? x1-1.0 : x[s-1] | ||
229 | + x2 = regular ? x1+1.0 : x[s+1] | ||
230 | + p = v[s-1] * (xout-x1) * (xout-x2) / ((x0-x1) * (x0-x2)) + $ | ||
231 | + v[s] * (xout-x0) * (xout-x2) / ((x1-x0) * (x1-x2)) + $ | ||
232 | + v[s+1] * (xout-x0) * (xout-x1) / ((x2-x0) * (x2-x1)) | ||
233 | + END | ||
234 | + | ||
235 | + KEYWORD_SET(spline): BEGIN | ||
236 | + s = s > 1L < (m-3) ;Make in range. | ||
237 | + p = replicate(v[0], n_elements(s)) ;Result | ||
238 | + sold = -1 | ||
239 | + for i=0L, n_elements(s)-1 do begin | ||
240 | + s0 = s[i]-1 | ||
241 | + if sold ne s0 then begin | ||
242 | + x0 = regular ? s0+findgen(4): x[s0: s0+3] | ||
243 | + v0 = v[s0: s0+3] | ||
244 | + q = spl_init(x0, v0) | ||
245 | + sold = s0 | ||
246 | + endif | ||
247 | + p[i] = spl_interp(x0, v0, q, xout[i]) | ||
248 | + endfor | ||
249 | + END | ||
250 | + | ||
251 | + ELSE: begin ;Linear, not regular | ||
252 | + case (type) of | ||
253 | + 1: diff = v[s+1] - FIX(v[s]) | ||
254 | + 12: diff = v[s+1] - LONG(v[s]) | ||
255 | + 13: diff = v[s+1] - LONG64(v[s]) | ||
256 | + 15: diff = LONG64(v[s+1]) - LONG64(v[s]) | ||
257 | + else: diff = v[s+1] - v[s] | ||
258 | + endcase | ||
259 | + p = (xout-x[s])*diff/(x[s+1] - x[s]) + v[s] | ||
260 | + end | ||
261 | + | ||
262 | + ENDCASE | ||
263 | + | ||
264 | + RETURN, p | ||
265 | +end |
@@ -0,0 +1,116 @@ | @@ -0,0 +1,116 @@ | ||
1 | +; $Id: //depot/Release/ENVI52_IDL84/idl/idldir/lib/obsolete/str_sep.pro#1 $ | ||
2 | +; | ||
3 | +; Copyright (c) 1992-2014, Exelis Visual Information Solutions, Inc and | ||
4 | +; CreaSo Creative Software Systems GmbH. | ||
5 | +; All rights reserved. Unauthorized reproduction prohibited. | ||
6 | +;+ | ||
7 | +; NAME: | ||
8 | +; STR_SEP | ||
9 | +; | ||
10 | +; PURPOSE: | ||
11 | +; This routine cuts a string into pieces which are separated by the | ||
12 | +; separator string. | ||
13 | +; CATEGORY: | ||
14 | +; String processing. | ||
15 | +; CALLING SEQUENCE: | ||
16 | +; arr = STR_SEP(str, separator) | ||
17 | +; | ||
18 | +; INPUTS: | ||
19 | +; str - The string to be separated. | ||
20 | +; separator - The separator. | ||
21 | +; | ||
22 | +; KEYWORDS: | ||
23 | +; ESC = escape character. Only valid if separator is a single character. | ||
24 | +; Characters following the escape character are treated | ||
25 | +; literally and not interpreted as separators. | ||
26 | +; For example, if the separator is a comma, | ||
27 | +; and the escape character is a backslash, the character | ||
28 | +; sequence 'a\,b' is a single field containing the characters | ||
29 | +; 'a,b'. | ||
30 | +; REMOVE_ALL = if set, remove all blanks from fields. | ||
31 | +; TRIM = if set, remove only leading and trailing blanks from fields. | ||
32 | +; | ||
33 | +; OUTPUT: | ||
34 | +; An array of strings as function value. | ||
35 | +; | ||
36 | +; COMMON BLOCKS: | ||
37 | +; None | ||
38 | +; | ||
39 | +; SIDE EFFECTS: | ||
40 | +; No known side effects. | ||
41 | +; | ||
42 | +; RESTRICTIONS: | ||
43 | +; None. | ||
44 | +; | ||
45 | +; EXAMPLE: | ||
46 | +; array = STR_SEP ("ulib.usca.test", ".") | ||
47 | +; | ||
48 | +; MODIFICATION HISTORY: | ||
49 | +; July 1992, AH, CreaSo Created. | ||
50 | +; December, 1994, DMS, RSI Added TRIM and REMOVE_ALL. | ||
51 | +;- | ||
52 | +function STR_SEP, str, separator, REMOVE_ALL = remove_all, TRIM = trim, ESC=esc | ||
53 | + | ||
54 | + | ||
55 | +ON_ERROR, 2 | ||
56 | +if n_params() ne 2 then message,'Wrong number of arguments.' | ||
57 | + | ||
58 | +spos = 0L | ||
59 | +if n_elements(esc) gt 0 then begin ;Check for escape character? | ||
60 | + if strpos(str, esc) lt 0 then goto, no_esc ;None in string, use fast case | ||
61 | + besc = (byte(esc))[0] | ||
62 | + bsep = (byte(separator))[0] | ||
63 | + new = bytarr(strlen(str)+1) | ||
64 | + new[0] = byte(str) | ||
65 | + j = 0L | ||
66 | + for i=0L, n_elements(new)-2 do begin | ||
67 | + if new[i] eq besc then begin | ||
68 | + new[j] = new[i+1] | ||
69 | + i = i + 1 | ||
70 | + endif else if new[i] eq bsep then new[j] = 1b $ ;Change seps to 1b char | ||
71 | + else new[j] = new[i] | ||
72 | + j = j + 1 | ||
73 | + endfor | ||
74 | + new = string(new[0:j-1]) | ||
75 | + w = where(byte(new) eq 1b, count) ;where seps are... | ||
76 | + arr = strarr(count+1) | ||
77 | + for i=0L, count-1 do begin | ||
78 | + arr[i] = strmid(new, spos, w[i]-spos) | ||
79 | + spos = w[i] + 1 | ||
80 | + endfor | ||
81 | + arr[count] = strmid(new, spos, strlen(str)) ;Last element | ||
82 | + goto, done | ||
83 | + endif ;esc | ||
84 | + | ||
85 | +no_esc: | ||
86 | +if strlen(separator) le 1 then begin ;Single character separator? | ||
87 | + w = where(byte(str) eq (byte(separator))[0], count) ;where seps are... | ||
88 | + arr = strarr(count+1) | ||
89 | + for i=0, count-1 do begin | ||
90 | + arr[i] = strmid(str, spos, w[i]-spos) | ||
91 | + spos = w[i] + 1 | ||
92 | + endfor | ||
93 | + arr[count] = strmid(str, spos, strlen(str)) ;Last element | ||
94 | +endif else begin ;Multi character separator.... | ||
95 | + n = 0L ; Determine number of seperators in string. | ||
96 | + repeat begin | ||
97 | + pos = strpos (str, separator, spos) | ||
98 | + spos = pos + strlen(separator) | ||
99 | + n = n+1 | ||
100 | + endrep until pos eq -1 | ||
101 | + | ||
102 | + arr = strarr(n) ; Create result array | ||
103 | + spos = 0L | ||
104 | + for i=0L, n-1 do begin ; Separate substrings | ||
105 | + pos = strpos (str, separator, spos) | ||
106 | + if pos ge 0 then arr[i] = strmid (str, spos, pos-spos) $ | ||
107 | + else arr[i] = strmid(str, spos, strlen(str)) | ||
108 | + spos = pos+strlen(separator) | ||
109 | + endfor | ||
110 | +endelse | ||
111 | + | ||
112 | +done: | ||
113 | +if keyword_set(trim) then arr = strtrim(arr,2) $ | ||
114 | +else if keyword_set(remove_all) then arr = strcompress(arr, /REMOVE_ALL) | ||
115 | +return, arr | ||
116 | +end |