[kde-doc-english] [labplot] /: added Legendre filter form
Stefan Gerlach
stefan.gerlach at uni-konstanz.de
Thu Jul 14 22:49:05 UTC 2016
Git commit ce3146c34bd53923c850fcaf62412adfeb5d802a by Stefan Gerlach.
Committed on 14/07/2016 at 22:48.
Pushed by sgerlach into branch 'master'.
added Legendre filter form
M +1 -1 ChangeLog
M +2 -1 doc/index.docbook
M +35 -3 src/backend/nsl/nsl_filter.c
M +2 -2 src/backend/nsl/nsl_filter.h
M +21 -5 src/backend/nsl/nsl_filter_test.c
M +1 -0 src/kdefrontend/dockwidgets/XYFourierFilterCurveDock.cpp
http://commits.kde.org/labplot/ce3146c34bd53923c850fcaf62412adfeb5d802a
diff --git a/ChangeLog b/ChangeLog
index fb7db99..a59a3a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,7 +5,7 @@ New features:
* Export of spreadsheets and matrices to LaTeX tables
* Interpolation of data including different splines, cosine, exponential, cubic Hermite (Catmull-Rom, cardinal, Kochanek-Bartels) and rational functions
* Data smoothing using moving average (centered or lagged), percentile filter or Savitzky-Golay algorithm
- * Fourier filter (low pass, high pass, band pass, band reject) with ideal, Butterworth or Chebychev I+II kernel
+ * Fourier filter (low pass, high pass, band pass, band reject) with ideal, Butterworth, Chebychev I+II or Legendre filter
* Fourier transform with many window functions (Welch, Hann, Hamming, etc.) calculating magnitude, amplitude, power, phase, dB, etc. and supporting
one/two sided spectrum with or without shift and x scaling to frequency, index or period
* Filter and search capabilities in the drop down box for the selection of data sources
diff --git a/doc/index.docbook b/doc/index.docbook
index 5585285..bef5754 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -860,7 +860,7 @@ The menu is only available when a datapicker object is selected on the <guilabel
<listitem><para>Low pass</para></listitem>
<listitem><para>High pass</para></listitem>
<listitem><para>Band pass</para></listitem>
- <listitem><para>Band reject (Band block)</para></listitem>
+ <listitem><para>Band reject (band block)</para></listitem>
</itemizedlist>
<para>
where any of them can have the form
@@ -869,6 +869,7 @@ The menu is only available when a datapicker object is selected on the <guilabel
<listitem><para>Ideal</para></listitem>
<listitem><para>Butterworth (order 1 to 10)</para></listitem>
<listitem><para>Chebyshev type I or II (order 1 to 10)</para></listitem>
+ <listitem><para>Optimal Legendre (order 1 to 10)</para></listitem>
</itemizedlist>
<para>
The cutoff value(s) can be specified in the units frequency (Hertz), fraction (0.0 to 1.0) or index
diff --git a/src/backend/nsl/nsl_filter.c b/src/backend/nsl/nsl_filter.c
index c669614..58d6c2d 100644
--- a/src/backend/nsl/nsl_filter.c
+++ b/src/backend/nsl/nsl_filter.c
@@ -62,21 +62,28 @@ int nsl_filter_apply(double data[], size_t n, nsl_filter_type type, nsl_filter_f
break;
case nsl_filter_form_butterworth:
for (i = 0; i < n/2+1; i++) {
- factor = 1./sqrt(1.+gsl_sf_pow_int(i/cutindex, 2*order));
+ factor = 1./sqrt(1. + gsl_sf_pow_int(i/cutindex, 2*order));
data[2*i] *= factor;
data[2*i+1] *= factor;
}
break;
case nsl_filter_form_chebyshev_i:
for (i = 0; i < n/2+1; i++) {
- factor = 1./sqrt(1.+gsl_sf_pow_int(nsl_sf_poly_chebyshev_T(order, i/cutindex), 2));
+ factor = 1./sqrt(1. + gsl_sf_pow_int(nsl_sf_poly_chebyshev_T(order, i/cutindex), 2));
data[2*i] *= factor;
data[2*i+1] *= factor;
}
break;
case nsl_filter_form_chebyshev_ii:
for (i = 1; i < n/2+1; i++) { /* i==0: factor=1 */
- factor = 1./sqrt(1.+1./gsl_sf_pow_int(nsl_sf_poly_chebyshev_T(order, cutindex/i), 2));
+ factor = 1./sqrt(1. + 1./gsl_sf_pow_int(nsl_sf_poly_chebyshev_T(order, cutindex/i), 2));
+ data[2*i] *= factor;
+ data[2*i+1] *= factor;
+ }
+ break;
+ case nsl_filter_form_legendre:
+ for (i = 0; i < n/2+1; i++) {
+ factor = 1./sqrt(1. + nsl_sf_poly_optimal_legendre(order, i*i/(cutindex*cutindex) ));
data[2*i] *= factor;
data[2*i+1] *= factor;
}
@@ -112,6 +119,14 @@ int nsl_filter_apply(double data[], size_t n, nsl_filter_type type, nsl_filter_f
data[2*i+1] *= factor;
}
break;
+ case nsl_filter_form_legendre:
+ data[0]=data[1]=0;
+ for (i = 1; i < n/2+1; i++) {
+ factor = 1./sqrt(1. + nsl_sf_poly_optimal_legendre(order, cutindex*cutindex/(i*i) ));
+ data[2*i] *= factor;
+ data[2*i+1] *= factor;
+ }
+ break;
}
break;
case nsl_filter_type_band_pass:
@@ -145,6 +160,15 @@ int nsl_filter_apply(double data[], size_t n, nsl_filter_type type, nsl_filter_f
data[2*i+1] *= factor;
}
break;
+ case nsl_filter_form_legendre:
+ data[0]=data[1]=0;
+ for (i = 1; i < n/2+1; i++) {
+ factor = 1./sqrt(1. + nsl_sf_poly_optimal_legendre(order,
+ (i*i-2.*centerindex*centerindex+gsl_pow_4(centerindex)/(i*i))/gsl_pow_2(bandwidth) ));
+ data[2*i] *= factor;
+ data[2*i+1] *= factor;
+ }
+ break;
}
break;
case nsl_filter_type_band_reject:
@@ -174,6 +198,14 @@ int nsl_filter_apply(double data[], size_t n, nsl_filter_type type, nsl_filter_f
data[2*i+1] *= factor;
}
break;
+ case nsl_filter_form_legendre:
+ for (i = 0; i < n/2+1; i++) {
+ factor = 1./sqrt(1. + nsl_sf_poly_optimal_legendre(order,
+ gsl_pow_2(i*bandwidth)/gsl_pow_2(i*i-centerindex*centerindex) ));
+ data[2*i] *= factor;
+ data[2*i+1] *= factor;
+ }
+ break;
}
break;
}
diff --git a/src/backend/nsl/nsl_filter.h b/src/backend/nsl/nsl_filter.h
index be97f88..2732093 100644
--- a/src/backend/nsl/nsl_filter.h
+++ b/src/backend/nsl/nsl_filter.h
@@ -35,9 +35,9 @@
typedef enum {nsl_filter_type_low_pass, nsl_filter_type_high_pass, nsl_filter_type_band_pass,
nsl_filter_type_band_reject} nsl_filter_type; /*TODO: Threshold */
extern const char* nsl_filter_type_name[];
-#define NSL_FILTER_FORM_COUNT 4
+#define NSL_FILTER_FORM_COUNT 5
typedef enum {nsl_filter_form_ideal, nsl_filter_form_butterworth, nsl_filter_form_chebyshev_i,
- nsl_filter_form_chebyshev_ii} nsl_filter_form; /*TODO: Gaussian, Bessel, ... */
+ nsl_filter_form_chebyshev_ii, nsl_filter_form_legendre} nsl_filter_form; /*TODO: Gaussian, Bessel, ... */
extern const char* nsl_filter_form_name[];
/* unit for cutoff
Frequency=0..f_max, Fraction=0..1, Index=0..N-1
diff --git a/src/backend/nsl/nsl_filter_test.c b/src/backend/nsl/nsl_filter_test.c
index 492a54d..f891488 100644
--- a/src/backend/nsl/nsl_filter_test.c
+++ b/src/backend/nsl/nsl_filter_test.c
@@ -37,14 +37,30 @@ print_data(double data[], int n) {
}
int main() {
- double data[]={1, 2, 3, 3, 1, -1, 0, 1, 1, 0};
+ /* double data[]={1, 2, 3, 3, 1, -1, 0, 1, 1, 0}; */
/*double data[]={1, 1, 3, 3, 1, -1, 0, 1, 1};*/
/*double data[]={1, 2, 3, 3, 1};*/
- const int N=10;
+ const int N=1002;
/*const int N=9;*/
+ double data[N];
- print_data(data, N);
- nsl_filter_fourier(data, N, nsl_filter_type_high_pass, nsl_filter_form_ideal, 0, 0, 2);
+ int i;
+ for(i=0;i<N;i++)
+ data[i]=1.0;
+
+ /* filter form */
+ /*nsl_filter_apply(data, N, nsl_filter_type_low_pass, nsl_filter_form_legendre, 2, 50, 2);*/
+ /*nsl_filter_apply(data, N, nsl_filter_type_high_pass, nsl_filter_form_legendre, 2, 50, 2);*/
+ /*nsl_filter_apply(data, N, nsl_filter_type_band_pass, nsl_filter_form_legendre, 2, 100, 50);*/
+ nsl_filter_apply(data, N, nsl_filter_type_band_reject, nsl_filter_form_legendre, 2, 100, 100);
+ for(i=0; i < N/2; i++)
+ printf("%d %g\n", i, data[2*i]);
+
+ /*print_data(data, N);*/
+ /* all pass order,cut,bw */
+ /*nsl_filter_fourier(data, N, nsl_filter_type_high_pass, nsl_filter_form_ideal, 0, 0, 2); */
+
+ /* filter tests */
/*nsl_filter_fourier(data, N, nsl_filter_type_low_pass, nsl_filter_form_ideal, 0, 3, 2);*/
/*nsl_filter_fourier(data, N, nsl_filter_type_high_pass, nsl_filter_form_ideal, 0, 3, 2);*/
/*nsl_filter_fourier(data, N, nsl_filter_type_band_pass, nsl_filter_form_ideal, 0, 2, 2);*/
@@ -52,7 +68,7 @@ int main() {
/*nsl_filter_fourier(data, N, nsl_filter_type_low_pass, nsl_filter_form_butterworth, 1, 2, 2);*/
/*nsl_filter_fourier(data, N, nsl_filter_type_high_pass, nsl_filter_form_butterworth, 1, 2, 2);*/
/*nsl_filter_fourier(data, N, nsl_filter_type_band_pass, nsl_filter_form_butterworth, 2, 2, 2);*/
- print_data(data, N);
+ /*print_data(data, N);*/
return 0;
}
diff --git a/src/kdefrontend/dockwidgets/XYFourierFilterCurveDock.cpp b/src/kdefrontend/dockwidgets/XYFourierFilterCurveDock.cpp
index d17e322..b6f8ef9 100644
--- a/src/kdefrontend/dockwidgets/XYFourierFilterCurveDock.cpp
+++ b/src/kdefrontend/dockwidgets/XYFourierFilterCurveDock.cpp
@@ -299,6 +299,7 @@ void XYFourierFilterCurveDock::formChanged() {
case nsl_filter_form_butterworth:
case nsl_filter_form_chebyshev_i:
case nsl_filter_form_chebyshev_ii:
+ case nsl_filter_form_legendre:
uiGeneralTab.sbOrder->setVisible(true);
uiGeneralTab.lOrder->setVisible(true);
break;
More information about the kde-doc-english
mailing list