added functions for psd Bartlett's method for real and complex data

Changes to be committed:
	new file:   _release/dspl.c
	new file:   _release/dspl.h
	modified:   dspl/dox/en/mainpage.dox
	modified:   dspl/dox/ru/mainpage.dox
	modified:   dspl/src/psd.c
	modified:   dspl/src/randgen.c
	new file:   examples/src/psd_bartlett_cmplx_test.c
	new file:   examples/src/psd_bartlett_test.c
	new file:   examples/src/psd_periodogram_cmplx_test.c
	new file:   examples/src/psd_periodogram_test.c
	modified:   include/dspl.c
	modified:   include/dspl.h
pull/6/merge
Dsplib 2020-10-09 21:36:46 +03:00
rodzic f306d067f4
commit 32d374a575
12 zmienionych plików z 2930 dodań i 28 usunięć

602
_release/dspl.c 100644
Wyświetl plik

@ -0,0 +1,602 @@
/*
* 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_print matrix_print ;
p_matrix_print_cmplx matrix_print_cmplx ;
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
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup SYS_LOADING_GROUP
\fn void* dspl_load()
\brief Perform dynamic linking and load libdspl-2.0 functions.
This function attempts to link to the library `libdspl.dll` in
Windows system and the `libdspl.so` library on the Linux system.
The library is assumed to be in the same directory as the application.
user, or the path to the library is registered in the operating path variables
system.
Upon successful binding and loading of library functions, the handle is returned
libraries, as well as in the address space of the application appear
pointers to libdspl-2.0 functions.
\note
The returned handle is of type `void *`, which can be cast on Windows
to type `HINSTANCE`. In practice, this is not necessary, because this
the type is cast to `HINSTANCE` automatically if the compiler flag is set,
indicating that the application is being built on Windows.
An example of a simple program that implements dynamic binding with DSPL-2.0.
\code
#include <stdio.h>
#include <stdlib.h>
#include "dspl.h"
int main (int argc, char* argv[])
{
void * hdspl; // DSPL handle
hdspl = dspl_load (); // Dynamic linking
// Check the pointer. If `NULL`, then the link failed
if (! hdspl)
{
printf ("libdspl loading error! \n");
return -1;
}
// The link was successful, you can call the functions of DSPL-2.0
//Before correctly terminating the application, you must unlink
//library and clear memory.
dspl_free(hdspl);
return 0;
}
\endcode
\author Bakhurin Sergey. www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup SYS_LOADING_GROUP
\fn void* dspl_load()
\brief Произвести динамическую линковку и загрузить функции libdspl-2.0.
Данная функция производит попытку связывания с библиотекой `libdspl.dll` в
системе Windows и с библиотекой `libdspl.so` в системе Linux.
Предполагается, что библиотека находится в одной директории с приложением
пользователя, или путь к библиотеке прописан в переменных пути операционной
системы.
При удачном связывании и загрузке функций библиотеки возвращается хэндл
библиотеки, а также в адресном пространстве приложения появляются
указатели на функции libdspl-2.0.
\note
Возвращаемый хэндл имеет тип `void*`, который в ОС Windows может быть приведен
к типу `HINSTANCE`. На практике необходимости в этом, нет, потому что данный
тип приводится к `HINSTANCE` автоматически, если выставлен флаг компилятора,
указывающий, что сборка приложения производится в ОС Windows.
Пример простейшей программы реализующей динамическое связывание с DSPL-2.0.
\code
#include <stdio.h>
#include <stdlib.h>
#include "dspl.h"
int main(int argc, char* argv[])
{
void* hdspl; // DSPL хэндл
hdspl = dspl_load(); // Динамическая линковка
// Проверяем указатель. Если `NULLL`, то линковка прошла неудачно
if(!hdspl)
{
printf("libdspl loading error!\n");
return -1;
}
// Линковка прошла успешно можно вызывать функции DSPL-2.0
// Перед корректным завершением приложения необходимо разлинковать
// библиотеку и очистить память.
dspl_free(hdspl);
return 0;
}
\endcode
\author Бахурин Сергей. www.dsplib.org
***************************************************************************** */
#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_print);
LOAD_FUNC(matrix_print_cmplx);
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 */
}
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup SYS_LOADING_GROUP
\fn void dspl_free(void* handle)
\brief Cleans up the previously linked DSPL-2.0 dynamic library.
This cross-platform function clears the library `libdspl.dll` in
Windows system and from the library `libdspl.so` on the Linux system.
After cleaning the library, all functions will become unavailable.
\param [in] handle
Handle of the previously linked DSPL-2.0 library. \n
This pointer can be `NULL`, in this case no action
are being produced.
\author Bakhurin Sergey. www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup SYS_LOADING_GROUP
\fn void dspl_free(void* handle)
\brief Очищает связанную ранее динамическую библиотеку DSPL-2.0.
Данная кроссплатформенная функция производит очистку библиотеки `libdspl.dll` в
системе Windows и с библиотеки `libdspl.so` в системе Linux.
После очистки библиотеки все функции станут недоступны.
\param[in] handle
Хэндл прилинкованной ранее библиотеки DSPL-2.0. \n
Данный указатель может быть `NULL`, в этом случае никакие действия не
производятся.
\author Бахурин Сергей. www.dsplib.org
**************************************************************************** */
#endif
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 */

1572
_release/dspl.h 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -57,6 +57,7 @@ Dsplib toolchain includes GCC, GNUPLOT, CodeBlocks IDE, Far file manager and als
<b>Digital spectral analysis: </b> \n
- \ref DFT_GROUP \n
- \ref WIN_GROUP \n
- \ref PSD_GROUP \n
- \ref HILBERT_GROUP \n
\n

Wyświetl plik

@ -49,6 +49,7 @@ DSPL-2.0 --- свободная библиотека алгоритмов циф
- \ref DFT_GROUP \n
- \ref WIN_GROUP \n
- \ref PSD_GROUP \n
- \ref HILBERT_GROUP \n
\n

Wyświetl plik

@ -134,33 +134,139 @@ exit_label:
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API psd_bartlett_cmplx(complex_t* x, int n, int nfft,
fft_t* pfft, double fs,
int flag, double* ppsd, double* pfrq)
{
int err, pos, k;
double *pdgr = NULL;
complex_t *tmp = NULL;
fft_t *ptr_fft = NULL;
pos = 0;
pdgr = (double*)malloc(nfft * sizeof(double));
if(!pdgr)
return ERROR_MALLOC;
if(!pfft)
{
ptr_fft = (fft_t*)malloc(sizeof(fft_t));
memset(ptr_fft, 0, sizeof(fft_t));
}
else
ptr_fft = pfft;
memset(ppsd, 0, nfft * sizeof(double));
while(pos + nfft <= n)
{
err = fft_mag_cmplx(x + pos, nfft, ptr_fft, fs,
flag & DSPL_FLAG_FFT_SHIFT, pdgr, NULL);
if(err != RES_OK)
goto exit_label;
for(k = 0; k < nfft; k++)
ppsd[k] += pdgr[k];
pos += nfft;
}
if(pos < n)
{
tmp = (complex_t*)malloc(nfft * sizeof(complex_t));
if(!tmp)
{
err = ERROR_MALLOC;
goto exit_label;
}
memset(tmp ,0, nfft * sizeof(complex_t));
memcpy(tmp, x + pos, (n - pos)*sizeof(complex_t));
err = fft_mag_cmplx(tmp, nfft, ptr_fft, fs,
flag & DSPL_FLAG_FFT_SHIFT, pdgr, NULL);
if(err != RES_OK)
goto exit_label;
for(k = 0; k < nfft; k++)
ppsd[k] += pdgr[k];
}
/* fill frequency */
if(pfrq)
{
if(flag & DSPL_FLAG_FFT_SHIFT)
if(n%2)
err = linspace(-fs*0.5 + fs*0.5/(double)nfft,
fs*0.5 - fs*0.5/(double)nfft,
n, DSPL_SYMMETRIC, pfrq);
else
err = linspace(-fs*0.5, fs*0.5, nfft, DSPL_PERIODIC, pfrq);
else
err = linspace(0, fs, nfft, DSPL_PERIODIC, pfrq);
}
/* scale magnitude */
if(flag & DSPL_FLAG_LOGMAG)
{
for(k = 0; k < nfft; k++)
ppsd[k] = 10.0 * log10(ppsd[k] / (double)n / fs);
}
else
{
for(k = 0; k < nfft; k++)
ppsd[k] /= (double)n * fs;
}
exit_label:
if(pdgr)
free(pdgr);
if(tmp)
free(tmp);
if(ptr_fft && (ptr_fft != pfft))
{
fft_free(ptr_fft);
free(ptr_fft);
}
return err;
}
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup PSD_GROUP
\fn
int psd_periodogram(double* x, int n,
int win_type, double win_param,
fft_t* pfft, double fs,
int flag, double* ppsd, double* pfrq)
\brief Непараметрическая оценка спектральной плотности сигнала методом
модифицированной периодограммы
\fn int psd_periodogram(double* x, int n,
int win_type, double win_param,
fft_t* pfft, double fs,
int flag, double* ppsd, double* pfrq)
\brief Непараметрическая оценка спектральной плотности мощности (СПМ)
вещественного сигнала методом модифицированной периодограммы.
Функция рассчитывает спектральную плотность мощности \f$ X(f) \f$
выборки сигнала длительности \$n \$ отсчетов методом модифицированной
периодограммы:
\f[
X(f) = \frac{1}{N U F_s} \Big| \sum_{m = 0}^{n-1} w(m) x(m) \exp
\left( -j \frac{2\pi} f m \right) \Big|^2,
X(f) = \frac{1}{U F_s} \left| \sum_{m = 0}^{n-1} w(m) x(m) \exp
\left( -j 2\pi f m \right) \right|^2,
\f]
где \f$ w(m) \f$ -- отсчёты оконной функции, \f$ F_s \f$ -- частота
дискретизации (Гц), \f$ U \f$ нормировочный коэффициент равный
\f[
U \sum_{m = 0}^{n-1} w^2(m)
U = \sum_{m = 0}^{n-1} w^2(m)
\f]
При использовании прямоугольного окна модифицированная периодограмма переходит
@ -171,12 +277,9 @@ int psd_periodogram(double* x, int n,
(по умолчанию), или от \f$-F_s /2 \f$ до \f$F_s /2 \f$, если установлен флаг
расчета двусторонней периодограммы.
\note Периодограмма, как стандартная, так и модифицированная возвращает
асимптотически несмещенную, но несостоятельную оценку СПМ (уроверь флуктуаций
шумовой составляющей СПМ не уменьшается с ростом длины выборки `n`).
\note Периодограмма возвращает асимптотически несмещенную,
но несостоятельную оценку СПМ (уровень флуктуаций шумовой составляющей СПМ
не уменьшается с ростом длины выборки `n`).
\param[in] x
Указатель на входной вектор вещественного сигнала \f$x(m)\f$,
@ -200,11 +303,12 @@ int psd_periodogram(double* x, int n,
Подробнее смотри описание функции \ref window. \n\n
\param[in] pfft
Указатель на структуру `fft_t`. \n
Указатель на структуру \ref fft_t. \n
Указатель может быть `NULL`. В этом случае объект структуры будет
создан внутри функции и удален перед завершением.\n
Если предполагается многократный вызов функции, то рекомендуется создать
объект `fft_t` и передавать в функцию, чтобы не создавать его каждый раз. \n\n
объект \ref fft_t и передавать в функцию, чтобы не
создавать его каждый раз. \n\n
\param[in] fs
частота дискретизации выборки исходного сигнала (Гц). \n\n
@ -217,25 +321,50 @@ DSPL_FLAG_PSD_TWOSIDED - двусторонняя СПМ (от -Fs/2 до Fs/2)
\endverbatim
\param[in, out] ppsd
Указатель на вектор СПМ расчитанных по входному сигналу $x$. \n
Указатель на вектор СПМ рассчитанных по входному сигналу $x$. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n\n
\param[in, out] pfrq
Указатель на вектор частоты, соответсвующей
Указатель на вектор частоты, соответствующей
значениям рассчитанного вектора СПМ. \n
Размер вектора `[n x 1]`. \n
Указатель можеть быть `NULL`,в этом случае вектор частоты не
Указатель может быть `NULL`,в этом случае вектор частоты не
рассчитывается и не возвращается. \n\n
\return
`RES_OK` если расчет произведен успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
Пример периодограммных оценок СПМ для различной длины выборки сигнала:
\include psd_periodogram_test.c
Программа производит расчет СПМ сигнала, состоящего из двух гармоник на
фоне белого гауссова шума. Расчет ведется по выборкам длины 128, 1024 и
8192 отсчетов.
В результате периодограммы (стандартная с прямоугольным окном
и модифицированная с окном Блэкмана) выводятся на графики:
`n = 8192` точек (черная -- классическая периодограмма с прямоугольным окном,
зеленая -- модифицированная с окном Блэкмана):
\image html psd_perodogram_8192.png
`n = 1024` точек (черная -- классическая периодограмма с прямоугольным окном,
зеленая -- модифицированная с окном Блэкмана):
\image html psd_perodogram_1024.png
`n = 128` точек (черная -- классическая периодограмма с прямоугольным окном,
зеленая -- модифицированная с окном Блэкмана):
\image html psd_perodogram_128.png
Можно видеть, что модифицированная периодограмма позволяет снизить
растекание СПМ, однако уровень флуктуация шума не уменьшается с увеличением
размера выборки от 128 до 8192 отсчетов (оценка несостоятельная).
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API psd_periodogram(double* x, int n,
int win_type, double win_param,
@ -347,7 +476,124 @@ exit_label:
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup PSD_GROUP
\fn int psd_periodogram_cmplx(complex_t* x, int n,
int win_type, double win_param,
fft_t* pfft, double fs,
int flag, double* ppsd, double* pfrq)
\brief Непараметрическая оценка спектральной плотности мощности (СПМ)
комплексного сигнала методом модифицированной периодограммы.
Функция рассчитывает спектральную плотность мощности \f$ X(f) \f$
выборки сигнала длительности \$n \$ отсчетов методом модифицированной
периодограммы:
\f[
X(f) = \frac{1}{U F_s} \left| \sum_{m = 0}^{n-1} w(m) x(m) \exp
\left( -j 2\pi f m \right) \right|^2,
\f]
где \f$ w(m) \f$ -- отсчёты оконной функции, \f$ F_s \f$ -- частота
дискретизации (Гц), \f$ U \f$ нормировочный коэффициент равный
\f[
U = \sum_{m = 0}^{n-1} w^2(m)
\f]
При использовании прямоугольного окна модифицированная периодограмма переходит
в стандартную периодограмму.
Расчет спектральной плотности мощности ведется при помощи алгоритмов быстрого
преобразования Фурье, для дискретной сетки частот от 0 Гц до \f$ F_s \f$ Гц
(по умолчанию), или от \f$-F_s /2 \f$ до \f$F_s /2 \f$, если установлен флаг
расчета двусторонней периодограммы.
\note Периодограмма возвращает асимптотически несмещенную,
но несостоятельную оценку СПМ (уровень флуктуаций шумовой составляющей СПМ
не уменьшается с ростом длины выборки `n`).
\param[in] x
Указатель на входной вектор вещественного сигнала \f$x(m)\f$,
\f$ m = 0 \ldots n-1 \f$. \n
Размер вектора `[n x 1]`. \n \n
\param[in] n
Размер вектора входного сигнала.
Также размер выходного вектора СПМ и
вектора частоты также равны `n`.\n\n
\param[in] win_type
Тип оконной функции, применяемой для модифицированной периодограммы.\n
Подробнее смотри описание функции \ref window. \n\n
\param[in] win_type
Параметр оконной функции.\n
Данный параметр используется, если задано параметрическая оконная функция.
Для непараметрических окон данный параметр игнорируется.\n
Подробнее смотри описание функции \ref window. \n\n
\param[in] pfft
Указатель на структуру \ref fft_t. \n
Указатель может быть `NULL`. В этом случае объект структуры будет
создан внутри функции и удален перед завершением.\n
Если предполагается многократный вызов функции, то рекомендуется создать
объект \ref fft_t и передавать в функцию, чтобы не создавать его каждый раз. \n\n
\param[in] fs
частота дискретизации выборки исходного сигнала (Гц). \n\n
\param[in] flag
Комбинация битовых флагов, задающих режим расчета:
\verbatim
DSPL_FLAG_LOGMAG - СПМ считать в логарифмическом масштабе в единицах дБ/Гц
DSPL_FLAG_PSD_TWOSIDED - двусторонняя СПМ (от -Fs/2 до Fs/2)
\endverbatim
\param[in, out] ppsd
Указатель на вектор СПМ рассчитанных по входному сигналу $x$. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n\n
\param[in, out] pfrq
Указатель на вектор частоты, соответствующей
значениям рассчитанного вектора СПМ. \n
Размер вектора `[n x 1]`. \n
Указатель может быть `NULL`,в этом случае вектор частоты не
рассчитывается и не возвращается. \n\n
\return
`RES_OK` если расчет произведен успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
Пример периодограммных оценок СПМ для различной длины выборки сигнала:
\include psd_periodogram_cmplx_test.c
Программа производит расчет СПМ сигнала, состоящего из двух гармоник на
фоне белого гауссова шума. Расчет ведется по выборкам длины 128, 1024 и
8192 отсчетов.
В результате периодограммы (стандартная с прямоугольным окном
и модифицированная с окном Блэкмана) выводятся на графики:
`n = 8192` точек (черная -- классическая периодограмма с прямоугольным окном,
зеленая -- модифицированная с окном Блэкмана):
\image html psd_perodogram_cmplx_8192.png
`n = 1024` точек (черная -- классическая периодограмма с прямоугольным окном,
зеленая -- модифицированная с окном Блэкмана):
\image html psd_perodogram_cmplx_1024.png
`n = 128` точек (черная -- классическая периодограмма с прямоугольным окном,
зеленая -- модифицированная с окном Блэкмана):
\image html psd_perodogram_cmplx_128.png
Можно видеть, что модифицированная периодограмма позволяет снизить
растекание СПМ, однако уровень флуктуация шума не уменьшается с увеличением
размера выборки от 128 до 8192 отсчетов (оценка несостоятельная).
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API psd_periodogram_cmplx(complex_t* x, int n,
int win_type, double win_param,

Wyświetl plik

@ -627,6 +627,35 @@ exit_label:
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API randn_cmplx(complex_t* x, int n, complex_t* mu,
double sigma, random_t* prnd)
{
int err, i;
err = randn((double*)x, 2*n, 0.0, sigma / M_SQRT2, prnd);
if(err!= RES_OK)
return err;
if(mu)
{
for(i = 0; i < n; i++)
{
RE(x[i]) += RE(mu[0]);
IM(x[i]) += IM(mu[0]);
}
}
return err;
}
#ifdef DOXYGEN_ENGLISH

Wyświetl plik

@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 8192
#define FS 1.0
void psd_plot(int argc, char* argv[], char* fn_png, char* fn_data)
{
char cmd[512] = {0};
void* hplot; /* GNUPLOT handle */
/* plotting by GNUPLOT */
gnuplot_create(argc, argv, 680, 480, fn_png, &hplot);
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set grid");
gnuplot_cmd(hplot, "set xlabel 'frequency, Hz'");
gnuplot_cmd(hplot, "set ylabel 'Power Spectral Density, [dB/Hz]'");
gnuplot_cmd(hplot, "set yrange [-60: 40]");
sprintf(cmd, "plot '%s' w l lt -1", fn_data);
gnuplot_cmd(hplot, cmd);
gnuplot_close(hplot);
}
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
hdspl = dspl_load(); /* Load DSPL function */
random_t rnd = {0}; /* random structure */
complex_t *x = NULL;
double *psd = NULL;
double *frq = NULL;
int k, err;
x = (complex_t*)malloc(N*sizeof(complex_t));
psd = (double*)malloc(N*sizeof(double));
frq = (double*)malloc(N*sizeof(double));
/* input signal fill as noise -20 dB/Hz power spectrum density */
random_init(&rnd, RAND_TYPE_MRG32K3A, NULL);
randn_cmplx(x, N, NULL, 0.1, &rnd);
/* x[k] = 0.1 * cos(2 * pi * 0.2 * k) + cos(2 * pi * 0.26 * k) + noise */
for(k = 0; k < N; k++)
{
RE(x[k]) += cos(M_2PI * 0.26 * (double)k) +
0.1*cos(M_2PI*0.2* (double)k);
IM(x[k]) += sin(M_2PI * 0.26 * (double)k) +
0.1*sin(M_2PI*0.2* (double)k);
}
/* Twosided PSD logscale magnitude n = 8192, nfft = 8192.
This case is periodogram */
err = psd_bartlett_cmplx(x, N, N, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N, "dat/psd_bartlett_cmplx_8192.txt");
psd_plot(argc, argv, "img/psd_bartlett_cmplx_8192.png",
"dat/psd_bartlett_cmplx_8192.txt");
/* Twosided PSD with logscale magnitude n = 8192, nfft = 1024 */
err = psd_bartlett_cmplx(x, N, N/8, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/8, "dat/psd_bartlett_cmplx_1024.txt");
psd_plot(argc, argv, "img/psd_bartlett_cmplx_1024.png",
"dat/psd_bartlett_cmplx_1024.txt");
/* Twosided PSD with logscale magnitude n = 8192, nfft = 128 */
err = psd_bartlett_cmplx(x, N, N/64, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/64, "dat/psd_bartlett_cmplx_128.txt");
psd_plot(argc, argv, "img/psd_bartlett_cmplx_128.png",
"dat/psd_bartlett_cmplx_128.txt");
dspl_free(hdspl); /* free dspl handle */
if(x)
free(x);
if(psd)
free(psd);
if(frq)
free(frq);
return 0;
}

Wyświetl plik

@ -0,0 +1,90 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 8192
#define FS 1.0
void psd_plot(int argc, char* argv[], char* fn_png, char* fn_data)
{
char cmd[512] = {0};
void* hplot; /* GNUPLOT handle */
/* plotting by GNUPLOT */
gnuplot_create(argc, argv, 680, 480, fn_png, &hplot);
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set grid");
gnuplot_cmd(hplot, "set xlabel 'frequency, Hz'");
gnuplot_cmd(hplot, "set ylabel 'Power Spectral Density, [dB/Hz]'");
gnuplot_cmd(hplot, "set yrange [-60: 40]");
sprintf(cmd, "plot '%s' w l lt -1", fn_data);
gnuplot_cmd(hplot, cmd);
gnuplot_close(hplot);
}
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
hdspl = dspl_load(); /* Load DSPL function */
random_t rnd = {0}; /* random structure */
double *x = NULL;
double *psd = NULL;
double *frq = NULL;
int k, err;
x = (double*)malloc(N*sizeof(double));
psd = (double*)malloc(N*sizeof(double));
frq = (double*)malloc(N*sizeof(double));
/* input signal fill as noise -20 dB/Hz power spectrum density */
random_init(&rnd, RAND_TYPE_MRG32K3A, NULL);
randn(x, N, 0.0, 0.1, &rnd);
/* x[k] = 0.1 * cos(2 * pi * 0.2 * k) + cos(2 * pi * 0.26 * k) + noise */
for(k = 0; k < N; k++)
x[k] += cos(M_2PI * 0.26 * (double)k) + 0.1*cos(M_2PI*0.2* (double)k);
/* Twosided PSD logscale magnitude n = 8192, nfft = 8192.
This case is periodogram */
err = psd_bartlett(x, N, N, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N, "dat/psd_bartlett_8192.txt");
psd_plot(argc, argv, "img/psd_bartlett_8192.png",
"dat/psd_bartlett_8192.txt");
/* Twosided PSD with logscale magnitude n = 8192, nfft = 1024 */
err = psd_bartlett(x, N, N/8, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/8, "dat/psd_bartlett_1024.txt");
psd_plot(argc, argv, "img/psd_bartlett_1024.png",
"dat/psd_bartlett_1024.txt");
/* Twosided PSD with logscale magnitude n = 8192, nfft = 128 */
err = psd_bartlett(x, N, N/64, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/64, "dat/psd_bartlett_128.txt");
psd_plot(argc, argv, "img/psd_bartlett_128.png",
"dat/psd_bartlett_128.txt");
dspl_free(hdspl); /* free dspl handle */
if(x)
free(x);
if(psd)
free(psd);
if(frq)
free(frq);
return 0;
}

Wyświetl plik

@ -0,0 +1,116 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 8192
#define FS 1.0
void psd_plot(int argc, char* argv[], char* fn_png,
char* fn_data0, char* fn_data1)
{
char cmd[512] = {0};
void* hplot; /* GNUPLOT handle */
/* plotting by GNUPLOT */
gnuplot_create(argc, argv, 680, 480, fn_png, &hplot);
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set grid");
gnuplot_cmd(hplot, "set xlabel 'frequency, Hz'");
gnuplot_cmd(hplot, "set ylabel 'Power Spectral Density, [dB/Hz]'");
gnuplot_cmd(hplot, "set yrange [-60: 40]");
sprintf(cmd, "plot '%s' w l lt -1,\\", fn_data0);
gnuplot_cmd(hplot, cmd);
memset(cmd, 0, 512);
sprintf(cmd, "'%s' w l lt 2", fn_data1);
gnuplot_cmd(hplot, cmd);
gnuplot_close(hplot);
}
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handle */
hdspl = dspl_load(); // Load DSPL function
random_t rnd = {0}; /* random structure */
complex_t *x = NULL;
double *psd = NULL;
double *frq = NULL;
int k, err;
x = (complex_t*)malloc(N*sizeof(complex_t));
psd = (double*)malloc(N*sizeof(double));
frq = (double*)malloc(N*sizeof(double));
/* input signal fill as noise -40 dB/Hz power spectrum density */
random_init(&rnd, RAND_TYPE_MRG32K3A, NULL);
randn_cmplx(x, N, NULL, 0.1, &rnd);
/* x[k] = 0.1*cos(2*pi*0.1*k) + cos(2*pi*0.2*k) + noise */
for(k = 0; k < N; k++)
{
RE(x[k]) += cos(M_2PI * 0.26 * (double)k) +
0.1*cos(M_2PI * 0.20 * (double)k);
IM(x[k]) += sin(M_2PI * 0.26 * (double)k) +
0.1*sin(M_2PI * 0.20 * (double)k);
}
/* Twosided PSD with logscale magnitude 8192 points with rect window */
err = psd_periodogram_cmplx(x, N, DSPL_WIN_RECT, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N, "dat/psd_periodogram_8192_win_rect.txt");
/* Twosided PSD with logscale magnitude 8192 points with blackman window */
err = psd_periodogram_cmplx(x, N, DSPL_WIN_BLACKMAN, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N, "dat/psd_periodogram_8192_win_blackman.txt");
psd_plot(argc, argv, "img/psd_perodogram_cmplx_8192.png",
"dat/psd_periodogram_8192_win_rect.txt",
"dat/psd_periodogram_8192_win_blackman.txt");
/* Twosided PSD with logscale magnitude 1024 points with rect window */
err = psd_periodogram_cmplx(x, N/8, DSPL_WIN_RECT, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/8, "dat/psd_periodogram_1024_win_rect.txt");
/* Twosided PSD with logscale magnitude 1024 points with blackman window */
err = psd_periodogram_cmplx(x, N/8, DSPL_WIN_BLACKMAN, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/8, "dat/psd_periodogram_1024_win_blackman.txt");
psd_plot(argc, argv, "img/psd_perodogram_cmplx_1024.png",
"dat/psd_periodogram_1024_win_rect.txt",
"dat/psd_periodogram_1024_win_blackman.txt");
/* Twosided PSD with logscale magnitude 128 points with rect window */
err = psd_periodogram_cmplx(x, N/64, DSPL_WIN_RECT, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/64, "dat/psd_periodogram_128_win_rect.txt");
/* Twosided PSD with logscale magnitude 128 points with blackman window */
err = psd_periodogram_cmplx(x, N/64, DSPL_WIN_BLACKMAN, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/64, "dat/psd_periodogram_128_win_blackman.txt");
psd_plot(argc, argv, "img/psd_perodogram_cmplx_128.png",
"dat/psd_periodogram_128_win_rect.txt",
"dat/psd_periodogram_128_win_blackman.txt");
dspl_free(hdspl); // free dspl handle
if(x)
free(x);
if(psd)
free(psd);
if(frq)
free(frq);
return 0;
}

Wyświetl plik

@ -0,0 +1,119 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 8192
#define FS 1.0
void psd_plot(int argc, char* argv[], char* fn_png,
char* fn_data0, char* fn_data1)
{
char cmd[512] = {0};
void* hplot; /* GNUPLOT handle */
/* plotting by GNUPLOT */
gnuplot_create(argc, argv, 680, 480, fn_png, &hplot);
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set grid");
gnuplot_cmd(hplot, "set xlabel 'frequency, Hz'");
gnuplot_cmd(hplot, "set ylabel 'Power Spectral Density, [dB/Hz]'");
gnuplot_cmd(hplot, "set yrange [-60: 40]");
sprintf(cmd, "plot '%s' w l lt -1,\\", fn_data0);
gnuplot_cmd(hplot, cmd);
memset(cmd, 0, 512);
sprintf(cmd, "'%s' w l lt 2", fn_data1);
gnuplot_cmd(hplot, cmd);
gnuplot_close(hplot);
}
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handle */
hdspl = dspl_load(); // Load DSPL function
random_t rnd = {0}; /* random structure */
double *x = NULL;
double *psd = NULL;
double *frq = NULL;
int k, err;
x = (double*)malloc(N*sizeof(double));
psd = (double*)malloc(N*sizeof(double));
frq = (double*)malloc(N*sizeof(double));
/* input signal fill as noise -40 dB/Hz power spectrum density */
random_init(&rnd, RAND_TYPE_MRG32K3A, NULL);
randn(x, N, 0.0, 0.1, &rnd);
/* x[k] = 0.1*cos(2*pi*0.1*k) + cos(2*pi*0.2*k) + noise */
for(k = 0; k < N; k++)
x[k] += cos(M_2PI * 0.26 * (double)k) + 0.1*cos(M_2PI*0.2* (double)k);
/* Twosided PSD with logscale magnitude 8192 points with rect window */
err = psd_periodogram(x, N, DSPL_WIN_RECT, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N, "dat/psd_periodogram_8192_win_rect.txt");
/* Twosided PSD with logscale magnitude 8192 points with blackman window */
err = psd_periodogram(x, N, DSPL_WIN_BLACKMAN, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N, "dat/psd_periodogram_8192_win_blackman.txt");
psd_plot(argc, argv, "img/psd_perodogram_8192.png",
"dat/psd_periodogram_8192_win_rect.txt",
"dat/psd_periodogram_8192_win_blackman.txt");
/* Twosided PSD with logscale magnitude 1024 points with rect window */
err = psd_periodogram(x, N/8, DSPL_WIN_RECT, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/8, "dat/psd_periodogram_1024_win_rect.txt");
/* Twosided PSD with logscale magnitude 1024 points with blackman window */
err = psd_periodogram(x, N/8, DSPL_WIN_BLACKMAN, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/8, "dat/psd_periodogram_1024_win_blackman.txt");
psd_plot(argc, argv, "img/psd_perodogram_1024.png",
"dat/psd_periodogram_1024_win_rect.txt",
"dat/psd_periodogram_1024_win_blackman.txt");
/* Twosided PSD with logscale magnitude 128 points with rect window */
err = psd_periodogram(x, N/64, DSPL_WIN_RECT, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/64, "dat/psd_periodogram_128_win_rect.txt");
/* Twosided PSD with logscale magnitude 128 points with blackman window */
err = psd_periodogram(x, N/64, DSPL_WIN_BLACKMAN, 0, NULL, FS,
DSPL_FLAG_LOGMAG | DSPL_FLAG_PSD_TWOSIDED, psd, frq);
writetxt(frq, psd, N/64, "dat/psd_periodogram_128_win_blackman.txt");
psd_plot(argc, argv, "img/psd_perodogram_128.png",
"dat/psd_periodogram_128_win_rect.txt",
"dat/psd_periodogram_128_win_blackman.txt");
dspl_free(hdspl); // free dspl handle
if(x)
free(x);
if(psd)
free(psd);
if(frq)
free(frq);
return 0;
}

Wyświetl plik

@ -154,7 +154,9 @@ 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 ;
@ -162,6 +164,7 @@ 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 ;
@ -472,7 +475,9 @@ void* dspl_load()
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);
@ -480,6 +485,7 @@ void* dspl_load()
LOAD_FUNC(randb);
LOAD_FUNC(randb2);
LOAD_FUNC(randn);
LOAD_FUNC(randn_cmplx);
LOAD_FUNC(random_init);
LOAD_FUNC(randu);
LOAD_FUNC(ratcompos);

Wyświetl plik

@ -1298,6 +1298,15 @@ DECLARE_FUNC(int, psd_bartlett, double* x
COMMA double* ppsd
COMMA double* pfrq);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, psd_bartlett_cmplx, complex_t* x
COMMA int n
COMMA int nfft
COMMA fft_t* pfft
COMMA double fs
COMMA int flag
COMMA double* ppsd
COMMA double* pfrq);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, psd_periodogram, double* x
COMMA int n
COMMA int win_type
@ -1308,6 +1317,16 @@ DECLARE_FUNC(int, psd_periodogram, double* x
COMMA double* ppsd
COMMA double* pfrq);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, psd_periodogram_cmplx, complex_t* x
COMMA int n
COMMA int win_type
COMMA double win_param
COMMA fft_t* pfft
COMMA double fs
COMMA int flag
COMMA double* ppsd
COMMA double* pfrq);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, psd_welch, double* x
COMMA int n
COMMA int win_type
@ -1346,10 +1365,16 @@ DECLARE_FUNC(int, randi, int* x
COMMA int stop
COMMA random_t* prnd);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, randn, double*
COMMA int
COMMA double
COMMA double
DECLARE_FUNC(int, randn, double* x
COMMA int n
COMMA double mu
COMMA double sigma
COMMA random_t* prnd);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, randn_cmplx, complex_t* x
COMMA int n
COMMA complex_t* mu
COMMA double sigma
COMMA random_t* prnd);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, random_init, random_t* prnd