source: trunk/SRC/Interpolation/spl_keep_mean.pro @ 238

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

improvements/corrections of some *.pro headers

  • Property svn:keywords set to Id
File size: 4.2 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 integral of the interpolated values is the same as the
10; integral of the input values. (-> for exemple to build daily data
11; from monthly mean and keep the monthly mean of the computed daily
12; data equa to the original values)
13;
14; @param x {in}{required}
15; An n-element (at least 2) input vector that specifies the tabulate points in
16; a strict ascending order.
17;
18; @param yin {in}{required}{type=array}
19; an array with one element less than x. y[i] represents the
20; mean value between x[i] and x[i+1]. if /GE0 is activated, y must
21; have positive values.
22;
23; @param x2 {in}{required}
24; The input values for which the interpolated values are desired.
25; Its values must be strictly monotonically increasing.
26;
27; @keyword GE0
28; to force that y2 is always GE than 0. In that case, y must also be GE than 0.
29;
30; @keyword YP0
31; The first derivative of the interpolating function at the
32; point X0. If YP0 is omitted, the second derivative at the
33; boundary is set to zero, resulting in a "natural spline."
34;
35; @keyword YPN_1
36; The first derivative of the interpolating function at the
37; point Xn-1. If YPN_1 is omitted, the second derivative at the
38; boundary is set to zero, resulting in a "natural spline."
39;
40; @returns
41; y2: the mean value between two consecutive values of x2. This
42; array has one element less than y2. y2 has double precision.
43;
44; @restrictions
45; It might be possible that y2 has very small negative values
46; (amplitude smaller than 1.e-6)...
47;
48; @examples
49;
50;    12 monthly values of precipitations into daily values:
51;
52; IDL> yr1 = 1990
53; IDL> yr2 = 1992
54; IDL> nyr = yr2-yr1+1
55; IDL> n1 = 12*nyr+1
56; IDL> x = julday(1+findgen(n1), replicate(1, n1) $
57; IDL>        , replicate(yr1, n1), fltarr(n1))
58; IDL> n2 = 365*nyr + total(leapyr(yr1+indgen(nyr))) + 1
59; IDL> x2 = julday(replicate(1, n2), 1+findgen(n2) $
60; IDL>            , replicate(yr1, n2), fltarr(n2))
61; IDL> y = abs(randomn(0, n1-1))
62; IDL> y2 = spl_keep_mean(x, y, x2, /ge0)
63
64; IDL> print, min(x, max = ma), ma
65; IDL> print, min(x2, max = ma), ma
66; IDL> print, vairdate([min(x, max = ma), ma])
67; IDL> print, total(y*(x[1:n1-1]-x[0:n1-2]))
68; IDL> print, total(y2*(x2[1:n2-1]-x2[0:n2-2]))
69;
70; @history
71;  Sebastien Masson (smasson\@lodyc.jussieu.fr): May 2005
72;
73; @version
74; $Id$
75;
76;-
77;
78FUNCTION spl_keep_mean, x, yin, x2, YP0 = yp0, YPN_1 = ypn_1, GE0 = ge0
79;
80  compile_opt idl2, strictarrsubs
81;
82;---------------------------------
83; check and initialization ...
84;---------------------------------
85;
86  nx = n_elements(x)
87  ny = n_elements(yin)
88  nx2 = n_elements(x2)
89; x must have at least 2 elements
90  IF nx LT 2 THEN stop
91; x2 must have at least 2 elements
92  IF nx2 LT 2 THEN stop
93; x be monotonically increasing
94  IF min(x[1:nx-1]-x[0:nx-2]) LE 0 THEN stop
95; x2 be monotonically increasing
96  IF min(x2[1:nx2-1]-x2[0:nx2-2])  LE 0 THEN stop
97;
98;---------------------------------
99; compute the integral of y
100;---------------------------------
101; if spl_keep_mean is called by the user (and not by itself) we must compute
102; the integral of y. yin must have one element less than x
103  IF nx NE ny+1 THEN stop
104  y = double(yin)*double(x[1:nx-1]-x[0:nx-2])
105  y = [0.0d, temporary(y)]
106  y = total(temporary(y), /cumulative, /double)
107;
108;---------------------------------
109; compute the "spline" interpolation
110;---------------------------------
111;
112  IF keyword_set(ge0) THEN BEGIN
113; if the want that the interpolated values are always >= 0, we must
114; have yin >= 0.0d
115    IF min(yin) LT 0 THEN stop
116; call spl_incr
117    y2 = spl_incr(x, temporary(y), x2, yp0 = yp0, ypn_1 = ypn_1)
118  ENDIF ELSE BEGIN
119    yscd = spl_init(x, y, yp0 = yp0, ypn_1 = ypn_1, /double)
120    y2 = spl_interp(x, y, temporary(yscd), x2, /double)
121  ENDELSE
122;                ;
123;---------------------------------
124; Compute the derivative of y
125;---------------------------------
126;
127  yfrst = (y2[1:nx2-1]-y2[0:nx2-2])/(x2[1:nx2-1]-x2[0:nx2-2])
128; it can happen that we have very small negative values (-1.e-6 for ex)
129;  yfrst = 0.0d > temporary(yfrst)
130  RETURN, yfrst
131;
132 END
Note: See TracBrowser for help on using the repository browser.