New Structure is beginning

Changes to be committed:
	deleted:    _release/.gitignore
	deleted:    _release/Makefile
	modified:   _release/dspl.c
	modified:   _release/dspl.h
	deleted:    _release/test.c
	modified:   dspl/Makefile
	modified:   dspl/src/array.c
	new file:   dspl/src/array/array_scale_lin.c
	new file:   dspl/src/array/concat.c
	new file:   dspl/src/array/decimate.c
	new file:   dspl/src/array/decimate_cmplx.c
	new file:   dspl/src/array/find_nearest.c
	new file:   dspl/src/array/flipip.c
	new file:   dspl/src/array/flipip_cmplx.c
	new file:   dspl/src/array/linspace.c
	new file:   dspl/src/array/logspace.c
	new file:   dspl/src/array/ones.c
	new file:   dspl/src/array/sum.c
	new file:   dspl/src/array/sum_sqr.c
	modified:   dspl/src/dft.c
	new file:   dspl/src/dft/dft.c
	new file:   dspl/src/dft/dft_cmplx.c
	new file:   dspl/src/dft/fft.c
	new file:   dspl/src/dft/fft_abs.c
	new file:   dspl/src/dft/fft_abs_cmplx.c
	new file:   dspl/src/dft/fft_cmplx.c
	new file:   dspl/src/dft/fft_create.c
	new file:   dspl/src/dft/fft_free.c
	new file:   dspl/src/dft/fft_krn.c
	new file:   dspl/src/dft/fft_mag.c
	new file:   dspl/src/dft/fft_mag_cmplx.c
	new file:   dspl/src/dft/fft_shift.c
	new file:   dspl/src/dft/fft_shift_cmplx.c
	renamed:    dspl/src/fft_subkernel.c -> dspl/src/dft/fft_subkernel.c
	new file:   dspl/src/dft/fourier_integral_cmplx.c
	new file:   dspl/src/dft/fourier_series_dec.c
	new file:   dspl/src/dft/fourier_series_dec_cmplx.c
	new file:   dspl/src/dft/fourier_series_rec.c
	new file:   dspl/src/dft/goertzel.c
	renamed:    dspl/src/goertzel.c -> dspl/src/dft/goertzel_cmplx.c
	new file:   dspl/src/dft/idft_cmplx.c
	new file:   dspl/src/dft/ifft_cmplx.c
	deleted:    dspl/src/fft.c
	deleted:    dspl/src/fourier_series.c
	new file:   dspl/src/math_poly.c
	new file:   dspl/src/math_poly/cheby_poly1.c
	renamed:    dspl/src/cheby.c -> dspl/src/math_poly/cheby_poly2.c
	new file:   dspl/src/math_poly/poly_z2a_cmplx.c
	renamed:    dspl/src/polyval.c -> dspl/src/math_poly/polyroots.c
	new file:   dspl/src/math_poly/polyval.c
	new file:   dspl/src/math_poly/polyval_cmplx.c
	modified:   make.inc
pull/6/merge
Dsplib 2021-12-29 14:33:52 +03:00
rodzic d509c033f6
commit c76bd63ace
52 zmienionych plików z 6197 dodań i 5354 usunięć

4
_release/.gitignore vendored
Wyświetl plik

@ -1,4 +0,0 @@
*.o
*.so
*.dll
*.exe

Wyświetl plik

@ -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

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifdef WIN_OS
#include <windows.h>
#endif /* WIN_OS */
#ifdef LINUX_OS
#include <dlfcn.h>
#endif /* LINUX_OS */
#include <stdio.h>
#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 <http://www.gnu.org/licenses/>.
*/
#ifdef WIN_OS
#include <windows.h>
#endif /* WIN_OS */
#ifdef LINUX_OS
#include <dlfcn.h>
#endif /* LINUX_OS */
#include <stdio.h>
#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 */

Wyświetl plik

@ -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);
/*----------------------------------------------------------------------------*/

Wyświetl plik

@ -1,30 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#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;
}

Wyświetl plik

@ -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

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
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 <stdlib.h>
#include <math.h>
#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;
}

192
dspl/src/dft/dft.c 100644
Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#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;
}

192
dspl/src/dft/fft.c 100644
Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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);
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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);
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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));
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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
<a href="http://en.dsplib.org/content/dft_freq/dft_freq.html">
to move the frequency 0 to the center
</a> 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 Перестановка спектральных отсчетов дискретного преобразования Фурье
Функция производит
<a href="http://ru.dsplib.org/content/dft_freq/dft_freq.html">
перестановку спектральных отсчетов ДПФ
</a> и переносит нулевую частоту в центр вектора ДПФ. \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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
\brief <a href = "http://en.dsplib.org/content/goertzel/goertzel.html">
Goertzel algorithm </a> 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 <a href = "http://ru.dsplib.org/content/goertzel/goertzel.html">
Алгоритм Гёрцеля</a> для расчета отдельных спектральных отсчетов дискретного
преобразования Фурье вещественного сигнала `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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
\brief <a href = "http://en.dsplib.org/content/goertzel/goertzel.html">
Goertzel algorithm </a> 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 <a href = "http://ru.dsplib.org/content/goertzel/goertzel.html">
Алгоритм Гёрцеля</a> для расчета отдельных спектральных отсчетов дискретного
преобразования Фурье вещественного сигнала `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 <a href = "http://en.dsplib.org/content/goertzel/goertzel.html">
Goertzel algorithm </a> 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 <a href = "http://ru.dsplib.org/content/goertzel/goertzel.html">
Алгоритм Гёрцеля</a> для расчета отдельных спектральных отсчетов дискретного
преобразования Фурье комплексного сигнала `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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#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 <a href = "http://en.dsplib.org/content/goertzel/goertzel.html">
Goertzel algorithm </a> 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 <a href = "http://ru.dsplib.org/content/goertzel/goertzel.html">
Алгоритм Гёрцеля</a> для расчета отдельных спектральных отсчетов дискретного
преобразования Фурье комплексного сигнала `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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#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;
}

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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"

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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