File indexing completed on 2024-05-12 03:47:53

0001 /*
0002     File                 : nsl_sf_window.c
0003     Project              : LabPlot
0004     Description          : NSL special window functions
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2016-2017 Stefan Gerlach <stefan.gerlach@uni.kn>
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "nsl_sf_window.h"
0011 #include "nsl_common.h"
0012 #include <gsl/gsl_math.h>
0013 #include <gsl/gsl_sf_trig.h>
0014 
0015 const char* nsl_sf_window_type_name[] = {i18n("Rectangular (Uniform)"),
0016                                          i18n("Triangular"),
0017                                          i18n("Triangular II (Bartlett)"),
0018                                          i18n("Triangular III (Parzen)"),
0019                                          i18n("Welch (Parabolic)"),
0020                                          i18n("Hann (Raised Cosine)"),
0021                                          i18n("Hamming"),
0022                                          i18n("Blackman"),
0023                                          i18n("Nuttall"),
0024                                          i18n("Blackman-Nuttall"),
0025                                          i18n("Blackman-Harris"),
0026                                          i18n("Flat Top"),
0027                                          i18n("Cosine"),
0028                                          i18n("Bartlett-Hann"),
0029                                          i18n("Lanczos")};
0030 
0031 int nsl_sf_apply_window(double data[], size_t N, nsl_sf_window_type type) {
0032     if (N == 0)
0033         return -1;
0034 
0035     size_t i;
0036     switch (type) {
0037     case nsl_sf_window_uniform:
0038         /* do nothing */
0039         break;
0040     case nsl_sf_window_triangle:
0041         for (i = 0; i < N; i++)
0042             data[i] = 1.0 - 2. / N * fabs(i - (N - 1) / 2.);
0043         break;
0044     case nsl_sf_window_triangleII:
0045         for (i = 0; i < N; i++)
0046             data[i] = 1.0 - 2. / (N - 1) * fabs(i - (N - 1) / 2.);
0047         break;
0048     case nsl_sf_window_triangleIII:
0049         for (i = 0; i < N; i++)
0050             data[i] = 1.0 - 2. / (N + 1) * fabs(i - (N - 1) / 2.);
0051         break;
0052     case nsl_sf_window_welch:
0053         for (i = 0; i < N; i++)
0054             data[i] = 1.0 - gsl_pow_2(2 * (i - (N - 1) / 2.) / (N + 1));
0055         break;
0056     case nsl_sf_window_hann:
0057         for (i = 0; i < N; i++)
0058             data[i] = 0.5 * (1. - cos(2. * M_PI * i / (N - 1)));
0059         break;
0060     case nsl_sf_window_hamming:
0061         for (i = 0; i < N; i++)
0062             data[i] = 0.54 - 0.46 * cos(2. * M_PI * i / (N - 1));
0063         break;
0064     case nsl_sf_window_blackman:
0065         for (i = 0; i < N; i++)
0066             data[i] = 0.42 - 0.5 * cos(2. * M_PI * i / (N - 1)) + 0.08 * cos(4. * M_PI * i / (N - 1));
0067         break;
0068     case nsl_sf_window_nuttall:
0069         for (i = 0; i < N; i++)
0070             data[i] = 0.355768 - 0.487396 * cos(2. * M_PI * i / (N - 1)) + 0.144232 * cos(4. * M_PI * i / (N - 1)) - 0.012604 * cos(6. * M_PI * i / (N - 1));
0071         break;
0072     case nsl_sf_window_blackman_nuttall:
0073         for (i = 0; i < N; i++)
0074             data[i] =
0075                 0.3635819 - 0.4891775 * cos(2. * M_PI * i / (N - 1)) + 0.1365995 * cos(4. * M_PI * i / (N - 1)) - 0.0106411 * cos(6. * M_PI * i / (N - 1));
0076         break;
0077     case nsl_sf_window_blackman_harris:
0078         for (i = 0; i < N; i++)
0079             data[i] = 0.35875 - 0.48829 * cos(2. * M_PI * i / (N - 1)) + 0.14128 * cos(4. * M_PI * i / (N - 1)) - 0.01168 * cos(6. * M_PI * i / (N - 1));
0080         break;
0081     case nsl_sf_window_flat_top:
0082         for (i = 0; i < N; i++)
0083             data[i] = 1 - 1.93 * cos(2. * M_PI * i / (N - 1)) + 1.29 * cos(4. * M_PI * i / (N - 1)) - 0.388 * cos(6. * M_PI * i / (N - 1))
0084                 + 0.028 * cos(8. * M_PI * i / (N - 1));
0085         break;
0086     case nsl_sf_window_cosine:
0087         for (i = 0; i < N; i++)
0088             data[i] = sin(M_PI * i / (N - 1));
0089         break;
0090     case nsl_sf_window_bartlett_hann:
0091         for (i = 0; i < N; i++)
0092             data[i] = 0.62 - 0.48 * fabs(i / (double)(N - 1) - 0.5) - 0.38 * cos(2. * M_PI * i / (N - 1));
0093         break;
0094     case nsl_sf_window_lanczos:
0095         for (i = 0; i < N; i++)
0096             data[i] = gsl_sf_sinc(2. * i / (N - 1) - 1.);
0097         break;
0098     }
0099 
0100     return 0;
0101 }