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;
_______________________________________________
kde-doc-english mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/kde-doc-english

Reply via email to