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
RevLine 
[69]1;+
2;
[101]3; @file_comments
[69]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
[238]7; spl_incr function returns an interpolated value for the given values
[69]8; of X2. The interpolation method is based on cubic spline, corrected
9; in a way that interpolated values are also monotonically increasing.
10;
[125]11; @param x1 {in}{required}
12; An n-element (at least 2) input vector that specifies the tabulate points in
[118]13; a strict ascending order.
[69]14;
[125]15; @param y1 {in}{required}
[118]16; f(x) = y. An n-element input vector that specifies the values
[136]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.
[69]20;
[125]21; @param x2 {in}{required}
[118]22; The input values for which the interpolated values are
[125]23; desired. Its values must be strictly monotonically increasing.
[69]24;
[118]25; @param der2
[136]26;
[125]27; @param x
[69]28;
[125]29; @returns
[69]30;
31;    y2: f(x2) = y2. Double precision array
32;
[101]33; @restrictions
[136]34; It might be possible that y2[i+1]-y2[i] has very small negative
35; values (amplitude smaller than 1.e-6)...
[69]36;
[125]37; @examples
[69]38;
[118]39; IDL> n = 100L
[125]40; IDL> x = (dindgen(n))^2
[118]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]
[125]53; IDL> print, min(c) LT 0
[118]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
[69]57;
[101]58; @history
59;  Sebastien Masson (smasson\@lodyc.jussieu.fr): May-Dec 2005
[118]60;
[231]61; @version
62; $Id$
[118]63;
[69]64;-
[231]65;
[69]66FUNCTION pure_concave, x1, x2, y1, y2, der2, x
[114]67;
68  compile_opt idl2, strictarrsubs
69;
[238]70; X^n type
71;
[69]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
[238]85;
[118]86;+
[238]87;
[125]88; @param x1 {in}{required}
89; An n-element (at least 2) input vector that specifies the tabulate points in
[118]90; a strict ascending order.
91;
[125]92; @param y1 {in}{required}
[118]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;
[125]98; @param x2 {in}{required}
[118]99; The input values for which the interpolated values are
[125]100; desired. Its values must be strictly monotonically increasing.
[118]101;
102; @param der2
[125]103; @param x
[118]104;
105;-
[238]106;
[69]107FUNCTION pure_convex, x1, x2, y1, y2, der2, x
[114]108;
109  compile_opt idl2, strictarrsubs
110;
[238]111; 1-(1-X)^n type
112;
[69]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
[238]127;
[101]128;+
[238]129;
[118]130; @param x
131; @param y
132; @param x2
[238]133; @keyword YP0
134; The first derivative of the interpolating function at the
[101]135;    point X0. If YP0 is omitted, the second derivative at the
136;    boundary is set to zero, resulting in a "natural spline."
[238]137; @keyword YPN_1
138; The first derivative of the interpolating function at the
[101]139;    point Xn-1. If YPN_1 is omitted, the second derivative at the
[125]140;    boundary is set to zero, resulting in a "natural spline."
[101]141;-
[238]142;
[69]143FUNCTION spl_incr, x, y, x2, YP0 = yp0, YPN_1 = ypn_1
144;
[114]145  compile_opt idl2, strictarrsubs
146;
[69]147;---------------------------------
[163]148; check and initialization ...
[69]149;---------------------------------
[114]150;
[69]151  nx = n_elements(x)
152  ny = n_elements(y)
153  nx2 = n_elements(x2)
154; x must have at least 2 elements
[125]155  IF nx LT 2 THEN stop
[69]156; y must have the same number of elements than x
157  IF nx NE ny THEN stop
158; x be monotonically increasing
[125]159  IF min(x[1:nx-1]-x[0:nx-2]) LE 0 THEN stop
[69]160; x2 be monotonically increasing
161  IF N_ELEMENTS(X2) GE 2 THEN $
[125]162  IF min(x2[1:nx2-1]-x2[0:nx2-2])  LE 0 THEN stop
[69]163; y be monotonically increasing
[125]164  IF min(y[1:ny-1]-y[0:ny-2]) LT 0 THEN stop
[69]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;
[125]179; left side ... if there is x2 values smaller that x[bad[0]].
[69]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]
[125]185      ENDIF ELSE BEGIN
[69]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)
[125]189      ENDELSE
190    ENDIF
[69]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
[125]213; right side ... if there is x2 values larger that x[bad[cntbad-1]+1].
[69]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:
[125]244; if the first derivative of the last value of x is negative
[69]245; we define the new values of the keyword ypn_1 to 0.0d0
[125]246    IF bad[cntbad-1] EQ nx-1 THEN BEGIN
[69]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:
[125]255; if the first derivative of the first value of x is negative
[69]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
[125]272; for each of this n spl_incr
[69]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)
[125]280; left side ... if there is x2 values smaller that x[bad[0]].
[69]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
[125]287; more than 2 pieces -> we have middle pieces for which
[69]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
[125]302; right side ... if there is x2 values larger that x[bad[cntbad-1]].
[69]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)
[125]309    ENDELSE
[69]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)
[125]313; ;        IF cnt NE 0 THEN y2[same] = y[i]
[69]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
[125]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)
[69]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
[125]328; where we know that the first derivative can be negative.
[69]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
[125]337;    d = y[i]; c = y'[i]; b = 0.5 * y''[i],
[69]338;    a = 1/6 * (y''[i+1]-y''[i])/(x[i+1]-x[i])
[125]339;
[69]340; y'[i] and y'[i+1] are positive so y' can be negative
[125]341; between x[i] and x[i+1] only if
[69]342;   1) a > 0
343;            ==> y''[i+1] > y''[i]
[125]344;   2) y' reach its minimum value between  x[i] and x[i+1]
345;      -> 0 < - b/(3a) < x[i+1]-x[i]
[69]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
[125]419; first derivative that correspond to the inflection point of y
[69]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]
[125]424;
[69]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]])
[125]457                  ENDIF
[69]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])
[125]487                  ENDIF
[69]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])
[125]503
504                  ENDIF
[69]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]])
[125]511                  ENDIF
[69]512                END
513              ENDCASE
514
[125]515            END
[69]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.