diff --git a/_release/.gitignore b/_release/.gitignore
deleted file mode 100644
index 2f5acf7..0000000
--- a/_release/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-*.o
-*.so
-*.dll
-*.exe
diff --git a/_release/Makefile b/_release/Makefile
deleted file mode 100644
index 2dae482..0000000
--- a/_release/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-
-CC = gcc
-
-# Define OS
-ifeq ($(OS),Windows_NT)
- DSPL_LIBNAME = libdspl.dll
- DEF_OS = WIN_OS
- LFLAGS = -lm
-else
- UNAME_S := $(shell uname -s)
- UNAME_P := $(shell uname -p)
- ifeq ($(UNAME_S),Linux)
- DSPL_LIBNAME = libdspl.so
- DEF_OS = LINUX_OS
- LFLAGS = -lm -ldl
- else ifeq ($(UNAME_S),Darwin)
- DSPL_LIBNAME = libdspl.so
- DEF_OS = LINUX_OS
- LFLAGS = -lm -ldl
- endif
-endif
-
-# C-compiler flags
-CFLAGS = -c -O3 -D$(DEF_OS)
-
-OBJFILES = test.o dspl.o
-
-all: test.exe clean
-
-test.exe: $(OBJFILES)
- $(CC) $(OBJFILES) -o $@ $(LFLAGS)
-
-%.o:%.c
- $(CC) $(CFLAGS) $< -o $@ $(LFLAGS)
-
-clean:
- rm -f *.o
\ No newline at end of file
diff --git a/_release/dspl.c b/_release/dspl.c
index 253d23b..68c384a 100644
--- a/_release/dspl.c
+++ b/_release/dspl.c
@@ -1,458 +1,464 @@
-/*
-* Copyright (c) 2015-2020 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of libdspl-2.0.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DSPL is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Foobar. If not, see .
-*/
-
-
-
-#ifdef WIN_OS
-#include
-#endif /* WIN_OS */
-
-#ifdef LINUX_OS
-#include
-#endif /* LINUX_OS */
-
-
-#include
-#include "dspl.h"
-
-
-#ifndef BUILD_LIB
-
-p_acos_cmplx acos_cmplx ;
-p_addlog addlog ;
-p_array_scale_lin array_scale_lin ;
-p_asin_cmplx asin_cmplx ;
-
-p_butter_ap butter_ap ;
-p_bessel_i0 bessel_i0 ;
-p_bilinear bilinear ;
-p_butter_ap_zp butter_ap_zp ;
-
-p_cheby_poly1 cheby_poly1 ;
-p_cheby_poly2 cheby_poly2 ;
-p_cheby1_ap cheby1_ap ;
-p_cheby1_ap_zp cheby1_ap_zp ;
-p_cheby2_ap cheby2_ap ;
-p_cheby2_ap_wp1 cheby2_ap_wp1 ;
-p_cheby2_ap_zp cheby2_ap_zp ;
-p_cmplx2re cmplx2re ;
-p_concat concat ;
-p_conv conv ;
-p_conv_cmplx conv_cmplx ;
-p_conv_fft conv_fft ;
-p_conv_fft_cmplx conv_fft_cmplx ;
-p_cos_cmplx cos_cmplx ;
-
-p_decimate decimate ;
-p_decimate_cmplx decimate_cmplx ;
-p_dft dft ;
-p_dft_cmplx dft_cmplx ;
-p_dmod dmod ;
-p_dspl_info dspl_info ;
-
-p_ellip_acd ellip_acd ;
-p_ellip_acd_cmplx ellip_acd_cmplx ;
-p_ellip_ap ellip_ap ;
-p_ellip_ap_zp ellip_ap_zp ;
-p_ellip_asn ellip_asn ;
-p_ellip_asn_cmplx ellip_asn_cmplx ;
-p_ellip_cd ellip_cd ;
-p_ellip_cd_cmplx ellip_cd_cmplx ;
-p_ellip_landen ellip_landen ;
-p_ellip_modulareq ellip_modulareq ;
-p_ellip_rat ellip_rat ;
-p_ellip_sn ellip_sn ;
-p_ellip_sn_cmplx ellip_sn_cmplx ;
-
-p_farrow_lagrange farrow_lagrange ;
-p_farrow_spline farrow_spline ;
-p_fft fft ;
-p_fft_abs fft_abs ;
-p_fft_abs_cmplx fft_abs_cmplx ;
-p_fft_cmplx fft_cmplx ;
-p_fft_create fft_create ;
-p_fft_free fft_free ;
-p_fft_mag fft_mag ;
-p_fft_mag_cmplx fft_mag_cmplx ;
-p_fft_shift fft_shift ;
-p_fft_shift_cmplx fft_shift_cmplx ;
-p_filter_freq_resp filter_freq_resp ;
-p_filter_iir filter_iir ;
-p_filter_ws1 filter_ws1 ;
-p_filter_zp2ab filter_zp2ab ;
-p_find_max_abs find_max_abs ;
-p_fir_linphase fir_linphase ;
-p_flipip flipip ;
-p_flipip_cmplx flipip_cmplx ;
-p_fourier_integral_cmplx fourier_integral_cmplx ;
-p_fourier_series_dec fourier_series_dec ;
-p_fourier_series_dec_cmplx fourier_series_dec_cmplx ;
-p_fourier_series_rec fourier_series_rec ;
-p_freqs freqs ;
-p_freqs_cmplx freqs_cmplx ;
-p_freqs2time freqs2time ;
-p_freqz freqz ;
-
-p_gnuplot_close gnuplot_close ;
-p_gnuplot_cmd gnuplot_cmd ;
-p_gnuplot_create gnuplot_create ;
-p_gnuplot_open gnuplot_open ;
-p_goertzel goertzel ;
-p_goertzel_cmplx goertzel_cmplx ;
-p_group_delay group_delay ;
-
-p_histogram histogram ;
-p_histogram_norm histogram_norm ;
-
-p_idft_cmplx idft_cmplx ;
-p_ifft_cmplx ifft_cmplx ;
-p_iir iir ;
-
-p_linspace linspace ;
-p_log_cmplx log_cmplx ;
-p_logspace logspace ;
-p_low2bp low2bp ;
-p_low2bs low2bs ;
-p_low2high low2high ;
-p_low2low low2low ;
-
-p_matrix_eig_cmplx matrix_eig_cmplx ;
-p_matrix_eye matrix_eye ;
-p_matrix_eye_cmplx matrix_eye_cmplx ;
-p_matrix_mul matrix_mul ;
-p_matrix_pinv matrix_pinv ;
-p_matrix_print matrix_print ;
-p_matrix_print_cmplx matrix_print_cmplx ;
-p_matrix_svd matrix_svd ;
-p_matrix_transpose matrix_transpose ;
-p_matrix_transpose_cmplx matrix_transpose_cmplx ;
-p_matrix_transpose_hermite matrix_transpose_hermite ;
-p_mean mean ;
-p_mean_cmplx mean_cmplx ;
-p_minmax minmax ;
-
-p_ones ones ;
-
-p_phase_delay phase_delay ;
-p_poly_z2a_cmplx poly_z2a_cmplx ;
-p_polyroots polyroots ;
-p_polyval polyval ;
-p_polyval_cmplx polyval_cmplx ;
-p_psd_bartlett psd_bartlett ;
-p_psd_bartlett_cmplx psd_bartlett_cmplx ;
-p_psd_periodogram psd_periodogram ;
-p_psd_periodogram_cmplx psd_periodogram_cmplx ;
-p_psd_welch psd_welch ;
-p_psd_welch_cmplx psd_welch_cmplx ;
-
-p_randb randb ;
-p_randb2 randb2 ;
-p_randi randi ;
-p_randn randn ;
-p_randn_cmplx randn_cmplx ;
-p_random_init random_init ;
-p_randu randu ;
-p_ratcompos ratcompos ;
-p_re2cmplx re2cmplx ;
-p_readbin readbin ;
-
-p_signal_pimp signal_pimp ;
-p_signal_saw signal_saw ;
-p_sin_cmplx sin_cmplx ;
-p_sinc sinc ;
-p_sine_int sine_int ;
-p_sqrt_cmplx sqrt_cmplx ;
-p_std std ;
-p_std_cmplx std_cmplx ;
-
-p_trapint trapint ;
-p_trapint_cmplx trapint_cmplx ;
-
-p_unwrap unwrap ;
-
-p_vector_dot vector_dot ;
-p_verif verif ;
-p_verif_data_gen verif_data_gen ;
-p_verif_cmplx verif_cmplx ;
-p_verif_str verif_str ;
-p_verif_str_cmplx verif_str_cmplx ;
-
-p_window window ;
-p_writebin writebin ;
-p_writetxt writetxt ;
-p_writetxt_3d writetxt_3d ;
-p_writetxt_3dline writetxt_3dline ;
-p_writetxt_cmplx writetxt_cmplx ;
-p_writetxt_cmplx_im writetxt_cmplx_im ;
-p_writetxt_cmplx_re writetxt_cmplx_re ;
-p_writetxt_int writetxt_int ;
-
-p_xcorr xcorr ;
-p_xcorr_cmplx xcorr_cmplx ;
-
-
-#ifdef WIN_OS
-#define LOAD_FUNC(fn) \
- fname = #fn;\
- fn = (p_##fn)GetProcAddress(handle, fname);\
- if(! fn) goto exit_label;
-#endif
-
-
-
-#ifdef LINUX_OS
-#define LOAD_FUNC(fn) \
- fname = #fn;\
- fn = (p_##fn)dlsym(handle, fname);\
- if ((error = dlerror()) != NULL) goto exit_label
-#endif
-
-
-void* dspl_load()
-{
- char* fname;
- #ifdef WIN_OS
- HINSTANCE handle;
- handle = LoadLibrary(TEXT("libdspl.dll"));
- if (!handle)
- {
- printf("libdspl.dll loading ERROR!\n");
- return NULL;
- }
- #endif /* WIN_OS */
-
-
- #ifdef LINUX_OS
- char* error;
- void *handle;
- /* open the *.so */
- handle = dlopen ("./libdspl.so", RTLD_LAZY);
- if (!handle)
- {
- printf("libdspl.so loading ERROR!\n");
- return NULL;
- }
- #endif /* LINUX_OS */
-
- LOAD_FUNC(acos_cmplx);
- LOAD_FUNC(addlog);
- LOAD_FUNC(array_scale_lin);
- LOAD_FUNC(asin_cmplx);
-
- LOAD_FUNC(bessel_i0);
- LOAD_FUNC(bilinear);
- LOAD_FUNC(butter_ap);
- LOAD_FUNC(butter_ap_zp);
-
- LOAD_FUNC(cheby_poly1);
- LOAD_FUNC(cheby_poly2);
- LOAD_FUNC(cheby1_ap);
- LOAD_FUNC(cheby1_ap_zp);
- LOAD_FUNC(cheby2_ap);
- LOAD_FUNC(cheby2_ap_wp1);
- LOAD_FUNC(cheby2_ap_zp);
- LOAD_FUNC(cmplx2re);
- LOAD_FUNC(concat);
- LOAD_FUNC(conv);
- LOAD_FUNC(conv_cmplx);
- LOAD_FUNC(conv_fft);
- LOAD_FUNC(conv_fft_cmplx);
- LOAD_FUNC(cos_cmplx);
-
- LOAD_FUNC(decimate);
- LOAD_FUNC(decimate_cmplx);
- LOAD_FUNC(dft);
- LOAD_FUNC(dft_cmplx);
- LOAD_FUNC(dmod);
- LOAD_FUNC(dspl_info);
-
- LOAD_FUNC(ellip_acd);
- LOAD_FUNC(ellip_acd_cmplx);
- LOAD_FUNC(ellip_ap);
- LOAD_FUNC(ellip_ap_zp);
- LOAD_FUNC(ellip_asn);
- LOAD_FUNC(ellip_asn_cmplx);
- LOAD_FUNC(ellip_cd);
- LOAD_FUNC(ellip_cd_cmplx);
- LOAD_FUNC(ellip_landen);
- LOAD_FUNC(ellip_modulareq);
- LOAD_FUNC(ellip_rat);
- LOAD_FUNC(ellip_sn);
- LOAD_FUNC(ellip_sn_cmplx);
-
- LOAD_FUNC(farrow_lagrange);
- LOAD_FUNC(farrow_spline);
- LOAD_FUNC(fft);
- LOAD_FUNC(fft_cmplx);
- LOAD_FUNC(fft_create);
- LOAD_FUNC(fft_free);
- LOAD_FUNC(fft_mag);
- LOAD_FUNC(fft_mag_cmplx);
- LOAD_FUNC(fft_shift);
- LOAD_FUNC(fft_shift_cmplx);
- LOAD_FUNC(filter_freq_resp);
- LOAD_FUNC(filter_iir);
- LOAD_FUNC(filter_ws1);
- LOAD_FUNC(filter_zp2ab);
- LOAD_FUNC(find_max_abs);
- LOAD_FUNC(fir_linphase);
- LOAD_FUNC(flipip);
- LOAD_FUNC(flipip_cmplx);
- LOAD_FUNC(fourier_integral_cmplx);
- LOAD_FUNC(fourier_series_dec);
- LOAD_FUNC(fourier_series_dec_cmplx);
- LOAD_FUNC(fourier_series_rec);
- LOAD_FUNC(freqz);
- LOAD_FUNC(freqs);
- LOAD_FUNC(freqs_cmplx);
- LOAD_FUNC(freqs2time);
-
- LOAD_FUNC(gnuplot_close);
- LOAD_FUNC(gnuplot_cmd);
- LOAD_FUNC(gnuplot_create);
- LOAD_FUNC(gnuplot_open);
- LOAD_FUNC(goertzel);
- LOAD_FUNC(goertzel_cmplx);
- LOAD_FUNC(group_delay);
-
- LOAD_FUNC(histogram);
- LOAD_FUNC(histogram_norm);
-
- LOAD_FUNC(idft_cmplx);
- LOAD_FUNC(ifft_cmplx);
- LOAD_FUNC(iir);
-
- LOAD_FUNC(linspace);
- LOAD_FUNC(log_cmplx);
- LOAD_FUNC(logspace);
- LOAD_FUNC(low2bp);
- LOAD_FUNC(low2bs);
- LOAD_FUNC(low2high);
- LOAD_FUNC(low2low);
-
- LOAD_FUNC(matrix_eig_cmplx);
- LOAD_FUNC(matrix_eye);
- LOAD_FUNC(matrix_eye_cmplx);
- LOAD_FUNC(matrix_mul);
- LOAD_FUNC(matrix_pinv);
- LOAD_FUNC(matrix_print);
- LOAD_FUNC(matrix_print_cmplx);
- LOAD_FUNC(matrix_svd);
- LOAD_FUNC(matrix_transpose);
- LOAD_FUNC(matrix_transpose_cmplx);
- LOAD_FUNC(matrix_transpose_hermite);
- LOAD_FUNC(mean);
- LOAD_FUNC(mean_cmplx);
- LOAD_FUNC(minmax);
-
- LOAD_FUNC(ones);
-
- LOAD_FUNC(phase_delay);
- LOAD_FUNC(poly_z2a_cmplx);
- LOAD_FUNC(polyroots);
- LOAD_FUNC(polyval);
- LOAD_FUNC(polyval_cmplx);
- LOAD_FUNC(psd_bartlett);
- LOAD_FUNC(psd_bartlett_cmplx);
- LOAD_FUNC(psd_periodogram);
- LOAD_FUNC(psd_periodogram_cmplx);
- LOAD_FUNC(psd_welch);
- LOAD_FUNC(psd_welch_cmplx);
-
- LOAD_FUNC(randi);
- LOAD_FUNC(randb);
- LOAD_FUNC(randb2);
- LOAD_FUNC(randn);
- LOAD_FUNC(randn_cmplx);
- LOAD_FUNC(random_init);
- LOAD_FUNC(randu);
- LOAD_FUNC(ratcompos);
- LOAD_FUNC(re2cmplx);
- LOAD_FUNC(readbin);
-
- LOAD_FUNC(signal_pimp);
- LOAD_FUNC(signal_saw);
- LOAD_FUNC(sin_cmplx);
- LOAD_FUNC(sinc);
- LOAD_FUNC(sine_int);
- LOAD_FUNC(sqrt_cmplx);
- LOAD_FUNC(std);
- LOAD_FUNC(std_cmplx);
-
- LOAD_FUNC(trapint);
- LOAD_FUNC(trapint_cmplx);
-
- LOAD_FUNC(unwrap);
-
- LOAD_FUNC(vector_dot);
- LOAD_FUNC(verif);
- LOAD_FUNC(verif_data_gen);
- LOAD_FUNC(verif_cmplx);
- LOAD_FUNC(verif_str);
- LOAD_FUNC(verif_str_cmplx);
-
- LOAD_FUNC(window);
- LOAD_FUNC(writebin);
- LOAD_FUNC(writetxt);
- LOAD_FUNC(writetxt_3d);
- LOAD_FUNC(writetxt_3dline);
- LOAD_FUNC(writetxt_cmplx);
- LOAD_FUNC(writetxt_cmplx_im);
- LOAD_FUNC(writetxt_cmplx_re);
- LOAD_FUNC(writetxt_int);
-
- LOAD_FUNC(xcorr);
- LOAD_FUNC(xcorr_cmplx);
-
-
- #ifdef WIN_OS
- return (void*)handle;
- exit_label:
- printf("function %s loading ERROR!\n", fname);
- if(handle)
- FreeLibrary(handle);
- return NULL;
- #endif /* WIN_OS */
-
-
- #ifdef LINUX_OS
- return handle;
- exit_label:
- printf("function %s loading ERROR!\n", fname);
- if(handle)
- dlclose(handle);
- return NULL;
- #endif /* LINUX_OS */
-}
-
-
-
-void dspl_free(void* handle)
-{
- #ifdef WIN_OS
- FreeLibrary((HINSTANCE)handle);
- #endif /* WIN_OS */
-
- #ifdef LINUX_OS
- dlclose(handle);
- #endif /* LINUX_OS */
-}
-
-#endif /* BUILD_LIB */
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+
+#ifdef WIN_OS
+#include
+#endif /* WIN_OS */
+
+#ifdef LINUX_OS
+#include
+#endif /* LINUX_OS */
+
+
+#include
+#include "dspl.h"
+
+
+#ifndef BUILD_LIB
+
+p_acos_cmplx acos_cmplx ;
+p_addlog addlog ;
+p_array_scale_lin array_scale_lin ;
+p_asin_cmplx asin_cmplx ;
+
+p_butter_ap butter_ap ;
+p_bessel_i0 bessel_i0 ;
+p_bilinear bilinear ;
+p_butter_ap_zp butter_ap_zp ;
+
+p_cheby_poly1 cheby_poly1 ;
+p_cheby_poly2 cheby_poly2 ;
+p_cheby1_ap cheby1_ap ;
+p_cheby1_ap_zp cheby1_ap_zp ;
+p_cheby2_ap cheby2_ap ;
+p_cheby2_ap_wp1 cheby2_ap_wp1 ;
+p_cheby2_ap_zp cheby2_ap_zp ;
+p_cmplx2re cmplx2re ;
+p_concat concat ;
+p_conv conv ;
+p_conv_cmplx conv_cmplx ;
+p_conv_fft conv_fft ;
+p_conv_fft_cmplx conv_fft_cmplx ;
+p_cos_cmplx cos_cmplx ;
+
+p_decimate decimate ;
+p_decimate_cmplx decimate_cmplx ;
+p_dft dft ;
+p_dft_cmplx dft_cmplx ;
+p_dmod dmod ;
+p_dspl_info dspl_info ;
+
+p_ellip_acd ellip_acd ;
+p_ellip_acd_cmplx ellip_acd_cmplx ;
+p_ellip_ap ellip_ap ;
+p_ellip_ap_zp ellip_ap_zp ;
+p_ellip_asn ellip_asn ;
+p_ellip_asn_cmplx ellip_asn_cmplx ;
+p_ellip_cd ellip_cd ;
+p_ellip_cd_cmplx ellip_cd_cmplx ;
+p_ellip_landen ellip_landen ;
+p_ellip_modulareq ellip_modulareq ;
+p_ellip_rat ellip_rat ;
+p_ellip_sn ellip_sn ;
+p_ellip_sn_cmplx ellip_sn_cmplx ;
+
+p_farrow_lagrange farrow_lagrange ;
+p_farrow_spline farrow_spline ;
+p_fft fft ;
+p_fft_abs fft_abs ;
+p_fft_abs_cmplx fft_abs_cmplx ;
+p_fft_cmplx fft_cmplx ;
+p_fft_create fft_create ;
+p_fft_free fft_free ;
+p_fft_mag fft_mag ;
+p_fft_mag_cmplx fft_mag_cmplx ;
+p_fft_shift fft_shift ;
+p_fft_shift_cmplx fft_shift_cmplx ;
+p_filter_freq_resp filter_freq_resp ;
+p_filter_iir filter_iir ;
+p_filter_ws1 filter_ws1 ;
+p_filter_zp2ab filter_zp2ab ;
+p_find_max_abs find_max_abs ;
+p_find_nearest find_nearest ;
+p_fir_linphase fir_linphase ;
+p_flipip flipip ;
+p_flipip_cmplx flipip_cmplx ;
+p_fourier_integral_cmplx fourier_integral_cmplx ;
+p_fourier_series_dec fourier_series_dec ;
+p_fourier_series_dec_cmplx fourier_series_dec_cmplx ;
+p_fourier_series_rec fourier_series_rec ;
+p_freqs freqs ;
+p_freqs_cmplx freqs_cmplx ;
+p_freqs2time freqs2time ;
+p_freqz freqz ;
+
+p_gnuplot_close gnuplot_close ;
+p_gnuplot_cmd gnuplot_cmd ;
+p_gnuplot_create gnuplot_create ;
+p_gnuplot_open gnuplot_open ;
+p_goertzel goertzel ;
+p_goertzel_cmplx goertzel_cmplx ;
+p_group_delay group_delay ;
+
+p_histogram histogram ;
+p_histogram_norm histogram_norm ;
+
+p_idft_cmplx idft_cmplx ;
+p_ifft_cmplx ifft_cmplx ;
+p_iir iir ;
+
+p_linspace linspace ;
+p_log_cmplx log_cmplx ;
+p_logspace logspace ;
+p_low2bp low2bp ;
+p_low2bs low2bs ;
+p_low2high low2high ;
+p_low2low low2low ;
+
+p_matrix_eig_cmplx matrix_eig_cmplx ;
+p_matrix_eye matrix_eye ;
+p_matrix_eye_cmplx matrix_eye_cmplx ;
+p_matrix_mul matrix_mul ;
+p_matrix_pinv matrix_pinv ;
+p_matrix_print matrix_print ;
+p_matrix_print_cmplx matrix_print_cmplx ;
+p_matrix_svd matrix_svd ;
+p_matrix_transpose matrix_transpose ;
+p_matrix_transpose_cmplx matrix_transpose_cmplx ;
+p_matrix_transpose_hermite matrix_transpose_hermite ;
+p_mean mean ;
+p_mean_cmplx mean_cmplx ;
+p_minmax minmax ;
+
+p_ones ones ;
+
+p_phase_delay phase_delay ;
+p_poly_z2a_cmplx poly_z2a_cmplx ;
+p_polyroots polyroots ;
+p_polyval polyval ;
+p_polyval_cmplx polyval_cmplx ;
+p_psd_bartlett psd_bartlett ;
+p_psd_bartlett_cmplx psd_bartlett_cmplx ;
+p_psd_periodogram psd_periodogram ;
+p_psd_periodogram_cmplx psd_periodogram_cmplx ;
+p_psd_welch psd_welch ;
+p_psd_welch_cmplx psd_welch_cmplx ;
+
+p_randb randb ;
+p_randb2 randb2 ;
+p_randi randi ;
+p_randn randn ;
+p_randn_cmplx randn_cmplx ;
+p_random_init random_init ;
+p_randu randu ;
+p_ratcompos ratcompos ;
+p_re2cmplx re2cmplx ;
+p_readbin readbin ;
+
+p_signal_pimp signal_pimp ;
+p_signal_saw signal_saw ;
+p_sin_cmplx sin_cmplx ;
+p_sinc sinc ;
+p_sine_int sine_int ;
+p_sqrt_cmplx sqrt_cmplx ;
+p_stat_std stat_std ;
+p_stat_std_cmplx stat_std_cmplx ;
+p_sum sum ;
+p_sum_sqr sum_sqr ;
+
+p_trapint trapint ;
+p_trapint_cmplx trapint_cmplx ;
+
+p_unwrap unwrap ;
+
+p_vector_dot vector_dot ;
+p_verif verif ;
+p_verif_data_gen verif_data_gen ;
+p_verif_cmplx verif_cmplx ;
+p_verif_str verif_str ;
+p_verif_str_cmplx verif_str_cmplx ;
+
+p_window window ;
+p_writebin writebin ;
+p_writetxt writetxt ;
+p_writetxt_3d writetxt_3d ;
+p_writetxt_3dline writetxt_3dline ;
+p_writetxt_cmplx writetxt_cmplx ;
+p_writetxt_cmplx_im writetxt_cmplx_im ;
+p_writetxt_cmplx_re writetxt_cmplx_re ;
+p_writetxt_int writetxt_int ;
+
+p_xcorr xcorr ;
+p_xcorr_cmplx xcorr_cmplx ;
+
+
+#ifdef WIN_OS
+#define LOAD_FUNC(fn) \
+ fname = #fn;\
+ fn = (p_##fn)GetProcAddress(handle, fname);\
+ if(! fn) goto exit_label;
+#endif
+
+
+
+#ifdef LINUX_OS
+#define LOAD_FUNC(fn) \
+ fname = #fn;\
+ fn = (p_##fn)dlsym(handle, fname);\
+ if ((error = dlerror()) != NULL) goto exit_label
+#endif
+
+
+void* dspl_load()
+{
+ char* fname;
+ #ifdef WIN_OS
+ HINSTANCE handle;
+ handle = LoadLibrary(TEXT("libdspl.dll"));
+ if (!handle)
+ {
+ printf("libdspl.dll loading ERROR!\n");
+ return NULL;
+ }
+ #endif /* WIN_OS */
+
+
+ #ifdef LINUX_OS
+ char* error;
+ void *handle;
+ /* open the *.so */
+ handle = dlopen ("./libdspl.so", RTLD_LAZY);
+ if (!handle)
+ {
+ printf("libdspl.so loading ERROR!\n");
+ return NULL;
+ }
+ #endif /* LINUX_OS */
+
+ LOAD_FUNC(acos_cmplx);
+ LOAD_FUNC(addlog);
+ LOAD_FUNC(array_scale_lin);
+ LOAD_FUNC(asin_cmplx);
+
+ LOAD_FUNC(bessel_i0);
+ LOAD_FUNC(bilinear);
+ LOAD_FUNC(butter_ap);
+ LOAD_FUNC(butter_ap_zp);
+
+ LOAD_FUNC(cheby_poly1);
+ LOAD_FUNC(cheby_poly2);
+ LOAD_FUNC(cheby1_ap);
+ LOAD_FUNC(cheby1_ap_zp);
+ LOAD_FUNC(cheby2_ap);
+ LOAD_FUNC(cheby2_ap_wp1);
+ LOAD_FUNC(cheby2_ap_zp);
+ LOAD_FUNC(cmplx2re);
+ LOAD_FUNC(concat);
+ LOAD_FUNC(conv);
+ LOAD_FUNC(conv_cmplx);
+ LOAD_FUNC(conv_fft);
+ LOAD_FUNC(conv_fft_cmplx);
+ LOAD_FUNC(cos_cmplx);
+
+ LOAD_FUNC(decimate);
+ LOAD_FUNC(decimate_cmplx);
+ LOAD_FUNC(dft);
+ LOAD_FUNC(dft_cmplx);
+ LOAD_FUNC(dmod);
+ LOAD_FUNC(dspl_info);
+
+ LOAD_FUNC(ellip_acd);
+ LOAD_FUNC(ellip_acd_cmplx);
+ LOAD_FUNC(ellip_ap);
+ LOAD_FUNC(ellip_ap_zp);
+ LOAD_FUNC(ellip_asn);
+ LOAD_FUNC(ellip_asn_cmplx);
+ LOAD_FUNC(ellip_cd);
+ LOAD_FUNC(ellip_cd_cmplx);
+ LOAD_FUNC(ellip_landen);
+ LOAD_FUNC(ellip_modulareq);
+ LOAD_FUNC(ellip_rat);
+ LOAD_FUNC(ellip_sn);
+ LOAD_FUNC(ellip_sn_cmplx);
+
+ LOAD_FUNC(farrow_lagrange);
+ LOAD_FUNC(farrow_spline);
+ LOAD_FUNC(fft);
+ LOAD_FUNC(fft_cmplx);
+ LOAD_FUNC(fft_create);
+ LOAD_FUNC(fft_free);
+ LOAD_FUNC(fft_mag);
+ LOAD_FUNC(fft_mag_cmplx);
+ LOAD_FUNC(fft_shift);
+ LOAD_FUNC(fft_shift_cmplx);
+ LOAD_FUNC(filter_freq_resp);
+ LOAD_FUNC(filter_iir);
+ LOAD_FUNC(filter_ws1);
+ LOAD_FUNC(filter_zp2ab);
+ LOAD_FUNC(find_max_abs);
+ LOAD_FUNC(find_nearest);
+ LOAD_FUNC(fir_linphase);
+ LOAD_FUNC(flipip);
+ LOAD_FUNC(flipip_cmplx);
+ LOAD_FUNC(fourier_integral_cmplx);
+ LOAD_FUNC(fourier_series_dec);
+ LOAD_FUNC(fourier_series_dec_cmplx);
+ LOAD_FUNC(fourier_series_rec);
+ LOAD_FUNC(freqz);
+ LOAD_FUNC(freqs);
+ LOAD_FUNC(freqs_cmplx);
+ LOAD_FUNC(freqs2time);
+
+ LOAD_FUNC(gnuplot_close);
+ LOAD_FUNC(gnuplot_cmd);
+ LOAD_FUNC(gnuplot_create);
+ LOAD_FUNC(gnuplot_open);
+ LOAD_FUNC(goertzel);
+ LOAD_FUNC(goertzel_cmplx);
+ LOAD_FUNC(group_delay);
+
+ LOAD_FUNC(histogram);
+ LOAD_FUNC(histogram_norm);
+
+ LOAD_FUNC(idft_cmplx);
+ LOAD_FUNC(ifft_cmplx);
+ LOAD_FUNC(iir);
+
+ LOAD_FUNC(linspace);
+ LOAD_FUNC(log_cmplx);
+ LOAD_FUNC(logspace);
+ LOAD_FUNC(low2bp);
+ LOAD_FUNC(low2bs);
+ LOAD_FUNC(low2high);
+ LOAD_FUNC(low2low);
+
+ LOAD_FUNC(matrix_eig_cmplx);
+ LOAD_FUNC(matrix_eye);
+ LOAD_FUNC(matrix_eye_cmplx);
+ LOAD_FUNC(matrix_mul);
+ LOAD_FUNC(matrix_pinv);
+ LOAD_FUNC(matrix_print);
+ LOAD_FUNC(matrix_print_cmplx);
+ LOAD_FUNC(matrix_svd);
+ LOAD_FUNC(matrix_transpose);
+ LOAD_FUNC(matrix_transpose_cmplx);
+ LOAD_FUNC(matrix_transpose_hermite);
+ LOAD_FUNC(mean);
+ LOAD_FUNC(mean_cmplx);
+ LOAD_FUNC(minmax);
+
+ LOAD_FUNC(ones);
+
+ LOAD_FUNC(phase_delay);
+ LOAD_FUNC(poly_z2a_cmplx);
+ LOAD_FUNC(polyroots);
+ LOAD_FUNC(polyval);
+ LOAD_FUNC(polyval_cmplx);
+ LOAD_FUNC(psd_bartlett);
+ LOAD_FUNC(psd_bartlett_cmplx);
+ LOAD_FUNC(psd_periodogram);
+ LOAD_FUNC(psd_periodogram_cmplx);
+ LOAD_FUNC(psd_welch);
+ LOAD_FUNC(psd_welch_cmplx);
+
+ LOAD_FUNC(randi);
+ LOAD_FUNC(randb);
+ LOAD_FUNC(randb2);
+ LOAD_FUNC(randn);
+ LOAD_FUNC(randn_cmplx);
+ LOAD_FUNC(random_init);
+ LOAD_FUNC(randu);
+ LOAD_FUNC(ratcompos);
+ LOAD_FUNC(re2cmplx);
+ LOAD_FUNC(readbin);
+
+ LOAD_FUNC(signal_pimp);
+ LOAD_FUNC(signal_saw);
+ LOAD_FUNC(sin_cmplx);
+ LOAD_FUNC(sinc);
+ LOAD_FUNC(sine_int);
+ LOAD_FUNC(sqrt_cmplx);
+ LOAD_FUNC(stat_std);
+ LOAD_FUNC(stat_std_cmplx);
+ LOAD_FUNC(sum);
+ LOAD_FUNC(sum_sqr);
+
+ LOAD_FUNC(trapint);
+ LOAD_FUNC(trapint_cmplx);
+
+ LOAD_FUNC(unwrap);
+
+ LOAD_FUNC(vector_dot);
+ LOAD_FUNC(verif);
+ LOAD_FUNC(verif_data_gen);
+ LOAD_FUNC(verif_cmplx);
+ LOAD_FUNC(verif_str);
+ LOAD_FUNC(verif_str_cmplx);
+
+ LOAD_FUNC(window);
+ LOAD_FUNC(writebin);
+ LOAD_FUNC(writetxt);
+ LOAD_FUNC(writetxt_3d);
+ LOAD_FUNC(writetxt_3dline);
+ LOAD_FUNC(writetxt_cmplx);
+ LOAD_FUNC(writetxt_cmplx_im);
+ LOAD_FUNC(writetxt_cmplx_re);
+ LOAD_FUNC(writetxt_int);
+
+ LOAD_FUNC(xcorr);
+ LOAD_FUNC(xcorr_cmplx);
+
+
+ #ifdef WIN_OS
+ return (void*)handle;
+ exit_label:
+ printf("function %s loading ERROR!\n", fname);
+ if(handle)
+ FreeLibrary(handle);
+ return NULL;
+ #endif /* WIN_OS */
+
+
+ #ifdef LINUX_OS
+ return handle;
+ exit_label:
+ printf("function %s loading ERROR!\n", fname);
+ if(handle)
+ dlclose(handle);
+ return NULL;
+ #endif /* LINUX_OS */
+}
+
+
+
+void dspl_free(void* handle)
+{
+ #ifdef WIN_OS
+ FreeLibrary((HINSTANCE)handle);
+ #endif /* WIN_OS */
+
+ #ifdef LINUX_OS
+ dlclose(handle);
+ #endif /* LINUX_OS */
+}
+
+#endif /* BUILD_LIB */
diff --git a/_release/dspl.h b/_release/dspl.h
index 9673989..534247c 100644
--- a/_release/dspl.h
+++ b/_release/dspl.h
@@ -1068,6 +1068,12 @@ DECLARE_FUNC(int, find_max_abs, double* a
COMMA double* m
COMMA int* ind);
/*----------------------------------------------------------------------------*/
+DECLARE_FUNC(int, find_nearest, double* x
+ COMMA int n
+ COMMA double val
+ COMMA int* idx
+ COMMA double* dist);
+/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, fir_linphase, int ord
COMMA double w0
COMMA double w1
@@ -1511,11 +1517,19 @@ DECLARE_FUNC(int, sqrt_cmplx, complex_t*
COMMA int
COMMA complex_t*);
/*----------------------------------------------------------------------------*/
-DECLARE_FUNC(int, std, double* x
+DECLARE_FUNC(int, stat_std, double* x
COMMA int n
COMMA double* s);
/*----------------------------------------------------------------------------*/
-DECLARE_FUNC(int, std_cmplx, complex_t* x
+DECLARE_FUNC(int, stat_std_cmplx, complex_t* x
+ COMMA int n
+ COMMA double* s);
+/*----------------------------------------------------------------------------*/
+DECLARE_FUNC(int, sum, double* x
+ COMMA int n
+ COMMA double* s);
+/*----------------------------------------------------------------------------*/
+DECLARE_FUNC(int, sum_sqr, double* x
COMMA int n
COMMA double* s);
/*----------------------------------------------------------------------------*/
diff --git a/_release/test.c b/_release/test.c
deleted file mode 100644
index 5209033..0000000
--- a/_release/test.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include
-#include
-#include "dspl.h"
-
-
-int main(int argc, char* argv[])
-{
- /* libdspl handle */
- void* hdspl;
-
- /* Load libdspl functions */
- hdspl = dspl_load();
-
- /* Check libdspl handle. */
- /* If hdspl == NULL means problem with libdspl loading */
- if(!hdspl)
- {
- printf("libdspl loading error!\n");
- return -1;
- }
-
- /* Print libdspl info */
- dspl_info();
-
-
- /* free dspl handle */
- dspl_free(hdspl);
- return 0;
-}
-
diff --git a/dspl/Makefile b/dspl/Makefile
index 93dac4a..2113580 100644
--- a/dspl/Makefile
+++ b/dspl/Makefile
@@ -2,13 +2,12 @@
include ../make.inc
# C-compiler flags
-CFLAGS = -c -fPIC -Wall -O3 -I$(INC_DIR) -DBUILD_LIB -D$(DEF_OS)
+CFLAGS = -c -fPIC -Wall -O3 -I$(INC_DIR) -Isrc -DBUILD_LIB -D$(DEF_OS)
# DSPL src and obj files list
DSPL_SRC_FILES = $(wildcard $(DSPL_SRC_DIR)/*.c)
DSPL_OBJ_FILES = $(addprefix $(DSPL_OBJ_DIR)/,$(notdir $(DSPL_SRC_FILES:.c=.o)))
-
all: $(RELEASE_DIR)/$(LIB_NAME)\
$(EXAMPLE_BIN_DIR)/$(LIB_NAME)\
$(PERFORMANCE_BIN_DIR)/$(LIB_NAME)\
@@ -18,7 +17,7 @@ all: $(RELEASE_DIR)/$(LIB_NAME)\
#Build libdspl.dll or libdspl.so
$(RELEASE_DIR)/$(LIB_NAME): $(DSPL_OBJ_FILES) $(BLAS_LIB_NAME) $(LAPACK_DOUBLE_LIB_NAME) $(LAPACK_COMPLEX_LIB_NAME)
- $(CC) -shared -o $(RELEASE_DIR)/$(LIB_NAME) $(DSPL_OBJ_FILES) -lm -L$(LAPACK_RELEASE_DIR) -llapack_complex -llapack_double -L$(BLAS_RELEASE_DIR) -lblas -lgfortran -lquadmath
+ $(CC) -shared -o $(RELEASE_DIR)/$(LIB_NAME) $(DSPL_OBJ_FILES) -lm -L$(LAPACK_RELEASE_DIR) -llapack_complex -llapack_double -L$(BLAS_RELEASE_DIR) -lblas -lgfortran -lquadmath
#Compile libdspl obj files from c sources
$(DSPL_OBJ_DIR)/%.o:$(DSPL_SRC_DIR)/%.c
diff --git a/dspl/src/array.c b/dspl/src/array.c
index d5c573f..ccef1e1 100644
--- a/dspl/src/array.c
+++ b/dspl/src/array.c
@@ -1,1410 +1,15 @@
-/*
-* Copyright (c) 2015-2020 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of libdspl-2.0.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DSPL is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Foobar. If not, see .
-*/
-
-
-
-
-#include
-#include
-#include
-#include "dspl.h"
-#include "blas.h"
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int array_scale_lin(double* x, int n,
- double xmin, double xmax, double dx,
- double h, double* y)
-\brief Vector `x` linear transformation
-
-Function transforms values \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
-to the \f$y(i)\f$, accordint to equation:
-
-\f[
-y(i) = k_x x(i) + d_x, \qquad k_x =
-\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
-\f]
-
-All values of the vector `x` between
-\f$x_{\textrm{min}}\f$ and \f$x_{\textrm{max}}\f$, transforms to
-the vector `y` between \f$d_x\f$ and \f$h + d_x\f$.
-Parameter \f$d_x\f$ sets mean shift of the vector `y`.
-
-This function is convenient for translating values
-of different dimensions. For example it can be used
-to transfer the values of the vector `x`
-to the graph of the height of` h`, where the height can
-be set in the number of pixels, in centimeters, etc.
-
-\param[in] x
-Pointer to the input vector `x`. \n
-Vector size is `[n x 1]`. \n
-\n
-
-\param[in] n
-Size of vector `x`. \n
-\n
-
-\param[in] xmin
-Parameter \f$x_{\textrm{min}}\f$. \n
-\n
-
-\param[in] xmax
-Parameter \f$x_{\textrm{min}}\f$. \n
-Value `xmax` must be more than `xmin`. \n
-\n
-
-\param[in] dx
-Displacement after transformation. \n
-This parameter must have output vector `y`
-dimensions (pixels, centimeters). \n
-\n
-
-\param[in] h
-Height of vector `y` after transforming between `dx` and `h+dx`. \n
-\n
-
-\param[out] y
-Pointer to the output vector `y`. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n
-\note
-Pointer `y` can be equal to `x`.
-Velues of vector `x` will be rewritten in this case. \n
-\n
-
-\return
-`RES_OK` if function returns successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int array_scale_lin(double* x, int n,
- double xmin, double xmax, double dx,
- double h, double* y)
-\brief Линейное растяжение вектора данных `x`
-Функция производит преобразование значений \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
-в значения \f$y(i)\f$, в соответствии с формулой:
-
-\f[
-y(i) = k_x x(i) + d_x, \qquad k_x =
-\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
-\f]
-
-Таким образом, все значения входного вектора `x` в диапазоне от
-\f$x_{\textrm{min}}\f$ до \f$x_{\textrm{max}}\f$, линейно растягиваются в
-значения вектора `y` в диапазоне от \f$d_x\f$ до \f$h + d_x\f$.
-Заметим, что \f$d_x\f$ задает линейное смещение значений вектора `y`.
-
-Данная функция удобна для перевода величин разных размерностей, в частности,
-для переноса значений вектора `x` на график высоты `h`, где высота может
-быть задана в количестве пикселей, в сантиметрах и т.д.
-
-\param[in] x
-Указатель на вектор входных значений `x`. \n
-Размер вектора `[n x 1]`. \n
-\n
-
-\param[in] n
-Размер вектора `x`. \n
-\n
-
-\param[in] xmin
-Нижняя граница диапазона трансформации. \n
-\n
-
-\param[in] xmax
-Верхняя граница диапазона трансформации. \n
-Значение `xmax` должно быть строго больше значения `xmin`. \n
-\n
-
-\param[in] dx
-Смещение после трансформации. \n
-Данный параметр должен иметь размерность выходного вектора `y`. \n
-\n
-
-\param[in] h
-Диапазон значений вектора `y` после трансформации от `dx` до `h+dx`. \n
-\n
-
-\param[out] y
-Указатель на вектора данных после трансформации. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
-\note
-Указатель `y` может совпадать с `x`, в этом случае,
-данные вектора `x` будут перезаписаны линейно измененными в соответствии
-с формулой выше. \n
-\n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API array_scale_lin(double* x, int n,
- double xmin, double xmax, double dx,
- double h, double* y)
-{
- double kx;
- int k;
- if(!x)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(h<0.0)
- return ERROR_NEGATIVE;
-
- if(xmin >= xmax)
- return ERROR_MIN_MAX;
-
- kx = h / (xmax - xmin);
-
- for(k = 0; k < n; k++)
- y[k] = (x[k] - xmin) * kx + dx;
-
- return RES_OK;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
-\brief
-Concatenate arrays `a` and `b`
-
-Let's arrays `a` and `b` are vectors: \n
-`a = [a(0), a(1), ... a(na-1)]`, \n
-`b = [b(0), b(1), ... b(nb-1)]`, \n
-concatenation of these arrays will be array `c` size `na+nb`: \n
-`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
-
-
-\param[in] a
-Pointer to the first array `a`. \n
-Array `a` size is `na` bytes. \n
-\n
-
-\param[in] na
-Array `a` size (bytes). \n
-\n
-
-\param[in] b
-Pointer to the second array `b`. \n
-Array `b` size is `nb` bytes. \n
-\n
-
-\param[in] nb
-Array `a` size (bytes). \n
-\n
-
-\param[out] c
-Pointer to the concatenation result array `c`. \n
-Array `c` size is `na + nb` bytes. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if function returns successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Function uses pointer type `void*` and can be useful for an arrays
-concatenation with different types. \n
-For example two `double` arrays concatenation:
-\code{.cpp}
-double a[3] = {1.0, 2.0, 3.0};
-double b[2] = {4.0, 5.0};
-double c[5];
-
-concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
-\endcode
-Vector `c` keeps follow data:
-\verbatim
-c = [1.0, 2.0, 3.0, 4.0, 5.0]
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
-\brief Конкатенация двух массивов данных
-
-Функция производит конкатенацию двух массивов. Пусть массивы `a` и `b`
-заданы как векторы: \n
-`a = [a(0), a(1), ... a(na-1)]`, \n
-`b = [b(0), b(1), ... b(nb-1)]`, \n
-тогда результатом конкатенации будет вектор размера `na+nb` вида: \n
-`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
-
-
-\param[in] a
-Указатель на первый вектор `a`. \n
-Размер вектора `na` байт. \n \n
-
-\param[in] na
-Размер первого вектора `a` в байт. \n \n
-
-\param[in] b
-Указатель на второй вектор `b`. \n
-Размер памяти вектора `nb` байт. \n \n
-
-\param[in] nb
-Размер второго вектора `b` в байт. \n \n
-
-\param[out] c
-Указатель на вектор конкатенации `c`. \n
-Размер памяти вектора `na + nb` байт. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\note
-Функция использует указатели типа `void*` и может быть использована для
-конкатенации данных различного типа. \n
-Например конкатенация массивов типа `double`:
-\code{.cpp}
-double a[3] = {1.0, 2.0, 3.0};
-double b[2] = {4.0, 5.0};
-double c[5];
-concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
-\endcode
-в результате вектор `c` будет хранить массив данных:
-\verbatim
-c = [1.0, 2.0, 3.0, 4.0, 5.0]
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API concat(void* a, size_t na, void* b, size_t nb, void* c)
-{
- if(!a || !b || !c || c == b)
- return ERROR_PTR;
- if(na < 1 || nb < 1)
- return ERROR_SIZE;
-
- if(c != a)
- memcpy(c, a, na);
-
- memcpy((char*)c+na, b, nb);
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int decimate(double* x, int n, int d, double* y, int* cnt)
-\brief
-Real vector decimation
-
-Function `d` times decimates real vector `x`. \n
-Output vector `y` keeps values corresponds to:
-`y(k) = x(k*d), k = 0...n/d-1` \n
-
-\param[in] x
-Pointer to the input real vector `x`. \n
-Vector `x` size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of input vector `x`. \n \n
-
-\param[in] d
-Decimation coefficient. \n
-Each d-th vector will be copy from vector `x` to the
-output vector `y`. \n \n
-
-\param[out] y
-Pointer to the output decimated vector `y`. \n
-Output vector size is `[n/d x 1]` will be copy
-to the address `cnt`. \n
-
-\param[out] cnt
-Address which will keep decimated vector `y` size. \n
-Pointer can be `NULL`, vector `y` will not return
-in this case. \n \n
-
-\return
-`RES_OK` if function calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Two-times decimation example:
-\code{.cpp}
-double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
-double y[5];
-int d = 2;
-int cnt;
-
-decimate(x, 10, d, y, &cnt);
-\endcode
-As result variable `cnt` will be written value 5 and
-vector `y` will keep array:
-\verbatim
-c = [0.0, 2.0, 4.0, 6.0, 8.0]
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int decimate(double* x, int n, int d, double* y, int* cnt)
-\brief Децимация вещественного вектора данных
-
-Функция производит децимацию вещественного вектора `x` в `d` раз. \n
-В результате выходной вектор `y` содержит значения:
-`y(k) = x(k*d), k = 0...n/d-1` \n
-
-\param[in] x
-Указатель на вектор входных данных `x`. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер входного вектора `x`. \n \n
-
-\param[in] d
-Коэффициент децимации. \n
-В результате децимации из вектора `x` будет взять каждый
-d-й элемент. \n \n
-
-\param[out] y
-Указатель на децимированный вектор `y`. \n
-Размер выходного вектора равен `[n/d x 1]`
-будет сохранен по адресу `cnt`. \n
-Память должна быть выделена. \n \n
-
-\param[out] cnt
-Указатель переменную, в которую будет сохранен
-размер выходного вектора после децимации. \n
-Указатель может быть `NULL`, в этом случае
-размер вектора `y` не возвращается. \n \n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример децимации вещественного массива данных в 2 раза:
-\code{.cpp}
-double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
-double y[5];
-int d = 2;
-int cnt;
-decimate(x, 10, d, y, &cnt);
-\endcode
-В результате в переменную `cnt` будет записан размер 5,
-а вектор `y` будет хранить массив данных:
-\verbatim
-c = [0.0, 2.0, 4.0, 6.0, 8.0]
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-#endif
-int DSPL_API decimate(double* x, int n, int d, double* y, int* cnt)
-{
- int k = 0, i = 0;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(d < 1)
- return ERROR_NEGATIVE;
-
- k = i = 0;
- while(k + d <= n)
- {
- y[i] = x[k];
- k+=d;
- i++;
- }
- if(cnt)
- *cnt = i;
-
- return RES_OK;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
-\brief
-Complex vector decimation
-
-Function `d` times decimates a complex vector `x`. \n
-Output vector `y` keeps values corresponds to:
-`y(k) = x(k*d), k = 0...n/d-1` \n
-
-\param[in] x
-Pointer to the input complex vector `x`. \n
-Vector `x` size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of input vector `x`. \n \n
-
-\param[in] d
-Decimation coefficient. \n
-Each d-th vector will be copy from vector `x` to the
-output vector `y`. \n \n
-
-\param[out] y
-Pointer to the output decimated vector `y`. \n
-Output vector size is `[n/d x 1]` will be copy
-to the address `cnt`. \n
-Memory must be allocated. \n \n
-
-\param[out] cnt
-Address which will keep decimated vector `y` size. \n
-Pointer can be `NULL`, vector `y` will not return
-in this case. \n \n
-
-\return
-`RES_OK` if function calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Two-times complex vector decimation example:
-
-\code{.cpp}
-compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
-{5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
-compex_t y[5];
-int d = 2;
-int cnt;
-
-decimate_cmplx(x, 10, d, y, &cnt);
-\endcode
-
-As result variable `cnt` will be written value 5 and
-vector `y` will keep array:
-
-\verbatim
-c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
-\brief Децимация комплексного вектора данных
-
-Функция производит децимацию комплексного вектора `x` в `d` раз. \n
-В результате выходной вектор `y` содержит значения:
-`y(k) = x(k*d), k = 0...n/d-1` \n
-
-\param[in] x
-Указатель на вектор входных данных `x`. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер входного вектора `x`. \n \n
-
-\param[in] d
-Коэффициент децимации. \n
-В результате децимации из вектора `x` будет взять каждый d-й элемент. \n \n
-
-\param[out] y
-Указатель на децимированный вектор `y`. \n
-Размер выходного вектора равен `[n/d x 1]` будет сохранен по адресу `cnt`. \n
-Память должна быть выделена. \n \n
-
-\param[out] cnt
-Указатель переменную, в которую будет сохранен
-размер выходного вектора после децимации. \n
-Указатель может быть `NULL`, в этом случае
-размер вектора `y` не возвращается. \n \n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример децимации комплексного массива данных в 2 раза:
-\code{.cpp}
-compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
- {5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
-compex_t y[5];
-int d = 2;
-int cnt;
-decimate_cmplx(x, 10, d, y, &cnt);
-\endcode
-В результате в переменную `cnt` будет записан размер 5, а вектор `y` будет
-хранить массив данных:
-\verbatim
-c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
-{
- int k = 0, i = 0;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(d < 1)
- return ERROR_NEGATIVE;
-
- k = i = 0;
- while(k + d < n)
- {
- RE(y[i]) = RE(x[k]);
- IM(y[i]) = IM(x[k]);
- k+=d;
- i++;
- }
- if(cnt)
- *cnt = i;
-
- return RES_OK;
-}
-
-
-
-
-int DSPL_API find_nearest(double* x, int n, double val, int *idx, double* dist)
-{
- double mind, dv;
- int iv, i;
-
- if(!x)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
-
- mind = fabs(x[0] - val);
- iv = 0;
- for(i = 1; i < n; i++)
- {
- dv = fabs(x[i] - val);
- if( dv < mind)
- {
- mind = dv;
- iv = i;
- }
- }
-
- if(idx)
- *idx = iv;
- if(dist)
- *dist = fabs(x[iv] - val);
-
- return RES_OK;
-
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int flipip(double* x, int n)
-\brief
-Flip real vector `x` in place
-
-Function flips real vector `x` length `n` in the memory. \n
-For example real vector `x` length 6:\n
-\verbatim
-x = [0, 1, 2, 3, 4, 5]
-\endverbatim
-After flipping it will be as follow:
-\verbatim
-x = [5, 4, 3, 2, 1, 0]
-\endverbatim
-
-\param[in, out] x
-Pointer to the real vector `x`. \n
-Vector size is `[n x 1]`. \n
-Flipped vector will be on the same address. \n
-\n
-
-\param[in] n
-Length of the vector `x`. \n
-\n
-
-\return
-`RES_OK` if function returns successfully. \n
- Else \ref ERROR_CODE_GROUP "error code".
-
-Example:
-\code{.cpp}
-double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
-int i;
-for(i = 0; i < 5; i++)
- printf("%6.1f ", x[i]);
-flipip(x, 5);
-printf("\n");
-for(i = 0; i < 5; i++)
- printf("%6.1f ", x[i]);
-\endcode
-\n
-Program result:
-\verbatim
- 0.0 1.0 2.0 3.0 4.0
- 4.0 3.0 2.0 1.0 0.0
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int flipip(double* x, int n)
-\brief Функция отражения вещественного вектора `x`
-
-Функция производит отражение вещественного вектора длины `n`
-в памяти данных. \n
-Например исходный вектор `x` длины 6: \n
-\verbatim
-x = [0, 1, 2, 3, 4, 5]
-\endverbatim
-После отражения вектор `x` будет иметь вид:
-\verbatim
-x = [5, 4, 3, 2, 1, 0]
-\endverbatim
-
-\param[in, out] x
-Указатель на вещественный вектор `x`. \n
-Размер вектора `[n x 1]`. \n
-Результат отражения будет помещен по этому же адресу. \n
-
-\param[in] n
-Размер вектора `x`. \n \n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример:
-\code{.cpp}
-double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
-int i;
-for(i = 0; i < 5; i++)
- printf("%6.1f ", x[i]);
-flipip(x, 5);
-printf("\n");
-for(i = 0; i < 5; i++)
- printf("%6.1f ", x[i]);
-\endcode
-\n
-Результат выполнения:
-\verbatim
- 0.0 1.0 2.0 3.0 4.0
- 4.0 3.0 2.0 1.0 0.0
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API flipip(double* x, int n)
-{
- int k;
- double tmp;
- if(!x)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
-
- for(k = 0; k < n/2; k++)
- {
- tmp = x[k];
- x[k] = x[n-1-k];
- x[n-1-k] = tmp;
- }
- return RES_OK;
-
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int flipip_cmplx(complex_t* x, int n)
-\brief Flip complex vector `x` in place
-
-Function flips complex vector `x` length `n` in the memory
- \n
-For example complex vector `x` length 6: \n
-\verbatim
-x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
-\endverbatim
-After flipping it will be as follow:
-\verbatim
-x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
-\endverbatim
-
-\param[in, out] x
-Pointer to the complex vector `x`. \n
-Vector size is `[n x 1]`. \n
-Flipped vector will be on the same address. \n
-
-\param[in] n
-Length of the vector `x`. \n \n
-
-\return
-`RES_OK` if function returns successfully. \n
-Else \ref ERROR_CODE_GROUP "error code".
-
-Example:
-\code{.cpp}
-complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
-for(i = 0; i < 5; i++)
- printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
-flipip_cmplx(y, 5);
-printf("\n");
-for(i = 0; i < 5; i++)
- printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
-\endcode
- \n
-Program result:
-\verbatim
-0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
-4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int flipip_cmplx(complex_t* x, int n)
-\brief Функция отражения комплексного вектора `x`
-
-Функция производит отражение комплексного вектора длины `n`
-в памяти данных. \n
-Например исходный вектор `x` длины 6: \n
-\verbatim
-x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
-\endverbatim
-После отражения вектор `x` будет иметь вид:
-\verbatim
-x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
-\endverbatim
-
-\param[in, out] x
-Указатель на комплексный вектор `x`. \n
-Размер вектора `[n x 1]`. \n
-Результат отражения будет помещен по этому же адресу. \n
-\n
-
-\param[in] n
-Размер вектора `x`. \n
-\n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример:
-\code{.cpp}
-complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
-for(i = 0; i < 5; i++)
- printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
-flipip_cmplx(y, 5);
-printf("\n");
-for(i = 0; i < 5; i++)
- printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
-\endcode
- \n
-Результат выполнения:
-\verbatim
-0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
-4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API flipip_cmplx(complex_t* x, int n)
-{
- int k;
- complex_t tmp;
- if(!x)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
-
- for(k = 0; k < n/2; k++)
- {
- RE(tmp) = RE(x[k]);
- RE(x[k]) = RE(x[n-1-k]);
- RE(x[n-1-k]) = RE(tmp);
-
- IM(tmp) = IM(x[k]);
- IM(x[k]) = IM(x[n-1-k]);
- IM(x[n-1-k]) = IM(tmp);
- }
- return RES_OK;
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int linspace(double x0, double x1, int n, int type, double* x)
-\brief Function fills a vector with `n` linearly spaced elements
-between `x0` and `x1`.
-
-Function supports two kinds of filling according to `type` parameter: \n
-
-Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
-
-\f$x(k) = x_0 + k \cdot dx\f$,
-\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
-
-Periodic fill (parameter `type=DSPL_PERIODIC`): \n
-
-\f$x(k) = x_0 + k \cdot dx\f$,
-\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
-
-\param[in] x0
-Start point \f$x_0\f$. \n \n
-
-\param[in] x1
-End point \f$x_1\f$. \n \n
-
-\param[in] n
-Number of points `x` (size of vector `x`). \n \n
-
-\param[in] type
-Fill type: \n
-`DSPL_SYMMETRIC` --- symmetric, \n
-`DSPL_PERIODIC` --- periodic. \n \n
-
-\param[in,out] x
-Pointer to the output linearly spaced vector `x`. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function returns successfully. \n
- Else \ref ERROR_CODE_GROUP "error code".
-
-\note
-Difference between symmetric and periodic filling we can
-understand from the follow examples. \n
-Example 1. Periodic fill.
- double x[5];
- linspace(0, 5, 5, DSPL_PERIODIC, x);
-\endcode
-Values in the vector `x` are:
-\verbatim
-0, 1, 2, 3, 4
-\endverbatim
- \n \n
-Example 2. Symmetric fill.
-\code{.cpp}
- double x[5];
- linspace(0, 5, 5, DSPL_SYMMETRIC, x);
-\endcode
-Values in the vector `x` are:
-\verbatim
-0, 1.25, 2.5, 3.75, 5
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int linspace(double x0, double x1, int n, int type, double* x)
-\brief Функция заполняет массив линейно-нарастающими, равноотстоящими
-значениями от `x0` до `x1`
-
-Заполняет массив `x` длиной `n` значениями в диапазоне
-от \f$x_0\f$ до \f$x_1\f$. Функция поддерживает два типа заполнения
-в соответствии с параметром `type`: \n
-
-Симметричное заполнение согласно выражению (параметр `type=DSPL_SYMMETRIC`): \n
-
-\f$x(k) = x_0 + k \cdot dx\f$,
-\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
-
-Периодическое заполнение (параметр `type=DSPL_PERIODIC`) согласно выражению: \n
-
-\f$x(k) = x_0 + k \cdot dx\f$,
-\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
-
-\param[in] x0
-Начальное показателя \f$x_0\f$. \n \n
-
-\param[in] x1
-Конечное значение \f$x_1\f$. \n \n
-
-\param[in] n
-Количество точек массива `x`. \n \n
-
-\param[in] type
-Тип заполнения: \n
-
-`DSPL_SYMMETRIC` --- симметричное заполнение, \n
-`DSPL_PERIODIC` --- периодическое заполнение. \n \n
-
-\param[in,out] x
-Указатель на вектор равноотстоящих значений . \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` --- функция выполнена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-\note
-Отличие периодического и симметричного заполнения можно
-понять из следующих примеров. \n
-Пример 1. Периодическое заполнение.
-\code{.cpp}
- double x[5];
- linspace(0, 5, 5, DSPL_PERIODIC, x);
-\endcode
-В массиве `x` будут лежать значения:
-\verbatim
-0, 1, 2, 3, 4
-\endverbatim
- \n \n
-Пример 2. Симметричное заполнение.
-\code{.cpp}
- double x[5];
- linspace(0, 5, 5, DSPL_SYMMETRIC, x);
-\endcode
-В массиве `x` будут лежать значения:
-\verbatim
-0, 1.25, 2.5, 3.75, 5
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API linspace(double x0, double x1, int n, int type, double* x)
-{
- double dx;
- int k;
-
- if(n < 2)
- return ERROR_SIZE;
- if(!x)
- return ERROR_PTR;
-
- switch (type)
- {
- case DSPL_SYMMETRIC:
- dx = (x1 - x0)/(double)(n-1);
- x[0] = x0;
- for(k = 1; k < n; k++)
- x[k] = x[k-1] + dx;
- break;
- case DSPL_PERIODIC:
- dx = (x1 - x0)/(double)n;
- x[0] = x0;
- for(k = 1; k < n; k++)
- x[k] = x[k-1] + dx;
- break;
- default:
- return ERROR_SYM_TYPE;
- }
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int logspace(double x0, double x1, int n, int type, double* x)
-\brief Function fills a vector with `n` logarithmically spaced elements
-between \f$10^{x_0}\f$ and \f$10^{x_1}\f$.
-
-
-Function supports two kinds of filling according to `type` parameter: \n
-
-Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
-
-\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
-\f$k = 0 \ldots n-1.\f$
-
-Periodic fill (parameter `type=DSPL_PERIODIC`): \n
-
-\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
-\f$k = 0 \ldots n-1.\f$ \n
-
-
-\param[in] x0
-Start exponent value \f$x_0\f$. \n \n
-
-\param[in] x1
-End exponent value \f$x_1\f$. \n \n
-
-\param[in] n
-Number of points `x` (size of vector `x`). \n \n
-
-\param[in] type
-Fill type: \n
-`DSPL_SYMMETRIC` --- symmetric, \n
-`DSPL_PERIODIC` --- periodic. \n \n
-
-\param[in,out] x
-Pointer to the output logarithmically spaced vector `x` . \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function returns successfully. \n
- Else \ref ERROR_CODE_GROUP "error code".
-
-\note
-Difference between symmetric and periodic filling we can
-understand from the follow examples. \n
-Example 1. Periodic fill.
-\code{.cpp}
- double x[5];
- logspace(-2, 3, 5, DSPL_PERIODIC, x);
-\endcode
-
-Values in the vector `x` are:
-
-\verbatim
-0.01, 0.1, 1, 10, 100
-\endverbatim
-
-\n \n
-
-Example 2. Symmetric fill.
-\code{.cpp}
- double x[5];
- logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
-\endcode
-
-Values in the vector `x` are:
-
-\verbatim
-0.01 0.178 3.162 56.234 1000
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int logspace(double x0, double x1, int n, int type, double* x)
-\brief Функция заполняет массив значениями логарифмической шкале
-
-Заполняет массив `x` длиной `n` значениями в диапазоне
-от \f$10^{x_0}\f$ до \f$10^{x_1}\f$. \n
-Функция поддерживает два типа заполнения в соответствии с параметром `type`: \n
-
-Симметричное заполнение согласно выражению: \n
-
-\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
-\f$k = 0 \ldots n-1.\f$
-
-Периодическое заполнение согласно выражению:
-
-\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
-\f$k = 0 \ldots n-1.\f$ \n
-
-\param[in] x0
-Начальное значение показателя \f$x_0\f$. \n \n
-
-\param[in] x1
-Конечное значение показателя \f$x_1\f$. \n \n
-
-\param[in] n
-Количество точек массива `x`. \n \n
-
-\param[in] type
-Тип заполнения: \n
-`DSPL_SYMMETRIC` --- симметричное заполнение, \n
-`DSPL_PERIODIC` --- периодическое заполнение. \n \n
-
-\param[in,out] x
-Указатель на вектор значений в логарифмической шкале. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` --- функция выполнена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\note
-Отличие периодического и симметричного заполнения можно
-понять из следующих примеров. \n
-
-Пример 1. Периодическое заполнение.
-\code{.cpp}
- double x[5];
- logspace(-2, 3, 5, DSPL_PERIODIC, x);
-\endcode
-В массиве `x` будут лежать значения:
-\verbatim
-0.01, 0.1, 1, 10, 100
-\endverbatim
-\n \n
-
-Пример 2. Симметричное заполнение.
-\code{.cpp}
- double x[5];
- logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
-\endcode
-
-В массиве `x` будут лежать значения:
-
-\verbatim
-0.01 0.178 3.162 56.234 1000
-\endverbatim
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API logspace(double x0, double x1, int n, int type, double* x)
-{
- double mx, a, b;
- int k;
-
- if(n < 2)
- return ERROR_SIZE;
- if(!x)
- return ERROR_PTR;
-
- a = pow(10.0, x0);
- b = pow(10.0, x1);
-
- switch (type)
- {
- case DSPL_SYMMETRIC:
- mx = pow(b/a, 1.0/(double)(n-1));
- x[0] = a;
- for(k = 1; k < n; k++)
- x[k] = x[k-1] * mx;
- break;
- case DSPL_PERIODIC:
- mx = pow(b/a, 1.0/(double)n);
- x[0] = a;
- for(k = 1; k < n; k++)
- x[k] = x[k-1] * mx;
- break;
- default:
- return ERROR_SYM_TYPE;
- }
- return RES_OK;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int ones(double* x, int n)
-\brief Function fills all real vector `x` by ones values.
-
-\param[in, out] x
-Pointer to the vector `x`. \n
-Vector size is `[n x 1]`. \n
-All elements on this vector will be set to one. \n
-\n
-
-\param[in] n
-Size of vector `x`. \n
-\n
-
-\return
-`RES_OK` if function returns successfully. \n
- Else \ref ERROR_CODE_GROUP "error code".
-
-Example:
-\code{.cpp}
-double y[5] = {0};
-int i;
-ones(y, 5);
-for(i = 0; i < 5; i++)
- printf("%6.1f% ", y[i]);
-\endcode
- \n
-Vector `y` values are:
-\verbatim
- 1.0 1.0 1.0 1.0 1.0
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int ones(double* x, int n)
-\brief Функция заполнения вещественного массива единицами
-
-\param[in, out] x
-Указатель на вещественный вектор `x`. \n
-Размер вектора `[n x 1]`. \n
-Значения данного вектора будут установлены в единицу. \n
-\n
-
-\param[in] n
-Размер вектора `x`. \n
-\n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример:
-\code{.cpp}
-double y[5] = {0};
-int i;
-ones(y, 5);
-for(i = 0; i < 5; i++)
- printf("%6.1f% ", y[i]);
-\endcode
- \n
-Результат выполнения:
-\verbatim
- 1.0 1.0 1.0 1.0 1.0
-\endverbatim
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ones(double* x, int n)
-{
- int i;
- if(!x)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- for(i = 0; i < n; i++)
- x[i] = 1.0;
- return RES_OK;
-}
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int sum(double* x, int n, double* s)
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int sum(double* x, int n, double* s)
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API sum(double* x, int n, double* s)
-{
- int i;
- double z = 0.0;
- if(!x || !s)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
-
- for(i = 0; i < n; i++)
- z += x[i];
- *s = z;
- return RES_OK;
-}
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int sum(double* x, int n, double* s)
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup ARRAY_GROUP
-\fn int sum(double* x, int n, double* s)
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API sum_sqr(double* x, int n, double* s)
-{
- int i;
- double z = 0.0;
- if(!x || !s)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
-
- for(i = 0; i < n; i++)
- z += x[i]*x[i];
- *s = z;
- return RES_OK;
-}
-
-
-
-
-
+#include "array/array_scale_lin.c"
+#include "array/concat.c"
+#include "array/decimate.c"
+#include "array/decimate_cmplx.c"
+#include "array/find_nearest.c"
+#include "array/flipip.c"
+#include "array/flipip_cmplx.c"
+#include "array/linspace.c"
+#include "array/logspace.c"
+#include "array/ones.c"
+#include "array/sum.c"
+#include "array/sum_sqr.c"
+
+
+
diff --git a/dspl/src/array/array_scale_lin.c b/dspl/src/array/array_scale_lin.c
new file mode 100644
index 0000000..c4e009e
--- /dev/null
+++ b/dspl/src/array/array_scale_lin.c
@@ -0,0 +1,193 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int array_scale_lin(double* x, int n,
+ double xmin, double xmax, double dx,
+ double h, double* y)
+\brief Vector `x` linear transformation
+
+Function transforms values \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
+to the \f$y(i)\f$, accordint to equation:
+
+\f[
+y(i) = k_x x(i) + d_x, \qquad k_x =
+\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
+\f]
+
+All values of the vector `x` between
+\f$x_{\textrm{min}}\f$ and \f$x_{\textrm{max}}\f$, transforms to
+the vector `y` between \f$d_x\f$ and \f$h + d_x\f$.
+Parameter \f$d_x\f$ sets mean shift of the vector `y`.
+
+This function is convenient for translating values
+of different dimensions. For example it can be used
+to transfer the values of the vector `x`
+to the graph of the height of` h`, where the height can
+be set in the number of pixels, in centimeters, etc.
+
+\param[in] x
+Pointer to the input vector `x`. \n
+Vector size is `[n x 1]`. \n
+\n
+
+\param[in] n
+Size of vector `x`. \n
+\n
+
+\param[in] xmin
+Parameter \f$x_{\textrm{min}}\f$. \n
+\n
+
+\param[in] xmax
+Parameter \f$x_{\textrm{min}}\f$. \n
+Value `xmax` must be more than `xmin`. \n
+\n
+
+\param[in] dx
+Displacement after transformation. \n
+This parameter must have output vector `y`
+dimensions (pixels, centimeters). \n
+\n
+
+\param[in] h
+Height of vector `y` after transforming between `dx` and `h+dx`. \n
+\n
+
+\param[out] y
+Pointer to the output vector `y`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n
+\note
+Pointer `y` can be equal to `x`.
+Velues of vector `x` will be rewritten in this case. \n
+\n
+
+\return
+`RES_OK` if function returns successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int array_scale_lin(double* x, int n,
+ double xmin, double xmax, double dx,
+ double h, double* y)
+\brief Линейное растяжение вектора данных `x`
+Функция производит преобразование значений \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
+в значения \f$y(i)\f$, в соответствии с формулой:
+
+\f[
+y(i) = k_x x(i) + d_x, \qquad k_x =
+\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
+\f]
+
+Таким образом, все значения входного вектора `x` в диапазоне от
+\f$x_{\textrm{min}}\f$ до \f$x_{\textrm{max}}\f$, линейно растягиваются в
+значения вектора `y` в диапазоне от \f$d_x\f$ до \f$h + d_x\f$.
+Заметим, что \f$d_x\f$ задает линейное смещение значений вектора `y`.
+
+Данная функция удобна для перевода величин разных размерностей, в частности,
+для переноса значений вектора `x` на график высоты `h`, где высота может
+быть задана в количестве пикселей, в сантиметрах и т.д.
+
+\param[in] x
+Указатель на вектор входных значений `x`. \n
+Размер вектора `[n x 1]`. \n
+\n
+
+\param[in] n
+Размер вектора `x`. \n
+\n
+
+\param[in] xmin
+Нижняя граница диапазона трансформации. \n
+\n
+
+\param[in] xmax
+Верхняя граница диапазона трансформации. \n
+Значение `xmax` должно быть строго больше значения `xmin`. \n
+\n
+
+\param[in] dx
+Смещение после трансформации. \n
+Данный параметр должен иметь размерность выходного вектора `y`. \n
+\n
+
+\param[in] h
+Диапазон значений вектора `y` после трансформации от `dx` до `h+dx`. \n
+\n
+
+\param[out] y
+Указатель на вектора данных после трансформации. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n
+\note
+Указатель `y` может совпадать с `x`, в этом случае,
+данные вектора `x` будут перезаписаны линейно измененными в соответствии
+с формулой выше. \n
+\n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+
+int DSPL_API array_scale_lin(double* x, int n,
+ double xmin, double xmax, double dx,
+ double h, double* y)
+{
+ double kx;
+ int k;
+ if(!x)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(h<0.0)
+ return ERROR_NEGATIVE;
+
+ if(xmin >= xmax)
+ return ERROR_MIN_MAX;
+
+ kx = h / (xmax - xmin);
+
+ for(k = 0; k < n; k++)
+ y[k] = (x[k] - xmin) * kx + dx;
+
+ return RES_OK;
+}
diff --git a/dspl/src/array/concat.c b/dspl/src/array/concat.c
new file mode 100644
index 0000000..9e69666
--- /dev/null
+++ b/dspl/src/array/concat.c
@@ -0,0 +1,160 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
+\brief
+Concatenate arrays `a` and `b`
+
+Let's arrays `a` and `b` are vectors: \n
+`a = [a(0), a(1), ... a(na-1)]`, \n
+`b = [b(0), b(1), ... b(nb-1)]`, \n
+concatenation of these arrays will be array `c` size `na+nb`: \n
+`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
+
+
+\param[in] a
+Pointer to the first array `a`. \n
+Array `a` size is `na` bytes. \n
+\n
+
+\param[in] na
+Array `a` size (bytes). \n
+\n
+
+\param[in] b
+Pointer to the second array `b`. \n
+Array `b` size is `nb` bytes. \n
+\n
+
+\param[in] nb
+Array `a` size (bytes). \n
+\n
+
+\param[out] c
+Pointer to the concatenation result array `c`. \n
+Array `c` size is `na + nb` bytes. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if function returns successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Function uses pointer type `void*` and can be useful for an arrays
+concatenation with different types. \n
+For example two `double` arrays concatenation:
+\code{.cpp}
+double a[3] = {1.0, 2.0, 3.0};
+double b[2] = {4.0, 5.0};
+double c[5];
+
+concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
+\endcode
+Vector `c` keeps follow data:
+\verbatim
+c = [1.0, 2.0, 3.0, 4.0, 5.0]
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
+\brief Конкатенация двух массивов данных
+
+Функция производит конкатенацию двух массивов. Пусть массивы `a` и `b`
+заданы как векторы: \n
+`a = [a(0), a(1), ... a(na-1)]`, \n
+`b = [b(0), b(1), ... b(nb-1)]`, \n
+тогда результатом конкатенации будет вектор размера `na+nb` вида: \n
+`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
+
+
+\param[in] a
+Указатель на первый вектор `a`. \n
+Размер вектора `na` байт. \n \n
+
+\param[in] na
+Размер первого вектора `a` в байт. \n \n
+
+\param[in] b
+Указатель на второй вектор `b`. \n
+Размер памяти вектора `nb` байт. \n \n
+
+\param[in] nb
+Размер второго вектора `b` в байт. \n \n
+
+\param[out] c
+Указатель на вектор конкатенации `c`. \n
+Размер памяти вектора `na + nb` байт. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\note
+Функция использует указатели типа `void*` и может быть использована для
+конкатенации данных различного типа. \n
+Например конкатенация массивов типа `double`:
+\code{.cpp}
+double a[3] = {1.0, 2.0, 3.0};
+double b[2] = {4.0, 5.0};
+double c[5];
+concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
+\endcode
+в результате вектор `c` будет хранить массив данных:
+\verbatim
+c = [1.0, 2.0, 3.0, 4.0, 5.0]
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API concat(void* a, size_t na, void* b, size_t nb, void* c)
+{
+ if(!a || !b || !c || c == b)
+ return ERROR_PTR;
+ if(na < 1 || nb < 1)
+ return ERROR_SIZE;
+
+ if(c != a)
+ memcpy(c, a, na);
+
+ memcpy((char*)c+na, b, nb);
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/array/decimate.c b/dspl/src/array/decimate.c
new file mode 100644
index 0000000..6670147
--- /dev/null
+++ b/dspl/src/array/decimate.c
@@ -0,0 +1,162 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int decimate(double* x, int n, int d, double* y, int* cnt)
+\brief
+Real vector decimation
+
+Function `d` times decimates real vector `x`. \n
+Output vector `y` keeps values corresponds to:
+`y(k) = x(k*d), k = 0...n/d-1` \n
+
+\param[in] x
+Pointer to the input real vector `x`. \n
+Vector `x` size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of input vector `x`. \n \n
+
+\param[in] d
+Decimation coefficient. \n
+Each d-th vector will be copy from vector `x` to the
+output vector `y`. \n \n
+
+\param[out] y
+Pointer to the output decimated vector `y`. \n
+Output vector size is `[n/d x 1]` will be copy
+to the address `cnt`. \n
+
+\param[out] cnt
+Address which will keep decimated vector `y` size. \n
+Pointer can be `NULL`, vector `y` will not return
+in this case. \n \n
+
+\return
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Two-times decimation example:
+\code{.cpp}
+double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
+double y[5];
+int d = 2;
+int cnt;
+
+decimate(x, 10, d, y, &cnt);
+\endcode
+As result variable `cnt` will be written value 5 and
+vector `y` will keep array:
+\verbatim
+c = [0.0, 2.0, 4.0, 6.0, 8.0]
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int decimate(double* x, int n, int d, double* y, int* cnt)
+\brief Децимация вещественного вектора данных
+
+Функция производит децимацию вещественного вектора `x` в `d` раз. \n
+В результате выходной вектор `y` содержит значения:
+`y(k) = x(k*d), k = 0...n/d-1` \n
+
+\param[in] x
+Указатель на вектор входных данных `x`. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер входного вектора `x`. \n \n
+
+\param[in] d
+Коэффициент децимации. \n
+В результате децимации из вектора `x` будет взять каждый
+d-й элемент. \n \n
+
+\param[out] y
+Указатель на децимированный вектор `y`. \n
+Размер выходного вектора равен `[n/d x 1]`
+будет сохранен по адресу `cnt`. \n
+Память должна быть выделена. \n \n
+
+\param[out] cnt
+Указатель переменную, в которую будет сохранен
+размер выходного вектора после децимации. \n
+Указатель может быть `NULL`, в этом случае
+размер вектора `y` не возвращается. \n \n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример децимации вещественного массива данных в 2 раза:
+\code{.cpp}
+double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
+double y[5];
+int d = 2;
+int cnt;
+decimate(x, 10, d, y, &cnt);
+\endcode
+В результате в переменную `cnt` будет записан размер 5,
+а вектор `y` будет хранить массив данных:
+\verbatim
+c = [0.0, 2.0, 4.0, 6.0, 8.0]
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+**************************************************************************** */
+#endif
+int DSPL_API decimate(double* x, int n, int d, double* y, int* cnt)
+{
+ int k = 0, i = 0;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(d < 1)
+ return ERROR_NEGATIVE;
+
+ k = i = 0;
+ while(k + d <= n)
+ {
+ y[i] = x[k];
+ k+=d;
+ i++;
+ }
+ if(cnt)
+ *cnt = i;
+
+ return RES_OK;
+}
+
diff --git a/dspl/src/array/decimate_cmplx.c b/dspl/src/array/decimate_cmplx.c
new file mode 100644
index 0000000..8e86770
--- /dev/null
+++ b/dspl/src/array/decimate_cmplx.c
@@ -0,0 +1,167 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
+\brief
+Complex vector decimation
+
+Function `d` times decimates a complex vector `x`. \n
+Output vector `y` keeps values corresponds to:
+`y(k) = x(k*d), k = 0...n/d-1` \n
+
+\param[in] x
+Pointer to the input complex vector `x`. \n
+Vector `x` size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of input vector `x`. \n \n
+
+\param[in] d
+Decimation coefficient. \n
+Each d-th vector will be copy from vector `x` to the
+output vector `y`. \n \n
+
+\param[out] y
+Pointer to the output decimated vector `y`. \n
+Output vector size is `[n/d x 1]` will be copy
+to the address `cnt`. \n
+Memory must be allocated. \n \n
+
+\param[out] cnt
+Address which will keep decimated vector `y` size. \n
+Pointer can be `NULL`, vector `y` will not return
+in this case. \n \n
+
+\return
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Two-times complex vector decimation example:
+
+\code{.cpp}
+compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
+{5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
+compex_t y[5];
+int d = 2;
+int cnt;
+
+decimate_cmplx(x, 10, d, y, &cnt);
+\endcode
+
+As result variable `cnt` will be written value 5 and
+vector `y` will keep array:
+
+\verbatim
+c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
+\brief Децимация комплексного вектора данных
+
+Функция производит децимацию комплексного вектора `x` в `d` раз. \n
+В результате выходной вектор `y` содержит значения:
+`y(k) = x(k*d), k = 0...n/d-1` \n
+
+\param[in] x
+Указатель на вектор входных данных `x`. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер входного вектора `x`. \n \n
+
+\param[in] d
+Коэффициент децимации. \n
+В результате децимации из вектора `x` будет взять каждый d-й элемент. \n \n
+
+\param[out] y
+Указатель на децимированный вектор `y`. \n
+Размер выходного вектора равен `[n/d x 1]` будет сохранен по адресу `cnt`. \n
+Память должна быть выделена. \n \n
+
+\param[out] cnt
+Указатель переменную, в которую будет сохранен
+размер выходного вектора после децимации. \n
+Указатель может быть `NULL`, в этом случае
+размер вектора `y` не возвращается. \n \n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример децимации комплексного массива данных в 2 раза:
+\code{.cpp}
+compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
+ {5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
+compex_t y[5];
+int d = 2;
+int cnt;
+decimate_cmplx(x, 10, d, y, &cnt);
+\endcode
+В результате в переменную `cnt` будет записан размер 5, а вектор `y` будет
+хранить массив данных:
+\verbatim
+c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
+{
+ int k = 0, i = 0;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(d < 1)
+ return ERROR_NEGATIVE;
+
+ k = i = 0;
+ while(k + d < n)
+ {
+ RE(y[i]) = RE(x[k]);
+ IM(y[i]) = IM(x[k]);
+ k+=d;
+ i++;
+ }
+ if(cnt)
+ *cnt = i;
+
+ return RES_OK;
+}
+
diff --git a/dspl/src/array/find_nearest.c b/dspl/src/array/find_nearest.c
new file mode 100644
index 0000000..f5fb3e5
--- /dev/null
+++ b/dspl/src/array/find_nearest.c
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+int DSPL_API find_nearest(double* x, int n, double val, int *idx, double* dist)
+{
+ double mind, dv;
+ int iv, i;
+
+ if(!x)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+
+ mind = fabs(x[0] - val);
+ iv = 0;
+ for(i = 1; i < n; i++)
+ {
+ dv = fabs(x[i] - val);
+ if( dv < mind)
+ {
+ mind = dv;
+ iv = i;
+ }
+ }
+
+ if(idx)
+ *idx = iv;
+ if(dist)
+ *dist = fabs(x[iv] - val);
+
+ return RES_OK;
+
+}
\ No newline at end of file
diff --git a/dspl/src/array/flipip.c b/dspl/src/array/flipip.c
new file mode 100644
index 0000000..4b778b0
--- /dev/null
+++ b/dspl/src/array/flipip.c
@@ -0,0 +1,151 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int flipip(double* x, int n)
+\brief
+Flip real vector `x` in place
+
+Function flips real vector `x` length `n` in the memory. \n
+For example real vector `x` length 6:\n
+\verbatim
+x = [0, 1, 2, 3, 4, 5]
+\endverbatim
+After flipping it will be as follow:
+\verbatim
+x = [5, 4, 3, 2, 1, 0]
+\endverbatim
+
+\param[in, out] x
+Pointer to the real vector `x`. \n
+Vector size is `[n x 1]`. \n
+Flipped vector will be on the same address. \n
+\n
+
+\param[in] n
+Length of the vector `x`. \n
+\n
+
+\return
+`RES_OK` if function returns successfully. \n
+ Else \ref ERROR_CODE_GROUP "error code".
+
+Example:
+\code{.cpp}
+double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
+int i;
+for(i = 0; i < 5; i++)
+ printf("%6.1f ", x[i]);
+flipip(x, 5);
+printf("\n");
+for(i = 0; i < 5; i++)
+ printf("%6.1f ", x[i]);
+\endcode
+\n
+Program result:
+\verbatim
+ 0.0 1.0 2.0 3.0 4.0
+ 4.0 3.0 2.0 1.0 0.0
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int flipip(double* x, int n)
+\brief Функция отражения вещественного вектора `x`
+
+Функция производит отражение вещественного вектора длины `n`
+в памяти данных. \n
+Например исходный вектор `x` длины 6: \n
+\verbatim
+x = [0, 1, 2, 3, 4, 5]
+\endverbatim
+После отражения вектор `x` будет иметь вид:
+\verbatim
+x = [5, 4, 3, 2, 1, 0]
+\endverbatim
+
+\param[in, out] x
+Указатель на вещественный вектор `x`. \n
+Размер вектора `[n x 1]`. \n
+Результат отражения будет помещен по этому же адресу. \n
+
+\param[in] n
+Размер вектора `x`. \n \n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример:
+\code{.cpp}
+double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
+int i;
+for(i = 0; i < 5; i++)
+ printf("%6.1f ", x[i]);
+flipip(x, 5);
+printf("\n");
+for(i = 0; i < 5; i++)
+ printf("%6.1f ", x[i]);
+\endcode
+\n
+Результат выполнения:
+\verbatim
+ 0.0 1.0 2.0 3.0 4.0
+ 4.0 3.0 2.0 1.0 0.0
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API flipip(double* x, int n)
+{
+ int k;
+ double tmp;
+ if(!x)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
+ for(k = 0; k < n/2; k++)
+ {
+ tmp = x[k];
+ x[k] = x[n-1-k];
+ x[n-1-k] = tmp;
+ }
+ return RES_OK;
+
+}
+
diff --git a/dspl/src/array/flipip_cmplx.c b/dspl/src/array/flipip_cmplx.c
new file mode 100644
index 0000000..6926600
--- /dev/null
+++ b/dspl/src/array/flipip_cmplx.c
@@ -0,0 +1,155 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int flipip_cmplx(complex_t* x, int n)
+\brief Flip complex vector `x` in place
+
+Function flips complex vector `x` length `n` in the memory
+ \n
+For example complex vector `x` length 6: \n
+\verbatim
+x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
+\endverbatim
+After flipping it will be as follow:
+\verbatim
+x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
+\endverbatim
+
+\param[in, out] x
+Pointer to the complex vector `x`. \n
+Vector size is `[n x 1]`. \n
+Flipped vector will be on the same address. \n
+
+\param[in] n
+Length of the vector `x`. \n \n
+
+\return
+`RES_OK` if function returns successfully. \n
+Else \ref ERROR_CODE_GROUP "error code".
+
+Example:
+\code{.cpp}
+complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
+for(i = 0; i < 5; i++)
+ printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
+flipip_cmplx(y, 5);
+printf("\n");
+for(i = 0; i < 5; i++)
+ printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
+\endcode
+ \n
+Program result:
+\verbatim
+0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
+4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int flipip_cmplx(complex_t* x, int n)
+\brief Функция отражения комплексного вектора `x`
+
+Функция производит отражение комплексного вектора длины `n`
+в памяти данных. \n
+Например исходный вектор `x` длины 6: \n
+\verbatim
+x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
+\endverbatim
+После отражения вектор `x` будет иметь вид:
+\verbatim
+x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
+\endverbatim
+
+\param[in, out] x
+Указатель на комплексный вектор `x`. \n
+Размер вектора `[n x 1]`. \n
+Результат отражения будет помещен по этому же адресу. \n
+\n
+
+\param[in] n
+Размер вектора `x`. \n
+\n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример:
+\code{.cpp}
+complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
+for(i = 0; i < 5; i++)
+ printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
+flipip_cmplx(y, 5);
+printf("\n");
+for(i = 0; i < 5; i++)
+ printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
+\endcode
+ \n
+Результат выполнения:
+\verbatim
+0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
+4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API flipip_cmplx(complex_t* x, int n)
+{
+ int k;
+ complex_t tmp;
+ if(!x)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
+ for(k = 0; k < n/2; k++)
+ {
+ RE(tmp) = RE(x[k]);
+ RE(x[k]) = RE(x[n-1-k]);
+ RE(x[n-1-k]) = RE(tmp);
+
+ IM(tmp) = IM(x[k]);
+ IM(x[k]) = IM(x[n-1-k]);
+ IM(x[n-1-k]) = IM(tmp);
+ }
+ return RES_OK;
+}
+
+
+
diff --git a/dspl/src/array/linspace.c b/dspl/src/array/linspace.c
new file mode 100644
index 0000000..4791a83
--- /dev/null
+++ b/dspl/src/array/linspace.c
@@ -0,0 +1,199 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int linspace(double x0, double x1, int n, int type, double* x)
+\brief Function fills a vector with `n` linearly spaced elements
+between `x0` and `x1`.
+
+Function supports two kinds of filling according to `type` parameter: \n
+
+Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
+
+\f$x(k) = x_0 + k \cdot dx\f$,
+\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
+
+Periodic fill (parameter `type=DSPL_PERIODIC`): \n
+
+\f$x(k) = x_0 + k \cdot dx\f$,
+\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
+
+\param[in] x0
+Start point \f$x_0\f$. \n \n
+
+\param[in] x1
+End point \f$x_1\f$. \n \n
+
+\param[in] n
+Number of points `x` (size of vector `x`). \n \n
+
+\param[in] type
+Fill type: \n
+`DSPL_SYMMETRIC` --- symmetric, \n
+`DSPL_PERIODIC` --- periodic. \n \n
+
+\param[in,out] x
+Pointer to the output linearly spaced vector `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function returns successfully. \n
+ Else \ref ERROR_CODE_GROUP "error code".
+
+\note
+Difference between symmetric and periodic filling we can
+understand from the follow examples. \n
+Example 1. Periodic fill.
+ double x[5];
+ linspace(0, 5, 5, DSPL_PERIODIC, x);
+\endcode
+Values in the vector `x` are:
+\verbatim
+0, 1, 2, 3, 4
+\endverbatim
+ \n \n
+Example 2. Symmetric fill.
+\code{.cpp}
+ double x[5];
+ linspace(0, 5, 5, DSPL_SYMMETRIC, x);
+\endcode
+Values in the vector `x` are:
+\verbatim
+0, 1.25, 2.5, 3.75, 5
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int linspace(double x0, double x1, int n, int type, double* x)
+\brief Функция заполняет массив линейно-нарастающими, равноотстоящими
+значениями от `x0` до `x1`
+
+Заполняет массив `x` длиной `n` значениями в диапазоне
+от \f$x_0\f$ до \f$x_1\f$. Функция поддерживает два типа заполнения
+в соответствии с параметром `type`: \n
+
+Симметричное заполнение согласно выражению (параметр `type=DSPL_SYMMETRIC`): \n
+
+\f$x(k) = x_0 + k \cdot dx\f$,
+\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
+
+Периодическое заполнение (параметр `type=DSPL_PERIODIC`) согласно выражению: \n
+
+\f$x(k) = x_0 + k \cdot dx\f$,
+\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
+
+\param[in] x0
+Начальное показателя \f$x_0\f$. \n \n
+
+\param[in] x1
+Конечное значение \f$x_1\f$. \n \n
+
+\param[in] n
+Количество точек массива `x`. \n \n
+
+\param[in] type
+Тип заполнения: \n
+
+`DSPL_SYMMETRIC` --- симметричное заполнение, \n
+`DSPL_PERIODIC` --- периодическое заполнение. \n \n
+
+\param[in,out] x
+Указатель на вектор равноотстоящих значений . \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` --- функция выполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+\note
+Отличие периодического и симметричного заполнения можно
+понять из следующих примеров. \n
+Пример 1. Периодическое заполнение.
+\code{.cpp}
+ double x[5];
+ linspace(0, 5, 5, DSPL_PERIODIC, x);
+\endcode
+В массиве `x` будут лежать значения:
+\verbatim
+0, 1, 2, 3, 4
+\endverbatim
+ \n \n
+Пример 2. Симметричное заполнение.
+\code{.cpp}
+ double x[5];
+ linspace(0, 5, 5, DSPL_SYMMETRIC, x);
+\endcode
+В массиве `x` будут лежать значения:
+\verbatim
+0, 1.25, 2.5, 3.75, 5
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API linspace(double x0, double x1, int n, int type, double* x)
+{
+ double dx;
+ int k;
+
+ if(n < 2)
+ return ERROR_SIZE;
+ if(!x)
+ return ERROR_PTR;
+
+ switch (type)
+ {
+ case DSPL_SYMMETRIC:
+ dx = (x1 - x0)/(double)(n-1);
+ x[0] = x0;
+ for(k = 1; k < n; k++)
+ x[k] = x[k-1] + dx;
+ break;
+ case DSPL_PERIODIC:
+ dx = (x1 - x0)/(double)n;
+ x[0] = x0;
+ for(k = 1; k < n; k++)
+ x[k] = x[k-1] + dx;
+ break;
+ default:
+ return ERROR_SYM_TYPE;
+ }
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/array/logspace.c b/dspl/src/array/logspace.c
new file mode 100644
index 0000000..9b95bf9
--- /dev/null
+++ b/dspl/src/array/logspace.c
@@ -0,0 +1,211 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int logspace(double x0, double x1, int n, int type, double* x)
+\brief Function fills a vector with `n` logarithmically spaced elements
+between \f$10^{x_0}\f$ and \f$10^{x_1}\f$.
+
+
+Function supports two kinds of filling according to `type` parameter: \n
+
+Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
+
+\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
+\f$k = 0 \ldots n-1.\f$
+
+Periodic fill (parameter `type=DSPL_PERIODIC`): \n
+
+\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
+\f$k = 0 \ldots n-1.\f$ \n
+
+
+\param[in] x0
+Start exponent value \f$x_0\f$. \n \n
+
+\param[in] x1
+End exponent value \f$x_1\f$. \n \n
+
+\param[in] n
+Number of points `x` (size of vector `x`). \n \n
+
+\param[in] type
+Fill type: \n
+`DSPL_SYMMETRIC` --- symmetric, \n
+`DSPL_PERIODIC` --- periodic. \n \n
+
+\param[in,out] x
+Pointer to the output logarithmically spaced vector `x` . \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function returns successfully. \n
+ Else \ref ERROR_CODE_GROUP "error code".
+
+\note
+Difference between symmetric and periodic filling we can
+understand from the follow examples. \n
+Example 1. Periodic fill.
+\code{.cpp}
+ double x[5];
+ logspace(-2, 3, 5, DSPL_PERIODIC, x);
+\endcode
+
+Values in the vector `x` are:
+
+\verbatim
+0.01, 0.1, 1, 10, 100
+\endverbatim
+
+\n \n
+
+Example 2. Symmetric fill.
+\code{.cpp}
+ double x[5];
+ logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
+\endcode
+
+Values in the vector `x` are:
+
+\verbatim
+0.01 0.178 3.162 56.234 1000
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int logspace(double x0, double x1, int n, int type, double* x)
+\brief Функция заполняет массив значениями логарифмической шкале
+
+Заполняет массив `x` длиной `n` значениями в диапазоне
+от \f$10^{x_0}\f$ до \f$10^{x_1}\f$. \n
+Функция поддерживает два типа заполнения в соответствии с параметром `type`: \n
+
+Симметричное заполнение согласно выражению: \n
+
+\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
+\f$k = 0 \ldots n-1.\f$
+
+Периодическое заполнение согласно выражению:
+
+\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
+\f$k = 0 \ldots n-1.\f$ \n
+
+\param[in] x0
+Начальное значение показателя \f$x_0\f$. \n \n
+
+\param[in] x1
+Конечное значение показателя \f$x_1\f$. \n \n
+
+\param[in] n
+Количество точек массива `x`. \n \n
+
+\param[in] type
+Тип заполнения: \n
+`DSPL_SYMMETRIC` --- симметричное заполнение, \n
+`DSPL_PERIODIC` --- периодическое заполнение. \n \n
+
+\param[in,out] x
+Указатель на вектор значений в логарифмической шкале. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` --- функция выполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\note
+Отличие периодического и симметричного заполнения можно
+понять из следующих примеров. \n
+
+Пример 1. Периодическое заполнение.
+\code{.cpp}
+ double x[5];
+ logspace(-2, 3, 5, DSPL_PERIODIC, x);
+\endcode
+В массиве `x` будут лежать значения:
+\verbatim
+0.01, 0.1, 1, 10, 100
+\endverbatim
+\n \n
+
+Пример 2. Симметричное заполнение.
+\code{.cpp}
+ double x[5];
+ logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
+\endcode
+
+В массиве `x` будут лежать значения:
+
+\verbatim
+0.01 0.178 3.162 56.234 1000
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API logspace(double x0, double x1, int n, int type, double* x)
+{
+ double mx, a, b;
+ int k;
+
+ if(n < 2)
+ return ERROR_SIZE;
+ if(!x)
+ return ERROR_PTR;
+
+ a = pow(10.0, x0);
+ b = pow(10.0, x1);
+
+ switch (type)
+ {
+ case DSPL_SYMMETRIC:
+ mx = pow(b/a, 1.0/(double)(n-1));
+ x[0] = a;
+ for(k = 1; k < n; k++)
+ x[k] = x[k-1] * mx;
+ break;
+ case DSPL_PERIODIC:
+ mx = pow(b/a, 1.0/(double)n);
+ x[0] = a;
+ for(k = 1; k < n; k++)
+ x[k] = x[k-1] * mx;
+ break;
+ default:
+ return ERROR_SYM_TYPE;
+ }
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/array/ones.c b/dspl/src/array/ones.c
new file mode 100644
index 0000000..7e78b9b
--- /dev/null
+++ b/dspl/src/array/ones.c
@@ -0,0 +1,113 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int ones(double* x, int n)
+\brief Function fills all real vector `x` by ones values.
+
+\param[in, out] x
+Pointer to the vector `x`. \n
+Vector size is `[n x 1]`. \n
+All elements on this vector will be set to one. \n
+\n
+
+\param[in] n
+Size of vector `x`. \n
+\n
+
+\return
+`RES_OK` if function returns successfully. \n
+ Else \ref ERROR_CODE_GROUP "error code".
+
+Example:
+\code{.cpp}
+double y[5] = {0};
+int i;
+ones(y, 5);
+for(i = 0; i < 5; i++)
+ printf("%6.1f% ", y[i]);
+\endcode
+ \n
+Vector `y` values are:
+\verbatim
+ 1.0 1.0 1.0 1.0 1.0
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int ones(double* x, int n)
+\brief Функция заполнения вещественного массива единицами
+
+\param[in, out] x
+Указатель на вещественный вектор `x`. \n
+Размер вектора `[n x 1]`. \n
+Значения данного вектора будут установлены в единицу. \n
+\n
+
+\param[in] n
+Размер вектора `x`. \n
+\n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример:
+\code{.cpp}
+double y[5] = {0};
+int i;
+ones(y, 5);
+for(i = 0; i < 5; i++)
+ printf("%6.1f% ", y[i]);
+\endcode
+ \n
+Результат выполнения:
+\verbatim
+ 1.0 1.0 1.0 1.0 1.0
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ones(double* x, int n)
+{
+ int i;
+ if(!x)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ for(i = 0; i < n; i++)
+ x[i] = 1.0;
+ return RES_OK;
+}
diff --git a/dspl/src/array/sum.c b/dspl/src/array/sum.c
new file mode 100644
index 0000000..b7296d0
--- /dev/null
+++ b/dspl/src/array/sum.c
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int sum(double* x, int n, double* s)
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int sum(double* x, int n, double* s)
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API sum(double* x, int n, double* s)
+{
+ int i;
+ double z = 0.0;
+ if(!x || !s)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
+ for(i = 0; i < n; i++)
+ z += x[i];
+ *s = z;
+ return RES_OK;
+}
\ No newline at end of file
diff --git a/dspl/src/array/sum_sqr.c b/dspl/src/array/sum_sqr.c
new file mode 100644
index 0000000..3cf00c3
--- /dev/null
+++ b/dspl/src/array/sum_sqr.c
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int sum(double* x, int n, double* s)
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int sum(double* x, int n, double* s)
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API sum_sqr(double* x, int n, double* s)
+{
+ int i;
+ double z = 0.0;
+ if(!x || !s)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
+ for(i = 0; i < n; i++)
+ z += x[i]*x[i];
+ *s = z;
+ return RES_OK;
+}
\ No newline at end of file
diff --git a/dspl/src/dft.c b/dspl/src/dft.c
index e5ef5ab..759b74e 100644
--- a/dspl/src/dft.c
+++ b/dspl/src/dft.c
@@ -1,532 +1,53 @@
+
/*
-* Copyright (c) 2015-2019 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of libdspl-2.0.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DSPL is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Foobar. If not, see .
+Discrete Fourier Transform Algorithms
*/
+#include "dft/dft.c"
+#include "dft/dft_cmplx.c"
+#include "dft/idft_cmplx.c"
+/*
+Fast Fourier Transform Algrithms
+*/
+#include "dft/fft.c"
+#include "dft/fft_abs.c"
+#include "dft/fft_abs_cmplx.c"
+#include "dft/fft_cmplx.c"
+#include "dft/fft_create.c"
+#include "dft/fft_free.c"
+#include "dft/fft_krn.c"
+#include "dft/fft_mag.c"
+#include "dft/fft_mag_cmplx.c"
+#include "dft/fft_shift.c"
+#include "dft/fft_shift_cmplx.c"
+#include "dft/fft_subkernel.c"
+#include "dft/ifft_cmplx.c"
-#include
-#include
-#include "dspl.h"
+/*
+Goertzel Algorithm
+*/
+#include "dft/goertzel.c"
+#include "dft/goertzel_cmplx.c"
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int dft(double* x, int n, complex_t* y)
-\brief Discrete Fourier transform of a real signal.
+/*
+Fourier Series and Fourier Intergral
+*/
+#include "dft/fourier_series_dec.c"
+#include "dft/fourier_series_dec_cmplx.c"
+#include "dft/fourier_integral_cmplx.c"
+#include "dft/fourier_series_rec.c"
-The function calculates the \f$ n \f$ -point discrete Fourier transform
-real signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y (k) = \sum_ {m = 0} ^ {n-1} x (m)
- \exp \left (-j \frac {2 \pi} {n} m k \right),
-\f]
-where \f$ k = 0 \ldots n-1 \f$.
-\param [in] x
-Pointer to the vector of the real input signal \f$ x (m) \f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-The size of the vector is `[n x 1]`. \n \n
-\param [in] n
-The size of the DFT \f$ n \f$
-(the size of the vectors of the input signal and the result of the DFT). \n \n
-\param [out] y
-Pointer to the complex vector of the DFT result \f$ Y (k) \f$,
-\f$ k = 0 \ldots n-1 \f$.
-The size of the vector is `[n x 1]`. \n
-Memory must be allocated. \n \n
-\return
-`RES_OK` if the DFT is calculated successfully. \n
-Otherwise, \ref ERROR_CODE_GROUP "error code".
-An example of using the `dft` function:
-\include dft_test.c
-The result of the program:
-\verbatim
-y [0] = 120.000 0.000
-y [1] = -8.000 40.219
-y [2] = -8.000 19.314
-y [3] = -8.000 11.973
-y [4] = -8.000 8.000
-y [5] = -8.000 5.345
-y [6] = -8.000 3.314
-y [7] = -8.000 1.591
-y [8] = -8.000 0.000
-y [9] = -8.000 -1.591
-y [10] = -8.000 -3.314
-y [11] = -8.000 -5.345
-y [12] = -8.000 -8.000
-y [13] = -8.000 -11.973
-y [14] = -8.000 -19.314
-y [15] = -8.000 -40.219
-\endverbatim
-\note
-This function performs the DFT calculation using the naive method and
-requires \f$ n ^ 2 \f$ complex multiplications. \n
-To increase the calculation speed, it is recommended to use
-fast Fourier transform algorithms.
-\author Bakhurin Sergey www.dsplib.org
-**************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int dft(double* x, int n, complex_t* y)
-\brief Дискретное преобразование Фурье вещественного сигнала.
-
-Функция рассчитывает \f$ n \f$-точечное дискретное преобразование Фурье
-вещественного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m)
- \exp \left( -j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-\param[in] x
-Указатель на вектор вещественного входного сигнала \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ДПФ \f$n\f$ (размер векторов входного сигнала и результата ДПФ). \n \n
-
-\param[out] y
-Указатель на комплексный вектор результата ДПФ \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$.
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-
-\return
-`RES_OK` если ДПФ рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример использования функции `dft`:
-
-\include dft_test.c
-
-Результат работы программы:
-
-\verbatim
-y[ 0] = 120.000 0.000
-y[ 1] = -8.000 40.219
-y[ 2] = -8.000 19.314
-y[ 3] = -8.000 11.973
-y[ 4] = -8.000 8.000
-y[ 5] = -8.000 5.345
-y[ 6] = -8.000 3.314
-y[ 7] = -8.000 1.591
-y[ 8] = -8.000 0.000
-y[ 9] = -8.000 -1.591
-y[10] = -8.000 -3.314
-y[11] = -8.000 -5.345
-y[12] = -8.000 -8.000
-y[13] = -8.000 -11.973
-y[14] = -8.000 -19.314
-y[15] = -8.000 -40.219
-\endverbatim
-
-\note
-Данная функция выполняет расчет ДПФ наивным методом и требует \f$ n^2 \f$
-комплексных умножений. \n
-Для увеличения скорости расчета рекомендуется использовать
-алгоритмы быстрого преобразования Фурье.
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API dft(double* x, int n, complex_t* y)
-{
- int k;
- int m;
- double divn;
- double phi;
-
-
- if(!x || !y)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- divn = 1.0 / (double)n;
-
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = IM(y[k]) = 0.0;
- for(m = 0; m < n; m++)
- {
- phi = -M_2PI * divn * (double)k * (double)m;
- RE(y[k]) += x[m] * cos(phi);
- IM(y[k]) += x[m] * sin(phi);
- }
- }
- return RES_OK;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
-\brief Discrete Fourier transform of a complex signal.
-
-The function calculates the \f$ n \f$ -point discrete Fourier transform
-complex signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y (k) = \sum_ {m = 0} ^ {n-1} x (m)
- \exp \left (-j \frac {2 \pi} {n} m k \right),
-\f]
-where \f$ k = 0 \ldots n-1 \f$.
-
-\param [in] x
-Pointer to a vector of complex
-input signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-The size of the vector is `[n x 1]`. \n \n
-
-\param [in] n
-The size of the DFT \f$ n \f$
-(the size of the vectors of the input signal and the result of the DFT). \n \n
-
-\param [out] y
-Integrated Vector Pointer
-DFT result \f$ Y (k) \f$, \f$ k = 0 \ldots n-1 \f$. \n
-The size of the vector is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-
-\return
-`RES_OK` if the DFT is calculated successfully. \n
-Otherwise, \ref ERROR_CODE_GROUP "error code".
-
-An example of using the `dft_cmplx` function:
-
-\include dft_cmplx_test.c
-
-The result of the program:
-
-\verbatim
-y [0] = 120.000 0.000
-y [1] = -8.000 40.219
-y [2] = -8.000 19.314
-y [3] = -8.000 11.973
-y [4] = -8.000 8.000
-y [5] = -8.000 5.345
-y [6] = -8.000 3.314
-y [7] = -8.000 1.591
-y [8] = -8.000 0.000
-y [9] = -8.000 -1.591
-y [10] = -8.000 -3.314
-y [11] = -8.000 -5.345
-y [12] = -8.000 -8.000
-y [13] = -8.000 -11.973
-y [14] = -8.000 -19.314
-y [15] = -8.000 -40.219
-\endverbatim
-
-\note
-This function performs the calculation of the DFT by the naive method
-and requires \f$ n ^ 2 \f$ complex multiplications. \n
-To increase the calculation speed, it is recommended
-use fast Fourier transform algorithms.
-
-\author Bakhurin Sergey www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
-\brief Дискретное преобразование Фурье комплексного сигнала.
-
-Функция рассчитывает \f$ n \f$-точечное дискретное преобразование Фурье
-комплексного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m)
- \exp \left( -j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-\param[in] x
-Указатель на вектор комплексного
-входного сигнала \f$x(m)\f$, \f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ДПФ \f$n\f$ (размер векторов входного сигнала и результата ДПФ). \n \n
-
-\param[out] y
-Указатель на комплексный вектор
-результата ДПФ \f$Y(k)\f$, \f$ k = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-
-\return
-`RES_OK` если ДПФ рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример использования функции `dft_cmplx`:
-
-\include dft_cmplx_test.c
-
-Результат работы программы:
-
-\verbatim
-y[ 0] = 120.000 0.000
-y[ 1] = -8.000 40.219
-y[ 2] = -8.000 19.314
-y[ 3] = -8.000 11.973
-y[ 4] = -8.000 8.000
-y[ 5] = -8.000 5.345
-y[ 6] = -8.000 3.314
-y[ 7] = -8.000 1.591
-y[ 8] = -8.000 0.000
-y[ 9] = -8.000 -1.591
-y[10] = -8.000 -3.314
-y[11] = -8.000 -5.345
-y[12] = -8.000 -8.000
-y[13] = -8.000 -11.973
-y[14] = -8.000 -19.314
-y[15] = -8.000 -40.219
-\endverbatim
-
-\note
-Данная функция выполняет расчет ДПФ наивным методом
-и требует \f$ n^2 \f$ комплексных умножений. \n
-Для увеличения скорости расчета рекомендуется
-использовать алгоритмы быстрого преобразования Фурье.
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API dft_cmplx(complex_t* x, int n, complex_t* y)
-{
- int k;
- int m;
- double divn;
- double phi;
- complex_t e;
-
- if(!x || !y)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- divn = 1.0 / (double)n;
-
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = IM(y[k]) = 0.0;
- for(m = 0; m < n; m++)
- {
- phi = -M_2PI * divn * (double)k * (double)m;
- RE(e) = cos(phi);
- IM(e) = sin(phi);
- RE(y[k]) += CMRE(x[m], e);
- IM(y[k]) += CMIM(x[m], e);
- }
- }
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
-\brief Inverse discrete Fourier transform of the complex spectrum.
-
-The function calculates the \f$ n \f$ -point inverse discrete transform
-Fourier complex spectrum \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- y (k) = \sum_ {m = 0} ^ {n-1} x (m)
- \exp \left (j \frac {2 \pi} {n} m k \right),
-\f]
-where \f$ k = 0 \ldots n-1 \f$.
-
-\param [in] x
-Pointer to the vector of the input complex signal spectrum \f$ x (m) \f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-The size of the vector is `[n x 1]`. \n \n
-
-\param [in] n
-The size of the ODPF \f$ n \f$
-(the size of the vectors of the input spectrum and the result of the ODPF). \n
-\n
-
-\param [out] y
-Pointer to the complex vector of the ODPF result \f$ y (k) \f$,
-\f$ k = 0 \ldots n-1 \f$.
-The size of the vector is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-
-\return
-`RES_OK` if the ODPF is calculated successfully. \n
-Otherwise, \ref ERROR_CODE_GROUP "error code".
-
-An example of using the `dft_cmplx` function:
-
-\include idft_cmplx_test.c
-
-The result of the program:
-
-\verbatim
-x [0] = 0.000 + 0.000j, z [0] = 0.000 -0.000
-x [1] = 1.000 + 0.000j, z [1] = 1.000 -0.000
-x [2] = 2.000 + 0.000j, z [2] = 2.000 -0.000
-x [3] = 3.000 + 0.000j, z [3] = 3.000 -0.000
-x [4] = 4.000 + 0.000j, z [4] = 4.000 -0.000
-x [5] = 5.000 + 0.000j, z [5] = 5.000 -0.000
-x [6] = 6.000 + 0.000j, z [6] = 6.000 -0.000
-x [7] = 7.000 + 0.000j, z [7] = 7.000 -0.000
-x [8] = 8.000 + 0.000j, z [8] = 8.000 -0.000
-x [9] = 9.000 + 0.000j, z [9] = 9.000 -0.000
-x [10] = 10.000 + 0.000j, z [10] = 10.000 -0.000
-x [11] = 11.000 + 0.000j, z [11] = 11.000 +0.000
-x [12] = 12.000 + 0.000j, z [12] = 12.000 +0.000
-x [13] = 13.000 + 0.000j, z [13] = 13.000 +0.000
-x [14] = 14.000 + 0.000j, z [14] = 14.000 +0.000
-x [15] = 15.000 + 0.000j, z [15] = 15.000 -0.000
-\endverbatim
-
-\note
-This function performs the calculation of the DFT using the naive method.
-and requires \f$ n ^ 2 \f$ complex multiplications. \n
-To increase the calculation speed, it is recommended
-use fast Fourier transform algorithms.
-
-\author Bakhurin Sergey www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
-\brief Обратное дискретное преобразование Фурье комплексного спектра.
-
-Функция рассчитывает \f$ n \f$-точечное обратное дискретное преобразование
-Фурье комплексного спектра \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- y(k) = \sum_{m = 0}^{n-1} x(m)
- \exp \left( j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-\param[in] x
-Указатель на вектор входного комплексного спектра сигнала \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ОДПФ \f$n\f$ (размер векторов входного спектра и результата ОДПФ). \n \n
-
-\param[out] y
-Указатель на комплексный вектор результата ОДПФ \f$y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$.
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-
-\return
-`RES_OK` если ОДПФ рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример использования функции `dft_cmplx`:
-
-\include idft_cmplx_test.c
-
-Результат работы программы:
-
-\verbatim
-x[ 0] = 0.000 +0.000j, z[ 0] = 0.000 -0.000
-x[ 1] = 1.000 +0.000j, z[ 1] = 1.000 -0.000
-x[ 2] = 2.000 +0.000j, z[ 2] = 2.000 -0.000
-x[ 3] = 3.000 +0.000j, z[ 3] = 3.000 -0.000
-x[ 4] = 4.000 +0.000j, z[ 4] = 4.000 -0.000
-x[ 5] = 5.000 +0.000j, z[ 5] = 5.000 -0.000
-x[ 6] = 6.000 +0.000j, z[ 6] = 6.000 -0.000
-x[ 7] = 7.000 +0.000j, z[ 7] = 7.000 -0.000
-x[ 8] = 8.000 +0.000j, z[ 8] = 8.000 -0.000
-x[ 9] = 9.000 +0.000j, z[ 9] = 9.000 -0.000
-x[10] = 10.000 +0.000j, z[10] = 10.000 -0.000
-x[11] = 11.000 +0.000j, z[11] = 11.000 +0.000
-x[12] = 12.000 +0.000j, z[12] = 12.000 +0.000
-x[13] = 13.000 +0.000j, z[13] = 13.000 +0.000
-x[14] = 14.000 +0.000j, z[14] = 14.000 +0.000
-x[15] = 15.000 +0.000j, z[15] = 15.000 -0.000
-\endverbatim
-
-\note
-Данная функция выполняет расчет ОДПФ наивным методом
-и требует \f$ n^2 \f$ комплексных умножений. \n
-Для увеличения скорости расчета рекомендуется
-использовать алгоритмы быстрого преобразования Фурье.
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API idft_cmplx(complex_t* x, int n, complex_t* y)
-{
- int k;
- int m;
- double divn;
- double phi;
- complex_t e;
-
- if(!x || !y)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- divn = 1.0 / (double)n;
-
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = IM(y[k]) = 0.0;
- for(m = 0; m < n; m++)
- {
- phi = M_2PI * divn * (double)k * (double)m;
- RE(e) = cos(phi);
- IM(e) = sin(phi);
- RE(y[k]) += CMRE(x[m], e);
- IM(y[k]) += CMIM(x[m], e);
- }
- RE(y[k]) /= (double)n;
- IM(y[k]) /= (double)n;
- }
- return RES_OK;
-}
diff --git a/dspl/src/dft/dft.c b/dspl/src/dft/dft.c
new file mode 100644
index 0000000..b356718
--- /dev/null
+++ b/dspl/src/dft/dft.c
@@ -0,0 +1,192 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int dft(double* x, int n, complex_t* y)
+\brief Discrete Fourier transform of a real signal.
+
+The function calculates the \f$ n \f$ -point discrete Fourier transform
+real signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y (k) = \sum_ {m = 0} ^ {n-1} x (m)
+ \exp \left (-j \frac {2 \pi} {n} m k \right),
+\f]
+where \f$ k = 0 \ldots n-1 \f$.
+
+\param [in] x
+Pointer to the vector of the real input signal \f$ x (m) \f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+The size of the vector is `[n x 1]`. \n \n
+
+\param [in] n
+The size of the DFT \f$ n \f$
+(the size of the vectors of the input signal and the result of the DFT). \n \n
+
+\param [out] y
+Pointer to the complex vector of the DFT result \f$ Y (k) \f$,
+\f$ k = 0 \ldots n-1 \f$.
+The size of the vector is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+
+\return
+`RES_OK` if the DFT is calculated successfully. \n
+Otherwise, \ref ERROR_CODE_GROUP "error code".
+
+An example of using the `dft` function:
+
+\include dft_test.c
+
+The result of the program:
+
+\verbatim
+y [0] = 120.000 0.000
+y [1] = -8.000 40.219
+y [2] = -8.000 19.314
+y [3] = -8.000 11.973
+y [4] = -8.000 8.000
+y [5] = -8.000 5.345
+y [6] = -8.000 3.314
+y [7] = -8.000 1.591
+y [8] = -8.000 0.000
+y [9] = -8.000 -1.591
+y [10] = -8.000 -3.314
+y [11] = -8.000 -5.345
+y [12] = -8.000 -8.000
+y [13] = -8.000 -11.973
+y [14] = -8.000 -19.314
+y [15] = -8.000 -40.219
+\endverbatim
+
+\note
+This function performs the DFT calculation using the naive method and
+requires \f$ n ^ 2 \f$ complex multiplications. \n
+To increase the calculation speed, it is recommended to use
+fast Fourier transform algorithms.
+
+\author Bakhurin Sergey www.dsplib.org
+**************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int dft(double* x, int n, complex_t* y)
+\brief Дискретное преобразование Фурье вещественного сигнала.
+
+Функция рассчитывает \f$ n \f$-точечное дискретное преобразование Фурье
+вещественного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m)
+ \exp \left( -j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+\param[in] x
+Указатель на вектор вещественного входного сигнала \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ДПФ \f$n\f$ (размер векторов входного сигнала и результата ДПФ). \n \n
+
+\param[out] y
+Указатель на комплексный вектор результата ДПФ \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$.
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+
+\return
+`RES_OK` если ДПФ рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример использования функции `dft`:
+
+\include dft_test.c
+
+Результат работы программы:
+
+\verbatim
+y[ 0] = 120.000 0.000
+y[ 1] = -8.000 40.219
+y[ 2] = -8.000 19.314
+y[ 3] = -8.000 11.973
+y[ 4] = -8.000 8.000
+y[ 5] = -8.000 5.345
+y[ 6] = -8.000 3.314
+y[ 7] = -8.000 1.591
+y[ 8] = -8.000 0.000
+y[ 9] = -8.000 -1.591
+y[10] = -8.000 -3.314
+y[11] = -8.000 -5.345
+y[12] = -8.000 -8.000
+y[13] = -8.000 -11.973
+y[14] = -8.000 -19.314
+y[15] = -8.000 -40.219
+\endverbatim
+
+\note
+Данная функция выполняет расчет ДПФ наивным методом и требует \f$ n^2 \f$
+комплексных умножений. \n
+Для увеличения скорости расчета рекомендуется использовать
+алгоритмы быстрого преобразования Фурье.
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API dft(double* x, int n, complex_t* y)
+{
+ int k;
+ int m;
+ double divn;
+ double phi;
+
+
+ if(!x || !y)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ divn = 1.0 / (double)n;
+
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = IM(y[k]) = 0.0;
+ for(m = 0; m < n; m++)
+ {
+ phi = -M_2PI * divn * (double)k * (double)m;
+ RE(y[k]) += x[m] * cos(phi);
+ IM(y[k]) += x[m] * sin(phi);
+ }
+ }
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/dft/dft_cmplx.c b/dspl/src/dft/dft_cmplx.c
new file mode 100644
index 0000000..93aec27
--- /dev/null
+++ b/dspl/src/dft/dft_cmplx.c
@@ -0,0 +1,194 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
+\brief Discrete Fourier transform of a complex signal.
+
+The function calculates the \f$ n \f$ -point discrete Fourier transform
+complex signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y (k) = \sum_ {m = 0} ^ {n-1} x (m)
+ \exp \left (-j \frac {2 \pi} {n} m k \right),
+\f]
+where \f$ k = 0 \ldots n-1 \f$.
+
+\param [in] x
+Pointer to a vector of complex
+input signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+The size of the vector is `[n x 1]`. \n \n
+
+\param [in] n
+The size of the DFT \f$ n \f$
+(the size of the vectors of the input signal and the result of the DFT). \n \n
+
+\param [out] y
+Integrated Vector Pointer
+DFT result \f$ Y (k) \f$, \f$ k = 0 \ldots n-1 \f$. \n
+The size of the vector is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+
+\return
+`RES_OK` if the DFT is calculated successfully. \n
+Otherwise, \ref ERROR_CODE_GROUP "error code".
+
+An example of using the `dft_cmplx` function:
+
+\include dft_cmplx_test.c
+
+The result of the program:
+
+\verbatim
+y [0] = 120.000 0.000
+y [1] = -8.000 40.219
+y [2] = -8.000 19.314
+y [3] = -8.000 11.973
+y [4] = -8.000 8.000
+y [5] = -8.000 5.345
+y [6] = -8.000 3.314
+y [7] = -8.000 1.591
+y [8] = -8.000 0.000
+y [9] = -8.000 -1.591
+y [10] = -8.000 -3.314
+y [11] = -8.000 -5.345
+y [12] = -8.000 -8.000
+y [13] = -8.000 -11.973
+y [14] = -8.000 -19.314
+y [15] = -8.000 -40.219
+\endverbatim
+
+\note
+This function performs the calculation of the DFT by the naive method
+and requires \f$ n ^ 2 \f$ complex multiplications. \n
+To increase the calculation speed, it is recommended
+use fast Fourier transform algorithms.
+
+\author Bakhurin Sergey www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
+\brief Дискретное преобразование Фурье комплексного сигнала.
+
+Функция рассчитывает \f$ n \f$-точечное дискретное преобразование Фурье
+комплексного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m)
+ \exp \left( -j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+\param[in] x
+Указатель на вектор комплексного
+входного сигнала \f$x(m)\f$, \f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ДПФ \f$n\f$ (размер векторов входного сигнала и результата ДПФ). \n \n
+
+\param[out] y
+Указатель на комплексный вектор
+результата ДПФ \f$Y(k)\f$, \f$ k = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+
+\return
+`RES_OK` если ДПФ рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример использования функции `dft_cmplx`:
+
+\include dft_cmplx_test.c
+
+Результат работы программы:
+
+\verbatim
+y[ 0] = 120.000 0.000
+y[ 1] = -8.000 40.219
+y[ 2] = -8.000 19.314
+y[ 3] = -8.000 11.973
+y[ 4] = -8.000 8.000
+y[ 5] = -8.000 5.345
+y[ 6] = -8.000 3.314
+y[ 7] = -8.000 1.591
+y[ 8] = -8.000 0.000
+y[ 9] = -8.000 -1.591
+y[10] = -8.000 -3.314
+y[11] = -8.000 -5.345
+y[12] = -8.000 -8.000
+y[13] = -8.000 -11.973
+y[14] = -8.000 -19.314
+y[15] = -8.000 -40.219
+\endverbatim
+
+\note
+Данная функция выполняет расчет ДПФ наивным методом
+и требует \f$ n^2 \f$ комплексных умножений. \n
+Для увеличения скорости расчета рекомендуется
+использовать алгоритмы быстрого преобразования Фурье.
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API dft_cmplx(complex_t* x, int n, complex_t* y)
+{
+ int k;
+ int m;
+ double divn;
+ double phi;
+ complex_t e;
+
+ if(!x || !y)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ divn = 1.0 / (double)n;
+
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = IM(y[k]) = 0.0;
+ for(m = 0; m < n; m++)
+ {
+ phi = -M_2PI * divn * (double)k * (double)m;
+ RE(e) = cos(phi);
+ IM(e) = sin(phi);
+ RE(y[k]) += CMRE(x[m], e);
+ IM(y[k]) += CMIM(x[m], e);
+ }
+ }
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/dft/fft.c b/dspl/src/dft/fft.c
new file mode 100644
index 0000000..6b4167e
--- /dev/null
+++ b/dspl/src/dft/fft.c
@@ -0,0 +1,192 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
+\brief Fast Fourier transform for the real vector.
+
+Function calculated \f$ n \f$-points FFT for the real vector
+\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
+ \left( -j \frac{2\pi}{n} m k \right),
+\f]
+here \f$ k = 0 \ldots n-1 \f$.
+
+
+\param[in] x
+Pointer to the input real vector \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+FFT size \f$n\f$. \n
+FFT size can be composite:
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+simple number less than 46340
+(see \ref fft_create function). \n \n
+
+\param[in] pfft
+Pointer to the `fft_t` object. \n
+This pointer cannot be `NULL`. \n
+Structure \ref fft_t should be previously once
+filled with the \ref fft_create function, and the memory should be
+cleared before exiting by the \ref fft_free function. \n \n
+
+\param[out] y
+Pointer to the FFT result complex vector \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if FFT is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Example:
+
+\include fft_test.c
+
+Result:
+
+\verbatim
+y[ 0] = 91.000 0.000
+y[ 1] = -7.000 30.669
+y[ 2] = -7.000 14.536
+y[ 3] = -7.000 8.778
+y[ 4] = -7.000 5.582
+y[ 5] = -7.000 3.371
+y[ 6] = -7.000 1.598
+y[ 7] = -7.000 0.000
+y[ 8] = -7.000 -1.598
+y[ 9] = -7.000 -3.371
+y[10] = -7.000 -5.582
+y[11] = -7.000 -8.778
+y[12] = -7.000 -14.536
+y[13] = -7.000 -30.669
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
+\brief Быстрое преобразование Фурье вещественного сигнала
+
+Функция рассчитывает \f$ n \f$-точечное быстрое преобразование Фурье
+вещественного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
+ \left( -j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+Для расчета используется алгоритм БПФ составной длины.
+
+\param[in] x
+Указатель на вектор вещественного входного сигнала \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер БПФ \f$n\f$. \n
+Размер БПФ может быть составным вида
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+произвольный простой множитель не превосходящий 46340
+(см. описание функции \ref fft_create). \n \n
+
+\param[in] pfft
+Указатель на структуру `fft_t`. \n
+Указатель не должен быть `NULL`. \n
+Структура \ref fft_t должна быть предварительно однократно
+заполнена функцией \ref fft_create, и память должна быть
+очищена перед выходом функцией \ref fft_free. \n \n
+
+\param[out] y
+Указатель на комплексный вектор результата БПФ \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если расчет произведен успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+Пример использования функции `fft`:
+
+\include fft_test.c
+
+Результат работы программы:
+
+\verbatim
+y[ 0] = 91.000 0.000
+y[ 1] = -7.000 30.669
+y[ 2] = -7.000 14.536
+y[ 3] = -7.000 8.778
+y[ 4] = -7.000 5.582
+y[ 5] = -7.000 3.371
+y[ 6] = -7.000 1.598
+y[ 7] = -7.000 0.000
+y[ 8] = -7.000 -1.598
+y[ 9] = -7.000 -3.371
+y[10] = -7.000 -5.582
+y[11] = -7.000 -8.778
+y[12] = -7.000 -14.536
+y[13] = -7.000 -30.669
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API fft(double* x, int n, fft_t* pfft, complex_t* y)
+{
+ int err;
+
+ if(!x || !pfft || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
+
+ err = fft_create(pfft, n);
+ if(err != RES_OK)
+ return err;
+
+ re2cmplx(x, n, pfft->t1);
+
+ return fft_krn(pfft->t1, y, pfft, n, 0);
+}
\ No newline at end of file
diff --git a/dspl/src/dft/fft_abs.c b/dspl/src/dft/fft_abs.c
new file mode 100644
index 0000000..86362c4
--- /dev/null
+++ b/dspl/src/dft/fft_abs.c
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API fft_abs(double* x, int n, fft_t* pfft,
+ double fs, int flag,
+ double* mag, double* freq)
+{
+ int k, err = RES_OK;
+ complex_t *X = NULL;
+ if(!x || !pfft)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ if(mag)
+ {
+ X = (complex_t*)malloc(n*sizeof(complex_t));
+ err = fft(x, n, pfft, X);
+ if(err!=RES_OK)
+ goto error_proc;
+
+
+ for(k = 0; k < n; k++)
+ mag[k] = ABS(X[k]);
+ if(flag & DSPL_FLAG_FFT_SHIFT)
+ {
+ err = fft_shift(mag, n, mag);
+ if(err!=RES_OK)
+ goto error_proc;
+ }
+ }
+
+ if(freq)
+ {
+ if(flag & DSPL_FLAG_FFT_SHIFT)
+ if(n%2)
+ err = linspace(-fs*0.5 + fs*0.5/(double)n,
+ fs*0.5 - fs*0.5/(double)n,
+ n, DSPL_SYMMETRIC, freq);
+ else
+ err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
+ else
+ err = linspace(0, fs, n, DSPL_PERIODIC, freq);
+ }
+
+error_proc:
+ if(X)
+ free(X);
+
+ return err;
+}
+
diff --git a/dspl/src/dft/fft_abs_cmplx.c b/dspl/src/dft/fft_abs_cmplx.c
new file mode 100644
index 0000000..621e9b6
--- /dev/null
+++ b/dspl/src/dft/fft_abs_cmplx.c
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API fft_abs_cmplx(complex_t* x, int n, fft_t* pfft,
+ double fs, int flag,
+ double* mag, double* freq)
+{
+ int k, err = RES_OK;
+ complex_t *X = NULL;
+
+ if(!x || !pfft)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ if(mag)
+ {
+ X = (complex_t*)malloc(n*sizeof(complex_t));
+ err = fft_cmplx(x, n, pfft, X);
+ if(err!=RES_OK)
+ goto error_proc;
+
+
+ for(k = 0; k < n; k++)
+ mag[k] = ABS(X[k]);
+
+ if(flag & DSPL_FLAG_FFT_SHIFT)
+ {
+ err = fft_shift(mag, n, mag);
+ if(err!=RES_OK)
+ goto error_proc;
+ }
+ }
+
+ if(freq)
+ {
+ if(flag & DSPL_FLAG_FFT_SHIFT)
+ if(n%2)
+ err = linspace(-fs*0.5 + fs*0.5/(double)n,
+ fs*0.5 - fs*0.5/(double)n,
+ n, DSPL_SYMMETRIC, freq);
+ else
+ err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
+ else
+ err = linspace(0, fs, n, DSPL_PERIODIC, freq);
+ }
+error_proc:
+ if(X)
+ free(X);
+
+ return err;
+}
diff --git a/dspl/src/dft/fft_cmplx.c b/dspl/src/dft/fft_cmplx.c
new file mode 100644
index 0000000..cd92bbb
--- /dev/null
+++ b/dspl/src/dft/fft_cmplx.c
@@ -0,0 +1,201 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+\brief Fast Fourier transform for the complex vector.
+
+Function calculated \f$ n \f$-points FFT for the complex vector
+\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m) \exp \left( -j \frac{2\pi}{n} m k \right),
+\f]
+here \f$ k = 0 \ldots n-1 \f$.
+
+\param[in] x
+Pointer to the input complex vector \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+FFT size \f$n\f$. \n
+FFT size can be composite:
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+simple number less than 46340
+(see \ref fft_create function). \n \n
+
+\param[in] pfft
+Pointer to the `fft_t` object. \n
+This pointer cannot be `NULL`. \n
+Structure \ref fft_t should be previously once
+filled with the \ref fft_create function, and the memory should be
+cleared before exiting by the \ref fft_free function. \n \n
+
+\param[out] y
+Pointer to the FFT result complex vector \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if FFT is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Example:
+
+\include fft_cmplx_test.c
+
+Result:
+
+\verbatim
+y[ 0] = -0.517 0.686
+y[ 1] = -0.943 0.879
+y[ 2] = -2.299 1.492
+y[ 3] = 16.078 -6.820
+y[ 4] = 2.040 -0.470
+y[ 5] = 1.130 -0.059
+y[ 6] = 0.786 0.097
+y[ 7] = 0.596 0.183
+y[ 8] = 0.470 0.240
+y[ 9] = 0.375 0.283
+y[10] = 0.297 0.318
+y[11] = 0.227 0.350
+y[12] = 0.161 0.380
+y[13] = 0.094 0.410
+y[14] = 0.023 0.442
+y[15] = -0.059 0.479
+y[16] = -0.161 0.525
+y[17] = -0.300 0.588
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+\brief Быстрое преобразование Фурье комплексного сигнала
+
+Функция рассчитывает \f$ n \f$-точечное быстрое преобразование Фурье
+комплексного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m) \exp \left( -j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+Для расчета используется алгоритм БПФ составной длины.
+
+\param[in] x
+Указатель на вектор комплексного
+входного сигнала \f$x(m)\f$, \f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер БПФ \f$n\f$. \n
+Размер БПФ может быть составным вида
+\f$ n = n_0 \times n_1 \times n_2 \times n_3 \times \ldots
+\times n_p \times m \f$,
+где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+произвольный простой множитель не превосходящий 46340
+(см. описание функции \ref fft_create). \n \n
+
+\param[in] pfft
+Указатель на структуру `fft_t`. \n
+Указатель не должен быть `NULL`. \n
+Структура \ref fft_t должна быть предварительно однократно
+заполнена функцией \ref fft_create, и память должна быть
+очищена перед выходом функцией \ref fft_free. \n \n
+
+\param[out] y
+Указатель на комплексный вектор
+результата БПФ \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$.
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если расчет произведен успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+Пример использования функции `fft`:
+
+\include fft_cmplx_test.c
+
+Результат работы программы:
+
+\verbatim
+y[ 0] = -0.517 0.686
+y[ 1] = -0.943 0.879
+y[ 2] = -2.299 1.492
+y[ 3] = 16.078 -6.820
+y[ 4] = 2.040 -0.470
+y[ 5] = 1.130 -0.059
+y[ 6] = 0.786 0.097
+y[ 7] = 0.596 0.183
+y[ 8] = 0.470 0.240
+y[ 9] = 0.375 0.283
+y[10] = 0.297 0.318
+y[11] = 0.227 0.350
+y[12] = 0.161 0.380
+y[13] = 0.094 0.410
+y[14] = 0.023 0.442
+y[15] = -0.059 0.479
+y[16] = -0.161 0.525
+y[17] = -0.300 0.588
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+{
+ int err;
+
+ if(!x || !pfft || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
+ err = fft_create(pfft, n);
+ if(err != RES_OK)
+ return err;
+
+ memcpy(pfft->t1, x, n*sizeof(complex_t));
+
+ return fft_krn(pfft->t1, y, pfft, n, 0);
+}
+
diff --git a/dspl/src/dft/fft_create.c b/dspl/src/dft/fft_create.c
new file mode 100644
index 0000000..3f44765
--- /dev/null
+++ b/dspl/src/dft/fft_create.c
@@ -0,0 +1,367 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_create(fft_t* pfft, int n)
+\brief Function creates and fill `fft_t` structure.
+
+The function allocates memory and calculates twiddle factors
+ of the `n`-point FFT for the structure` fft_t`.
+
+\param[in,out] pfft
+Pointer to the `fft_t` object. \n
+Pointer cannot be `NULL`. \n \n
+
+\param[in] n
+FFT size \f$n\f$. \n
+FFT size can be composite
+\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
+here \f$n_i = 2,3,5,7\f$, and \f$m \f$ --
+ arbitrary prime factor not exceeding 46340. \n
+Thus, the FFT algorithm supports arbitrary integer lengths.
+degrees of numbers 2,3,5,7, as well as their various combinations. \n
+For example, with \f$ n = 725760 \f$ the structure will be successfully filled,
+because
+\f$ 725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$. \n
+If \f$ n = 172804 = 43201 \cdot 4 \f$ then the structure will also be
+successfully filled, because the simple factor in \f$ n \f$ does not
+exceed 46340. \n
+For size \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$
+the function will return an error since 66079 is greater than 46340 and is
+not the result of the product of numbers 2,3,5,7. \n \n
+
+\return
+`RES_OK` if FFT structure is created and filled successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\note
+Some compilers do not nullify its contents when creating a structure.
+Therefore, it is recommended to reset the structure after its declaration:
+\code{.cpp}
+fft_t pfft = {0}; // fill and fields of fft_t as zeros
+int n = 64; // FFT size
+
+int err;
+
+// Create fft_t object for 64-points FFT
+
+err = fft_create(&pfft, n);
+
+// ...................................
+
+// Clear fft_t structure
+
+fft_free(&pfft);
+\endcode
+
+Before exiting the program, the memory allocated in the structure
+need to clear by \ref fft_free function. \n \n
+
+\note
+The "magic number" 46340 because \f$\sqrt{2^{31}} = 46340.95\f$. \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_create(fft_t* pfft, int n)
+\brief Заполнение структуры `fft_t` для алгоритма БПФ
+
+Функция производит выделение памяти и рассчет векторов
+поворотных коэффициентов `n`-точечного БПФ для структуры `fft_t`.
+
+\param[in,out] pfft
+Указатель на структуру `fft_t`. \n
+Указатель не должен быть `NULL`. \n \n
+
+\param[in] n
+Размер БПФ \f$n\f$. \n
+Размер БПФ может быть составным вида
+\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
+где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+произвольный простой множитель не превосходящий 46340. \n
+Таким образом алгоритм БПФ поддерживает произвольные длины, равные целой
+степени чисел 2,3,5,7, а также различные их комбинации. \n
+Так например, при \f$ n = 725760 \f$ структура будет успешно заполнена,
+потому что
+\f$725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$,
+т.е. получается как произведение множителей 2,3,5,7. \n
+При \f$ n = 172804 = 43201 \cdot 4 \f$ структура также будет успешно заполнена,
+потому что простой множитель входящий в \f$n\f$ не превосходит 46340. \n
+Для размера \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$
+функция вернет ошибку, поскольку 66079 больше 46340 и не является результатом
+произведения чисел 2,3,5,7. \n \n
+
+\return
+`RES_OK` если структура заполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+\note
+Некоторые компиляторы при создании структуры не обнуляют ее содержимое.
+Поэтому рекомендуется произвести обнуление структуры после ее объявления:
+\code{.cpp}
+fft_t pfft = {0}; // объявляем объект fft_t
+int n = 64; // Размер БПФ
+
+int err;
+
+// создаем объект для 64-точечного БПФ
+
+err = fft_create(&pfft, n);
+
+// ...................................
+
+// очистить память объекта БПФ
+
+fft_free(&pfft);
+\endcode
+
+Перед выходом из программы выделенную в структуре память
+необходимо очистить функцией \ref fft_free . \n \n
+
+\note
+Магия числа 46340 заключается в том, что \f$\sqrt{2^{31}} = 46340.95\f$. \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API fft_create(fft_t* pfft, int n)
+{
+
+ int n1, n2, addr, s, k, m, nw, err;
+ double phi;
+ s = n;
+ nw = addr = 0;
+
+ if(pfft->n == n)
+ return RES_OK;
+
+ while(s > 1)
+ {
+ n2 = 1;
+ if(s%4096 == 0) { n2 = 4096; goto label_size; }
+ if(s%2048 == 0) { n2 = 2048; goto label_size; }
+ if(s%1024 == 0) { n2 = 1024; goto label_size; }
+ if(s%512 == 0) { n2 = 512; goto label_size; }
+ if(s%256 == 0) { n2 = 256; goto label_size; }
+ if(s%128 == 0) { n2 = 128; goto label_size; }
+ if(s% 64 == 0) { n2 = 64; goto label_size; }
+ if(s% 32 == 0) { n2 = 32; goto label_size; }
+ if(s% 16 == 0) { n2 = 16; goto label_size; }
+ if(s% 7 == 0) { n2 = 7; goto label_size; }
+ if(s% 8 == 0) { n2 = 8; goto label_size; }
+ if(s% 5 == 0) { n2 = 5; goto label_size; }
+ if(s% 4 == 0) { n2 = 4; goto label_size; }
+ if(s% 3 == 0) { n2 = 3; goto label_size; }
+ if(s% 2 == 0) { n2 = 2; goto label_size; }
+
+
+label_size:
+ if(n2 == 1)
+ {
+ if(s > FFT_COMPOSITE_MAX)
+ {
+ err = ERROR_FFT_SIZE;
+ goto error_proc;
+ }
+
+ nw += s;
+ pfft->w = pfft->w ?
+ (complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
+ (complex_t*) malloc( nw*sizeof(complex_t));
+ for(k = 0; k < s; k++)
+ {
+ phi = - M_2PI * (double)k / (double)s;
+ RE(pfft->w[addr]) = cos(phi);
+ IM(pfft->w[addr]) = sin(phi);
+ addr++;
+ }
+ s = 1;
+ }
+ else
+ {
+ n1 = s / n2;
+ nw += s;
+ pfft->w = pfft->w ?
+ (complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
+ (complex_t*) malloc( nw*sizeof(complex_t));
+
+ for(k = 0; k < n1; k++)
+ {
+ for(m = 0; m < n2; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / (double)s;
+ RE(pfft->w[addr]) = cos(phi);
+ IM(pfft->w[addr]) = sin(phi);
+ addr++;
+ }
+ }
+ }
+ s /= n2;
+ }
+
+ pfft->t0 = pfft->t0 ? (complex_t*) realloc(pfft->t0, n*sizeof(complex_t)):
+ (complex_t*) malloc( n*sizeof(complex_t));
+
+ pfft->t1 = pfft->t1 ? (complex_t*) realloc(pfft->t1, n*sizeof(complex_t)):
+ (complex_t*) malloc( n*sizeof(complex_t));
+ pfft->n = n;
+
+ /* w32 fill */
+ addr = 0;
+ for(k = 0; k < 4; k++)
+ {
+ for(m = 0; m < 8; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / 32.0;
+ RE(pfft->w32[addr]) = cos(phi);
+ IM(pfft->w32[addr]) = sin(phi);
+ addr++;
+ }
+ }
+
+
+ /* w64 fill */
+ addr = 0;
+ for(k = 0; k < 8; k++)
+ {
+ for(m = 0; m < 8; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / 64.0;
+ RE(pfft->w64[addr]) = cos(phi);
+ IM(pfft->w64[addr]) = sin(phi);
+ addr++;
+ }
+ }
+
+ /* w128 fill */
+ addr = 0;
+ for(k = 0; k < 8; k++)
+ {
+ for(m = 0; m < 16; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / 128.0;
+ RE(pfft->w128[addr]) = cos(phi);
+ IM(pfft->w128[addr]) = sin(phi);
+ addr++;
+ }
+ }
+
+ /* w256 fill */
+ addr = 0;
+ for(k = 0; k < 16; k++)
+ {
+ for(m = 0; m < 16; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / 256.0;
+ RE(pfft->w256[addr]) = cos(phi);
+ IM(pfft->w256[addr]) = sin(phi);
+ addr++;
+ }
+ }
+
+ /* w512 fill */
+ addr = 0;
+ for(k = 0; k < 16; k++)
+ {
+ for(m = 0; m < 32; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / 512.0;
+ RE(pfft->w512[addr]) = cos(phi);
+ IM(pfft->w512[addr]) = sin(phi);
+ addr++;
+ }
+ }
+
+ /* w1024 fill */
+ if(pfft->w1024 == NULL)
+ {
+ pfft->w1024 = (complex_t*) malloc(1024 * sizeof(complex_t));
+ addr = 0;
+ for(k = 0; k < 32; k++)
+ {
+ for(m = 0; m < 32; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / 1024.0;
+ RE(pfft->w1024[addr]) = cos(phi);
+ IM(pfft->w1024[addr]) = sin(phi);
+ addr++;
+ }
+ }
+ }
+
+ /* w2048 fill */
+ if(pfft->w2048 == NULL)
+ {
+ pfft->w2048= (complex_t*) malloc(2048 * sizeof(complex_t));
+ addr = 0;
+ for(k = 0; k < 32; k++)
+ {
+ for(m = 0; m < 64; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / 2048.0;
+ RE(pfft->w2048[addr]) = cos(phi);
+ IM(pfft->w2048[addr]) = sin(phi);
+ addr++;
+ }
+ }
+ }
+
+ /* w4096 fill */
+ if(pfft->w4096 == NULL)
+ {
+ pfft->w4096= (complex_t*) malloc(4096 * sizeof(complex_t));
+ addr = 0;
+ for(k = 0; k < 16; k++)
+ {
+ for(m = 0; m < 256; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / 4096.0;
+ RE(pfft->w4096[addr]) = cos(phi);
+ IM(pfft->w4096[addr]) = sin(phi);
+ addr++;
+ }
+ }
+ }
+
+ return RES_OK;
+error_proc:
+ if(pfft->t0) free(pfft->t0);
+ if(pfft->t1) free(pfft->t1);
+ if(pfft->w) free(pfft->w);
+ pfft->n = 0;
+ return err;
+}
diff --git a/dspl/src/dft/fft_free.c b/dspl/src/dft/fft_free.c
new file mode 100644
index 0000000..e81a841
--- /dev/null
+++ b/dspl/src/dft/fft_free.c
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn void fft_free(fft_t *pfft)
+\brief Free `fft_t` structure.
+
+The function clears the intermediate data memory
+and vectors of FFT twiddle factors of the structure `fft_t`.
+
+\param[in] pfft
+Pointer to the `fft_t` object. \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn void fft_free(fft_t *pfft)
+\brief Очистить структуру `fft_t` алгоритма БПФ
+
+Функция производит очищение памяти промежуточных данных
+и векторов поворотных коэффициентов структуры `fft_t`.
+
+\param[in] pfft
+Указатель на структуру `fft_t`. \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+void DSPL_API fft_free(fft_t *pfft)
+{
+ if(!pfft)
+ return;
+ if(pfft->w)
+ free(pfft->w);
+ if(pfft->t0)
+ free(pfft->t0);
+ if(pfft->t1)
+ free(pfft->t1);
+
+ if(pfft->w1024)
+ free(pfft->w1024);
+
+ if(pfft->w2048)
+ free(pfft->w2048);
+
+ if(pfft->w4096)
+ free(pfft->w4096);
+
+ memset(pfft, 0, sizeof(fft_t));
+}
+
diff --git a/dspl/src/dft/fft_krn.c b/dspl/src/dft/fft_krn.c
new file mode 100644
index 0000000..e601d77
--- /dev/null
+++ b/dspl/src/dft/fft_krn.c
@@ -0,0 +1,170 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int fft_krn(complex_t* t0, complex_t* t1, fft_t* p, int n, int addr)
+{
+ int n1, n2, k, m, i;
+ complex_t *pw = p->w+addr;
+ complex_t tmp;
+
+ n1 = 1;
+ if(n % 4096 == 0) { n1 = 4096; goto label_size; }
+ if(n % 2048 == 0) { n1 = 2048; goto label_size; }
+ if(n % 1024 == 0) { n1 = 1024; goto label_size; }
+ if(n % 512 == 0) { n1 = 512; goto label_size; }
+ if(n % 256 == 0) { n1 = 256; goto label_size; }
+ if(n % 128 == 0) { n1 = 128; goto label_size; }
+ if(n % 64 == 0) { n1 = 64; goto label_size; }
+ if(n % 32 == 0) { n1 = 32; goto label_size; }
+ if(n % 16 == 0) { n1 = 16; goto label_size; }
+ if(n % 7 == 0) { n1 = 7; goto label_size; }
+ if(n % 8 == 0) { n1 = 8; goto label_size; }
+ if(n % 5 == 0) { n1 = 5; goto label_size; }
+ if(n % 4 == 0) { n1 = 4; goto label_size; }
+ if(n % 3 == 0) { n1 = 3; goto label_size; }
+ if(n % 2 == 0) { n1 = 2; goto label_size; }
+
+label_size:
+ if(n1 == 1)
+ {
+ for(k = 0; k < n; k++)
+ {
+ RE(t1[k]) = IM(t1[k]) = 0.0;
+ for(m = 0; m < n; m++)
+ {
+ i = (k*m) % n;
+ RE(tmp) = CMRE(t0[m], pw[i]);
+ IM(tmp) = CMIM(t0[m], pw[i]);
+ RE(t1[k]) += RE(tmp);
+ IM(t1[k]) += IM(tmp);
+ }
+ }
+ }
+ else
+ {
+ n2 = n / n1;
+
+ if(n2>1)
+ {
+ memcpy(t1, t0, n*sizeof(complex_t));
+ matrix_transpose_cmplx(t1, n2, n1, t0);
+ }
+
+ if(n1 == 4096)
+ for(k = 0; k < n2; k++)
+ dft4096(t0+4096*k, t1+4096*k, p->w4096, p->w256);
+
+ if(n1 == 2048)
+ for(k = 0; k < n2; k++)
+ dft2048(t0+2048*k, t1+2048*k, p->w2048, p->w32, p->w64);
+
+ if(n1 == 1024)
+ for(k = 0; k < n2; k++)
+ dft1024(t0+1024*k, t1+1024*k, p->w1024, p->w32);
+
+ if(n1 == 512)
+ for(k = 0; k < n2; k++)
+ dft512(t0+512*k, t1+512*k, p->w512, p->w32);
+
+ if(n1 == 256)
+ for(k = 0; k < n2; k++)
+ dft256(t0+256*k, t1+256*k, p->w256);
+
+ if(n1 == 128)
+ for(k = 0; k < n2; k++)
+ dft128(t0+128*k, t1+128*k, p->w128);
+
+ if(n1 == 64)
+ for(k = 0; k < n2; k++)
+ dft64(t0+64*k, t1+64*k, p->w64);
+
+ if(n1 == 32)
+ for(k = 0; k < n2; k++)
+ dft32(t0+32*k, t1+32*k, p->w32);
+
+ if(n1 == 16)
+ for(k = 0; k < n2; k++)
+ dft16(t0+16*k, t1+16*k);
+
+ if(n1 == 7)
+ for(k = 0; k < n2; k++)
+ dft7(t0+7*k, t1+7*k);
+
+ if(n1 == 8)
+ for(k = 0; k < n2; k++)
+ dft8(t0+8*k, t1+8*k);
+
+ if(n1 == 5)
+ for(k = 0; k < n2; k++)
+ dft5(t0+5*k, t1+5*k);
+
+ if(n1 == 4)
+ for(k = 0; k < n2; k++)
+ dft4(t0+4*k, t1+4*k);
+
+ if(n1 == 3)
+ for(k = 0; k < n2; k++)
+ dft3(t0+3*k, t1+3*k);
+
+ if(n1 == 2)
+ for(k = 0; k < n2; k++)
+ dft2(t0+2*k, t1+2*k);
+
+ if(n2 > 1)
+ {
+
+ for(k =0; k < n; k++)
+ {
+ RE(t0[k]) = CMRE(t1[k], pw[k]);
+ IM(t0[k]) = CMIM(t1[k], pw[k]);
+ }
+
+ matrix_transpose_cmplx(t0, n1, n2, t1);
+
+
+ for(k = 0; k < n1; k++)
+ {
+ fft_krn(t1+k*n2, t0+k*n2, p, n2, addr+n);
+ }
+
+ matrix_transpose_cmplx(t0, n2, n1, t1);
+ }
+ }
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/dft/fft_mag.c b/dspl/src/dft/fft_mag.c
new file mode 100644
index 0000000..7917c20
--- /dev/null
+++ b/dspl/src/dft/fft_mag.c
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API fft_mag(double* x, int n, fft_t* pfft,
+ double fs, int flag,
+ double* mag, double* freq)
+{
+ int k, err;
+ fft_t *cfft = NULL;
+
+ if(pfft)
+ cfft = pfft;
+ else
+ {
+ cfft = (fft_t*) malloc(sizeof(fft_t));
+ memset(cfft, 0, sizeof(fft_t));
+ }
+
+ err = fft_abs(x, n, cfft, fs, flag, mag, freq);
+ if(err != RES_OK)
+ goto error_proc;
+
+ if(mag)
+ {
+ if(flag & DSPL_FLAG_LOGMAG)
+ for(k = 0; k < n; k++)
+ mag[k] = 20.0 * log10(mag[k] + DBL_EPSILON);
+ else
+ for(k = 0; k < n; k++)
+ mag[k] *= mag[k];
+ }
+error_proc:
+ if(cfft && cfft != pfft)
+ free(cfft);
+ return err;
+}
diff --git a/dspl/src/dft/fft_mag_cmplx.c b/dspl/src/dft/fft_mag_cmplx.c
new file mode 100644
index 0000000..2cd5169
--- /dev/null
+++ b/dspl/src/dft/fft_mag_cmplx.c
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API fft_mag_cmplx(complex_t* x, int n, fft_t* pfft,
+ double fs, int flag,
+ double* mag, double* freq)
+{
+ int k, err;
+ fft_t *cfft = NULL;
+
+ if(pfft)
+ cfft = pfft;
+ else
+ {
+ cfft = (fft_t*) malloc(sizeof(fft_t));
+ memset(cfft, 0, sizeof(fft_t));
+ }
+
+ err = fft_abs_cmplx(x, n, cfft, fs, flag, mag, freq);
+ if(err != RES_OK)
+ goto error_proc;
+
+ if(mag)
+ {
+ if(flag & DSPL_FLAG_LOGMAG)
+ for(k = 0; k < n; k++)
+ mag[k] = 20.0 * log10(mag[k] + DBL_EPSILON);
+ else
+ for(k = 0; k < n; k++)
+ mag[k] *= mag[k];
+ }
+error_proc:
+ if(cfft && cfft != pfft)
+ free(cfft);
+ return err;
+}
+
diff --git a/dspl/src/dft/fft_shift.c b/dspl/src/dft/fft_shift.c
new file mode 100644
index 0000000..b1b5e47
--- /dev/null
+++ b/dspl/src/dft/fft_shift.c
@@ -0,0 +1,129 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_shift(double* x, int n, double* y)
+\brief Perform a shift of the vector `x`, for use with the `fft` and `ifft`
+functions, in order
+
+ to move the frequency 0 to the center
+ of the vector `y`.
+
+\param[in] x
+Pointer to the input vector (FFT or IFFT result). \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Input and output vector size. \n \n
+
+\param[out] y
+Pointer to the output vector with frequency 0 in the center. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+
+\return
+`RES_OK` if function is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_shift(double* x, int n, double* y)
+\brief Перестановка спектральных отсчетов дискретного преобразования Фурье
+
+Функция производит
+
+перестановку спектральных отсчетов ДПФ
+ и переносит нулевую частоту в центр вектора ДПФ. \n
+Данная функция обрабатывает вещественные входные и выходные вектора
+и может применяться для перестановки
+амплитудного или фазового спектра.
+
+\param[in] x
+Указатель на исходный вектор ДПФ. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ДПФ \f$n\f$ (размер векторов до и после перестановки). \n \n
+
+\param[out] y
+Указатель на вектор результата перестановки. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если перестановка произведена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API fft_shift(double* x, int n, double* y)
+{
+ int n2, r;
+ int k;
+ double tmp;
+ double *buf;
+
+ if(!x || !y)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ r = n%2;
+ if(!r)
+ {
+ n2 = n>>1;
+ for(k = 0; k < n2; k++)
+ {
+ tmp = x[k];
+ y[k] = x[k+n2];
+ y[k+n2] = tmp;
+ }
+ }
+ else
+ {
+ n2 = (n+1) >> 1;
+ buf = (double*) malloc(n2*sizeof(double));
+ memcpy(buf, x, n2*sizeof(double));
+ memcpy(y, x+n2, (n2-1)*sizeof(double));
+ memcpy(y+n2-1, buf, n2*sizeof(double));
+ free(buf);
+ }
+ return RES_OK;
+}
diff --git a/dspl/src/dft/fft_shift_cmplx.c b/dspl/src/dft/fft_shift_cmplx.c
new file mode 100644
index 0000000..d78015a
--- /dev/null
+++ b/dspl/src/dft/fft_shift_cmplx.c
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API fft_shift_cmplx(complex_t* x, int n, complex_t* y)
+{
+ int n2, r;
+ int k;
+ complex_t tmp;
+ complex_t *buf;
+
+ if(!x || !y)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ r = n%2;
+ if(!r)
+ {
+ n2 = n>>1;
+ for(k = 0; k < n2; k++)
+ {
+ RE(tmp) = RE(x[k]);
+ IM(tmp) = IM(x[k]);
+
+ RE(y[k]) = RE(x[k+n2]);
+ IM(y[k]) = IM(x[k+n2]);
+
+ RE(y[k+n2]) = RE(tmp);
+ IM(y[k+n2]) = IM(tmp);
+ }
+ }
+ else
+ {
+ n2 = (n+1) >> 1;
+ buf = (complex_t*) malloc(n2*sizeof(complex_t));
+ memcpy(buf, x, n2*sizeof(complex_t));
+ memcpy(y, x+n2, (n2-1)*sizeof(complex_t));
+ memcpy(y+n2-1, buf, n2*sizeof(complex_t));
+ free(buf);
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/fft_subkernel.c b/dspl/src/dft/fft_subkernel.c
similarity index 100%
rename from dspl/src/fft_subkernel.c
rename to dspl/src/dft/fft_subkernel.c
diff --git a/dspl/src/dft/fourier_integral_cmplx.c b/dspl/src/dft/fourier_integral_cmplx.c
new file mode 100644
index 0000000..12202f3
--- /dev/null
+++ b/dspl/src/dft/fourier_integral_cmplx.c
@@ -0,0 +1,69 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API fourier_integral_cmplx(double* t, complex_t* s, int nt,
+ int nw, double* w, complex_t* y)
+{
+ int k, m;
+ complex_t e[2];
+
+ if(!t || !s || !w || !y)
+ return ERROR_PTR;
+ if(nt<1 || nw < 1)
+ return ERROR_SIZE;
+
+
+ memset(y, 0 , nw*sizeof(complex_t));
+
+ for(k = 0; k < nw; k++)
+ {
+ RE(e[1]) = RE(s[0]) * cos(w[k] * t[0]) +
+ IM(s[0]) * sin(w[k] * t[0]);
+ IM(e[1]) = -RE(s[0]) * sin(w[k] * t[0]) +
+ IM(s[0]) * cos(w[k] * t[0]);
+ for(m = 1; m < nt; m++)
+ {
+ RE(e[0]) = RE(e[1]);
+ IM(e[0]) = IM(e[1]);
+ RE(e[1]) = RE(s[m]) * cos(w[k] * t[m]) +
+ IM(s[m]) * sin(w[k] * t[m]);
+ IM(e[1]) = -RE(s[m]) * sin(w[k] * t[m]) +
+ IM(s[m]) * cos(w[k] * t[m]);
+ RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
+ IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
+ }
+ }
+
+ return RES_OK;
+}
+
diff --git a/dspl/src/dft/fourier_series_dec.c b/dspl/src/dft/fourier_series_dec.c
new file mode 100644
index 0000000..3f531e3
--- /dev/null
+++ b/dspl/src/dft/fourier_series_dec.c
@@ -0,0 +1,190 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fourier_series_dec(double* t, double* s, int nt, double period,
+ int nw, double* w, complex_t* y)
+
+\brief
+Fourier series coefficient calculation for periodic signal
+
+\param[in] t
+Pointer to the time vector. \n
+Vector size is `[nt x 1]`. \n
+\n
+
+\param[in] s
+Pointer to the signal corresponds to time `t`. \n
+Vector size is `[nt x 1]`. \n
+\n
+
+\param[in] nt
+Size of time and signal vectors. \n
+This value must be positive. \n
+\n
+
+\param[in] period
+Signal time period. \n
+\n
+
+\param[in] nw
+Number of Fourie series coefficients. \n
+\n
+
+\param[out] w
+Pointer to the frequency vector (rad/s). \n
+Vector size is `[nw x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[out] y
+Pointer to the complex Fourier series coefficients vector. \n
+Vector size is `[nw x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if function is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\note
+Numerical integration is used for Fourier series coefficients calculation.
+This function is not effective.
+To increase the speed of calculation of the signal spectrum
+it is more expedient to use fast Fourier transform algorithms.
+\n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fourier_series_dec(double* t, double* s, int nt, double period,
+ int nw, double* w, complex_t* y)
+
+\brief
+Расчет коэффициентов разложения в ряд Фурье
+
+Функция рассчитывает спектр периодического сигнала при усечении ряда Фурье \n
+
+
+\param[in] t
+Указатель на массив моментов времени дискретизации исходного сигнала `s`. \n
+Размер вектора вектора `[nt x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] s
+Указатель на массив значений исходного сигнала`s`. \n
+Размер вектора `[nt x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+
+\param[in] nt
+Размер выборки исходного сигнала. \n
+Значение должно быть положительным. \n
+\n
+
+\param[in] period
+Период повторения сигнала. \n
+\n
+
+\param[in] nw
+Размер усеченного ряда Фурье. \n
+\n
+
+\param[out] w
+Указатель на массив частот спектра периодического сигнала. \n
+Размер вектора `[nw x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] y
+Указатель массив комплексных значений спектра периодического сигнала. \n
+Размер вектора `[nw x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- коэффициенты ряда Фурье рассчитаны успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\note
+Для расчета спектра сигнала используется численное интегрирование
+исходного сигнала методом трапеций. Данная функция не является
+эффективной. Для увеличения скорости расчета спектра сигнала
+целесообразнее использовать алгоритмы дискретного
+и быстрого преобразования Фурье.
+\n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API fourier_series_dec(double* t, double* s, int nt, double period,
+ int nw, double* w, complex_t* y)
+{
+ int k, m;
+ double dw = M_2PI / period;
+ complex_t e[2];
+
+ if(!t || !s || !w || !y)
+ return ERROR_PTR;
+ if(nt<1 || nw < 1)
+ return ERROR_SIZE;
+ if(period <= 0.0)
+ return ERROR_NEGATIVE;
+
+ memset(y, 0 , nw*sizeof(complex_t));
+
+ for(k = 0; k < nw; k++)
+ {
+ w[k] = (k - nw/2) * dw;
+ RE(e[1]) = s[0] * cos(w[k] * t[0]);
+ IM(e[1]) = -s[0] * sin(w[k] * t[0]);
+ for(m = 1; m < nt; m++)
+ {
+ RE(e[0]) = RE(e[1]);
+ IM(e[0]) = IM(e[1]);
+ RE(e[1]) = s[m] * cos(w[k] * t[m]);
+ IM(e[1]) = - s[m] * sin(w[k] * t[m]);
+ RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
+ IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
+ }
+ RE(y[k]) /= period;
+ IM(y[k]) /= period;
+ }
+
+ if(!(nw%2))
+ RE(y[0]) = RE(y[1]) = 0.0;
+
+ return RES_OK;
+}
diff --git a/dspl/src/dft/fourier_series_dec_cmplx.c b/dspl/src/dft/fourier_series_dec_cmplx.c
new file mode 100644
index 0000000..2f105b9
--- /dev/null
+++ b/dspl/src/dft/fourier_series_dec_cmplx.c
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API fourier_series_dec_cmplx(double* t, complex_t* s, int nt,
+ double period, int nw, double* w, complex_t* y)
+{
+ int k, m;
+ double dw = M_2PI / period;
+ complex_t e[2];
+
+ if(!t || !s || !w || !y)
+ return ERROR_PTR;
+ if(nt<1 || nw < 1)
+ return ERROR_SIZE;
+ if(period <= 0.0)
+ return ERROR_NEGATIVE;
+
+ memset(y, 0 , nw*sizeof(complex_t));
+
+ for(k = 0; k < nw; k++)
+ {
+ w[k] = (k - nw/2) * dw;
+ RE(e[1]) = RE(s[0]) * cos(w[k] * t[0]) +
+ IM(s[0]) * sin(w[k] * t[0]);
+ IM(e[1]) = -RE(s[0]) * sin(w[k] * t[0]) +
+ IM(s[0]) * cos(w[k] * t[0]);
+ for(m = 1; m < nt; m++)
+ {
+ RE(e[0]) = RE(e[1]);
+ IM(e[0]) = IM(e[1]);
+ RE(e[1]) = RE(s[m]) * cos(w[k] * t[m]) +
+ IM(s[m]) * sin(w[k] * t[m]);
+ IM(e[1]) = -RE(s[m]) * sin(w[k] * t[m]) +
+ IM(s[m]) * cos(w[k] * t[m]);
+ RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
+ IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
+ }
+ RE(y[k]) /= period;
+ IM(y[k]) /= period;
+ }
+
+ if(!(nw%2))
+ RE(y[0]) = RE(y[1]) = 0.0;
+
+ return RES_OK;
+}
diff --git a/dspl/src/dft/fourier_series_rec.c b/dspl/src/dft/fourier_series_rec.c
new file mode 100644
index 0000000..341b1f6
--- /dev/null
+++ b/dspl/src/dft/fourier_series_rec.c
@@ -0,0 +1,185 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+
+
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fourier_series_rec(double* w, complex_t* s, int nw,
+ double* t, int nt, complex_t* y)
+\brief Time signal reconstruction from Fourier series coefficients.
+
+Function reconstructs the time signal:
+
+\f[
+s(t) = \sum\limits_{n = 0}^{n_{\omega}-1} S(\omega_n) \exp(j\omega_n t)
+\f]
+
+\param[in] w
+Pointer to the Fourier series spectrum frequency vector \f$\omega_n\f$. \n
+Vector size is `[nw x 1]`. \n
+\n
+
+\param[in] s
+Pointer to the Fourier series coefficients vector \f$S(\omega_n)\f$. \n
+Vector size is `[nw x 1]`. \n
+\n
+
+
+\param[in] nw
+Number of Fourier series coefficients. \n
+This value must be positive. \n
+\n
+
+\param[in] t
+Pointer to the reconstructed signal time vector. \n
+Vector size is `[nt x 1]`. \n
+\n
+
+\param[in] nt
+Size of time vector and reconstructed signal vector . \n
+\n
+
+\param[out] y
+Pointer to the reconstructed signal vector. \n
+Vector size is `[nt x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if function is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\note
+The output reconstructed signal is generally complex.
+However, subject to the symmetry properties of the vectors `w` and` s`
+with respect to zero frequency we get the imaginary part of the vector `y`
+at the EPS level. The negligible imaginary part in this case
+can be ignored.
+\n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fourier_series_rec(double* w, complex_t* s, int nw,
+ double* t, int nt, complex_t* y)
+\brief Восстановление сигнала при усечении ряда Фурье
+
+Функция рассчитывает восстановленный сигнал при усечении ряда Фурье:
+
+\f[
+s(t) = \sum\limits_{n = 0}^{n_{\omega}-1} S(\omega_n) \exp(j\omega_n t)
+\f]
+
+\param[in] w
+Указатель на массив частот \f$\omega_n\f$ усеченного ряда Фурье. \n
+Размер вектора `[nw x 1]`. \n
+Память должна быть выделена и заполнена. \n
+\n
+
+\param[in] s
+Указатель на массив значений спектра \f$S(\omega_n)\f$. \n
+Размер вектора `[nw x 1]`. \n
+Память должна быть выделена и заполнена. \n
+\n
+
+
+\param[in] nw
+Количество членов усеченного ряда Фурье. \n
+Значение должно быть положительным. \n
+\n
+
+\param[in] t
+Указатель на массив временных отсчетов восстановленного сигнала. \n
+Размер вектора `[nt x 1]`. \n
+Память должна быть выделена и заполнена. \n
+\n
+
+\param[in] nt
+Размер вектора времени и восстановленного сигнала. \n
+\n
+
+\param[out] y
+Указатель на массив восстановленного сигнала. \n
+Размер вектора `[nt x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- восстановление сигнала прошло успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\note
+Выходной восстановленный сигнал в общем случае является комплексным.
+Однако при соблюдении свойств симметрии векторов `w` и `s` относительно
+нулевой частоты получим мнимую часть элементов вектора `y` на уровне ошибок
+округления числа с двойной точностью. Ничтожно малую мнимую часть в этом случае
+можно игнорировать.
+\n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API fourier_series_rec(double* w, complex_t* s, int nw,
+ double* t, int nt, complex_t* y)
+{
+ int k, m;
+ complex_t e;
+
+ if(!t || !s || !w || !y)
+ return ERROR_PTR;
+ if(nt<1 || nw < 1)
+ return ERROR_SIZE;
+
+ memset(y, 0, nt*sizeof(complex_t));
+
+
+ for(k = 0; k < nw; k++)
+ {
+ for(m = 0; m < nt; m++)
+ {
+ RE(e) = cos(w[k] * t[m]);
+ IM(e) = sin(w[k] * t[m]);
+
+ RE(y[m]) += CMRE(s[k], e);
+ IM(y[m]) += CMIM(s[k], e);
+ }
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/dft/goertzel.c b/dspl/src/dft/goertzel.c
new file mode 100644
index 0000000..ae21e7a
--- /dev/null
+++ b/dspl/src/dft/goertzel.c
@@ -0,0 +1,157 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
+\brief
+Goertzel algorithm individual DFT samples calculation for the real input vector `x`.
+
+Goertzel algorithm calculates `k` samples of `n`-point DFT, according to
+`ind` indexes vector.
+
+\param[in] x
+Pointer to the real input vector `x` \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of vector `x`. \n \n
+
+\param[in] ind
+Pointer to the DFT samples indexes which need
+to calculate by Goertzel algorithm. \n
+Vector size is `[k x 1]`. \n \n
+
+\param[in] k
+Size of vector `ind`. \n \n
+
+\param[out] y
+Pointer to the DFT samples vector corresponds to indexes `ind`. \n
+Vector size is `[k x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\note
+Goertzel's algorithm is effective when it is necessary to calculate
+several DFT samples of a signal of long duration. \n
+However, the size `k` of the vector of indices` ind` can be arbitrary,
+including more than the length of the signal `n`.
+In this case, some DFT samples will be repeated, but this will not entail
+a runtime error. \n
+The values of the indices of the DFT spectral samples `ind`
+can also be arbitrary integers, including negative ones.
+In this case, the DFT samples will be calculated.
+with indices modulo `n`. \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
+\brief
+Алгоритм Гёрцеля для расчета отдельных спектральных отсчетов дискретного
+преобразования Фурье вещественного сигнала `x`.
+
+Данный алгоритм позволяет рассчитать `k` спектральных отсчетов
+`n`-точечного ДПФ, заданных вектором индексов `ind`.
+
+\param[in] x
+Указатель на вектор вещественного входного сигнала. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер вектора входного сигнала. \n \n
+
+\param[in] ind
+Указатель на вектор индексов спектральных отсчетов для расчета которых
+будет использоваться алгоритм Герцеля. \n
+Размер вектора `[k x 1]`. \n \n
+
+\param[in] k
+Размер вектора индексов спектральных отсчетов `ind`. \n \n
+
+\param[out] y
+Указатель на вектор спектральных отсчетов, соответствующих номерам `ind`. \n
+Размер вектора `[k x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` --- расчёт выполнен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\note
+Алгоритм Гёрцеля эффективен когда необходимо рассчитать несколько
+спектральных отсчетов сигнала большой длительности. \n
+Однако, размер `k` вектора индексов `ind` может быть произвольным,
+в том числе больше длины сигнала `n`.
+В этом случае некоторые спектральные отсчеты будут повторяться, но это
+не повлечет за собой ошибки выполнения. \n
+Значения индексов спектральных отсчетов `ind` также могут быть
+произвольными целыми, в том числе и отрицательными.
+В этом случае будут рассчитаны спектральные отсчеты
+с индексами по модулю `n`. \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API goertzel(double *x, int n, int *ind, int k, complex_t *y)
+{
+
+ int m, p;
+ double wR, wI;
+ double alpha;
+ double v[3];
+
+ if(!x || !y || !ind)
+ return ERROR_PTR;
+
+ if(n < 1 || k < 1)
+ return ERROR_SIZE;
+
+ for(p = 0; p < k; p++)
+ {
+ wR = cos(M_2PI * (double)ind[p] / (double)n);
+ wI = sin(M_2PI * (double)ind[p] / (double)n);
+
+ alpha = 2.0 * wR;
+ v[0] = v[1] = v[2] = 0.0;
+
+ for(m = 0; m < n; m++)
+ {
+ v[2] = v[1];
+ v[1] = v[0];
+ v[0] = x[m]+alpha*v[1] - v[2];
+ }
+ RE(y[p]) = wR * v[0] - v[1];
+ IM(y[p]) = wI * v[0];
+ }
+ return RES_OK;
+}
diff --git a/dspl/src/goertzel.c b/dspl/src/dft/goertzel_cmplx.c
similarity index 54%
rename from dspl/src/goertzel.c
rename to dspl/src/dft/goertzel_cmplx.c
index a2bcd3c..26aefdd 100644
--- a/dspl/src/goertzel.c
+++ b/dspl/src/dft/goertzel_cmplx.c
@@ -1,302 +1,166 @@
-/*
-* Copyright (c) 2015-2019 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of libdspl-2.0.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DSPL is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Foobar. If not, see .
-*/
-
-#include
-#include
-#include "dspl.h"
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
-\brief
-Goertzel algorithm individual DFT samples calculation for the real input vector `x`.
-
-Goertzel algorithm calculates `k` samples of `n`-point DFT, according to
-`ind` indexes vector.
-
-\param[in] x
-Pointer to the real input vector `x` \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of vector `x`. \n \n
-
-\param[in] ind
-Pointer to the DFT samples indexes which need
-to calculate by Goertzel algorithm. \n
-Vector size is `[k x 1]`. \n \n
-
-\param[in] k
-Size of vector `ind`. \n \n
-
-\param[out] y
-Pointer to the DFT samples vector corresponds to indexes `ind`. \n
-Vector size is `[k x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\note
-Goertzel's algorithm is effective when it is necessary to calculate
-several DFT samples of a signal of long duration. \n
-However, the size `k` of the vector of indices` ind` can be arbitrary,
-including more than the length of the signal `n`.
-In this case, some DFT samples will be repeated, but this will not entail
-a runtime error. \n
-The values of the indices of the DFT spectral samples `ind`
-can also be arbitrary integers, including negative ones.
-In this case, the DFT samples will be calculated.
-with indices modulo `n`. \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
-\brief
-Алгоритм Гёрцеля для расчета отдельных спектральных отсчетов дискретного
-преобразования Фурье вещественного сигнала `x`.
-
-Данный алгоритм позволяет рассчитать `k` спектральных отсчетов
-`n`-точечного ДПФ, заданных вектором индексов `ind`.
-
-\param[in] x
-Указатель на вектор вещественного входного сигнала. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер вектора входного сигнала. \n \n
-
-\param[in] ind
-Указатель на вектор индексов спектральных отсчетов для расчета которых
-будет использоваться алгоритм Герцеля. \n
-Размер вектора `[k x 1]`. \n \n
-
-\param[in] k
-Размер вектора индексов спектральных отсчетов `ind`. \n \n
-
-\param[out] y
-Указатель на вектор спектральных отсчетов, соответствующих номерам `ind`. \n
-Размер вектора `[k x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` --- расчёт выполнен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\note
-Алгоритм Гёрцеля эффективен когда необходимо рассчитать несколько
-спектральных отсчетов сигнала большой длительности. \n
-Однако, размер `k` вектора индексов `ind` может быть произвольным,
-в том числе больше длины сигнала `n`.
-В этом случае некоторые спектральные отсчеты будут повторяться, но это
-не повлечет за собой ошибки выполнения. \n
-Значения индексов спектральных отсчетов `ind` также могут быть
-произвольными целыми, в том числе и отрицательными.
-В этом случае будут рассчитаны спектральные отсчеты
-с индексами по модулю `n`. \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API goertzel(double *x, int n, int *ind, int k, complex_t *y)
-{
-
- int m, p;
- double wR, wI;
- double alpha;
- double v[3];
-
- if(!x || !y || !ind)
- return ERROR_PTR;
-
- if(n < 1 || k < 1)
- return ERROR_SIZE;
-
- for(p = 0; p < k; p++)
- {
- wR = cos(M_2PI * (double)ind[p] / (double)n);
- wI = sin(M_2PI * (double)ind[p] / (double)n);
-
- alpha = 2.0 * wR;
- v[0] = v[1] = v[2] = 0.0;
-
- for(m = 0; m < n; m++)
- {
- v[2] = v[1];
- v[1] = v[0];
- v[0] = x[m]+alpha*v[1] - v[2];
- }
- RE(y[p]) = wR * v[0] - v[1];
- IM(y[p]) = wI * v[0];
- }
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int goertzel_cmplx(complex_t *x, int n, int *ind, int k, complex_t *y)
-\brief
-Goertzel algorithm individual DFT samples calculation for
-the complex input vector `x`.
-
-Goertzel algorithm calculates `k` samples of `n`-point DFT, according to
-`ind` indexes vector.
-
-\param[in] x
-Pointer to the complex input vector `x` \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of vector `x`. \n \n
-
-\param[in] ind
-Pointer to the DFT samples indexes which need
-to calculate by Goertzel algorithm. \n
-Vector size is `[k x 1]`. \n \n
-
-\param[in] k
-Size of vector `ind`. \n \n
-
-\param[out] y
-Pointer to the DFT samples vector corresponds to indexes `ind`. \n
-Vector size is `[k x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\note
-Goertzel's algorithm is effective when it is necessary to calculate
-several DFT samples of a signal of long duration. \n
-However, the size `k` of the vector of indices` ind` can be arbitrary,
-including more than the length of the signal `n`.
-In this case, some DFT samples will be repeated, but this will not entail
-a runtime error. \n
-The values of the indices of the DFT spectral samples `ind`
-can also be arbitrary integers, including negative ones.
-In this case, the DFT samples will be calculated.
-with indices modulo `n`. \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int goertzel_cmplx(complex_t *x, int n, int *ind, int k, complex_t *y)
-\brief
-Алгоритм Гёрцеля для расчета отдельных спектральных отсчетов дискретного
-преобразования Фурье комплексного сигнала `x`.
-
-Данный алгоритм позволяет рассчитать `k` спектральных отсчетов
-`n`-точечного ДПФ, заданных вектором индексов `ind`.
-
-\param[in] x
-Указатель на вектор комплексного входного сигнала. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер вектора входного сигнала. \n \n
-
-\param[in] ind
-Указатель на вектор индексов спектральных отсчетов для расчета которых
-будет использоваться алгоритм Герцеля. \n
-Размер вектора `[k x 1]`. \n \n
-
-\param[in] k
-Размер вектора индексов спектральных отсчетов `ind`. \n \n
-
-\param[out] y
-Указатель на вектор спектральных отсчетов, соответствующих номерам `ind`. \n
-Размер вектора `[k x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` --- функция выполнена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\note
-Алгоритм Герцеля эффективен когда необходимо рассчитать несколько
-спектральных отсчетов сигнала большой длительности. \n
-Однако, размер `k` вектора индексов `ind` может быть произвольным,
-в том числе больше длины сигнала `n`.
-В этом случае некоторые спектральные отсчеты
-будут повторяться, но это не повлечет за собой ошибки выполнения. \n
-Значения индексов спектральных отсчетов `ind` также могут быть
-произвольными целыми, в том числе и отрицательными.
-В этом случае будут рассчитаны спектральные отсчеты с индексами
-по модулю `n`. \n \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API goertzel_cmplx(complex_t *x, int n, int *ind, int k, complex_t *y)
-{
-
- int m, p;
- complex_t w;
- double alpha;
- complex_t v[3];
-
- if(!x || !y || !ind)
- return ERROR_PTR;
-
- if(n < 1 || k < 1)
- return ERROR_SIZE;
-
- for(p = 0; p < k; p++)
- {
- RE(w) = cos(M_2PI * (double)ind[p] / (double)n);
- IM(w) = sin(M_2PI * (double)ind[p] / (double)n);
-
- alpha = 2.0 * RE(w);
- memset(v, 0, 3*sizeof(complex_t));
-
- for(m = 0; m < n; m++)
- {
- RE(v[2]) = RE(v[1]);
- RE(v[1]) = RE(v[0]);
- RE(v[0]) = RE(x[m]) + alpha * RE(v[1]) - RE(v[2]);
-
- IM(v[2]) = IM(v[1]);
- IM(v[1]) = IM(v[0]);
- IM(v[0]) = IM(x[m]) + alpha * IM(v[1]) - IM(v[2]);
- }
-
- RE(y[p]) = CMRE(w, v[0]) - RE(v[1]);
- IM(y[p]) = CMIM(w, v[0]) - IM(v[1]);
- }
-
- return RES_OK;
-}
-
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int goertzel_cmplx(complex_t *x, int n, int *ind, int k, complex_t *y)
+\brief
+Goertzel algorithm individual DFT samples calculation for
+the complex input vector `x`.
+
+Goertzel algorithm calculates `k` samples of `n`-point DFT, according to
+`ind` indexes vector.
+
+\param[in] x
+Pointer to the complex input vector `x` \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of vector `x`. \n \n
+
+\param[in] ind
+Pointer to the DFT samples indexes which need
+to calculate by Goertzel algorithm. \n
+Vector size is `[k x 1]`. \n \n
+
+\param[in] k
+Size of vector `ind`. \n \n
+
+\param[out] y
+Pointer to the DFT samples vector corresponds to indexes `ind`. \n
+Vector size is `[k x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\note
+Goertzel's algorithm is effective when it is necessary to calculate
+several DFT samples of a signal of long duration. \n
+However, the size `k` of the vector of indices` ind` can be arbitrary,
+including more than the length of the signal `n`.
+In this case, some DFT samples will be repeated, but this will not entail
+a runtime error. \n
+The values of the indices of the DFT spectral samples `ind`
+can also be arbitrary integers, including negative ones.
+In this case, the DFT samples will be calculated.
+with indices modulo `n`. \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int goertzel_cmplx(complex_t *x, int n, int *ind, int k, complex_t *y)
+\brief
+Алгоритм Гёрцеля для расчета отдельных спектральных отсчетов дискретного
+преобразования Фурье комплексного сигнала `x`.
+
+Данный алгоритм позволяет рассчитать `k` спектральных отсчетов
+`n`-точечного ДПФ, заданных вектором индексов `ind`.
+
+\param[in] x
+Указатель на вектор комплексного входного сигнала. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер вектора входного сигнала. \n \n
+
+\param[in] ind
+Указатель на вектор индексов спектральных отсчетов для расчета которых
+будет использоваться алгоритм Герцеля. \n
+Размер вектора `[k x 1]`. \n \n
+
+\param[in] k
+Размер вектора индексов спектральных отсчетов `ind`. \n \n
+
+\param[out] y
+Указатель на вектор спектральных отсчетов, соответствующих номерам `ind`. \n
+Размер вектора `[k x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` --- функция выполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\note
+Алгоритм Герцеля эффективен когда необходимо рассчитать несколько
+спектральных отсчетов сигнала большой длительности. \n
+Однако, размер `k` вектора индексов `ind` может быть произвольным,
+в том числе больше длины сигнала `n`.
+В этом случае некоторые спектральные отсчеты
+будут повторяться, но это не повлечет за собой ошибки выполнения. \n
+Значения индексов спектральных отсчетов `ind` также могут быть
+произвольными целыми, в том числе и отрицательными.
+В этом случае будут рассчитаны спектральные отсчеты с индексами
+по модулю `n`. \n \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API goertzel_cmplx(complex_t *x, int n, int *ind, int k, complex_t *y)
+{
+
+ int m, p;
+ complex_t w;
+ double alpha;
+ complex_t v[3];
+
+ if(!x || !y || !ind)
+ return ERROR_PTR;
+
+ if(n < 1 || k < 1)
+ return ERROR_SIZE;
+
+ for(p = 0; p < k; p++)
+ {
+ RE(w) = cos(M_2PI * (double)ind[p] / (double)n);
+ IM(w) = sin(M_2PI * (double)ind[p] / (double)n);
+
+ alpha = 2.0 * RE(w);
+ memset(v, 0, 3*sizeof(complex_t));
+
+ for(m = 0; m < n; m++)
+ {
+ RE(v[2]) = RE(v[1]);
+ RE(v[1]) = RE(v[0]);
+ RE(v[0]) = RE(x[m]) + alpha * RE(v[1]) - RE(v[2]);
+
+ IM(v[2]) = IM(v[1]);
+ IM(v[1]) = IM(v[0]);
+ IM(v[0]) = IM(x[m]) + alpha * IM(v[1]) - IM(v[2]);
+ }
+
+ RE(y[p]) = CMRE(w, v[0]) - RE(v[1]);
+ IM(y[p]) = CMIM(w, v[0]) - IM(v[1]);
+ }
+
+ return RES_OK;
+}
+
diff --git a/dspl/src/dft/idft_cmplx.c b/dspl/src/dft/idft_cmplx.c
new file mode 100644
index 0000000..1283c28
--- /dev/null
+++ b/dspl/src/dft/idft_cmplx.c
@@ -0,0 +1,195 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
+\brief Inverse discrete Fourier transform of the complex spectrum.
+
+The function calculates the \f$ n \f$ -point inverse discrete transform
+Fourier complex spectrum \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ y (k) = \sum_ {m = 0} ^ {n-1} x (m)
+ \exp \left (j \frac {2 \pi} {n} m k \right),
+\f]
+where \f$ k = 0 \ldots n-1 \f$.
+
+\param [in] x
+Pointer to the vector of the input complex signal spectrum \f$ x (m) \f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+The size of the vector is `[n x 1]`. \n \n
+
+\param [in] n
+The size of the ODPF \f$ n \f$
+(the size of the vectors of the input spectrum and the result of the ODPF). \n
+\n
+
+\param [out] y
+Pointer to the complex vector of the ODPF result \f$ y (k) \f$,
+\f$ k = 0 \ldots n-1 \f$.
+The size of the vector is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+
+\return
+`RES_OK` if the ODPF is calculated successfully. \n
+Otherwise, \ref ERROR_CODE_GROUP "error code".
+
+An example of using the `dft_cmplx` function:
+
+\include idft_cmplx_test.c
+
+The result of the program:
+
+\verbatim
+x [0] = 0.000 + 0.000j, z [0] = 0.000 -0.000
+x [1] = 1.000 + 0.000j, z [1] = 1.000 -0.000
+x [2] = 2.000 + 0.000j, z [2] = 2.000 -0.000
+x [3] = 3.000 + 0.000j, z [3] = 3.000 -0.000
+x [4] = 4.000 + 0.000j, z [4] = 4.000 -0.000
+x [5] = 5.000 + 0.000j, z [5] = 5.000 -0.000
+x [6] = 6.000 + 0.000j, z [6] = 6.000 -0.000
+x [7] = 7.000 + 0.000j, z [7] = 7.000 -0.000
+x [8] = 8.000 + 0.000j, z [8] = 8.000 -0.000
+x [9] = 9.000 + 0.000j, z [9] = 9.000 -0.000
+x [10] = 10.000 + 0.000j, z [10] = 10.000 -0.000
+x [11] = 11.000 + 0.000j, z [11] = 11.000 +0.000
+x [12] = 12.000 + 0.000j, z [12] = 12.000 +0.000
+x [13] = 13.000 + 0.000j, z [13] = 13.000 +0.000
+x [14] = 14.000 + 0.000j, z [14] = 14.000 +0.000
+x [15] = 15.000 + 0.000j, z [15] = 15.000 -0.000
+\endverbatim
+
+\note
+This function performs the calculation of the DFT using the naive method.
+and requires \f$ n ^ 2 \f$ complex multiplications. \n
+To increase the calculation speed, it is recommended
+use fast Fourier transform algorithms.
+
+\author Bakhurin Sergey www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
+\brief Обратное дискретное преобразование Фурье комплексного спектра.
+
+Функция рассчитывает \f$ n \f$-точечное обратное дискретное преобразование
+Фурье комплексного спектра \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ y(k) = \sum_{m = 0}^{n-1} x(m)
+ \exp \left( j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+\param[in] x
+Указатель на вектор входного комплексного спектра сигнала \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ОДПФ \f$n\f$ (размер векторов входного спектра и результата ОДПФ). \n \n
+
+\param[out] y
+Указатель на комплексный вектор результата ОДПФ \f$y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$.
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+
+\return
+`RES_OK` если ОДПФ рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример использования функции `dft_cmplx`:
+
+\include idft_cmplx_test.c
+
+Результат работы программы:
+
+\verbatim
+x[ 0] = 0.000 +0.000j, z[ 0] = 0.000 -0.000
+x[ 1] = 1.000 +0.000j, z[ 1] = 1.000 -0.000
+x[ 2] = 2.000 +0.000j, z[ 2] = 2.000 -0.000
+x[ 3] = 3.000 +0.000j, z[ 3] = 3.000 -0.000
+x[ 4] = 4.000 +0.000j, z[ 4] = 4.000 -0.000
+x[ 5] = 5.000 +0.000j, z[ 5] = 5.000 -0.000
+x[ 6] = 6.000 +0.000j, z[ 6] = 6.000 -0.000
+x[ 7] = 7.000 +0.000j, z[ 7] = 7.000 -0.000
+x[ 8] = 8.000 +0.000j, z[ 8] = 8.000 -0.000
+x[ 9] = 9.000 +0.000j, z[ 9] = 9.000 -0.000
+x[10] = 10.000 +0.000j, z[10] = 10.000 -0.000
+x[11] = 11.000 +0.000j, z[11] = 11.000 +0.000
+x[12] = 12.000 +0.000j, z[12] = 12.000 +0.000
+x[13] = 13.000 +0.000j, z[13] = 13.000 +0.000
+x[14] = 14.000 +0.000j, z[14] = 14.000 +0.000
+x[15] = 15.000 +0.000j, z[15] = 15.000 -0.000
+\endverbatim
+
+\note
+Данная функция выполняет расчет ОДПФ наивным методом
+и требует \f$ n^2 \f$ комплексных умножений. \n
+Для увеличения скорости расчета рекомендуется
+использовать алгоритмы быстрого преобразования Фурье.
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API idft_cmplx(complex_t* x, int n, complex_t* y)
+{
+ int k;
+ int m;
+ double divn;
+ double phi;
+ complex_t e;
+
+ if(!x || !y)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ divn = 1.0 / (double)n;
+
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = IM(y[k]) = 0.0;
+ for(m = 0; m < n; m++)
+ {
+ phi = M_2PI * divn * (double)k * (double)m;
+ RE(e) = cos(phi);
+ IM(e) = sin(phi);
+ RE(y[k]) += CMRE(x[m], e);
+ IM(y[k]) += CMIM(x[m], e);
+ }
+ RE(y[k]) /= (double)n;
+ IM(y[k]) /= (double)n;
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/dft/ifft_cmplx.c b/dspl/src/dft/ifft_cmplx.c
new file mode 100644
index 0000000..85ccae3
--- /dev/null
+++ b/dspl/src/dft/ifft_cmplx.c
@@ -0,0 +1,209 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "dspl.h"
+#include "dspl_internal.h"
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+\brief Inverse fast Fourier transform
+
+Function calculates \f$ n \f$-point IFFT of complex data
+\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \frac{1}{N} \sum_{m = 0}^{n-1} x(m) \exp
+ \left( j \frac{2\pi}{n} m k \right),
+\f]
+here \f$ k = 0 \ldots n-1 \f$.
+
+
+\param[in] x
+Pointer to the input vector \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+IFFT size \f$n\f$. \n
+IFFT size can be composite:
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+simple number less than 46340
+(see \ref fft_create function). \n \n
+
+\param[in] pfft
+Pointer to the `fft_t` object. \n
+This pointer cannot be `NULL`. \n
+Structure \ref fft_t should be previously once
+filled with the \ref fft_create function, and the memory should be
+cleared before exiting by the \ref fft_free function. \n \n
+
+\param[out] y
+Pointer to the IFFT result vector \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if IFFT is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+IFFT example:
+
+\include ifft_cmplx_test.c
+
+Result:
+
+\verbatim
+| x[ 0] = 1.000 0.000 | y[ 0] = -0.517 0.686 | z[ 0] = 1.000 0.000 |
+| x[ 1] = 0.540 0.841 | y[ 1] = -0.943 0.879 | z[ 1] = 0.540 0.841 |
+| x[ 2] = -0.416 0.909 | y[ 2] = -2.299 1.492 | z[ 2] = -0.416 0.909 |
+| x[ 3] = -0.990 0.141 | y[ 3] = 16.078 -6.820 | z[ 3] = -0.990 0.141 |
+| x[ 4] = -0.654 -0.757 | y[ 4] = 2.040 -0.470 | z[ 4] = -0.654 -0.757 |
+| x[ 5] = 0.284 -0.959 | y[ 5] = 1.130 -0.059 | z[ 5] = 0.284 -0.959 |
+| x[ 6] = 0.960 -0.279 | y[ 6] = 0.786 0.097 | z[ 6] = 0.960 -0.279 |
+| x[ 7] = 0.754 0.657 | y[ 7] = 0.596 0.183 | z[ 7] = 0.754 0.657 |
+| x[ 8] = -0.146 0.989 | y[ 8] = 0.470 0.240 | z[ 8] = -0.146 0.989 |
+| x[ 9] = -0.911 0.412 | y[ 9] = 0.375 0.283 | z[ 9] = -0.911 0.412 |
+| x[10] = -0.839 -0.544 | y[10] = 0.297 0.318 | z[10] = -0.839 -0.544 |
+| x[11] = 0.004 -1.000 | y[11] = 0.227 0.350 | z[11] = 0.004 -1.000 |
+| x[12] = 0.844 -0.537 | y[12] = 0.161 0.380 | z[12] = 0.844 -0.537 |
+| x[13] = 0.907 0.420 | y[13] = 0.094 0.410 | z[13] = 0.907 0.420 |
+| x[14] = 0.137 0.991 | y[14] = 0.023 0.442 | z[14] = 0.137 0.991 |
+| x[15] = -0.760 0.650 | y[15] = -0.059 0.479 | z[15] = -0.760 0.650 |
+| x[16] = -0.958 -0.288 | y[16] = -0.161 0.525 | z[16] = -0.958 -0.288 |
+| x[17] = -0.275 -0.961 | y[17] = -0.300 0.588 | z[17] = -0.275 -0.961 |
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+\brief Обратное быстрое преобразование Фурье
+
+Функция рассчитывает \f$ n \f$-точечное обратное быстрое преобразование Фурье
+от \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \frac{1}{N} \sum_{m = 0}^{n-1} x(m) \exp
+ \left( j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+Для расчета используется алгоритм БПФ составной длины.
+
+\param[in] x
+Указатель на входной комплексный вектор \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ОБПФ \f$n\f$. \n
+Размер ОБПФ может быть составным вида
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+произвольный простой множитель не превосходящий 46340
+(см. описание функции \ref fft_create). \n \n
+
+\param[in] pfft
+Указатель на структуру `fft_t`. \n
+Указатель не должен быть `NULL`. \n
+Структура \ref fft_t должна быть предварительно однократно
+заполнена функцией \ref fft_create, и память должна быть
+очищена перед выходом функцией \ref fft_free. \n \n
+
+\param[out] y
+Указатель на вектор результата ОБПФ \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+Пример использования функции `fft`:
+
+\include ifft_cmplx_test.c
+
+Результат работы программы:
+
+\verbatim
+| x[ 0] = 1.000 0.000 | y[ 0] = -0.517 0.686 | z[ 0] = 1.000 0.000 |
+| x[ 1] = 0.540 0.841 | y[ 1] = -0.943 0.879 | z[ 1] = 0.540 0.841 |
+| x[ 2] = -0.416 0.909 | y[ 2] = -2.299 1.492 | z[ 2] = -0.416 0.909 |
+| x[ 3] = -0.990 0.141 | y[ 3] = 16.078 -6.820 | z[ 3] = -0.990 0.141 |
+| x[ 4] = -0.654 -0.757 | y[ 4] = 2.040 -0.470 | z[ 4] = -0.654 -0.757 |
+| x[ 5] = 0.284 -0.959 | y[ 5] = 1.130 -0.059 | z[ 5] = 0.284 -0.959 |
+| x[ 6] = 0.960 -0.279 | y[ 6] = 0.786 0.097 | z[ 6] = 0.960 -0.279 |
+| x[ 7] = 0.754 0.657 | y[ 7] = 0.596 0.183 | z[ 7] = 0.754 0.657 |
+| x[ 8] = -0.146 0.989 | y[ 8] = 0.470 0.240 | z[ 8] = -0.146 0.989 |
+| x[ 9] = -0.911 0.412 | y[ 9] = 0.375 0.283 | z[ 9] = -0.911 0.412 |
+| x[10] = -0.839 -0.544 | y[10] = 0.297 0.318 | z[10] = -0.839 -0.544 |
+| x[11] = 0.004 -1.000 | y[11] = 0.227 0.350 | z[11] = 0.004 -1.000 |
+| x[12] = 0.844 -0.537 | y[12] = 0.161 0.380 | z[12] = 0.844 -0.537 |
+| x[13] = 0.907 0.420 | y[13] = 0.094 0.410 | z[13] = 0.907 0.420 |
+| x[14] = 0.137 0.991 | y[14] = 0.023 0.442 | z[14] = 0.137 0.991 |
+| x[15] = -0.760 0.650 | y[15] = -0.059 0.479 | z[15] = -0.760 0.650 |
+| x[16] = -0.958 -0.288 | y[16] = -0.161 0.525 | z[16] = -0.958 -0.288 |
+| x[17] = -0.275 -0.961 | y[17] = -0.300 0.588 | z[17] = -0.275 -0.961 |
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ifft_cmplx(complex_t *x, int n, fft_t* pfft, complex_t* y)
+{
+ int err, k;
+ double norm;
+
+ if(!x || !pfft || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
+
+ err = fft_create(pfft, n);
+ if(err != RES_OK)
+ return err;
+
+ memcpy(pfft->t1, x, n*sizeof(complex_t));
+ for(k = 0; k < n; k++)
+ IM(pfft->t1[k]) = -IM(pfft->t1[k]);
+
+ err = fft_krn(pfft->t1, pfft->t0, pfft, n, 0);
+
+ if(err!=RES_OK)
+ return err;
+
+ norm = 1.0 / (double)n;
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = RE(pfft->t0[k])*norm;
+ IM(y[k]) = -IM(pfft->t0[k])*norm;
+ }
+ return RES_OK;
+}
\ No newline at end of file
diff --git a/dspl/src/fft.c b/dspl/src/fft.c
deleted file mode 100644
index 5fe7e16..0000000
--- a/dspl/src/fft.c
+++ /dev/null
@@ -1,1441 +0,0 @@
-/*
-* Copyright (c) 2015-2019 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of libdspl-2.0.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DSPL is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Foobar. If not, see .
-*/
-
-#include
-#include
-#include
-#include
-
-#include "dspl.h"
-#include "dspl_internal.h"
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-\brief Inverse fast Fourier transform
-
-Function calculates \f$ n \f$-point IFFT of complex data
-\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \frac{1}{N} \sum_{m = 0}^{n-1} x(m) \exp
- \left( j \frac{2\pi}{n} m k \right),
-\f]
-here \f$ k = 0 \ldots n-1 \f$.
-
-
-\param[in] x
-Pointer to the input vector \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-IFFT size \f$n\f$. \n
-IFFT size can be composite:
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-simple number less than 46340
-(see \ref fft_create function). \n \n
-
-\param[in] pfft
-Pointer to the `fft_t` object. \n
-This pointer cannot be `NULL`. \n
-Structure \ref fft_t should be previously once
-filled with the \ref fft_create function, and the memory should be
-cleared before exiting by the \ref fft_free function. \n \n
-
-\param[out] y
-Pointer to the IFFT result vector \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if IFFT is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-IFFT example:
-
-\include ifft_cmplx_test.c
-
-Result:
-
-\verbatim
-| x[ 0] = 1.000 0.000 | y[ 0] = -0.517 0.686 | z[ 0] = 1.000 0.000 |
-| x[ 1] = 0.540 0.841 | y[ 1] = -0.943 0.879 | z[ 1] = 0.540 0.841 |
-| x[ 2] = -0.416 0.909 | y[ 2] = -2.299 1.492 | z[ 2] = -0.416 0.909 |
-| x[ 3] = -0.990 0.141 | y[ 3] = 16.078 -6.820 | z[ 3] = -0.990 0.141 |
-| x[ 4] = -0.654 -0.757 | y[ 4] = 2.040 -0.470 | z[ 4] = -0.654 -0.757 |
-| x[ 5] = 0.284 -0.959 | y[ 5] = 1.130 -0.059 | z[ 5] = 0.284 -0.959 |
-| x[ 6] = 0.960 -0.279 | y[ 6] = 0.786 0.097 | z[ 6] = 0.960 -0.279 |
-| x[ 7] = 0.754 0.657 | y[ 7] = 0.596 0.183 | z[ 7] = 0.754 0.657 |
-| x[ 8] = -0.146 0.989 | y[ 8] = 0.470 0.240 | z[ 8] = -0.146 0.989 |
-| x[ 9] = -0.911 0.412 | y[ 9] = 0.375 0.283 | z[ 9] = -0.911 0.412 |
-| x[10] = -0.839 -0.544 | y[10] = 0.297 0.318 | z[10] = -0.839 -0.544 |
-| x[11] = 0.004 -1.000 | y[11] = 0.227 0.350 | z[11] = 0.004 -1.000 |
-| x[12] = 0.844 -0.537 | y[12] = 0.161 0.380 | z[12] = 0.844 -0.537 |
-| x[13] = 0.907 0.420 | y[13] = 0.094 0.410 | z[13] = 0.907 0.420 |
-| x[14] = 0.137 0.991 | y[14] = 0.023 0.442 | z[14] = 0.137 0.991 |
-| x[15] = -0.760 0.650 | y[15] = -0.059 0.479 | z[15] = -0.760 0.650 |
-| x[16] = -0.958 -0.288 | y[16] = -0.161 0.525 | z[16] = -0.958 -0.288 |
-| x[17] = -0.275 -0.961 | y[17] = -0.300 0.588 | z[17] = -0.275 -0.961 |
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-\brief Обратное быстрое преобразование Фурье
-
-Функция рассчитывает \f$ n \f$-точечное обратное быстрое преобразование Фурье
-от \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \frac{1}{N} \sum_{m = 0}^{n-1} x(m) \exp
- \left( j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-Для расчета используется алгоритм БПФ составной длины.
-
-\param[in] x
-Указатель на входной комплексный вектор \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ОБПФ \f$n\f$. \n
-Размер ОБПФ может быть составным вида
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-произвольный простой множитель не превосходящий 46340
-(см. описание функции \ref fft_create). \n \n
-
-\param[in] pfft
-Указатель на структуру `fft_t`. \n
-Указатель не должен быть `NULL`. \n
-Структура \ref fft_t должна быть предварительно однократно
-заполнена функцией \ref fft_create, и память должна быть
-очищена перед выходом функцией \ref fft_free. \n \n
-
-\param[out] y
-Указатель на вектор результата ОБПФ \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-Пример использования функции `fft`:
-
-\include ifft_cmplx_test.c
-
-Результат работы программы:
-
-\verbatim
-| x[ 0] = 1.000 0.000 | y[ 0] = -0.517 0.686 | z[ 0] = 1.000 0.000 |
-| x[ 1] = 0.540 0.841 | y[ 1] = -0.943 0.879 | z[ 1] = 0.540 0.841 |
-| x[ 2] = -0.416 0.909 | y[ 2] = -2.299 1.492 | z[ 2] = -0.416 0.909 |
-| x[ 3] = -0.990 0.141 | y[ 3] = 16.078 -6.820 | z[ 3] = -0.990 0.141 |
-| x[ 4] = -0.654 -0.757 | y[ 4] = 2.040 -0.470 | z[ 4] = -0.654 -0.757 |
-| x[ 5] = 0.284 -0.959 | y[ 5] = 1.130 -0.059 | z[ 5] = 0.284 -0.959 |
-| x[ 6] = 0.960 -0.279 | y[ 6] = 0.786 0.097 | z[ 6] = 0.960 -0.279 |
-| x[ 7] = 0.754 0.657 | y[ 7] = 0.596 0.183 | z[ 7] = 0.754 0.657 |
-| x[ 8] = -0.146 0.989 | y[ 8] = 0.470 0.240 | z[ 8] = -0.146 0.989 |
-| x[ 9] = -0.911 0.412 | y[ 9] = 0.375 0.283 | z[ 9] = -0.911 0.412 |
-| x[10] = -0.839 -0.544 | y[10] = 0.297 0.318 | z[10] = -0.839 -0.544 |
-| x[11] = 0.004 -1.000 | y[11] = 0.227 0.350 | z[11] = 0.004 -1.000 |
-| x[12] = 0.844 -0.537 | y[12] = 0.161 0.380 | z[12] = 0.844 -0.537 |
-| x[13] = 0.907 0.420 | y[13] = 0.094 0.410 | z[13] = 0.907 0.420 |
-| x[14] = 0.137 0.991 | y[14] = 0.023 0.442 | z[14] = 0.137 0.991 |
-| x[15] = -0.760 0.650 | y[15] = -0.059 0.479 | z[15] = -0.760 0.650 |
-| x[16] = -0.958 -0.288 | y[16] = -0.161 0.525 | z[16] = -0.958 -0.288 |
-| x[17] = -0.275 -0.961 | y[17] = -0.300 0.588 | z[17] = -0.275 -0.961 |
-\endverbatim
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ifft_cmplx(complex_t *x, int n, fft_t* pfft, complex_t* y)
-{
- int err, k;
- double norm;
-
- if(!x || !pfft || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
-
-
- err = fft_create(pfft, n);
- if(err != RES_OK)
- return err;
-
- memcpy(pfft->t1, x, n*sizeof(complex_t));
- for(k = 0; k < n; k++)
- IM(pfft->t1[k]) = -IM(pfft->t1[k]);
-
- err = fft_krn(pfft->t1, pfft->t0, pfft, n, 0);
-
- if(err!=RES_OK)
- return err;
-
- norm = 1.0 / (double)n;
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = RE(pfft->t0[k])*norm;
- IM(y[k]) = -IM(pfft->t0[k])*norm;
- }
- return RES_OK;
-}
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
-\brief Fast Fourier transform for the real vector.
-
-Function calculated \f$ n \f$-points FFT for the real vector
-\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
- \left( -j \frac{2\pi}{n} m k \right),
-\f]
-here \f$ k = 0 \ldots n-1 \f$.
-
-
-\param[in] x
-Pointer to the input real vector \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-FFT size \f$n\f$. \n
-FFT size can be composite:
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-simple number less than 46340
-(see \ref fft_create function). \n \n
-
-\param[in] pfft
-Pointer to the `fft_t` object. \n
-This pointer cannot be `NULL`. \n
-Structure \ref fft_t should be previously once
-filled with the \ref fft_create function, and the memory should be
-cleared before exiting by the \ref fft_free function. \n \n
-
-\param[out] y
-Pointer to the FFT result complex vector \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if FFT is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Example:
-
-\include fft_test.c
-
-Result:
-
-\verbatim
-y[ 0] = 91.000 0.000
-y[ 1] = -7.000 30.669
-y[ 2] = -7.000 14.536
-y[ 3] = -7.000 8.778
-y[ 4] = -7.000 5.582
-y[ 5] = -7.000 3.371
-y[ 6] = -7.000 1.598
-y[ 7] = -7.000 0.000
-y[ 8] = -7.000 -1.598
-y[ 9] = -7.000 -3.371
-y[10] = -7.000 -5.582
-y[11] = -7.000 -8.778
-y[12] = -7.000 -14.536
-y[13] = -7.000 -30.669
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
-\brief Быстрое преобразование Фурье вещественного сигнала
-
-Функция рассчитывает \f$ n \f$-точечное быстрое преобразование Фурье
-вещественного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
- \left( -j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-Для расчета используется алгоритм БПФ составной длины.
-
-\param[in] x
-Указатель на вектор вещественного входного сигнала \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер БПФ \f$n\f$. \n
-Размер БПФ может быть составным вида
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-произвольный простой множитель не превосходящий 46340
-(см. описание функции \ref fft_create). \n \n
-
-\param[in] pfft
-Указатель на структуру `fft_t`. \n
-Указатель не должен быть `NULL`. \n
-Структура \ref fft_t должна быть предварительно однократно
-заполнена функцией \ref fft_create, и память должна быть
-очищена перед выходом функцией \ref fft_free. \n \n
-
-\param[out] y
-Указатель на комплексный вектор результата БПФ \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если расчет произведен успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-Пример использования функции `fft`:
-
-\include fft_test.c
-
-Результат работы программы:
-
-\verbatim
-y[ 0] = 91.000 0.000
-y[ 1] = -7.000 30.669
-y[ 2] = -7.000 14.536
-y[ 3] = -7.000 8.778
-y[ 4] = -7.000 5.582
-y[ 5] = -7.000 3.371
-y[ 6] = -7.000 1.598
-y[ 7] = -7.000 0.000
-y[ 8] = -7.000 -1.598
-y[ 9] = -7.000 -3.371
-y[10] = -7.000 -5.582
-y[11] = -7.000 -8.778
-y[12] = -7.000 -14.536
-y[13] = -7.000 -30.669
-\endverbatim
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API fft(double* x, int n, fft_t* pfft, complex_t* y)
-{
- int err;
-
- if(!x || !pfft || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
-
-
- err = fft_create(pfft, n);
- if(err != RES_OK)
- return err;
-
- re2cmplx(x, n, pfft->t1);
-
- return fft_krn(pfft->t1, y, pfft, n, 0);
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API fft_abs(double* x, int n, fft_t* pfft,
- double fs, int flag,
- double* mag, double* freq)
-{
- int k, err = RES_OK;
- complex_t *X = NULL;
- if(!x || !pfft)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- if(mag)
- {
- X = (complex_t*)malloc(n*sizeof(complex_t));
- err = fft(x, n, pfft, X);
- if(err!=RES_OK)
- goto error_proc;
-
-
- for(k = 0; k < n; k++)
- mag[k] = ABS(X[k]);
- if(flag & DSPL_FLAG_FFT_SHIFT)
- {
- err = fft_shift(mag, n, mag);
- if(err!=RES_OK)
- goto error_proc;
- }
- }
-
- if(freq)
- {
- if(flag & DSPL_FLAG_FFT_SHIFT)
- if(n%2)
- err = linspace(-fs*0.5 + fs*0.5/(double)n,
- fs*0.5 - fs*0.5/(double)n,
- n, DSPL_SYMMETRIC, freq);
- else
- err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
- else
- err = linspace(0, fs, n, DSPL_PERIODIC, freq);
- }
-
-error_proc:
- if(X)
- free(X);
-
- return err;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API fft_abs_cmplx(complex_t* x, int n, fft_t* pfft,
- double fs, int flag,
- double* mag, double* freq)
-{
- int k, err = RES_OK;
- complex_t *X = NULL;
-
- if(!x || !pfft)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- if(mag)
- {
- X = (complex_t*)malloc(n*sizeof(complex_t));
- err = fft_cmplx(x, n, pfft, X);
- if(err!=RES_OK)
- goto error_proc;
-
-
- for(k = 0; k < n; k++)
- mag[k] = ABS(X[k]);
-
- if(flag & DSPL_FLAG_FFT_SHIFT)
- {
- err = fft_shift(mag, n, mag);
- if(err!=RES_OK)
- goto error_proc;
- }
- }
-
- if(freq)
- {
- if(flag & DSPL_FLAG_FFT_SHIFT)
- if(n%2)
- err = linspace(-fs*0.5 + fs*0.5/(double)n,
- fs*0.5 - fs*0.5/(double)n,
- n, DSPL_SYMMETRIC, freq);
- else
- err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
- else
- err = linspace(0, fs, n, DSPL_PERIODIC, freq);
- }
-error_proc:
- if(X)
- free(X);
-
- return err;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-\brief Fast Fourier transform for the complex vector.
-
-Function calculated \f$ n \f$-points FFT for the complex vector
-\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m) \exp \left( -j \frac{2\pi}{n} m k \right),
-\f]
-here \f$ k = 0 \ldots n-1 \f$.
-
-\param[in] x
-Pointer to the input complex vector \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-FFT size \f$n\f$. \n
-FFT size can be composite:
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-simple number less than 46340
-(see \ref fft_create function). \n \n
-
-\param[in] pfft
-Pointer to the `fft_t` object. \n
-This pointer cannot be `NULL`. \n
-Structure \ref fft_t should be previously once
-filled with the \ref fft_create function, and the memory should be
-cleared before exiting by the \ref fft_free function. \n \n
-
-\param[out] y
-Pointer to the FFT result complex vector \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if FFT is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Example:
-
-\include fft_cmplx_test.c
-
-Result:
-
-\verbatim
-y[ 0] = -0.517 0.686
-y[ 1] = -0.943 0.879
-y[ 2] = -2.299 1.492
-y[ 3] = 16.078 -6.820
-y[ 4] = 2.040 -0.470
-y[ 5] = 1.130 -0.059
-y[ 6] = 0.786 0.097
-y[ 7] = 0.596 0.183
-y[ 8] = 0.470 0.240
-y[ 9] = 0.375 0.283
-y[10] = 0.297 0.318
-y[11] = 0.227 0.350
-y[12] = 0.161 0.380
-y[13] = 0.094 0.410
-y[14] = 0.023 0.442
-y[15] = -0.059 0.479
-y[16] = -0.161 0.525
-y[17] = -0.300 0.588
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-\brief Быстрое преобразование Фурье комплексного сигнала
-
-Функция рассчитывает \f$ n \f$-точечное быстрое преобразование Фурье
-комплексного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m) \exp \left( -j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-Для расчета используется алгоритм БПФ составной длины.
-
-\param[in] x
-Указатель на вектор комплексного
-входного сигнала \f$x(m)\f$, \f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер БПФ \f$n\f$. \n
-Размер БПФ может быть составным вида
-\f$ n = n_0 \times n_1 \times n_2 \times n_3 \times \ldots
-\times n_p \times m \f$,
-где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-произвольный простой множитель не превосходящий 46340
-(см. описание функции \ref fft_create). \n \n
-
-\param[in] pfft
-Указатель на структуру `fft_t`. \n
-Указатель не должен быть `NULL`. \n
-Структура \ref fft_t должна быть предварительно однократно
-заполнена функцией \ref fft_create, и память должна быть
-очищена перед выходом функцией \ref fft_free. \n \n
-
-\param[out] y
-Указатель на комплексный вектор
-результата БПФ \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$.
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если расчет произведен успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-Пример использования функции `fft`:
-
-\include fft_cmplx_test.c
-
-Результат работы программы:
-
-\verbatim
-y[ 0] = -0.517 0.686
-y[ 1] = -0.943 0.879
-y[ 2] = -2.299 1.492
-y[ 3] = 16.078 -6.820
-y[ 4] = 2.040 -0.470
-y[ 5] = 1.130 -0.059
-y[ 6] = 0.786 0.097
-y[ 7] = 0.596 0.183
-y[ 8] = 0.470 0.240
-y[ 9] = 0.375 0.283
-y[10] = 0.297 0.318
-y[11] = 0.227 0.350
-y[12] = 0.161 0.380
-y[13] = 0.094 0.410
-y[14] = 0.023 0.442
-y[15] = -0.059 0.479
-y[16] = -0.161 0.525
-y[17] = -0.300 0.588
-\endverbatim
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-{
- int err;
-
- if(!x || !pfft || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
-
- err = fft_create(pfft, n);
- if(err != RES_OK)
- return err;
-
- memcpy(pfft->t1, x, n*sizeof(complex_t));
-
- return fft_krn(pfft->t1, y, pfft, n, 0);
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int fft_krn(complex_t* t0, complex_t* t1, fft_t* p, int n, int addr)
-{
- int n1, n2, k, m, i;
- complex_t *pw = p->w+addr;
- complex_t tmp;
-
- n1 = 1;
- if(n % 4096 == 0) { n1 = 4096; goto label_size; }
- if(n % 2048 == 0) { n1 = 2048; goto label_size; }
- if(n % 1024 == 0) { n1 = 1024; goto label_size; }
- if(n % 512 == 0) { n1 = 512; goto label_size; }
- if(n % 256 == 0) { n1 = 256; goto label_size; }
- if(n % 128 == 0) { n1 = 128; goto label_size; }
- if(n % 64 == 0) { n1 = 64; goto label_size; }
- if(n % 32 == 0) { n1 = 32; goto label_size; }
- if(n % 16 == 0) { n1 = 16; goto label_size; }
- if(n % 7 == 0) { n1 = 7; goto label_size; }
- if(n % 8 == 0) { n1 = 8; goto label_size; }
- if(n % 5 == 0) { n1 = 5; goto label_size; }
- if(n % 4 == 0) { n1 = 4; goto label_size; }
- if(n % 3 == 0) { n1 = 3; goto label_size; }
- if(n % 2 == 0) { n1 = 2; goto label_size; }
-
-label_size:
- if(n1 == 1)
- {
- for(k = 0; k < n; k++)
- {
- RE(t1[k]) = IM(t1[k]) = 0.0;
- for(m = 0; m < n; m++)
- {
- i = (k*m) % n;
- RE(tmp) = CMRE(t0[m], pw[i]);
- IM(tmp) = CMIM(t0[m], pw[i]);
- RE(t1[k]) += RE(tmp);
- IM(t1[k]) += IM(tmp);
- }
- }
- }
- else
- {
- n2 = n / n1;
-
- if(n2>1)
- {
- memcpy(t1, t0, n*sizeof(complex_t));
- matrix_transpose_cmplx(t1, n2, n1, t0);
- }
-
- if(n1 == 4096)
- for(k = 0; k < n2; k++)
- dft4096(t0+4096*k, t1+4096*k, p->w4096, p->w256);
-
- if(n1 == 2048)
- for(k = 0; k < n2; k++)
- dft2048(t0+2048*k, t1+2048*k, p->w2048, p->w32, p->w64);
-
- if(n1 == 1024)
- for(k = 0; k < n2; k++)
- dft1024(t0+1024*k, t1+1024*k, p->w1024, p->w32);
-
- if(n1 == 512)
- for(k = 0; k < n2; k++)
- dft512(t0+512*k, t1+512*k, p->w512, p->w32);
-
- if(n1 == 256)
- for(k = 0; k < n2; k++)
- dft256(t0+256*k, t1+256*k, p->w256);
-
- if(n1 == 128)
- for(k = 0; k < n2; k++)
- dft128(t0+128*k, t1+128*k, p->w128);
-
- if(n1 == 64)
- for(k = 0; k < n2; k++)
- dft64(t0+64*k, t1+64*k, p->w64);
-
- if(n1 == 32)
- for(k = 0; k < n2; k++)
- dft32(t0+32*k, t1+32*k, p->w32);
-
- if(n1 == 16)
- for(k = 0; k < n2; k++)
- dft16(t0+16*k, t1+16*k);
-
- if(n1 == 7)
- for(k = 0; k < n2; k++)
- dft7(t0+7*k, t1+7*k);
-
- if(n1 == 8)
- for(k = 0; k < n2; k++)
- dft8(t0+8*k, t1+8*k);
-
- if(n1 == 5)
- for(k = 0; k < n2; k++)
- dft5(t0+5*k, t1+5*k);
-
- if(n1 == 4)
- for(k = 0; k < n2; k++)
- dft4(t0+4*k, t1+4*k);
-
- if(n1 == 3)
- for(k = 0; k < n2; k++)
- dft3(t0+3*k, t1+3*k);
-
- if(n1 == 2)
- for(k = 0; k < n2; k++)
- dft2(t0+2*k, t1+2*k);
-
- if(n2 > 1)
- {
-
- for(k =0; k < n; k++)
- {
- RE(t0[k]) = CMRE(t1[k], pw[k]);
- IM(t0[k]) = CMIM(t1[k], pw[k]);
- }
-
- matrix_transpose_cmplx(t0, n1, n2, t1);
-
-
- for(k = 0; k < n1; k++)
- {
- fft_krn(t1+k*n2, t0+k*n2, p, n2, addr+n);
- }
-
- matrix_transpose_cmplx(t0, n2, n1, t1);
- }
- }
- return RES_OK;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_create(fft_t* pfft, int n)
-\brief Function creates and fill `fft_t` structure.
-
-The function allocates memory and calculates twiddle factors
- of the `n`-point FFT for the structure` fft_t`.
-
-\param[in,out] pfft
-Pointer to the `fft_t` object. \n
-Pointer cannot be `NULL`. \n \n
-
-\param[in] n
-FFT size \f$n\f$. \n
-FFT size can be composite
-\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
-here \f$n_i = 2,3,5,7\f$, and \f$m \f$ --
- arbitrary prime factor not exceeding 46340. \n
-Thus, the FFT algorithm supports arbitrary integer lengths.
-degrees of numbers 2,3,5,7, as well as their various combinations. \n
-For example, with \f$ n = 725760 \f$ the structure will be successfully filled,
-because
-\f$ 725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$. \n
-If \f$ n = 172804 = 43201 \cdot 4 \f$ then the structure will also be
-successfully filled, because the simple factor in \f$ n \f$ does not
-exceed 46340. \n
-For size \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$
-the function will return an error since 66079 is greater than 46340 and is
-not the result of the product of numbers 2,3,5,7. \n \n
-
-\return
-`RES_OK` if FFT structure is created and filled successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\note
-Some compilers do not nullify its contents when creating a structure.
-Therefore, it is recommended to reset the structure after its declaration:
-\code{.cpp}
-fft_t pfft = {0}; // fill and fields of fft_t as zeros
-int n = 64; // FFT size
-
-int err;
-
-// Create fft_t object for 64-points FFT
-
-err = fft_create(&pfft, n);
-
-// ...................................
-
-// Clear fft_t structure
-
-fft_free(&pfft);
-\endcode
-
-Before exiting the program, the memory allocated in the structure
-need to clear by \ref fft_free function. \n \n
-
-\note
-The "magic number" 46340 because \f$\sqrt{2^{31}} = 46340.95\f$. \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_create(fft_t* pfft, int n)
-\brief Заполнение структуры `fft_t` для алгоритма БПФ
-
-Функция производит выделение памяти и рассчет векторов
-поворотных коэффициентов `n`-точечного БПФ для структуры `fft_t`.
-
-\param[in,out] pfft
-Указатель на структуру `fft_t`. \n
-Указатель не должен быть `NULL`. \n \n
-
-\param[in] n
-Размер БПФ \f$n\f$. \n
-Размер БПФ может быть составным вида
-\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
-где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-произвольный простой множитель не превосходящий 46340. \n
-Таким образом алгоритм БПФ поддерживает произвольные длины, равные целой
-степени чисел 2,3,5,7, а также различные их комбинации. \n
-Так например, при \f$ n = 725760 \f$ структура будет успешно заполнена,
-потому что
-\f$725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$,
-т.е. получается как произведение множителей 2,3,5,7. \n
-При \f$ n = 172804 = 43201 \cdot 4 \f$ структура также будет успешно заполнена,
-потому что простой множитель входящий в \f$n\f$ не превосходит 46340. \n
-Для размера \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$
-функция вернет ошибку, поскольку 66079 больше 46340 и не является результатом
-произведения чисел 2,3,5,7. \n \n
-
-\return
-`RES_OK` если структура заполнена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-\note
-Некоторые компиляторы при создании структуры не обнуляют ее содержимое.
-Поэтому рекомендуется произвести обнуление структуры после ее объявления:
-\code{.cpp}
-fft_t pfft = {0}; // объявляем объект fft_t
-int n = 64; // Размер БПФ
-
-int err;
-
-// создаем объект для 64-точечного БПФ
-
-err = fft_create(&pfft, n);
-
-// ...................................
-
-// очистить память объекта БПФ
-
-fft_free(&pfft);
-\endcode
-
-Перед выходом из программы выделенную в структуре память
-необходимо очистить функцией \ref fft_free . \n \n
-
-\note
-Магия числа 46340 заключается в том, что \f$\sqrt{2^{31}} = 46340.95\f$. \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API fft_create(fft_t* pfft, int n)
-{
-
- int n1, n2, addr, s, k, m, nw, err;
- double phi;
- s = n;
- nw = addr = 0;
-
- if(pfft->n == n)
- return RES_OK;
-
- while(s > 1)
- {
- n2 = 1;
- if(s%4096 == 0) { n2 = 4096; goto label_size; }
- if(s%2048 == 0) { n2 = 2048; goto label_size; }
- if(s%1024 == 0) { n2 = 1024; goto label_size; }
- if(s%512 == 0) { n2 = 512; goto label_size; }
- if(s%256 == 0) { n2 = 256; goto label_size; }
- if(s%128 == 0) { n2 = 128; goto label_size; }
- if(s% 64 == 0) { n2 = 64; goto label_size; }
- if(s% 32 == 0) { n2 = 32; goto label_size; }
- if(s% 16 == 0) { n2 = 16; goto label_size; }
- if(s% 7 == 0) { n2 = 7; goto label_size; }
- if(s% 8 == 0) { n2 = 8; goto label_size; }
- if(s% 5 == 0) { n2 = 5; goto label_size; }
- if(s% 4 == 0) { n2 = 4; goto label_size; }
- if(s% 3 == 0) { n2 = 3; goto label_size; }
- if(s% 2 == 0) { n2 = 2; goto label_size; }
-
-
-label_size:
- if(n2 == 1)
- {
- if(s > FFT_COMPOSITE_MAX)
- {
- err = ERROR_FFT_SIZE;
- goto error_proc;
- }
-
- nw += s;
- pfft->w = pfft->w ?
- (complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
- (complex_t*) malloc( nw*sizeof(complex_t));
- for(k = 0; k < s; k++)
- {
- phi = - M_2PI * (double)k / (double)s;
- RE(pfft->w[addr]) = cos(phi);
- IM(pfft->w[addr]) = sin(phi);
- addr++;
- }
- s = 1;
- }
- else
- {
- n1 = s / n2;
- nw += s;
- pfft->w = pfft->w ?
- (complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
- (complex_t*) malloc( nw*sizeof(complex_t));
-
- for(k = 0; k < n1; k++)
- {
- for(m = 0; m < n2; m++)
- {
- phi = - M_2PI * (double)(k*m) / (double)s;
- RE(pfft->w[addr]) = cos(phi);
- IM(pfft->w[addr]) = sin(phi);
- addr++;
- }
- }
- }
- s /= n2;
- }
-
- pfft->t0 = pfft->t0 ? (complex_t*) realloc(pfft->t0, n*sizeof(complex_t)):
- (complex_t*) malloc( n*sizeof(complex_t));
-
- pfft->t1 = pfft->t1 ? (complex_t*) realloc(pfft->t1, n*sizeof(complex_t)):
- (complex_t*) malloc( n*sizeof(complex_t));
- pfft->n = n;
-
- /* w32 fill */
- addr = 0;
- for(k = 0; k < 4; k++)
- {
- for(m = 0; m < 8; m++)
- {
- phi = - M_2PI * (double)(k*m) / 32.0;
- RE(pfft->w32[addr]) = cos(phi);
- IM(pfft->w32[addr]) = sin(phi);
- addr++;
- }
- }
-
-
- /* w64 fill */
- addr = 0;
- for(k = 0; k < 8; k++)
- {
- for(m = 0; m < 8; m++)
- {
- phi = - M_2PI * (double)(k*m) / 64.0;
- RE(pfft->w64[addr]) = cos(phi);
- IM(pfft->w64[addr]) = sin(phi);
- addr++;
- }
- }
-
- /* w128 fill */
- addr = 0;
- for(k = 0; k < 8; k++)
- {
- for(m = 0; m < 16; m++)
- {
- phi = - M_2PI * (double)(k*m) / 128.0;
- RE(pfft->w128[addr]) = cos(phi);
- IM(pfft->w128[addr]) = sin(phi);
- addr++;
- }
- }
-
- /* w256 fill */
- addr = 0;
- for(k = 0; k < 16; k++)
- {
- for(m = 0; m < 16; m++)
- {
- phi = - M_2PI * (double)(k*m) / 256.0;
- RE(pfft->w256[addr]) = cos(phi);
- IM(pfft->w256[addr]) = sin(phi);
- addr++;
- }
- }
-
- /* w512 fill */
- addr = 0;
- for(k = 0; k < 16; k++)
- {
- for(m = 0; m < 32; m++)
- {
- phi = - M_2PI * (double)(k*m) / 512.0;
- RE(pfft->w512[addr]) = cos(phi);
- IM(pfft->w512[addr]) = sin(phi);
- addr++;
- }
- }
-
- /* w1024 fill */
- if(pfft->w1024 == NULL)
- {
- pfft->w1024 = (complex_t*) malloc(1024 * sizeof(complex_t));
- addr = 0;
- for(k = 0; k < 32; k++)
- {
- for(m = 0; m < 32; m++)
- {
- phi = - M_2PI * (double)(k*m) / 1024.0;
- RE(pfft->w1024[addr]) = cos(phi);
- IM(pfft->w1024[addr]) = sin(phi);
- addr++;
- }
- }
- }
-
- /* w2048 fill */
- if(pfft->w2048 == NULL)
- {
- pfft->w2048= (complex_t*) malloc(2048 * sizeof(complex_t));
- addr = 0;
- for(k = 0; k < 32; k++)
- {
- for(m = 0; m < 64; m++)
- {
- phi = - M_2PI * (double)(k*m) / 2048.0;
- RE(pfft->w2048[addr]) = cos(phi);
- IM(pfft->w2048[addr]) = sin(phi);
- addr++;
- }
- }
- }
-
- /* w4096 fill */
- if(pfft->w4096 == NULL)
- {
- pfft->w4096= (complex_t*) malloc(4096 * sizeof(complex_t));
- addr = 0;
- for(k = 0; k < 16; k++)
- {
- for(m = 0; m < 256; m++)
- {
- phi = - M_2PI * (double)(k*m) / 4096.0;
- RE(pfft->w4096[addr]) = cos(phi);
- IM(pfft->w4096[addr]) = sin(phi);
- addr++;
- }
- }
- }
-
- return RES_OK;
-error_proc:
- if(pfft->t0) free(pfft->t0);
- if(pfft->t1) free(pfft->t1);
- if(pfft->w) free(pfft->w);
- pfft->n = 0;
- return err;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn void fft_free(fft_t *pfft)
-\brief Free `fft_t` structure.
-
-The function clears the intermediate data memory
-and vectors of FFT twiddle factors of the structure `fft_t`.
-
-\param[in] pfft
-Pointer to the `fft_t` object. \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn void fft_free(fft_t *pfft)
-\brief Очистить структуру `fft_t` алгоритма БПФ
-
-Функция производит очищение памяти промежуточных данных
-и векторов поворотных коэффициентов структуры `fft_t`.
-
-\param[in] pfft
-Указатель на структуру `fft_t`. \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-void DSPL_API fft_free(fft_t *pfft)
-{
- if(!pfft)
- return;
- if(pfft->w)
- free(pfft->w);
- if(pfft->t0)
- free(pfft->t0);
- if(pfft->t1)
- free(pfft->t1);
-
- if(pfft->w1024)
- free(pfft->w1024);
-
- if(pfft->w2048)
- free(pfft->w2048);
-
- if(pfft->w4096)
- free(pfft->w4096);
-
- memset(pfft, 0, sizeof(fft_t));
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API fft_mag(double* x, int n, fft_t* pfft,
- double fs, int flag,
- double* mag, double* freq)
-{
- int k, err;
- fft_t *cfft = NULL;
-
- if(pfft)
- cfft = pfft;
- else
- {
- cfft = (fft_t*) malloc(sizeof(fft_t));
- memset(cfft, 0, sizeof(fft_t));
- }
-
- err = fft_abs(x, n, cfft, fs, flag, mag, freq);
- if(err != RES_OK)
- goto error_proc;
-
- if(mag)
- {
- if(flag & DSPL_FLAG_LOGMAG)
- for(k = 0; k < n; k++)
- mag[k] = 20.0 * log10(mag[k] + DBL_EPSILON);
- else
- for(k = 0; k < n; k++)
- mag[k] *= mag[k];
- }
-error_proc:
- if(cfft && cfft != pfft)
- free(cfft);
- return err;
-}
-
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API fft_mag_cmplx(complex_t* x, int n, fft_t* pfft,
- double fs, int flag,
- double* mag, double* freq)
-{
- int k, err;
- fft_t *cfft = NULL;
-
- if(pfft)
- cfft = pfft;
- else
- {
- cfft = (fft_t*) malloc(sizeof(fft_t));
- memset(cfft, 0, sizeof(fft_t));
- }
-
- err = fft_abs_cmplx(x, n, cfft, fs, flag, mag, freq);
- if(err != RES_OK)
- goto error_proc;
-
- if(mag)
- {
- if(flag & DSPL_FLAG_LOGMAG)
- for(k = 0; k < n; k++)
- mag[k] = 20.0 * log10(mag[k] + DBL_EPSILON);
- else
- for(k = 0; k < n; k++)
- mag[k] *= mag[k];
- }
-error_proc:
- if(cfft && cfft != pfft)
- free(cfft);
- return err;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_shift(double* x, int n, double* y)
-\brief Perform a shift of the vector `x`, for use with the `fft` and `ifft`
-functions, in order
-
- to move the frequency 0 to the center
- of the vector `y`.
-
-\param[in] x
-Pointer to the input vector (FFT or IFFT result). \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Input and output vector size. \n \n
-
-\param[out] y
-Pointer to the output vector with frequency 0 in the center. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-
-\return
-`RES_OK` if function is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_shift(double* x, int n, double* y)
-\brief Перестановка спектральных отсчетов дискретного преобразования Фурье
-
-Функция производит
-
-перестановку спектральных отсчетов ДПФ
- и переносит нулевую частоту в центр вектора ДПФ. \n
-Данная функция обрабатывает вещественные входные и выходные вектора
-и может применяться для перестановки
-амплитудного или фазового спектра.
-
-\param[in] x
-Указатель на исходный вектор ДПФ. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ДПФ \f$n\f$ (размер векторов до и после перестановки). \n \n
-
-\param[out] y
-Указатель на вектор результата перестановки. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если перестановка произведена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API fft_shift(double* x, int n, double* y)
-{
- int n2, r;
- int k;
- double tmp;
- double *buf;
-
- if(!x || !y)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- r = n%2;
- if(!r)
- {
- n2 = n>>1;
- for(k = 0; k < n2; k++)
- {
- tmp = x[k];
- y[k] = x[k+n2];
- y[k+n2] = tmp;
- }
- }
- else
- {
- n2 = (n+1) >> 1;
- buf = (double*) malloc(n2*sizeof(double));
- memcpy(buf, x, n2*sizeof(double));
- memcpy(y, x+n2, (n2-1)*sizeof(double));
- memcpy(y+n2-1, buf, n2*sizeof(double));
- free(buf);
- }
- return RES_OK;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API fft_shift_cmplx(complex_t* x, int n, complex_t* y)
-{
- int n2, r;
- int k;
- complex_t tmp;
- complex_t *buf;
-
- if(!x || !y)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- r = n%2;
- if(!r)
- {
- n2 = n>>1;
- for(k = 0; k < n2; k++)
- {
- RE(tmp) = RE(x[k]);
- IM(tmp) = IM(x[k]);
-
- RE(y[k]) = RE(x[k+n2]);
- IM(y[k]) = IM(x[k+n2]);
-
- RE(y[k+n2]) = RE(tmp);
- IM(y[k+n2]) = IM(tmp);
- }
- }
- else
- {
- n2 = (n+1) >> 1;
- buf = (complex_t*) malloc(n2*sizeof(complex_t));
- memcpy(buf, x, n2*sizeof(complex_t));
- memcpy(y, x+n2, (n2-1)*sizeof(complex_t));
- memcpy(y+n2-1, buf, n2*sizeof(complex_t));
- free(buf);
- }
- return RES_OK;
-}
-
diff --git a/dspl/src/fourier_series.c b/dspl/src/fourier_series.c
deleted file mode 100644
index d611d43..0000000
--- a/dspl/src/fourier_series.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
-* Copyright (c) 2015-2019 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of libdspl-2.0.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DSPL is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Foobar. If not, see .
-*/
-
-
-#include
-#include
-#include
-#include "dspl.h"
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fourier_series_dec(double* t, double* s, int nt, double period,
- int nw, double* w, complex_t* y)
-
-\brief
-Fourier series coefficient calculation for periodic signal
-
-\param[in] t
-Pointer to the time vector. \n
-Vector size is `[nt x 1]`. \n
-\n
-
-\param[in] s
-Pointer to the signal corresponds to time `t`. \n
-Vector size is `[nt x 1]`. \n
-\n
-
-\param[in] nt
-Size of time and signal vectors. \n
-This value must be positive. \n
-\n
-
-\param[in] period
-Signal time period. \n
-\n
-
-\param[in] nw
-Number of Fourie series coefficients. \n
-\n
-
-\param[out] w
-Pointer to the frequency vector (rad/s). \n
-Vector size is `[nw x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[out] y
-Pointer to the complex Fourier series coefficients vector. \n
-Vector size is `[nw x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if function is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\note
-Numerical integration is used for Fourier series coefficients calculation.
-This function is not effective.
-To increase the speed of calculation of the signal spectrum
-it is more expedient to use fast Fourier transform algorithms.
-\n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fourier_series_dec(double* t, double* s, int nt, double period,
- int nw, double* w, complex_t* y)
-
-\brief
-Расчет коэффициентов разложения в ряд Фурье
-
-Функция рассчитывает спектр периодического сигнала при усечении ряда Фурье \n
-
-
-\param[in] t
-Указатель на массив моментов времени дискретизации исходного сигнала `s`. \n
-Размер вектора вектора `[nt x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] s
-Указатель на массив значений исходного сигнала`s`. \n
-Размер вектора `[nt x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-
-\param[in] nt
-Размер выборки исходного сигнала. \n
-Значение должно быть положительным. \n
-\n
-
-\param[in] period
-Период повторения сигнала. \n
-\n
-
-\param[in] nw
-Размер усеченного ряда Фурье. \n
-\n
-
-\param[out] w
-Указатель на массив частот спектра периодического сигнала. \n
-Размер вектора `[nw x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] y
-Указатель массив комплексных значений спектра периодического сигнала. \n
-Размер вектора `[nw x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- коэффициенты ряда Фурье рассчитаны успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\note
-Для расчета спектра сигнала используется численное интегрирование
-исходного сигнала методом трапеций. Данная функция не является
-эффективной. Для увеличения скорости расчета спектра сигнала
-целесообразнее использовать алгоритмы дискретного
-и быстрого преобразования Фурье.
-\n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API fourier_series_dec(double* t, double* s, int nt, double period,
- int nw, double* w, complex_t* y)
-{
- int k, m;
- double dw = M_2PI / period;
- complex_t e[2];
-
- if(!t || !s || !w || !y)
- return ERROR_PTR;
- if(nt<1 || nw < 1)
- return ERROR_SIZE;
- if(period <= 0.0)
- return ERROR_NEGATIVE;
-
- memset(y, 0 , nw*sizeof(complex_t));
-
- for(k = 0; k < nw; k++)
- {
- w[k] = (k - nw/2) * dw;
- RE(e[1]) = s[0] * cos(w[k] * t[0]);
- IM(e[1]) = -s[0] * sin(w[k] * t[0]);
- for(m = 1; m < nt; m++)
- {
- RE(e[0]) = RE(e[1]);
- IM(e[0]) = IM(e[1]);
- RE(e[1]) = s[m] * cos(w[k] * t[m]);
- IM(e[1]) = - s[m] * sin(w[k] * t[m]);
- RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
- IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
- }
- RE(y[k]) /= period;
- IM(y[k]) /= period;
- }
-
- if(!(nw%2))
- RE(y[0]) = RE(y[1]) = 0.0;
-
- return RES_OK;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API fourier_series_dec_cmplx(double* t, complex_t* s, int nt,
- double period, int nw, double* w, complex_t* y)
-{
- int k, m;
- double dw = M_2PI / period;
- complex_t e[2];
-
- if(!t || !s || !w || !y)
- return ERROR_PTR;
- if(nt<1 || nw < 1)
- return ERROR_SIZE;
- if(period <= 0.0)
- return ERROR_NEGATIVE;
-
- memset(y, 0 , nw*sizeof(complex_t));
-
- for(k = 0; k < nw; k++)
- {
- w[k] = (k - nw/2) * dw;
- RE(e[1]) = RE(s[0]) * cos(w[k] * t[0]) +
- IM(s[0]) * sin(w[k] * t[0]);
- IM(e[1]) = -RE(s[0]) * sin(w[k] * t[0]) +
- IM(s[0]) * cos(w[k] * t[0]);
- for(m = 1; m < nt; m++)
- {
- RE(e[0]) = RE(e[1]);
- IM(e[0]) = IM(e[1]);
- RE(e[1]) = RE(s[m]) * cos(w[k] * t[m]) +
- IM(s[m]) * sin(w[k] * t[m]);
- IM(e[1]) = -RE(s[m]) * sin(w[k] * t[m]) +
- IM(s[m]) * cos(w[k] * t[m]);
- RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
- IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
- }
- RE(y[k]) /= period;
- IM(y[k]) /= period;
- }
-
- if(!(nw%2))
- RE(y[0]) = RE(y[1]) = 0.0;
-
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API fourier_integral_cmplx(double* t, complex_t* s, int nt,
- int nw, double* w, complex_t* y)
-{
- int k, m;
- complex_t e[2];
-
- if(!t || !s || !w || !y)
- return ERROR_PTR;
- if(nt<1 || nw < 1)
- return ERROR_SIZE;
-
-
- memset(y, 0 , nw*sizeof(complex_t));
-
- for(k = 0; k < nw; k++)
- {
- RE(e[1]) = RE(s[0]) * cos(w[k] * t[0]) +
- IM(s[0]) * sin(w[k] * t[0]);
- IM(e[1]) = -RE(s[0]) * sin(w[k] * t[0]) +
- IM(s[0]) * cos(w[k] * t[0]);
- for(m = 1; m < nt; m++)
- {
- RE(e[0]) = RE(e[1]);
- IM(e[0]) = IM(e[1]);
- RE(e[1]) = RE(s[m]) * cos(w[k] * t[m]) +
- IM(s[m]) * sin(w[k] * t[m]);
- IM(e[1]) = -RE(s[m]) * sin(w[k] * t[m]) +
- IM(s[m]) * cos(w[k] * t[m]);
- RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
- IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
- }
- }
-
- return RES_OK;
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fourier_series_rec(double* w, complex_t* s, int nw,
- double* t, int nt, complex_t* y)
-\brief Time signal reconstruction from Fourier series coefficients.
-
-Function reconstructs the time signal:
-
-\f[
-s(t) = \sum\limits_{n = 0}^{n_{\omega}-1} S(\omega_n) \exp(j\omega_n t)
-\f]
-
-\param[in] w
-Pointer to the Fourier series spectrum frequency vector \f$\omega_n\f$. \n
-Vector size is `[nw x 1]`. \n
-\n
-
-\param[in] s
-Pointer to the Fourier series coefficients vector \f$S(\omega_n)\f$. \n
-Vector size is `[nw x 1]`. \n
-\n
-
-
-\param[in] nw
-Number of Fourier series coefficients. \n
-This value must be positive. \n
-\n
-
-\param[in] t
-Pointer to the reconstructed signal time vector. \n
-Vector size is `[nt x 1]`. \n
-\n
-
-\param[in] nt
-Size of time vector and reconstructed signal vector . \n
-\n
-
-\param[out] y
-Pointer to the reconstructed signal vector. \n
-Vector size is `[nt x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if function is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\note
-The output reconstructed signal is generally complex.
-However, subject to the symmetry properties of the vectors `w` and` s`
-with respect to zero frequency we get the imaginary part of the vector `y`
-at the EPS level. The negligible imaginary part in this case
-can be ignored.
-\n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fourier_series_rec(double* w, complex_t* s, int nw,
- double* t, int nt, complex_t* y)
-\brief Восстановление сигнала при усечении ряда Фурье
-
-Функция рассчитывает восстановленный сигнал при усечении ряда Фурье:
-
-\f[
-s(t) = \sum\limits_{n = 0}^{n_{\omega}-1} S(\omega_n) \exp(j\omega_n t)
-\f]
-
-\param[in] w
-Указатель на массив частот \f$\omega_n\f$ усеченного ряда Фурье. \n
-Размер вектора `[nw x 1]`. \n
-Память должна быть выделена и заполнена. \n
-\n
-
-\param[in] s
-Указатель на массив значений спектра \f$S(\omega_n)\f$. \n
-Размер вектора `[nw x 1]`. \n
-Память должна быть выделена и заполнена. \n
-\n
-
-
-\param[in] nw
-Количество членов усеченного ряда Фурье. \n
-Значение должно быть положительным. \n
-\n
-
-\param[in] t
-Указатель на массив временных отсчетов восстановленного сигнала. \n
-Размер вектора `[nt x 1]`. \n
-Память должна быть выделена и заполнена. \n
-\n
-
-\param[in] nt
-Размер вектора времени и восстановленного сигнала. \n
-\n
-
-\param[out] y
-Указатель на массив восстановленного сигнала. \n
-Размер вектора `[nt x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- восстановление сигнала прошло успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\note
-Выходной восстановленный сигнал в общем случае является комплексным.
-Однако при соблюдении свойств симметрии векторов `w` и `s` относительно
-нулевой частоты получим мнимую часть элементов вектора `y` на уровне ошибок
-округления числа с двойной точностью. Ничтожно малую мнимую часть в этом случае
-можно игнорировать.
-\n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API fourier_series_rec(double* w, complex_t* s, int nw,
- double* t, int nt, complex_t* y)
-{
- int k, m;
- complex_t e;
-
- if(!t || !s || !w || !y)
- return ERROR_PTR;
- if(nt<1 || nw < 1)
- return ERROR_SIZE;
-
- memset(y, 0, nt*sizeof(complex_t));
-
-
- for(k = 0; k < nw; k++)
- {
- for(m = 0; m < nt; m++)
- {
- RE(e) = cos(w[k] * t[m]);
- IM(e) = sin(w[k] * t[m]);
-
- RE(y[m]) += CMRE(s[k], e);
- IM(y[m]) += CMIM(s[k], e);
- }
- }
- return RES_OK;
-}
-
diff --git a/dspl/src/math_poly.c b/dspl/src/math_poly.c
new file mode 100644
index 0000000..eac513d
--- /dev/null
+++ b/dspl/src/math_poly.c
@@ -0,0 +1,10 @@
+
+
+#include "math_poly/poly_z2a_cmplx.c"
+#include "math_poly/polyroots.c"
+#include "math_poly/polyval.c"
+#include "math_poly/polyval_cmplx.c"
+
+
+#include "math_poly/cheby_poly1.c"
+#include "math_poly/cheby_poly2.c"
diff --git a/dspl/src/math_poly/cheby_poly1.c b/dspl/src/math_poly/cheby_poly1.c
new file mode 100644
index 0000000..23141ca
--- /dev/null
+++ b/dspl/src/math_poly/cheby_poly1.c
@@ -0,0 +1,177 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int cheby_poly1(double* x, int n, int ord, double* y)
+\brief Chebyshev polynomial of the first kind order `ord`
+
+Function calculates Chebyshev polynomial \f$ C_{ord}(x)\f$ of the first kind
+order `ord` for the real vector `x` (length `n`) by recurrent equation:
+\f[
+C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
+\f]
+where \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
+
+\param[in] x
+Pointer to the real argument vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of vectors `x` and `y`. \n \n
+
+\param[in] ord
+Chebyshev polynomial order. \n \n
+
+\param[out] y
+Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if Chebyshev polynomial is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example:
+
+\include cheby_poly1_test.c
+
+Text files will be created in `dat` directory: \n
+
+\verbatim
+cheby_poly1_ord1.txt
+cheby_poly1_ord2.txt
+cheby_poly1_ord3.txt
+cheby_poly1_ord4.txt
+\endverbatim
+
+GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
+
+\image html cheby_poly1.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int cheby_poly1(double* x, int n, int ord, double* y)
+\brief Многочлен Чебышева первого рода порядка `ord`
+
+Функция производит расчет многочлена Чебышева первого рода \f$ C_{ord}(x)\f$ для
+вещественного вектора `x` длины `n`на основе рекуррентной формулы
+\f[
+C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
+\f]
+где \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
+
+\param[in] x
+Указатель на вектор `x` аргумента полинома Чебышева первого рода. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер векторов `x` и `y`. \n \n
+
+\param[in] ord
+Порядок полинома Чебышева первого рода. \n \n
+
+\param[out] y
+Указатель на вектор значений полинома Чебышева,
+соответствующих аргументу `x`. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции:
+
+\include cheby_poly1_test.c
+
+В каталоге `dat` будут созданы текстовые файлы значений
+полиномов порядка 1-4: \n
+
+\verbatim
+cheby_poly1_ord1.txt
+cheby_poly1_ord2.txt
+cheby_poly1_ord3.txt
+cheby_poly1_ord4.txt
+\endverbatim
+
+Кроме того программа GNUPLOT произведет построение следующих графиков
+по сохраненным в файлах данным:
+
+\image html cheby_poly1.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API cheby_poly1(double* x, int n, int ord, double* y)
+{
+ int k, m;
+ double t[2];
+
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(ord<0)
+ return ERROR_POLY_ORD;
+ if(ord==0)
+ {
+ for(k = 0; k < n; k++)
+ {
+ y[k] = 1.0;
+ }
+ return RES_OK;
+ }
+
+ if(ord==1)
+ {
+ memcpy(y, x, n*sizeof(double));
+ return RES_OK;
+ }
+
+ for(k = 0; k < n; k++)
+ {
+ m = 2;
+ t[1] = x[k];
+ t[0] = 1.0;
+ while(m <= ord)
+ {
+ y[k] = 2.0 * x[k] *t[1] - t[0];
+ t[0] = t[1];
+ t[1] = y[k];
+ m++;
+ }
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/cheby.c b/dspl/src/math_poly/cheby_poly2.c
similarity index 54%
rename from dspl/src/cheby.c
rename to dspl/src/math_poly/cheby_poly2.c
index 6a5c179..290d522 100644
--- a/dspl/src/cheby.c
+++ b/dspl/src/math_poly/cheby_poly2.c
@@ -1,329 +1,177 @@
-/*
-* Copyright (c) 2015-2019 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of libdspl-2.0.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DSPL is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Foobar. If not, see .
-*/
-
-#include
-#include
-#include
-#include "dspl.h"
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_POLY_GROUP
-\fn int cheby_poly1(double* x, int n, int ord, double* y)
-\brief Chebyshev polynomial of the first kind order `ord`
-
-Function calculates Chebyshev polynomial \f$ C_{ord}(x)\f$ of the first kind
-order `ord` for the real vector `x` (length `n`) by recurrent equation:
-\f[
-C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
-\f]
-where \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
-
-\param[in] x
-Pointer to the real argument vector `x`. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of vectors `x` and `y`. \n \n
-
-\param[in] ord
-Chebyshev polynomial order. \n \n
-
-\param[out] y
-Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if Chebyshev polynomial is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example:
-
-\include cheby_poly1_test.c
-
-Text files will be created in `dat` directory: \n
-
-\verbatim
-cheby_poly1_ord1.txt
-cheby_poly1_ord2.txt
-cheby_poly1_ord3.txt
-cheby_poly1_ord4.txt
-\endverbatim
-
-GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
-
-\image html cheby_poly1.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_POLY_GROUP
-\fn int cheby_poly1(double* x, int n, int ord, double* y)
-\brief Многочлен Чебышева первого рода порядка `ord`
-
-Функция производит расчет многочлена Чебышева первого рода \f$ C_{ord}(x)\f$ для
-вещественного вектора `x` длины `n`на основе рекуррентной формулы
-\f[
-C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
-\f]
-где \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
-
-\param[in] x
-Указатель на вектор `x` аргумента полинома Чебышева первого рода. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер векторов `x` и `y`. \n \n
-
-\param[in] ord
-Порядок полинома Чебышева первого рода. \n \n
-
-\param[out] y
-Указатель на вектор значений полинома Чебышева,
-соответствующих аргументу `x`. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции:
-
-\include cheby_poly1_test.c
-
-В каталоге `dat` будут созданы текстовые файлы значений
-полиномов порядка 1-4: \n
-
-\verbatim
-cheby_poly1_ord1.txt
-cheby_poly1_ord2.txt
-cheby_poly1_ord3.txt
-cheby_poly1_ord4.txt
-\endverbatim
-
-Кроме того программа GNUPLOT произведет построение следующих графиков
-по сохраненным в файлах данным:
-
-\image html cheby_poly1.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API cheby_poly1(double* x, int n, int ord, double* y)
-{
- int k, m;
- double t[2];
-
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(ord<0)
- return ERROR_POLY_ORD;
- if(ord==0)
- {
- for(k = 0; k < n; k++)
- {
- y[k] = 1.0;
- }
- return RES_OK;
- }
-
- if(ord==1)
- {
- memcpy(y, x, n*sizeof(double));
- return RES_OK;
- }
-
- for(k = 0; k < n; k++)
- {
- m = 2;
- t[1] = x[k];
- t[0] = 1.0;
- while(m <= ord)
- {
- y[k] = 2.0 * x[k] *t[1] - t[0];
- t[0] = t[1];
- t[1] = y[k];
- m++;
- }
- }
- return RES_OK;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_POLY_GROUP
-\fn int cheby_poly2(double* x, int n, int ord, double* y)
-\brief Chebyshev polynomial of the second kind order `ord`
-
-Function calculates Chebyshev polynomial \f$ U_ord(x)\f$ of the first kind
-order `ord` for the real vector `x` (length `n`) by recurrent equation:
-\f[
-U_{ord}(x) = 2 x U_{ord-1}(x) - U_{ord-2}(x),
-\f]
-where \f$ U_0(x) = 1 \f$, \f$ U_1(x) = 2x\f$
-
-\param[in] x
-Pointer to the real argument vector `x`. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of vectors `x` and `y`. \n \n
-
-\param[in] ord
-Chebyshev polynomial order. \n \n
-
-\param[out] y
-Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if Chebyshev polynomial is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example:
-\include cheby_poly2_test.c
-
-Text files will be created in `dat` directory: \n
-
-\verbatim
-cheby_poly2_ord1.txt
-cheby_poly2_ord2.txt
-cheby_poly2_ord3.txt
-cheby_poly2_ord4.txt
-\endverbatim
-
-GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
-
-\image html cheby_poly2.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_POLY_GROUP
-\fn int cheby_poly2(double* x, int n, int ord, double* y)
-\brief Многочлен Чебышева второго рода порядка `ord`
-
-Функция производит расчет многочлена Чебышева второго рода \f$ U_{ord}(x)\f$
-для вещественного вектора `x` длины `n`на основе рекуррентной формулы
-\f[
-U_{ord}(x) = 2 x U_{ord-1}(x) - U_{ord-2}(x),
-\f]
-где \f$ U_0(x) = 1 \f$, \f$ U_1(x) = 2x\f$
-
-\param[in] x
-Указатель на вектор `x` аргумента полинома Чебышева второго рода. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер векторов `x` и `y`. \n \n
-
-\param[in] ord
-Порядок полинома Чебышева второго рода. \n \n
-
-\param[out] y
-Указатель на вектор значений полинома Чебышева,
-соответствующих аргументу `x`. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции:
-
-\include cheby_poly2_test.c
-
-В каталоге `dat` будут созданы текстовые файлы значений
-полиномов порядка 1-4: \n
-
-\verbatim
-cheby_poly2_ord1.txt
-cheby_poly2_ord2.txt
-cheby_poly2_ord3.txt
-cheby_poly2_ord4.txt
-\endverbatim
-
-Кроме того программа GNUPLOT произведет построение следующих графиков
-по сохраненным в файлах данным:
-
-\image html cheby_poly2.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API cheby_poly2(double* x, int n, int ord, double* y)
-{
- int k, m;
- double t[2];
-
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(ord<0)
- return ERROR_POLY_ORD;
- if(ord==0)
- {
- for(k = 0; k < n; k++)
- {
- y[k] = 1.0;
- }
- return RES_OK;
- }
-
- if(ord==1)
- {
- for(k = 0; k < n; k++)
- {
- y[k] = 2.0*x[k];
- };
- return RES_OK;
- }
-
- for(k = 0; k < n; k++)
- {
- m = 2;
- t[1] = 2.0*x[k];
- t[0] = 1.0;
- while(m <= ord)
- {
- y[k] = 2.0 * x[k] *t[1] - t[0];
- t[0] = t[1];
- t[1] = y[k];
- m++;
- }
- }
- return RES_OK;
-}
-
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int cheby_poly2(double* x, int n, int ord, double* y)
+\brief Chebyshev polynomial of the second kind order `ord`
+
+Function calculates Chebyshev polynomial \f$ U_ord(x)\f$ of the first kind
+order `ord` for the real vector `x` (length `n`) by recurrent equation:
+\f[
+U_{ord}(x) = 2 x U_{ord-1}(x) - U_{ord-2}(x),
+\f]
+where \f$ U_0(x) = 1 \f$, \f$ U_1(x) = 2x\f$
+
+\param[in] x
+Pointer to the real argument vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of vectors `x` and `y`. \n \n
+
+\param[in] ord
+Chebyshev polynomial order. \n \n
+
+\param[out] y
+Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if Chebyshev polynomial is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example:
+\include cheby_poly2_test.c
+
+Text files will be created in `dat` directory: \n
+
+\verbatim
+cheby_poly2_ord1.txt
+cheby_poly2_ord2.txt
+cheby_poly2_ord3.txt
+cheby_poly2_ord4.txt
+\endverbatim
+
+GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
+
+\image html cheby_poly2.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int cheby_poly2(double* x, int n, int ord, double* y)
+\brief Многочлен Чебышева второго рода порядка `ord`
+
+Функция производит расчет многочлена Чебышева второго рода \f$ U_{ord}(x)\f$
+для вещественного вектора `x` длины `n`на основе рекуррентной формулы
+\f[
+U_{ord}(x) = 2 x U_{ord-1}(x) - U_{ord-2}(x),
+\f]
+где \f$ U_0(x) = 1 \f$, \f$ U_1(x) = 2x\f$
+
+\param[in] x
+Указатель на вектор `x` аргумента полинома Чебышева второго рода. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер векторов `x` и `y`. \n \n
+
+\param[in] ord
+Порядок полинома Чебышева второго рода. \n \n
+
+\param[out] y
+Указатель на вектор значений полинома Чебышева,
+соответствующих аргументу `x`. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции:
+
+\include cheby_poly2_test.c
+
+В каталоге `dat` будут созданы текстовые файлы значений
+полиномов порядка 1-4: \n
+
+\verbatim
+cheby_poly2_ord1.txt
+cheby_poly2_ord2.txt
+cheby_poly2_ord3.txt
+cheby_poly2_ord4.txt
+\endverbatim
+
+Кроме того программа GNUPLOT произведет построение следующих графиков
+по сохраненным в файлах данным:
+
+\image html cheby_poly2.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API cheby_poly2(double* x, int n, int ord, double* y)
+{
+ int k, m;
+ double t[2];
+
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(ord<0)
+ return ERROR_POLY_ORD;
+ if(ord==0)
+ {
+ for(k = 0; k < n; k++)
+ {
+ y[k] = 1.0;
+ }
+ return RES_OK;
+ }
+
+ if(ord==1)
+ {
+ for(k = 0; k < n; k++)
+ {
+ y[k] = 2.0*x[k];
+ };
+ return RES_OK;
+ }
+
+ for(k = 0; k < n; k++)
+ {
+ m = 2;
+ t[1] = 2.0*x[k];
+ t[0] = 1.0;
+ while(m <= ord)
+ {
+ y[k] = 2.0 * x[k] *t[1] - t[0];
+ t[0] = t[1];
+ t[1] = y[k];
+ m++;
+ }
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/math_poly/poly_z2a_cmplx.c b/dspl/src/math_poly/poly_z2a_cmplx.c
new file mode 100644
index 0000000..7c671ce
--- /dev/null
+++ b/dspl/src/math_poly/poly_z2a_cmplx.c
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API poly_z2a_cmplx(complex_t* z, int nz, int ord, complex_t* a)
+{
+ int k, ind, res;
+ complex_t x[2];
+
+ if(!z || !a)
+ return ERROR_PTR;
+ if(nz < 0)
+ return ERROR_SIZE;
+ if(nz > ord || ord < 1)
+ return ERROR_POLY_ORD;
+
+ RE(x[1]) = 1.0;
+ IM(x[1]) = 0.0;
+
+ memset(a, 0, (ord+1) * sizeof(complex_t));
+
+ RE(a[0]) = 1.0;
+ ind = 1;
+ for(k = 0; k < nz; k++)
+ {
+ RE(x[0]) = -RE(z[k]);
+ IM(x[0]) = -IM(z[k]);
+ res = conv_cmplx(a, ind, x, 2, a);
+ if(res!=RES_OK)
+ return res;
+ ind++;
+ }
+
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/polyval.c b/dspl/src/math_poly/polyroots.c
similarity index 52%
rename from dspl/src/polyval.c
rename to dspl/src/math_poly/polyroots.c
index 7df35f0..ddb69e7 100644
--- a/dspl/src/polyval.c
+++ b/dspl/src/math_poly/polyroots.c
@@ -1,384 +1,186 @@
-/*
-* Copyright (c) 2015-2019 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of libdspl-2.0.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DSPL is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Foobar. If not, see .
-*/
-
-
-#include
-#include
-#include "dspl.h"
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API poly_z2a_cmplx(complex_t* z, int nz, int ord, complex_t* a)
-{
- int k, ind, res;
- complex_t x[2];
-
- if(!z || !a)
- return ERROR_PTR;
- if(nz < 0)
- return ERROR_SIZE;
- if(nz > ord || ord < 1)
- return ERROR_POLY_ORD;
-
- RE(x[1]) = 1.0;
- IM(x[1]) = 0.0;
-
- memset(a, 0, (ord+1) * sizeof(complex_t));
-
- RE(a[0]) = 1.0;
- ind = 1;
- for(k = 0; k < nz; k++)
- {
- RE(x[0]) = -RE(z[k]);
- IM(x[0]) = -IM(z[k]);
- res = conv_cmplx(a, ind, x, 2, a);
- if(res!=RES_OK)
- return res;
- ind++;
- }
-
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int polyroots(double* a, int ord, complex_t* r, int* info)
-\brief Function calculates real polynomial roots.
-
-Function calculates roots of the real polynomial \f$P_N(x)\f$ order \f$N\f$
-with `a` coefficient vector size `[(N+1) x 1]`.
-\f[
- P_N(x) = a_0 + a_1 x + a_2 x^2 + a_3 x^3 + ... a_N x^N.
-\f]
-
-The roots of the polynomial are calculated as eigenvalues of the polynomial
-companion matrix. To calculate the eigenvalues,
-a subroutine of the LAPACK package is used.
-
-
-\param[in] a
-Pointer to the vector of coefficients. \n
-Vector size is `[ord+1 x 1]`. \n
-Coefficient `a[0]` corresponds to the \f$a_0\f$ polynomial coefficient. \n
-Coefficient `a[ord]` cannot be zero. \n \n
-
-\param[in] ord
-Polynomial order \f$N\f$. \n \n
-
-\param[out] r
-Pointer to the polynomial roots vector. \n
-Vector size is `[ord x 1]`. \n
-Memory must be allocated. \n
-The roots of a real polynomial can be either real or form simple
-or multiple complex conjugate pairs of roots. Therefore, the output
-root vector is of a complex data type. \n \n
-
-\param[out] info
-Pointer to the LAPACK subroutine error code. \n
-This code is returned by the LAPACK subroutine and translated through
-this variable for analysis.. \n\n
-
-\return
-`RES_OK` --- roots are calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Example:
-
-\include polyroots_test.c
-
-This program calculates the roots of the polynomial
-\f[
-P(x) = 2 + 2x + x^2
-\f]
-and prints the calculated roots.
-The result of the program:
-
-\verbatim
-Error code: 0x00000000
-r[0] = -1.00000 1.00000 j
-r[1] = -1.00000-1.00000 j
-\endverbatim
-
-\author Sergey Bakhurin. www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int polyroots(double* a, int ord, complex_t* r, int* info)
-\brief Расчет корней вещественного полинома
-
-Функция рассчитывает корни полинома \f$P_N(x)\f$ \f$N-\f$ого
-порядка, заданного вектором коэффициентов `a`.
-\f[
- P_N(x) = a_0 + a_1 x + a_2 x^2 + a_3 x^3 + ... a_N x^N.
-\f]
-
-Корни полинома рассчитываются как собственные числа характеристической
-матрицы полинома. Для расчета собственных чисел используется подпрограмма
-пакета LAPACK.
-
-
-\param[in] a
-Указатель на вектор вещественных коэффициентов полинома. \n
-Размер вектора `[ord+1 x 1]`. \n
-Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n
-Коэффициент `a[ord]` не должен быть равен нулю. \n \n
-
-\param[in] ord
-Порядок полинома \f$N\f$. \n \n
-
-\param[out] r
-Указатель на вектор комплексных корней полинома. \n
-Размер вектора `[ord x 1]`. \n
-Память должна быть выделена. \n
-Корни вещественного полинома могут быть как вещественными,
-так и образовывать простые или кратные комплексно-сопряженные пары корней.
-Поэтому выходной вектор корней имеет комплексный тип данных.
-\n \n
-
-\param[out] info
-Указатель наа код возврата пакета LAPACK. \n
-Данный код возвращается подпрограммой LAPACK и транслируется через данную
-переменную для возможности анализа. \n\n
-
-\return
-`RES_OK` --- корни полинома рассчитаны успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример расчета корней полинома:
-
-\include polyroots_test.c
-
-Данная программа производит расчет корней полинома
-\f[
-P(x) = 2 + 2x + x^2
-\f]
-и выводит рассчитанные корни на печать.
-Результат работы программы:
-
-\verbatim
-Error code: 0x00000000
-r[0] = -1.00000 1.00000 j
-r[1] = -1.00000-1.00000 j
-\endverbatim
-
-Получили пару комплексно-сопряженных корней полинома.
-
-\author Бахурин Сергей. www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API polyroots(double* a, int ord, complex_t* r, int* info)
-{
- complex_t *t = NULL;
- int m;
- int err;
-
- if(!a || !r)
- return ERROR_PTR;
- if(ord<0)
- return ERROR_POLY_ORD;
- if(a[ord] == 0.0)
- return ERROR_POLY_AN;
-
- t = (complex_t*)malloc(ord * ord * sizeof(complex_t));
- if(!t)
- return ERROR_MALLOC;
-
- for(m = 0; m < ord-1; m++)
- {
- RE(t[m * (ord+1) + 1]) = 1.0;
- RE(t[m + ord * (ord - 1)]) = -a[m] / a[ord];
- }
- RE(t[ord * ord - 1]) = -a[ord-1] / a[ord];
-
- err = matrix_eig_cmplx(t, ord, r, info);
-
- if(t)
- free(t);
- return err;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int polyval(double* a, int ord, double* x, int n, double* y)
-\brief Расчет вещественного полинома
-
-Функция рассчитывает полином \f$P_N(x)\f$ \f$N-\f$ого порядка для вещественного
-аргумента, заданного вектором `x`.
-\f[
- P_N(x) = a_0 + a_1 \cdot x + a_2 \cdot x^2 +
- a_3 \cdot x^3 + ... a_N \cdot x^N.
-\f]
-
-Для расчета используется формула Горнера:
-\f[
- P_N(x) = a_0 + x \cdot (a_1 + x \cdot (a_2 + \cdot
- ( \ldots x \cdot (a_{N-1} + x\cdot a_N) \ldots )))
-\f]
-
-\param[in] a
-Указатель на вектор вещественных коэффициентов полинома. \n
-Размер вектора `[ord+1 x 1]`. \n
-Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n \n
-
-\param[in] ord
-Порядок полинома \f$N\f$. \n \n
-
-\param[in] x
-Указатель на вектор аргумента полинома. \n
-Размер вектора `[n x 1]`. \n
-Значения полинома будут расчитаны для всех значений аргумента вектора `x`. \n\n
-
-\param[in] n
-Размер вектора агрумента полинома. \n \n
-
-\param[out] y
-Указатель на значения полинома для аргумента `x`. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n\n
-
-\return
-`RES_OK` --- полином рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\author Бахурин Сергей. www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API polyval(double* a, int ord, double* x, int n, double* y)
-{
- int k, m;
-
- if(!a || !x || !y)
- return ERROR_PTR;
- if(ord<0)
- return ERROR_POLY_ORD;
- if(n<1)
- return ERROR_SIZE;
-
- for(k = 0; k < n; k++)
- {
- y[k] = a[ord];
- for(m = ord-1; m>-1; m--)
- y[k] = y[k]*x[k] + a[m];
- }
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int polyval_cmplx(complex_t* a, int ord, complex_t* x, int n, complex_t* y)
-\brief Расчет комплексного полинома
-
-Функция рассчитывает полином \f$P_N(x)\f$ \f$N\f$-го порядка
-комплексного аргумента, заданного вектором `x`. \n
-
-\f[
-P_N(x) = a_0 + a_1 \cdot x + a_2 \cdot x^2 + a_3 \cdot x^3 + ... a_N \cdot x^N.
-\f]
-
-Для расчета используется формула Горнера: \n
-\f[
- P_N(x) = a_0 + x \cdot (a_1 + x \cdot (a_2 + \cdot
- ( \ldots x \cdot (a_{N-1} + x\cdot a_N) \ldots )))
-\f]
-
-\param[in] a
-Указатель на вектор комплексных коэффициентов полинома. \n
-Размер вектора `[ord+1 x 1]`. \n
-Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n \n
-
-\param[in] ord
-Порядок полинома \f$N\f$. \n \n
-
-\param[in] x
-Указатель на вектор аргумента полинома. \n
-Размер вектора `[n x 1]`. \n
-Значения полинома будут расчитаны для всех значений аргумента вектора `x`. \n \n
-
-\param[in] n
-Размер вектора агрумента полинома. \n\n
-
-\param[out] y
-Указатель вектор значения полинома для аргумента `x`. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` --- полином расчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\author Бахурин Сергей. www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API polyval_cmplx(complex_t* a, int ord,
- complex_t* x, int n, complex_t* y)
-{
- int k, m;
- complex_t t;
-
- if(!a || !x || !y)
- return ERROR_PTR;
- if(ord<0)
- return ERROR_POLY_ORD;
- if(n<1)
- return ERROR_SIZE;
-
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = RE(a[ord]);
- IM(y[k]) = IM(a[ord]);
- for(m = ord-1; m>-1; m--)
- {
- RE(t) = CMRE(y[k], x[k]);
- IM(t) = CMIM(y[k], x[k]);
- RE(y[k]) = RE(t) + RE(a[m]);
- IM(y[k]) = IM(t) + IM(a[m]);
- }
- }
- return RES_OK;
-}
-
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int polyroots(double* a, int ord, complex_t* r, int* info)
+\brief Function calculates real polynomial roots.
+
+Function calculates roots of the real polynomial \f$P_N(x)\f$ order \f$N\f$
+with `a` coefficient vector size `[(N+1) x 1]`.
+\f[
+ P_N(x) = a_0 + a_1 x + a_2 x^2 + a_3 x^3 + ... a_N x^N.
+\f]
+
+The roots of the polynomial are calculated as eigenvalues of the polynomial
+companion matrix. To calculate the eigenvalues,
+a subroutine of the LAPACK package is used.
+
+
+\param[in] a
+Pointer to the vector of coefficients. \n
+Vector size is `[ord+1 x 1]`. \n
+Coefficient `a[0]` corresponds to the \f$a_0\f$ polynomial coefficient. \n
+Coefficient `a[ord]` cannot be zero. \n \n
+
+\param[in] ord
+Polynomial order \f$N\f$. \n \n
+
+\param[out] r
+Pointer to the polynomial roots vector. \n
+Vector size is `[ord x 1]`. \n
+Memory must be allocated. \n
+The roots of a real polynomial can be either real or form simple
+or multiple complex conjugate pairs of roots. Therefore, the output
+root vector is of a complex data type. \n \n
+
+\param[out] info
+Pointer to the LAPACK subroutine error code. \n
+This code is returned by the LAPACK subroutine and translated through
+this variable for analysis.. \n\n
+
+\return
+`RES_OK` --- roots are calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Example:
+
+\include polyroots_test.c
+
+This program calculates the roots of the polynomial
+\f[
+P(x) = 2 + 2x + x^2
+\f]
+and prints the calculated roots.
+The result of the program:
+
+\verbatim
+Error code: 0x00000000
+r[0] = -1.00000 1.00000 j
+r[1] = -1.00000-1.00000 j
+\endverbatim
+
+\author Sergey Bakhurin. www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int polyroots(double* a, int ord, complex_t* r, int* info)
+\brief Расчет корней вещественного полинома
+
+Функция рассчитывает корни полинома \f$P_N(x)\f$ \f$N-\f$ого
+порядка, заданного вектором коэффициентов `a`.
+\f[
+ P_N(x) = a_0 + a_1 x + a_2 x^2 + a_3 x^3 + ... a_N x^N.
+\f]
+
+Корни полинома рассчитываются как собственные числа характеристической
+матрицы полинома. Для расчета собственных чисел используется подпрограмма
+пакета LAPACK.
+
+
+\param[in] a
+Указатель на вектор вещественных коэффициентов полинома. \n
+Размер вектора `[ord+1 x 1]`. \n
+Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n
+Коэффициент `a[ord]` не должен быть равен нулю. \n \n
+
+\param[in] ord
+Порядок полинома \f$N\f$. \n \n
+
+\param[out] r
+Указатель на вектор комплексных корней полинома. \n
+Размер вектора `[ord x 1]`. \n
+Память должна быть выделена. \n
+Корни вещественного полинома могут быть как вещественными,
+так и образовывать простые или кратные комплексно-сопряженные пары корней.
+Поэтому выходной вектор корней имеет комплексный тип данных.
+\n \n
+
+\param[out] info
+Указатель наа код возврата пакета LAPACK. \n
+Данный код возвращается подпрограммой LAPACK и транслируется через данную
+переменную для возможности анализа. \n\n
+
+\return
+`RES_OK` --- корни полинома рассчитаны успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример расчета корней полинома:
+
+\include polyroots_test.c
+
+Данная программа производит расчет корней полинома
+\f[
+P(x) = 2 + 2x + x^2
+\f]
+и выводит рассчитанные корни на печать.
+Результат работы программы:
+
+\verbatim
+Error code: 0x00000000
+r[0] = -1.00000 1.00000 j
+r[1] = -1.00000-1.00000 j
+\endverbatim
+
+Получили пару комплексно-сопряженных корней полинома.
+
+\author Бахурин Сергей. www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API polyroots(double* a, int ord, complex_t* r, int* info)
+{
+ complex_t *t = NULL;
+ int m;
+ int err;
+
+ if(!a || !r)
+ return ERROR_PTR;
+ if(ord<0)
+ return ERROR_POLY_ORD;
+ if(a[ord] == 0.0)
+ return ERROR_POLY_AN;
+
+ t = (complex_t*)malloc(ord * ord * sizeof(complex_t));
+ if(!t)
+ return ERROR_MALLOC;
+
+ for(m = 0; m < ord-1; m++)
+ {
+ RE(t[m * (ord+1) + 1]) = 1.0;
+ RE(t[m + ord * (ord - 1)]) = -a[m] / a[ord];
+ }
+ RE(t[ord * ord - 1]) = -a[ord-1] / a[ord];
+
+ err = matrix_eig_cmplx(t, ord, r, info);
+
+ if(t)
+ free(t);
+ return err;
+}
diff --git a/dspl/src/math_poly/polyval.c b/dspl/src/math_poly/polyval.c
new file mode 100644
index 0000000..b5dd7bf
--- /dev/null
+++ b/dspl/src/math_poly/polyval.c
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int polyval(double* a, int ord, double* x, int n, double* y)
+\brief Расчет вещественного полинома
+
+Функция рассчитывает полином \f$P_N(x)\f$ \f$N-\f$ого порядка для вещественного
+аргумента, заданного вектором `x`.
+\f[
+ P_N(x) = a_0 + a_1 \cdot x + a_2 \cdot x^2 +
+ a_3 \cdot x^3 + ... a_N \cdot x^N.
+\f]
+
+Для расчета используется формула Горнера:
+\f[
+ P_N(x) = a_0 + x \cdot (a_1 + x \cdot (a_2 + \cdot
+ ( \ldots x \cdot (a_{N-1} + x\cdot a_N) \ldots )))
+\f]
+
+\param[in] a
+Указатель на вектор вещественных коэффициентов полинома. \n
+Размер вектора `[ord+1 x 1]`. \n
+Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n \n
+
+\param[in] ord
+Порядок полинома \f$N\f$. \n \n
+
+\param[in] x
+Указатель на вектор аргумента полинома. \n
+Размер вектора `[n x 1]`. \n
+Значения полинома будут расчитаны для всех значений аргумента вектора `x`. \n\n
+
+\param[in] n
+Размер вектора агрумента полинома. \n \n
+
+\param[out] y
+Указатель на значения полинома для аргумента `x`. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n\n
+
+\return
+`RES_OK` --- полином рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\author Бахурин Сергей. www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API polyval(double* a, int ord, double* x, int n, double* y)
+{
+ int k, m;
+
+ if(!a || !x || !y)
+ return ERROR_PTR;
+ if(ord<0)
+ return ERROR_POLY_ORD;
+ if(n<1)
+ return ERROR_SIZE;
+
+ for(k = 0; k < n; k++)
+ {
+ y[k] = a[ord];
+ for(m = ord-1; m>-1; m--)
+ y[k] = y[k]*x[k] + a[m];
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/math_poly/polyval_cmplx.c b/dspl/src/math_poly/polyval_cmplx.c
new file mode 100644
index 0000000..464cf3a
--- /dev/null
+++ b/dspl/src/math_poly/polyval_cmplx.c
@@ -0,0 +1,107 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of libdspl-2.0.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DSPL is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Foobar. If not, see .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int polyval_cmplx(complex_t* a, int ord, complex_t* x, int n, complex_t* y)
+\brief Расчет комплексного полинома
+
+Функция рассчитывает полином \f$P_N(x)\f$ \f$N\f$-го порядка
+комплексного аргумента, заданного вектором `x`. \n
+
+\f[
+P_N(x) = a_0 + a_1 \cdot x + a_2 \cdot x^2 + a_3 \cdot x^3 + ... a_N \cdot x^N.
+\f]
+
+Для расчета используется формула Горнера: \n
+\f[
+ P_N(x) = a_0 + x \cdot (a_1 + x \cdot (a_2 + \cdot
+ ( \ldots x \cdot (a_{N-1} + x\cdot a_N) \ldots )))
+\f]
+
+\param[in] a
+Указатель на вектор комплексных коэффициентов полинома. \n
+Размер вектора `[ord+1 x 1]`. \n
+Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n \n
+
+\param[in] ord
+Порядок полинома \f$N\f$. \n \n
+
+\param[in] x
+Указатель на вектор аргумента полинома. \n
+Размер вектора `[n x 1]`. \n
+Значения полинома будут расчитаны для всех значений аргумента вектора `x`. \n \n
+
+\param[in] n
+Размер вектора агрумента полинома. \n\n
+
+\param[out] y
+Указатель вектор значения полинома для аргумента `x`. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` --- полином расчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\author Бахурин Сергей. www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API polyval_cmplx(complex_t* a, int ord,
+ complex_t* x, int n, complex_t* y)
+{
+ int k, m;
+ complex_t t;
+
+ if(!a || !x || !y)
+ return ERROR_PTR;
+ if(ord<0)
+ return ERROR_POLY_ORD;
+ if(n<1)
+ return ERROR_SIZE;
+
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = RE(a[ord]);
+ IM(y[k]) = IM(a[ord]);
+ for(m = ord-1; m>-1; m--)
+ {
+ RE(t) = CMRE(y[k], x[k]);
+ IM(t) = CMIM(y[k], x[k]);
+ RE(y[k]) = RE(t) + RE(a[m]);
+ IM(y[k]) = IM(t) + IM(a[m]);
+ }
+ }
+ return RES_OK;
+}
+
diff --git a/make.inc b/make.inc
index 8acf6ee..6f4cdac 100644
--- a/make.inc
+++ b/make.inc
@@ -22,6 +22,8 @@ LAPACK_DOUBLE_LIB_NAME = $(LAPACK_RELEASE_DIR)/liblapack_double.a
LAPACK_COMPLEX_SRC_DIR = $(LAPACK_LIB_DIR)/src
LAPACK_COMPLEX_LIB_NAME = $(LAPACK_RELEASE_DIR)/liblapack_complex.a
+
+
INC_DIR = ../include
RELEASE_DIR = ../_release
EXAMPLE_BIN_DIR = ../examples/bin