[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