Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

smooth.f

Go to the documentation of this file.
00001 
00002 c
00003 c       Copyright (c) 1986,1987,1988,1989,1990,1991,1992,1993,
00004 c       by Steve McMillan, Drexel University, Philadelphia, PA.
00005 c
00006 c       All rights reserved.
00007 c
00008 c       Redistribution and use in source and binary forms are permitted
00009 c       provided that the above copyright notice and this paragraph are
00010 c       duplicated in all such forms and that any documentation,
00011 c       advertising materials, and other materials related to such
00012 c       distribution and use acknowledge that the software was developed
00013 c       by the author named above.
00014 c
00015 c       THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00016 c       IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00017 c       WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00018 c
00019 
00020         subroutine smooth(t,x,xsmooth,n,dts,iopt,iw)
00021         save
00022 c
00023 c       Smooth the input data, using one of a variety of methods.
00024 c
00025 c       Options:
00026 c
00027 c           iopt = 0:  median
00028 c                  1:  arithmetic mean
00029 c                  2:  harmonic mean
00030 c                  3:  geometric mean
00031 c                  11: clipped arithmetic mean
00032 c                  12: clipped harmonic mean
00033 c                  13: clipped geometric mean
00034 c
00035 c           iwindow = 0:  flat window
00036 c                     1:  triangular window
00037 c      
00038         parameter (NMAX = 10000, FCLIP = 0.1)
00039 c
00040         dimension t(1),x(1),xsmooth(1),work(NMAX),tt(NMAX)
00041 c
00042         external comp
00043 c
00044 c       Smooth the input data over a window of width dts.
00045 c       Brute-force approach recalculates the sum at each data point!
00046 c
00047 c       Window function:
00048 c
00049         window(xx) = max(0., 1. - iwindow*abs(xx/dt2))
00050 c
00051         if (dts.le.0.) return
00052         iwindow = iw
00053         if (iwindow.ne.0) iwindow = 1
00054         dt2 = .5*dts
00055 c
00056         if (iopt.gt.0.and.iopt.le.10.and.iwindow.eq.0) then
00057 c
00058 c           Flat window, straight average only:
00059 c
00060             sum = 0.
00061             ns = 0
00062             j0 = 1
00063             j1 = 0
00064 c
00065             do 190 i=1,n
00066 c
00067 120             continue
00068 c
00069 c               if (j1.lt.n
00070 c     &                  .and.t(j1+1).le.t(i)+min(dt2,t(i)-t(1))) then
00071 c
00072                 if (j1.lt.n.and.t(j1+1).le.t(i)+dt2) then
00073                     j1 = j1 + 1
00074                     sum = sum + f(x(j1),iopt)
00075                     ns = ns + 1
00076                     go to 120
00077                 end if
00078 c
00079 130             continue
00080 c               if (t(j0).lt.t(i)-min(dt2,t(n)-t(i))) then
00081                 if (t(j0).lt.t(i)-dt2) then
00082                     sum = sum - f(x(j0),iopt)
00083                     ns = ns - 1
00084                     j0 = j0 + 1
00085                     go to 130
00086                 end if
00087 c
00088                 xsmooth(i) = finv(sum/max(ns,1),iopt)
00089 c
00090 190         continue
00091         else
00092 c
00093 c           All other options:
00094 c
00095             j0 = 1
00096             j1 = 0
00097 c
00098 c           Locate the range containing the desired interval.
00099 c
00100             do 290 i=1,n
00101 c
00102 220             if (j1.lt.n
00103      &                  .and.t(j1+1).le.t(i)+min(dt2,t(i)-t(1))) then
00104                     j1 = j1 + 1
00105                     go to 220
00106                 end if
00107 c
00108 230             if (t(j0).lt.t(i)-min(dt2,t(n)-t(i))) then
00109                     j0 = j0 + 1
00110                     go to 230
00111                 end if
00112 c
00113 c               Range is j0 to j1.
00114 c
00115                 do 240 j=j0,j1
00116                     work(j-j0+1) = x(j)
00117                     tt(j-j0+1) = t(j)
00118 240             continue
00119                 nw = j1-j0+1
00120 c
00121                 if (iopt.eq.0.or.iopt.gt.10) then
00122 c
00123 c                   Sort the data.
00124 c
00125                     if (nw.gt.1) call sort2(nw,work,tt)
00126 c
00127                     if (iopt.eq.0) then
00128 c
00129 c                       Interpolate to the median.
00130 c
00131                         xj = .5*(nw+1)
00132                         jj = xj
00133                         xsmooth(i) = work(jj)
00134      &                               + (xj-jj)*(work(jj+1) - work(jj))
00135                     else
00136 c
00137 c                       Clip the data.
00138 c
00139                         xj1 = FCLIP*(nw+1)
00140                         jj1 = max(1,nint(xj1))
00141                         xj2 = (1.-FCLIP)*(nw+1)
00142                         jj2 = min(nw,nint(xj2))
00143 c
00144 c                       New range is jj1 to jj2.
00145 c
00146                         do 250 j=jj1,jj2
00147                             work(j-jj1+1) = work(j)
00148                             tt(j-jj1+1) = tt(j)
00149 250                     continue
00150                         nw = jj2-jj1+1
00151                     end if
00152                 end if
00153 c
00154                 if (iopt.gt.0) then
00155 c
00156 c                   Perform averaging on the work data.
00157 c
00158                     sum = 0.
00159                     wsum = 0.
00160 c
00161                     do 260 j=1,nw
00162                         weight = window(tt(j)-t(i))
00163                         wsum = wsum + weight
00164                         sum = sum + weight*f(work(j),iopt)
00165 260                 continue
00166 c
00167                     if (wsum.gt.0.) then
00168                         xsmooth(i) = finv(sum/wsum,iopt)
00169                     else
00170                         xsmooth(i) = x(i)
00171                     end if
00172                 else
00173                 end if
00174 c
00175 290         continue
00176         end if
00177 c
00178         end
00179 
00180 
00181 
00182         function f(x,iopt)
00183         save
00184 c
00185         if (iopt.eq.1.or.iopt.eq.11) then
00186             f = x
00187         else if (iopt.eq.2.or.iopt.eq.12) then
00188             if (x.ne.0.) then
00189                 f = 1./x
00190             else
00191                 f = 0.
00192             end if
00193         else if (iopt.eq.3.or.iopt.eq.13) then
00194             if (x.gt.1.e-20) then
00195                 f = log(x)
00196             else
00197                 f = -46.05
00198             end if
00199         end if
00200 c
00201         end
00202 
00203 
00204 
00205         function finv(x,iopt)
00206         save
00207 c
00208 c       Compute the inverse function to f above.
00209 c
00210         if (iopt.eq.1.or.iopt.eq.11) then
00211             finv = x
00212         else if (iopt.eq.2.or.iopt.eq.12) then
00213             if (x.ne.0.) then
00214                 finv = 1./x
00215             else
00216                 finv = 0.
00217             end if
00218         else if (iopt.eq.3.or.iopt.eq.13) then
00219             if (x.gt.-46.05) then
00220                 finv = exp(x)
00221             else
00222                 finv = 1.e-20
00223             end if
00224         end if
00225 c
00226         end
00227 
00228 
00229 
00230         integer*2 function comp(x,y)
00231         save
00232 c
00233 c       Comparison function for use with qsort.
00234 c
00235         if (x.gt.y) then
00236             comp = 1
00237         else if (x.lt.y) then
00238             comp = -1
00239         else
00240             comp = 0
00241         end if
00242 c
00243         end

Generated at Sun Feb 24 09:57:16 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001