View Raw SPL
/*****************************************************************************
* *
* AVGFILT.SPL Copyright (C) 1999 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Filters data by using the average of neighbors *
* *
* Revisions: 16 Jun 1999 RRR Creation *
* *
*****************************************************************************/
#include
#if @HELP_AVGFILT
AVGFILT
Purpose: Filters a series using the average of the N neighboring points
Syntax: AVGFILT(s, n, gval, lval)
s - input series or array
n - an optional integer, the number of neighbors to average.
For point i, average points i-n through i+n exclusive of
point i. Defaults to 1, i.e. for point i, average points
i-1 and i+1
gval - optional real, the "greater than" threshold at which to
replace a point. Point i is replaced if:
point[i] > gval * current average[i]
Defaults to 1.0, i.e. replace each point if it is greater
than the average of the neighbors.
lval - optional real, the "less than" threshold at which to
replace a point. Point i is replaced if:
point[i] < lval * current average[i]
Defaults to unspecified, i.e. do not use a "lesser than"
threshold.
Returns: A series
Example:
W1: gnorm(100,.01)
W2: avgfilt(w1)
Replaces each point of w1 with average of the previous and next
point if it exceeeds the average.
W3: avgfilt(w1, 2)
Replaces each point of w1 with average of the two previous and
two next points if it exceeeds the average.
W3: avgfilt(w1, 1, 1.2)
Replaces each point of w1 with average of the previous and next
point if it exceeds the average by 20%.
W4: avgfilt(w1, 1, 1.2, 1.3)
Replaces each point of w1 with average of the previous and next
point if it exceeds the average by 20% or is less than the
average by 30%.
W5: avgfilt(w1, 1, 0, 0)
Replaces each point of w1 with average of the previous and next
point unconditionally.
W6: -avgfilt(-w1, 1, 1.2)
Replaces each point of w1 with average of the previous and next
point if it is less than the average by 20%.
Remarks:
AVGFILT uses the convolution function to calculate the
neighbor averages. For n == 1, the kernal is simply
{1, 0, 1} / 2
See Also:
Conv
#endif
avgfilt(s, n, gval, lval)
{
local k, r, avg, outlier, usemin = FALSE;
/* check input args */
if (argc < 4)
{
if (argc < 3)
{
if (argc < 2)
{
if (argc < 1)
{
error("avgfilt - input series required");
}
/* average previous and next neighbor */
n = 1;
}
gval = 1.0;
}
}
else
{
/* we have lval */
usemin = TRUE;
}
if (n <= 0) error("avgfilt - n must be > 0");
/* make sure n is an integer */
n = castint(n);
/* build convolution kernal, size: 2n+1 by numcols(s) */
k = {ones(n, numcols(s)), zeros(1, numcols(s)), ones(n, numcols(s))};
/* set attributes to input series */
setdeltax(k, deltax(s));
setxoffset(k, xoffset(s));
/* perform convolution to get neighbor averages */
avg = conv(s, k) / (2 * n);
/* align with data - remove first 2*n points */
avg = extract(avg, 2 * n, length(s));
/* get "greater than" outliers */
outlier = s > (gval * avg);
if (usemin)
{
/* add in "lesser than" outliers */
outlier += s < (lval * avg);
}
/* replace outliers with avg */
r = s * not(outlier) + avg * outlier;
return(r);
}