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 */