source: trunk/SRC/Interpolation/spl_incr.pro @ 240

Last change on this file since 240 was 238, checked in by pinsard, 17 years ago

improvements/corrections of some *.pro headers

  • Property svn:keywords set to Id
File size: 19.3 KB
Line 
1;+
2;
3; @file_comments
4;
5; Given the arrays X and Y, which tabulate a function (with the X[i]
6; AND Y[i] in ascending order), and given an input value X2, the
7; spl_incr function returns an interpolated value for the given values
8; of X2. The interpolation method is based on cubic spline, corrected
9; in a way that interpolated values are also monotonically increasing.
10;
11; @param x1 {in}{required}
12; An n-element (at least 2) input vector that specifies the tabulate points in
13; a strict ascending order.
14;
15; @param y1 {in}{required}
16; f(x) = y. An n-element input vector that specifies the values
17; of the tabulated function F(Xi) corresponding to Xi. As f is
18; supposed to be monotonically increasing, y values must be
19; monotonically increasing. y can have equal consecutive values.
20;
21; @param x2 {in}{required}
22; The input values for which the interpolated values are
23; desired. Its values must be strictly monotonically increasing.
24;
25; @param der2
26;
27; @param x
28;
29; @returns
30;
31;    y2: f(x2) = y2. Double precision array
32;
33; @restrictions
34; It might be possible that y2[i+1]-y2[i] has very small negative
35; values (amplitude smaller than 1.e-6)...
36;
37; @examples
38;
39; IDL> n = 100L
40; IDL> x = (dindgen(n))^2
41; IDL> y = abs(randomn(0, n))
42; IDL> y[n/2:n/2+1] = 0.
43; IDL> y[n-n/3] = 0.
44; IDL> y[n-n/6:n-n/6+5] = 0.
45; IDL> y = total(y, /cumulative, /double)
46; IDL> x2 = dindgen((n-1)^2)
47; IDL> n2 = n_elements(x2)
48; IDL> print, min(y[1:n-1]-y[0:n-2]) LT 0
49; IDL> y2 = spl_incr( x, y, x2)
50; IDL> splot, x, y, xstyle = 1, ystyle = 1, ysurx=.25, petit = [1, 2, 1], /land
51; IDL> oplot, x2, y2, color = 100
52; IDL> c = y2[1:n2-1] - y2[0:n2-2]
53; IDL> print, min(c) LT 0
54; IDL> print, min(c, max = ma), ma
55; IDL> splot,c,xstyle=1,ystyle=1, yrange=[-.01,.05], ysurx=.25, petit = [1, 2, 2], /noerase
56; IDL> oplot,[0, n_elements(c)], [0, 0], linestyle = 1
57;
58; @history
59;  Sebastien Masson (smasson\@lodyc.jussieu.fr): May-Dec 2005
60;
61; @version
62; $Id$
63;
64;-
65;
66FUNCTION pure_concave, x1, x2, y1, y2, der2, x
67;
68  compile_opt idl2, strictarrsubs
69;
70; X^n type
71;
72  xx = (double(x)-double(x1))/(double(x2)-double(x1))
73  f = (double(x2)-double(x1))/(double(y2)-double(y1))
74  n = der2*temporary(f)
75  res = xx^(n)
76;   IF check_math() GT 0 THEN BEGIN
77;       zero = where(abs(res) LT 1.e-10)
78;       IF zero[0] NE -1 THEN res[zero] = 0.0d
79;   END
80  res = temporary(res)*(double(y2)-double(y1))+y1
81;
82;  IF array_equal(sort(res), lindgen(n_elements(res)) ) NE 1 THEN stop
83  RETURN, res
84END
85;
86;+
87;
88; @param x1 {in}{required}
89; An n-element (at least 2) input vector that specifies the tabulate points in
90; a strict ascending order.
91;
92; @param y1 {in}{required}
93; f(x) = y. An n-element input vector that specifies the values
94;    of the tabulated function F(Xi) corresponding to Xi. As f is
95;    supposed to be monotonically increasing, y values must be
96;    monotonically increasing. y can have equal consecutive values.
97;
98; @param x2 {in}{required}
99; The input values for which the interpolated values are
100; desired. Its values must be strictly monotonically increasing.
101;
102; @param der2
103; @param x
104;
105;-
106;
107FUNCTION pure_convex, x1, x2, y1, y2, der2, x
108;
109  compile_opt idl2, strictarrsubs
110;
111; 1-(1-X)^n type
112;
113  xx = 1.0d - (double(x)-double(x1))/(double(x2)-double(x1))
114  f = (double(x2)-double(x1))/(double(y2)-double(y1))
115  n = der2*temporary(f)
116  res = xx^(n)
117;   IF check_math() GT 0 THEN BEGIN
118;       zero = where(abs(res) LT 1.e-10)
119;       IF zero[0] NE -1 THEN res[zero] = 0.0d
120;   END
121  res = 1.0d - temporary(res)
122  res = temporary(res)*(y2-y1)+y1
123;
124;  IF array_equal(sort(res), lindgen(n_elements(res)) ) NE 1 THEN stop
125  RETURN, res
126END
127;
128;+
129;
130; @param x
131; @param y
132; @param x2
133; @keyword YP0
134; The first derivative of the interpolating function at the
135;    point X0. If YP0 is omitted, the second derivative at the
136;    boundary is set to zero, resulting in a "natural spline."
137; @keyword YPN_1
138; The first derivative of the interpolating function at the
139;    point Xn-1. If YPN_1 is omitted, the second derivative at the
140;    boundary is set to zero, resulting in a "natural spline."
141;-
142;
143FUNCTION spl_incr, x, y, x2, YP0 = yp0, YPN_1 = ypn_1
144;
145  compile_opt idl2, strictarrsubs
146;
147;---------------------------------
148; check and initialization ...
149;---------------------------------
150;
151  nx = n_elements(x)
152  ny = n_elements(y)
153  nx2 = n_elements(x2)
154; x must have at least 2 elements
155  IF nx LT 2 THEN stop
156; y must have the same number of elements than x
157  IF nx NE ny THEN stop
158; x be monotonically increasing
159  IF min(x[1:nx-1]-x[0:nx-2]) LE 0 THEN stop
160; x2 be monotonically increasing
161  IF N_ELEMENTS(X2) GE 2 THEN $
162  IF min(x2[1:nx2-1]-x2[0:nx2-2])  LE 0 THEN stop
163; y be monotonically increasing
164  IF min(y[1:ny-1]-y[0:ny-2]) LT 0 THEN stop
165;---------------------------------
166; first check: check if two consecutive values are equal
167;---------------------------------
168  bad = where(y[1:ny-1]-y[0:ny-2] EQ 0, cntbad)
169  IF cntbad NE 0 THEN BEGIN
170; define the results: y2
171      y2 = dblarr(nx2)
172; define xinx2: see help of value_locate
173;  if xinx2[i] eq -1   :                 x[bad[i]] <  x2[0]
174;  if xinx2[i] eq nx2-1:                 x[bad[i]] >= x2[nx2-1]
175;  else                : x2[xinx2[i]] <= x[bad[i]] <  x2[xinx2[i]+1]
176    xinx2 = value_locate(x2, x[bad])
177    xinx2_1 = value_locate(x2, x[bad+1])
178;
179; left side ... if there is x2 values smaller that x[bad[0]].
180; we force ypn_1 = 0.0d
181    IF xinx2[0] NE -1 THEN BEGIN
182      IF bad[0] EQ 0 THEN BEGIN
183        IF xinx2[0] NE 0 THEN stop
184        y2[0] = y[0]
185      ENDIF ELSE BEGIN
186        y2[0:xinx2[0]] $
187          = spl_incr(x[0:bad[0]], y[0:bad[0]], x2[0:xinx2[0]] $
188                     , yp0 = yp0, ypn_1 = 0.0d)
189      ENDELSE
190    ENDIF
191; flat section
192    IF xinx2_1[0] NE -1 THEN $
193      y2[(xinx2[0]+1) < xinx2_1[0] : xinx2_1[0]] = y[bad[0]]
194; middle pieces ... if cntbad gt 1 then we have to cut spl_incr in
195; more than 2 pieces...
196      IF cntbad GT 1 THEN BEGIN
197; we take care of the piece located wetween bad[ib-1]+1 and bad[ib]
198        FOR ib = 1, cntbad-1 DO BEGIN
199; if there is x2 values smaller that x[bad[ib]], then the x2 values
200; located between bad[ib-1]+1 and bad[ib] are (xinx2_1[ib-1]+1:xinx2[ib]
201; and if we don't have two consecutive flat sections
202          IF xinx2[ib] NE -1 AND (bad[ib-1] NE bad[ib]-1) THEN begin
203            y2[(xinx2_1[ib-1]+1) < xinx2[ib]:xinx2[ib]] $
204              = spl_incr(x[bad[ib-1]+1:bad[ib]], y[bad[ib-1]+1:bad[ib]] $
205                         , x2[(xinx2_1[ib-1]+1) < xinx2[ib]:xinx2[ib]] $
206                         , yp0 = 0.0d, ypn_1 = 0.0d)
207          ENDIF
208; flat section
209          IF xinx2_1[ib] NE -1 THEN $
210            y2[(xinx2[ib]+1) < xinx2_1[ib] : xinx2_1[ib]] = y[bad[ib]]
211        ENDFOR
212      ENDIF
213; right side ... if there is x2 values larger that x[bad[cntbad-1]+1].
214; we force yp0 = 0.0d
215      IF xinx2_1[cntbad-1] NE nx2-1 THEN $
216        y2[xinx2_1[cntbad-1]+1:nx2-1] $
217        = spl_incr(x[bad[cntbad-1]+1:nx-1], y[bad[cntbad-1]+1:nx-1] $
218                        , x2[xinx2_1[cntbad-1]+1:nx2-1] $
219                        , yp0 = 0.0d, ypn_1 = ypn_1new)
220
221    RETURN, y2
222
223  ENDIF
224;-----------
225; compute the second derivative of the cubic spline on each x.
226;-----------
227  yscd = spl_init(x, y, yp0 = yp0, ypn_1 = ypn_1, /double)
228;---------------------------------
229; second check: none of the first derivative on x values must be negative.
230;---------------------------------
231;
232; compute the first derivative on x
233;
234  yifrst = spl_fstdrv(x, y, yscd, x)
235;
236; we force the negative first derivative to 0 by calling again
237; spl_incr with the keywords yp0 and ypn_1 to specify the
238; first derivative equal to 0
239;
240  bad = where(yifrst LT 0.0d, cntbad)
241  IF cntbad NE 0 THEN BEGIN
242;
243; we define the new values of the keyword ypn_1:
244; if the first derivative of the last value of x is negative
245; we define the new values of the keyword ypn_1 to 0.0d0
246    IF bad[cntbad-1] EQ nx-1 THEN BEGIN
247      ypn_1new = 0.0d
248; we remove this case from the list
249      IF cntbad GE 2 THEN bad = bad[0:cntbad-2]
250      cntbad = cntbad-1
251; else we take the value of ypn_1 if it was already defined
252    ENDIF ELSE IF n_elements(ypn_1) NE 0 THEN ypn_1new = ypn_1
253;
254; we define the new values of the keyword yp0:
255; if the first derivative of the first value of x is negative
256; we define the new values of the keyword yp0 to 0.0
257    IF bad[0] EQ 0 THEN BEGIN
258      yp0new = 0.0d
259; we remove this case from the list
260      IF cntbad GE 2 THEN bad = bad[1:cntbad-1]
261      cntbad = cntbad-1
262; else we take the value of yp0 if it was already defined
263    ENDIF ELSE IF n_elements(yp0) NE 0 THEN yp0new = yp0
264;
265; if all the negative derivative corresponded to one of the cases above,
266; then we can directly call spl_incr with the new yp0new and ypn_1new
267    IF cntbad LE 0 THEN BEGIN
268      y2 = spl_incr(x, y, x2, yp0 = yp0new, ypn_1 = ypn_1new)
269;
270; else: there is still cases with negative derivative ...
271; we will cut spl_incr in n spl_incr and specify yp0, ypn_1
272; for each of this n spl_incr
273    ENDIF ELSE BEGIN
274; define xinx2: see help of value_locate
275;  if xinx2[i] eq -1   :                 x[bad[i]] <  x2[0]
276;  if xinx2[i] eq nx2-1:                 x[bad[i]] >= x2[nx2-1]
277;  else                : x2[xinx2[i]] <= x[bad[i]] <  x2[xinx2[i]+1]
278      xinx2 = value_locate(x2, x[bad])
279      y2 = dblarr(nx2)
280; left side ... if there is x2 values smaller that x[bad[0]].
281; we force ypn_1 = 0.0d
282      IF xinx2[0] NE -1 THEN $
283        y2[0:xinx2[0]] $
284        = spl_incr(x[0:bad[0]], y[0:bad[0]], x2[0:xinx2[0]] $
285                        , yp0 = yp0new, ypn_1 = 0.0d)
286; middle pieces ... if cntbad gt 1 then we have to cut spl_incr in
287; more than 2 pieces -> we have middle pieces for which
288; we force yp0 = 0.0d and ypn_1 = 0.0d
289      IF cntbad GT 1 THEN BEGIN
290; we take care of the piece located wetween bad[ib-1] and bad[ib]
291        FOR ib = 1, cntbad-1 DO BEGIN
292; if there is x2 values smaller that x[bad[ib]], then the x2 values
293; located between bad[ib-1] and bad[ib] are (xinx2[ib-1]+1:xinx2[ib]
294          IF xinx2[ib] NE -1 THEN begin
295            y2[(xinx2[ib-1]+1) < xinx2[ib]:xinx2[ib]] $
296              = spl_incr(x[bad[ib-1]:bad[ib]], y[bad[ib-1]:bad[ib]] $
297                              , x2[(xinx2[ib-1]+1) < xinx2[ib]:xinx2[ib]] $
298                              , yp0 = 0.0d, ypn_1 = 0.0d)
299          endif
300        ENDFOR
301      ENDIF
302; right side ... if there is x2 values larger that x[bad[cntbad-1]].
303; we force yp0 = 0.0d
304      IF xinx2[cntbad-1] NE nx2-1 THEN $
305        y2[xinx2[cntbad-1]+1:nx2-1] $
306        = spl_incr(x[bad[cntbad-1]:nx-1], y[bad[cntbad-1]:nx-1] $
307                        , x2[xinx2[cntbad-1]+1:nx2-1] $
308                        , yp0 = 0.0d, ypn_1 = ypn_1new)
309    ENDELSE
310; we return the checked and corrected value of yfrst
311;       FOR i = 0, nx-1 DO BEGIN
312;         same = where(abs(x2- x[i]) LT 1.e-10, cnt)
313; ;        IF cnt NE 0 THEN y2[same] = y[i]
314;       ENDFOR
315    RETURN, y2
316  ENDIF
317;
318; we can be in this part of the code only if:
319;  (1) spl_incr is called by itself
320;  (2) none are the first derivative in x are negative (because they have been
321;      checked and corrected by the previous call to spl_incr, see above)
322;---------------------------------
323; third check: we have to make sure that the first derivative cannot
324;               have negative values between on x[0] and x[nx-1]
325;---------------------------------
326;
327; first we compute the first derivative, next we correct the values
328; where we know that the first derivative can be negative.
329;
330  y2 = spl_interp(x, y, yscd, x2, /double)
331;
332; between x[i] and x[i+1], the cubic spline is a cubic function:
333; y  =  a*X^3 +  b*X^2 + c*X + d
334; y' = 3a*X^2 + 2b*X   + c
335; y''= 6a*X   + 2b
336; if we take X = x[i+1]-x[i] then
337;    d = y[i]; c = y'[i]; b = 0.5 * y''[i],
338;    a = 1/6 * (y''[i+1]-y''[i])/(x[i+1]-x[i])
339;
340; y'[i] and y'[i+1] are positive so y' can be negative
341; between x[i] and x[i+1] only if
342;   1) a > 0
343;            ==> y''[i+1] > y''[i]
344;   2) y' reach its minimum value between  x[i] and x[i+1]
345;      -> 0 < - b/(3a) < x[i+1]-x[i]
346;            ==> y''[i+1] > 0 > y''[i]
347;
348; we do a first selection by looking for those points...
349;
350  loc = lindgen(nx-1)
351  maybebad = where(yscd[loc] LE 0.0d AND yscd[loc+1] GE 0.0d, cntbad)
352;
353  IF cntbad NE 0 THEN BEGIN
354
355    mbbloc = loc[maybebad]
356
357    aaa = (yscd[mbbloc+1]-yscd[mbbloc])/(6.0d*(x[mbbloc+1]-x[mbbloc]))
358    bbb = 0.5d * yscd[mbbloc]
359    ccc = yifrst[mbbloc]
360    ddd = y[mbbloc]
361;
362; definitive selection:
363; y' can become negative if and only if (2b)^2 - 4(3a)c > 0
364; y' can become negative if and only if    b^2  - (3a)c > 0
365;
366    delta = bbb*bbb - 3.0d*aaa*ccc
367;
368    bad = where(delta GT 0, cntbad)
369;
370    IF cntbad NE 0 THEN BEGIN
371      delta = delta[bad]
372      aaa = aaa[bad]
373      bbb = bbb[bad]
374      ccc = ccc[bad]
375      ddd = ddd[bad]
376      bad = maybebad[bad]
377; define xinx2_1: see help of value_locate
378;  if xinx2_1[i] eq -1   :                   x[bad[i]] <  x2[0]
379;  if xinx2_1[i] eq nx2-1:                   x[bad[i]] >= x2[nx2-1]
380;  else                  : x2[xinx2_1[i]] <= x[bad[i]] <  x2[xinx2_1[i]+1]
381      xinx2_1 = value_locate(x2, x[bad])
382; define xinx2_2: see help of value_locate
383;  if xinx2_2[i] eq -1   :                   x[bad[i]+1] <  x2[0]
384;  if xinx2_2[i] eq nx2-1:                   x[bad[i]+1] >= x2[nx2-1]
385;  else                  : x2[xinx2_2[i]] <= x[bad[i]+1] <  x2[xinx2_2[i]+1]
386      xinx2_2 = value_locate(x2, x[bad+1])
387; to avoid the particular case when x2 = x[bad[i]]
388; and there is no other x2 point until x[bad[i]+1]
389      xinx2_1 = xinx2_1 < (xinx2_2-1)
390;
391      FOR ib = 0, cntbad-1 DO BEGIN
392;
393; at least one of the x2 points must be located between
394; x[bad[ib]] and x[bad[ib]+1]
395        IF x2[0] LE x[bad[ib]+1] AND x2[nx2-1] GE x[bad[ib]] THEN BEGIN
396;
397          CASE 1 OF
398            yifrst[bad[ib]+1] EQ 0.0d:BEGIN
399; case pur convex: we use the first derivative of 1-(1-x)^n
400; and ajust n to get the good value: yifrst[bad[ib]] in x[bad[ib]]
401              y2[xinx2_1[ib]+1:xinx2_2[ib]] $
402                = pure_convex(x[bad[ib]], x[bad[ib]+1] $
403                              , y[bad[ib]], y[bad[ib]+1]  $
404                              , yifrst[bad[ib]] $
405                              , x2[xinx2_1[ib]+1:xinx2_2[ib]])
406            END
407            yifrst[bad[ib]] EQ 0.0d:BEGIN
408; case pur concave: we use the first derivative of x^n
409; and ajust n to get the good value: yifrst[bad[ib]+1] in x[bad[ib]+1]
410              y2[xinx2_1[ib]+1:xinx2_2[ib]] $
411                = pure_concave(x[bad[ib]], x[bad[ib]+1] $
412                               , y[bad[ib]], y[bad[ib]+1] $
413                               , yifrst[bad[ib]+1] $
414                               , x2[xinx2_1[ib]+1:xinx2_2[ib]])
415            END
416            ELSE:BEGIN
417; in those cases, the first derivative has 2 zero between
418; x[bad[ib]] and x[bad[ib]+1]. We look for the minimum value of the
419; first derivative that correspond to the inflection point of y
420              xinfl = -bbb[ib]/(3.0d*aaa[ib])
421; we compute the y value for xinfl
422              yinfl = aaa[ib]*xinfl*xinfl*xinfl + bbb[ib]*xinfl*xinfl $
423                + ccc[ib]*xinfl + ddd[ib]
424;
425              CASE 1 OF
426; if y[xinfl] smaller than y[bad[ib]] then we conserve y2 until
427; the first zero of y2 and from this point we use x^n and ajust n to
428; get the good value: yifrst[bad[ib]+1] in x[bad[ib]+1]
429                yinfl LT y[bad[ib]]:BEGIN
430; value of the first zero (y'[xzero]=0)
431                  xzero = (-bbb[ib]-sqrt(delta[ib]))/(3.0d*aaa[ib])
432; value of y[xzero]...
433                  yzero = aaa[ib]*xzero*xzero*xzero + bbb[ib]*xzero*xzero $
434                    + ccc[ib]*xzero + ddd[ib]
435; if yzero > y[bad[ib]+1] then we cannot applay the method we want to
436; apply => we use then convex-concave case by changing by hand the
437; value of yinfl and xinfl
438                  IF yzero GT y[bad[ib]+1] THEN BEGIN
439                    yinfl = 0.5d*(y[bad[ib]+1]+y[bad[ib]])
440                    xinfl = 0.5d*(x[bad[ib]+1]-x[bad[ib]])
441                    GOTO, convexconcave
442                  ENDIF
443; define xinx2_3: see help of value_locate
444;  if xinx2_3[ib] eq -1   :                x[bad[ib]]+xzero <  x2[0]
445;  if xinx2_3[ib] eq nx2-1:                x[bad[ib]]+xzero >= x2[nx2-1]
446;  else                   : x2[xinx2_3] <= x[bad[ib]]+xzero <  x2[xinx3_2+1]
447                  xinx2_3 = value_locate(x2, x[bad[ib]]+xzero)
448; to avoid the particular case when x2 = x[bad[ib]]+xzero
449; and there is no other x2 point until x[bad[ib]+1]
450                  xinx2_3 = xinx2_3 < (xinx2_2[ib]-1)
451                  IF xinx2_2[ib] GE xinx2_3+1 THEN BEGIN
452                    y2[xinx2_3+1:xinx2_2[ib]] $
453                      = pure_concave(x[bad[ib]]+xzero, x[bad[ib]+1] $
454                                     , yzero, y[bad[ib]+1] $
455                                     , yifrst[bad[ib]+1] $
456                                     , x2[xinx2_3+1:xinx2_2[ib]])
457                  ENDIF
458                END
459; if y[xinfl] bigger than y[bad[ib]+1] then we conserve y2 from
460; the second zero of y2 and before this point we use 1-(1-x)^n and
461; ajust n to get the good value: yifrst[bad[ib]] in x[bad[ib]]
462                yinfl GT y[bad[ib]+1]:BEGIN
463; value of the second zero (y'[xzero]=0)
464                  xzero = (-bbb[ib]+sqrt(delta[ib]))/(3.0d*aaa[ib])
465; value of y[xzero]...
466                  yzero = aaa[ib]*xzero*xzero*xzero + bbb[ib]*xzero*xzero $
467                    + ccc[ib]*xzero + ddd[ib]
468; if yzero < y[bad[ib]] then we cannot applay the method we want to
469; apply => we use then convex-concave case by changing by hand the
470; value of yinfl and xinfl
471                  IF yzero lt y[bad[ib]] THEN BEGIN
472                    yinfl = 0.5d*(y[bad[ib]+1]+y[bad[ib]])
473                    xinfl = 0.5d*(x[bad[ib]+1]-x[bad[ib]])
474                    GOTO, convexconcave
475                  ENDIF
476; define xinx2_3: see help of value_locate
477;  if xinx2_3[ib] eq -1   :                x[bad[ib]]+xzero <  x2[0]
478;  if xinx2_3[ib] eq nx2-1:                x[bad[ib]]+xzero >= x2[nx2-1]
479;  else                   : x2[xinx2_3] <= x[bad[ib]]+xzero <  x2[xinx3_2+1]
480                  xinx2_3 = value_locate(x2, x[bad[ib]]+xzero)
481                  IF xinx2_3 ge xinx2_1[ib]+1 THEN BEGIN
482                    y2[xinx2_1[ib]+1:xinx2_3] $
483                      = pure_convex(x[bad[ib]], x[bad[ib]]+xzero  $
484                                    , y[bad[ib]], yzero   $
485                                    , yifrst[bad[ib]] $
486                                    , x2[xinx2_1[ib]+1:xinx2_3])
487                  ENDIF
488                END
489                ELSE:BEGIN
490convexconcave:
491; define xinx2_3: see help of value_locate
492;  if xinx2_3[ib] eq -1   :                x[bad[ib]]+xzero <  x2[0]
493;  if xinx2_3[ib] eq nx2-1:                x[bad[ib]]+xzero >= x2[nx2-1]
494;  else                   : x2[xinx2_3] <= x[bad[ib]]+xzero <  x2[xinx3_2+1]
495                  xinx2_3 = value_locate(x2, x[bad[ib]]+xinfl)
496
497                  IF xinx2_3 ge xinx2_1[ib]+1 THEN BEGIN
498                    y2[xinx2_1[ib]+1:xinx2_3] $
499                      = pure_convex(x[bad[ib]], x[bad[ib]]+xinfl  $
500                                    , y[bad[ib]], yinfl  $
501                                    , yifrst[bad[ib]] $
502                                    , x2[xinx2_1[ib]+1:xinx2_3])
503
504                  ENDIF
505                  IF xinx2_2[ib] GE xinx2_3+1 THEN BEGIN
506                    y2[xinx2_3+1:xinx2_2[ib]] $
507                      = pure_concave(x[bad[ib]]+xinfl, x[bad[ib]+1] $
508                                     , yinfl, y[bad[ib]+1] $
509                                     , yifrst[bad[ib]+1] $
510                                     , x2[xinx2_3+1:xinx2_2[ib]])
511                  ENDIF
512                END
513              ENDCASE
514
515            END
516          ENDCASE
517        ENDIF
518      ENDFOR
519
520    ENDIF
521  ENDIF
522;
523  RETURN, y2
524;
525END
Note: See TracBrowser for help on using the repository browser.