|
Packit |
67cb25 |
/* filter/test_impulse.c
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* Copyright (C) 2018 Patrick Alken
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
67cb25 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
67cb25 |
* the Free Software Foundation; either version 3 of the License, or (at
|
|
Packit |
67cb25 |
* your option) any later version.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
67cb25 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
67cb25 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
67cb25 |
* General Public License for more details.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
67cb25 |
* along with this program; if not, write to the Free Software
|
|
Packit |
67cb25 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#include <gsl/gsl_math.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_vector.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_filter.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_movstat.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_test.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_rng.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_randist.h>
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static int
|
|
Packit |
67cb25 |
vector_sum(const gsl_vector_int * v)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
int sum = 0;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < v->size; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int vi = gsl_vector_int_get(v, i);
|
|
Packit |
67cb25 |
sum += vi;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return sum;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_impulse_proc(const double tol, const size_t n, const size_t K, const double nsigma,
|
|
Packit |
67cb25 |
const gsl_filter_end_t etype, const gsl_filter_scale_t stype,
|
|
Packit |
67cb25 |
const double outlier_percentage, gsl_rng * r)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_vector * x = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector * y = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector * z = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector * y_med = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector * xmedian = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector * xsigma = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
size_t noutlier;
|
|
Packit |
67cb25 |
gsl_vector_int * ioutlier = gsl_vector_int_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector_int * ioutlier_exact = gsl_vector_int_alloc(n);
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
gsl_filter_impulse_workspace *impulse_p = gsl_filter_impulse_alloc(K);
|
|
Packit |
67cb25 |
gsl_filter_median_workspace *median_p = gsl_filter_median_alloc(K);
|
|
Packit |
67cb25 |
size_t noutlier_exact = 0;
|
|
Packit |
67cb25 |
char buf[1024];
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_int_set_zero(ioutlier_exact);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < n; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double xi = gsl_ran_gaussian(r, 1.0);
|
|
Packit |
67cb25 |
double vi = gsl_rng_uniform(r);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (vi <= outlier_percentage)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
xi += 15.0 * GSL_SIGN(xi);
|
|
Packit |
67cb25 |
++noutlier_exact;
|
|
Packit |
67cb25 |
gsl_vector_int_set(ioutlier_exact, i, 1);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set(x, i, xi);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* first test that median filter is equal to impulse filter with nsigma = 0 */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_filter_median(etype, x, y_med, median_p);
|
|
Packit |
67cb25 |
gsl_filter_impulse(etype, stype, 0.0, x, y, xmedian, xsigma, &noutlier, ioutlier, impulse_p);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
sprintf(buf, "impulse nsigma=0 smf comparison, etype=%u stype=%u", etype, stype);
|
|
Packit |
67cb25 |
compare_vectors(tol, y, y_med, buf);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* second test: filter y = impulse(x) with given nsigma */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_filter_impulse(etype, stype, nsigma, x, y, xmedian, xsigma, &noutlier, ioutlier, impulse_p);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* test correct number of outliers detected */
|
|
Packit |
67cb25 |
gsl_test(noutlier != noutlier_exact, "impulse [n=%zu,K=%zu,nsigma=%g,outlier_percentage=%g] noutlier=%zu exact=%zu",
|
|
Packit |
67cb25 |
n, K, nsigma, outlier_percentage, noutlier, noutlier_exact);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#if 0
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
for (i = 0; i < n; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
printf("%.12e %.12e %d %.12e %.12e\n",
|
|
Packit |
67cb25 |
gsl_vector_get(x, i),
|
|
Packit |
67cb25 |
gsl_vector_get(y, i),
|
|
Packit |
67cb25 |
gsl_vector_int_get(ioutlier, i),
|
|
Packit |
67cb25 |
gsl_vector_get(xmedian, i) + nsigma * gsl_vector_get(xsigma, i),
|
|
Packit |
67cb25 |
gsl_vector_get(xmedian, i) - nsigma * gsl_vector_get(xsigma, i));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
#endif
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* test outliers found in correct locations */
|
|
Packit |
67cb25 |
for (i = 0; i < n; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int val = gsl_vector_int_get(ioutlier, i);
|
|
Packit |
67cb25 |
int val_exact = gsl_vector_int_get(ioutlier_exact, i);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test(val != val_exact, "test_impulse: outlier mismatch [i=%zu,K=%zu,nsigma=%g,outlier_percentage=%g] ioutlier=%d ioutlier_exact=%d",
|
|
Packit |
67cb25 |
i, K, nsigma, outlier_percentage, val, val_exact);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* test noutlier = sum(ioutlier) */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t iout_sum = vector_sum(ioutlier);
|
|
Packit |
67cb25 |
gsl_test(noutlier != iout_sum, "impulse [K=%zu,nsigma=%g,outlier_percentage=%g] noutlier=%zu sum(ioutlier)=%zu",
|
|
Packit |
67cb25 |
K, nsigma, outlier_percentage, noutlier, iout_sum);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* third test: test in-place filter z = impulse(z) */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_memcpy(z, x);
|
|
Packit |
67cb25 |
gsl_filter_impulse(etype, stype, nsigma, z, z, xmedian, xsigma, &noutlier, ioutlier, impulse_p);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
sprintf(buf, "impulse in-place nsigma=%g,n=%zu,K=%zu,etype=%u stype=%u", nsigma, n, K, etype, stype);
|
|
Packit |
67cb25 |
compare_vectors(GSL_DBL_EPSILON, z, y, buf);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_free(x);
|
|
Packit |
67cb25 |
gsl_vector_free(y);
|
|
Packit |
67cb25 |
gsl_vector_free(z);
|
|
Packit |
67cb25 |
gsl_vector_free(y_med);
|
|
Packit |
67cb25 |
gsl_vector_free(xmedian);
|
|
Packit |
67cb25 |
gsl_vector_free(xsigma);
|
|
Packit |
67cb25 |
gsl_vector_int_free(ioutlier);
|
|
Packit |
67cb25 |
gsl_vector_int_free(ioutlier_exact);
|
|
Packit |
67cb25 |
gsl_filter_impulse_free(impulse_p);
|
|
Packit |
67cb25 |
gsl_filter_median_free(median_p);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_impulse(gsl_rng * r)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const double tol = 1.0e-10;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
test_impulse_proc(tol, 1000, 21, 6.0, GSL_FILTER_END_TRUNCATE, GSL_FILTER_SCALE_QN, 0.05, r);
|
|
Packit |
67cb25 |
test_impulse_proc(tol, 1000, 21, 6.0, GSL_FILTER_END_TRUNCATE, GSL_FILTER_SCALE_SN, 0.05, r);
|
|
Packit |
67cb25 |
test_impulse_proc(tol, 1000, 21, 6.0, GSL_FILTER_END_TRUNCATE, GSL_FILTER_SCALE_MAD, 0.05, r);
|
|
Packit |
67cb25 |
test_impulse_proc(tol, 1000, 21, 6.0, GSL_FILTER_END_TRUNCATE, GSL_FILTER_SCALE_IQR, 0.05, r);
|
|
Packit |
67cb25 |
}
|