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

0001 /*
0002     File                 : nsl_conv.h
0003     Project              : LabPlot
0004     Description          : NSL discrete convolution functions
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2018 Stefan Gerlach <stefan.gerlach@uni.kn>
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #ifndef NSL_CONV_H
0011 #define NSL_CONV_H
0012 
0013 #include <stdlib.h>
0014 
0015 /* when to switch from direct to FFT method */
0016 /* set to zero to use FFT method for any length */
0017 #define NSL_CONV_METHOD_BORDER 100
0018 
0019 #define NSL_CONV_DIRECTION_COUNT 2
0020 /* forward: convolution, backward: deconvolution */
0021 typedef enum { nsl_conv_direction_forward, nsl_conv_direction_backward } nsl_conv_direction_type;
0022 extern const char* nsl_conv_direction_name[];
0023 
0024 #define NSL_CONV_TYPE_COUNT 2
0025 /* linear (zero-padded), circular */
0026 typedef enum { nsl_conv_type_linear, nsl_conv_type_circular } nsl_conv_type_type;
0027 extern const char* nsl_conv_type_name[];
0028 
0029 #define NSL_CONV_METHOD_COUNT 3
0030 /* auto: use direct method for small data size (NSL_CONV_METHOD_BORDER) and FFT method otherwise */
0031 typedef enum { nsl_conv_method_auto, nsl_conv_method_direct, nsl_conv_method_fft } nsl_conv_method_type;
0032 extern const char* nsl_conv_method_name[];
0033 
0034 #define NSL_CONV_NORM_COUNT 3
0035 /* how to normalize response */
0036 typedef enum { nsl_conv_norm_none, nsl_conv_norm_sum, nsl_conv_norm_euclidean } nsl_conv_norm_type;
0037 extern const char* nsl_conv_norm_name[];
0038 
0039 #define NSL_CONV_WRAP_COUNT 3
0040 /* how to wrap response */
0041 typedef enum { nsl_conv_wrap_none, nsl_conv_wrap_max, nsl_conv_wrap_center } nsl_conv_wrap_type;
0042 extern const char* nsl_conv_wrap_name[];
0043 
0044 /* TODO: mode: full, same, valid (see NumPy, SciPy) */
0045 
0046 #define NSL_CONV_KERNEL_COUNT 10
0047 /* standard kernel (response)
0048  * option: number of points
0049  */
0050 typedef enum {
0051     nsl_conv_kernel_avg,
0052     nsl_conv_kernel_smooth_triangle,
0053     nsl_conv_kernel_smooth_gaussian,
0054     nsl_conv_kernel_first_derivative,
0055     nsl_conv_kernel_smooth_first_derivative,
0056     nsl_conv_kernel_second_derivative,
0057     nsl_conv_kernel_third_derivative,
0058     nsl_conv_kernel_fourth_derivative,
0059     nsl_conv_kernel_gaussian,
0060     nsl_conv_kernel_lorentzian
0061 } nsl_conv_kernel_type;
0062 extern const char* nsl_conv_kernel_name[];
0063 
0064 /* standard kernel */
0065 int nsl_conv_standard_kernel(double k[], size_t n, nsl_conv_kernel_type);
0066 
0067 /* calculate convolution/deconvolution
0068  * of signal s of size n with response r of size m
0069  */
0070 int nsl_conv_convolution_direction(double s[],
0071                                    size_t n,
0072                                    double r[],
0073                                    size_t m,
0074                                    nsl_conv_direction_type,
0075                                    nsl_conv_type_type,
0076                                    nsl_conv_method_type,
0077                                    nsl_conv_norm_type normalize,
0078                                    nsl_conv_wrap_type wrap,
0079                                    double out[]);
0080 
0081 int nsl_conv_convolution(double s[],
0082                          size_t n,
0083                          double r[],
0084                          size_t m,
0085                          nsl_conv_type_type,
0086                          nsl_conv_method_type,
0087                          nsl_conv_norm_type normalize,
0088                          nsl_conv_wrap_type wrap,
0089                          double out[]);
0090 /* deconvolution only supported by FFT method */
0091 int nsl_conv_deconvolution(double s[], size_t n, double r[], size_t m, nsl_conv_type_type, nsl_conv_norm_type normalize, nsl_conv_wrap_type wrap, double out[]);
0092 
0093 /* linear/circular convolution using direct method
0094  * s and r are untouched
0095  */
0096 int nsl_conv_linear_direct(const double s[], size_t n, double r[], size_t m, nsl_conv_norm_type normalize, nsl_conv_wrap_type wrap, double out[]);
0097 int nsl_conv_circular_direct(const double s[], size_t n, double r[], size_t m, nsl_conv_norm_type normalize, nsl_conv_wrap_type wrap, double out[]);
0098 /* linear/circular convolution/deconvolution using FFT method
0099  * s and r are untouched
0100  */
0101 int nsl_conv_fft_type(const double s[],
0102                       size_t n,
0103                       double r[],
0104                       size_t m,
0105                       nsl_conv_direction_type,
0106                       nsl_conv_type_type,
0107                       nsl_conv_norm_type normalize,
0108                       nsl_conv_wrap_type wrap,
0109                       double out[]);
0110 /* actual FFT method calculation using zero-padded arrays
0111  * uses FFTW if available and GSL otherwise
0112  * wi is the wrap index
0113  * s and r are overwritten
0114  */
0115 #ifdef HAVE_FFTW3
0116 int nsl_conv_fft_FFTW(double s[], double r[], size_t n, nsl_conv_direction_type, size_t wi, double out[]);
0117 #endif
0118 int nsl_conv_fft_GSL(double s[], double r[], size_t n, nsl_conv_direction_type, double out[]);
0119 
0120 #endif /* NSL_CONV_H */