kopia lustrzana https://github.com/Dsplib/libdspl-2.0
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.incpull/6/merge
rodzic
d509c033f6
commit
c76bd63ace
|
@ -1,4 +0,0 @@
|
|||
*.o
|
||||
*.so
|
||||
*.dll
|
||||
*.exe
|
|
@ -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
|
922
_release/dspl.c
922
_release/dspl.c
|
@ -1,458 +1,464 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2020 Sergey Bakhurin
|
||||
* Digital Signal Processing Library [http://dsplib.org]
|
||||
*
|
||||
* This file is part of libdspl-2.0.
|
||||
*
|
||||
* is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DSPL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Foobar. If not, see <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 */
|
||||
|
|
|
@ -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);
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
1425
dspl/src/array.c
1425
dspl/src/array.c
Plik diff jest za duży
Load Diff
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
545
dspl/src/dft.c
545
dspl/src/dft.c
|
@ -1,532 +1,53 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2015-2019 Sergey Bakhurin
|
||||
* Digital Signal Processing Library [http://dsplib.org]
|
||||
*
|
||||
* This file is part of libdspl-2.0.
|
||||
*
|
||||
* is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DSPL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Foobar. If not, see <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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
1441
dspl/src/fft.c
1441
dspl/src/fft.c
Plik diff jest za duży
Load Diff
|
@ -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;
|
||||
}
|
||||
|
|
@ -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"
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
2
make.inc
2
make.inc
|
@ -22,6 +22,8 @@ LAPACK_DOUBLE_LIB_NAME = $(LAPACK_RELEASE_DIR)/liblapack_double.a
|
|||
LAPACK_COMPLEX_SRC_DIR = $(LAPACK_LIB_DIR)/src
|
||||
LAPACK_COMPLEX_LIB_NAME = $(LAPACK_RELEASE_DIR)/liblapack_complex.a
|
||||
|
||||
|
||||
|
||||
INC_DIR = ../include
|
||||
RELEASE_DIR = ../_release
|
||||
EXAMPLE_BIN_DIR = ../examples/bin
|
||||
|
|
Ładowanie…
Reference in New Issue