kopia lustrzana https://github.com/Dsplib/libdspl-2.0
Changed html template for doxygen and some docs for conv function
Changes to be committed: modified: dox/doxy_stylesheet.css modified: dox/footer.html modified: dox/header.html modified: dspl/dox/ru/conv.dox modified: dspl/src/conv.c new file: examples/src/conv_fft_test.c modified: include/dspl.c modified: include/dspl.h modified: release/include/dspl.c modified: release/include/dspl.hpull/6/merge
rodzic
4054894f46
commit
eebe14a493
|
@ -1,8 +1,15 @@
|
|||
/* The standard CSS for doxygen 1.8.13 */
|
||||
|
||||
/*
|
||||
body, table, div, p, dl {
|
||||
font: 400 14px/22px Roboto,sans-serif;
|
||||
}
|
||||
*/
|
||||
|
||||
code{
|
||||
font-size:12pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p.reference, p.definition {
|
||||
font: 400 14px/22px Roboto,sans-serif;
|
||||
|
|
|
@ -18,18 +18,7 @@ $generatedby  <a href="http://www.doxygen.org/index.html">
|
|||
</small></address>
|
||||
<!--END !GENERATE_TREEVIEW-->
|
||||
|
||||
</div>
|
||||
|
||||
</div><!--div id="dsplib_maket"-->
|
||||
|
||||
|
||||
</div> <!-- div id="dsplib_main" -->
|
||||
|
||||
|
||||
|
||||
<div class="dsplib_copyright">
|
||||
© Бахурин Сергей 2015 - 2019. Все права защищены.
|
||||
Любое копирование материалов сайте без разрешения автора запрещено.
|
||||
</div>
|
||||
</div> <!-- div id="wrapper" -->
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
|
@ -20,11 +20,16 @@
|
|||
$treeview
|
||||
$search
|
||||
$mathjax
|
||||
<link href="http://dsplib.org/header_footer.css" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||
$extrastylesheet
|
||||
|
||||
|
||||
<link href="http://dsplib.org/dsplib-stylesheet.css".css" rel="stylesheet" type="text/css">
|
||||
|
||||
|
||||
</head>
|
||||
|
@ -64,36 +69,27 @@ $extrastylesheet
|
|||
|
||||
|
||||
|
||||
|
||||
<div id="dsplib_wrapper">
|
||||
<div id="dsplib_main">
|
||||
|
||||
<div id="dsplib_header">
|
||||
<div id = "dsplib_menubar">
|
||||
|
||||
<div class = "header-bar">
|
||||
<div class = "menu-bar">
|
||||
<nav>
|
||||
<ul>
|
||||
<div id = "dsplib_logo"><img src="http://dsplib.org/logo.png" /> </div>
|
||||
<li><a href="http://ru.dsplib.org">Содержание</a></li>
|
||||
<li><a href="http://ru.dsplib.org/dspl">DSPL</a></li>
|
||||
<li><a href="http://ru.dsplib.org/forum">Форум</a></li>
|
||||
|
||||
|
||||
<div class="dsplib_search">
|
||||
|
||||
<div class="ya-site-form ya-site-form_inited_no" onclick="return {'action':'http://ru.dsplib.org/search_results.html','arrow':false,'bg':'transparent','fontsize':12,'fg':'#000000','language':'ru','logo':'rb','publicname':'ru.dsplib.org поиск','suggest':true,'target':'_self','tld':'ru','type':2,'usebigdictionary':true,'searchid':2332185,'input_fg':'#000000','input_bg':'#ffffff','input_fontStyle':'normal','input_fontWeight':'normal','input_placeholder':'поиск','input_placeholderColor':'#000000','input_borderColor':'#7f9db9'}"><form action="https://yandex.ru/search/site/" method="get" target="_self" accept-charset="utf-8"><input type="hidden" name="searchid" value="2332185"/><input type="hidden" name="l10n" value="ru"/><input type="hidden" name="reqenc" value=""/><input type="search" name="text" value="" style = "height: 24px; font-family: verdana,arial; font-size: 12px"/><input type="submit" value="Найти" style = "display: none; "/></form></div><style type="text/css">.ya-page_js_yes .ya-site-form_inited_no { display: none; }</style><script type="text/javascript">(function(w,d,c){var s=d.createElement('script'),h=d.getElementsByTagName('script')[0],e=d.documentElement;if((' '+e.className+' ').indexOf(' ya-page_js_yes ')===-1){e.className+=' ya-page_js_yes';}s.type='text/javascript';s.async=true;s.charset='utf-8';s.src=(d.location.protocol==='https:'?'https:':'http:')+'//site.yandex.net/v2.0/js/all.js';h.parentNode.insertBefore(s,h);(w[c]||(w[c]=[])).push(function(){Ya.Site.Form.init()})})(window,document,'yandex_site_callbacks');</script>
|
||||
|
||||
<ul>
|
||||
<div class = "dsplib-logo"><img src="http://dsplib.org/logo.png" /> </div>
|
||||
<li><a href="http://ru.dsplib.org">Содержание</a></li>
|
||||
<li><a href="http://ru.dsplib.org/dspl">DSPL</a></li>
|
||||
<li><a href="http://ru.dsplib.org/forum">Форум</a></li>
|
||||
<li>
|
||||
<div class="search-bar">
|
||||
<div class="ya-site-form ya-site-form_inited_no" onclick="return {'action':'http://ru.dsplib.org/search_results.html','arrow':false,'bg':'transparent','fontsize':12,'fg':'#000000','language':'ru','logo':'rb','publicname':'ru.dsplib.org поиск','suggest':true,'target':'_self','tld':'ru','type':2,'usebigdictionary':true,'searchid':2332185,'input_fg':'#000000','input_bg':'#ffffff','input_fontStyle':'normal','input_fontWeight':'normal','input_placeholder':'поиск','input_placeholderColor':'#000000','input_borderColor':'#7f9db9'}"><form action="https://yandex.ru/search/site/" method="get" target="_self" accept-charset="utf-8"><input type="hidden" name="searchid" value="2332185"/><input type="hidden" name="l10n" value="ru"/><input type="hidden" name="reqenc" value=""/><input type="search" name="text" value="" style = "height: 24px; font-family: verdana,arial; font-size: 12px"/><input type="submit" value="Найти" style = "display: none;"/></form></div><style type="text/css">.ya-page_js_yes .ya-site-form_inited_no { display: none; }</style><script type="text/javascript">(function(w,d,c){var s=d.createElement('script'),h=d.getElementsByTagName('script')[0],e=d.documentElement;if((' '+e.className+' ').indexOf(' ya-page_js_yes ')===-1){e.className+=' ya-page_js_yes';}s.type='text/javascript';s.async=true;s.charset='utf-8';s.src=(d.location.protocol==='https:'?'https:':'http:')+'//site.yandex.net/v2.0/js/all.js';h.parentNode.insertBefore(s,h);(w[c]||(w[c]=[])).push(function(){Ya.Site.Form.init()})})(window,document,'yandex_site_callbacks');</script>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</div><!--div id="dsplib_header"-->
|
||||
</div><!--div id = "dsplib_menubar"-->
|
||||
|
||||
|
||||
<div id="dsplib_maket">
|
||||
|
||||
<div class="main-dsplib">
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -134,6 +134,100 @@ cc[5] = 0.0+24.0j
|
|||
|
||||
|
||||
|
||||
/*! ****************************************************************************
|
||||
\ingroup FILTER_CONV_GROUP
|
||||
\fn int conv_fft(double* a, int na, double* b, int nb,
|
||||
fft_t* pfft, double* c)
|
||||
\brief Линейная свертка двух вещественных векторов с использованием алгоритмов
|
||||
быстрого преобразования Фурье
|
||||
|
||||
Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$ используя
|
||||
секционную обработку с перекрытием в частотной области. Это позволяет сократить
|
||||
вычислительные операции при расчете длинных сверток.
|
||||
|
||||
|
||||
|
||||
\param[in] a Указатель на первый вектор \f$a\f$.<BR>
|
||||
Размер вектора `[na x 1]`.<BR><BR>
|
||||
|
||||
\param[in] na Размер первого вектора.<BR><BR>
|
||||
|
||||
\param[in] b Указатель на второй вектор \f$b\f$.<BR>
|
||||
Размер вектора `[nb x 1]`.<BR><BR>
|
||||
|
||||
\param[in] nb Размер второго вектора.<BR><BR>
|
||||
|
||||
\param[in] pfft Указатель на структуру `fft_t` алгоритма
|
||||
быстрого преобразования Фурье.<BR>
|
||||
Функция изменит состояние полей структуры `fft_t`,
|
||||
поэтому структура должна быть очищена перед выходом из
|
||||
программы для исключения утечек памяти.<BR>
|
||||
|
||||
\param[in] nfft Размер алгоритма БПФ который будет использован для расчета
|
||||
секционной свертки с перекрытием.<BR>
|
||||
Данный параметр должен быть больше чем минимальное значение
|
||||
размеров сворачиваемых векторов.<BR>
|
||||
Например если `na=10`, а `nb=4`, то параметр `nfft` должен
|
||||
быть больше 4.<BR>
|
||||
Библиотека поддерживает алгоритмы БПФ составной длины
|
||||
\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). Однако, максимальное
|
||||
быстродействие достигается при использовании длин равных
|
||||
степени двойки.
|
||||
|
||||
\param[out] c Указатель на вектор свертки \f$ c = a * b\f$.<BR>
|
||||
Размер вектора `[na + nb - 1 x 1]`.<BR>
|
||||
Память должна быть выделена.<BR><BR>
|
||||
|
||||
\return
|
||||
`RES_OK` если свертка рассчитана успешно.<BR>
|
||||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
|
||||
|
||||
|
||||
\note Данная функция наиболее эффективна при вычислении длинных сверток.
|
||||
|
||||
Пример использования функции:
|
||||
|
||||
\include conv_fft_test.c
|
||||
|
||||
Результат работы:
|
||||
\verbatim
|
||||
|
||||
conv_fft error: 0x00000000
|
||||
conv error: 0x00000000
|
||||
c[ 0] = -0.00 d[ 0] = 0.00
|
||||
c[ 1] = -0.00 d[ 1] = 0.00
|
||||
c[ 2] = 1.00 d[ 2] = 1.00
|
||||
c[ 3] = 4.00 d[ 3] = 4.00
|
||||
c[ 4] = 10.00 d[ 4] = 10.00
|
||||
c[ 5] = 20.00 d[ 5] = 20.00
|
||||
c[ 6] = 35.00 d[ 6] = 35.00
|
||||
c[ 7] = 56.00 d[ 7] = 56.00
|
||||
c[ 8] = 77.00 d[ 8] = 77.00
|
||||
c[ 9] = 98.00 d[ 9] = 98.00
|
||||
c[ 10] = 119.00 d[ 10] = 119.00
|
||||
c[ 11] = 140.00 d[ 11] = 140.00
|
||||
c[ 12] = 161.00 d[ 12] = 161.00
|
||||
c[ 13] = 182.00 d[ 13] = 182.00
|
||||
c[ 14] = 190.00 d[ 14] = 190.00
|
||||
c[ 15] = 184.00 d[ 15] = 184.00
|
||||
c[ 16] = 163.00 d[ 16] = 163.00
|
||||
c[ 17] = 126.00 d[ 17] = 126.00
|
||||
c[ 18] = 72.00 d[ 18] = 72.00
|
||||
\endverbatim
|
||||
|
||||
\author Бахурин Сергей www.dsplib.org
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*! ****************************************************************************
|
||||
\ingroup FILTER_CONV_GROUP
|
||||
\fn int conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
|
||||
|
|
357
dspl/src/conv.c
357
dspl/src/conv.c
|
@ -218,18 +218,125 @@ int DSPL_API conv_cmplx(complex_t* a, int na, complex_t* b,
|
|||
free(t);
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
\ingroup FILTER_CONV_GROUP
|
||||
\fn int conv_fft(double* a, int na, double* b, int nb,
|
||||
fft_t* pfft, int nfft, double* c)
|
||||
\brief Real vectors fast linear convolution by using fast Fourier
|
||||
transform algorithms
|
||||
|
||||
Function convolves two real vectors \f$ c = a * b\f$ length `na` and `nb`
|
||||
in the frequency domain by using FFT algorithms. This approach provide
|
||||
high-performance convolution which increases with `na` and `nb` increasing.
|
||||
The output convolution is a vector `c` with length equal to `na + nb - 1`.
|
||||
|
||||
\param[in] a Pointer to the first vector `a`.<BR>
|
||||
Vector size is `[na x 1]`.<BR><BR>
|
||||
|
||||
\param[in] na Size of the first vector `a`.<BR><BR>
|
||||
|
||||
\param[in] b Pointer to the second vector `b`.<BR>
|
||||
Vector size is `[nb x 1]`.<BR><BR>
|
||||
|
||||
\param[in] nb Size of the second vector `b`.<BR><BR>
|
||||
|
||||
\param[in] pfft Pointer to the structure `fft_t`.<BR>
|
||||
Function changes `fft_t` structure fields so `fft_t` must
|
||||
be clear before program returns.<BR><BR>
|
||||
|
||||
\param[in] nfft FFT size. <BR>
|
||||
This parameter set which FFT size will be used
|
||||
for overlapped frequency domain convolution.<BR>
|
||||
FFT size must be more of minimal `na` and `nb` value.
|
||||
For example if `na = 10`, `nb = 4` then `nfft` parameter must
|
||||
be more than 4. <BR>
|
||||
|
||||
\param[out] c Pointer to the convolution output vector \f$ c = a * b\f$.<BR>
|
||||
Vector size is `[na + nb - 1 x 1]`.<BR>
|
||||
Memory must be allocated.<BR><BR>
|
||||
|
||||
\return `RES_OK` if convolution is calculated successfully.<BR>
|
||||
Else \ref ERROR_CODE_GROUP "code error". <BR><BR>
|
||||
|
||||
Example:
|
||||
\include conv_fft_test.c
|
||||
|
||||
Program output:
|
||||
|
||||
\verbatim
|
||||
conv_fft error: 0x00000000
|
||||
conv error: 0x00000000
|
||||
c[ 0] = -0.00 d[ 0] = 0.00
|
||||
c[ 1] = -0.00 d[ 1] = 0.00
|
||||
c[ 2] = 1.00 d[ 2] = 1.00
|
||||
c[ 3] = 4.00 d[ 3] = 4.00
|
||||
c[ 4] = 10.00 d[ 4] = 10.00
|
||||
c[ 5] = 20.00 d[ 5] = 20.00
|
||||
c[ 6] = 35.00 d[ 6] = 35.00
|
||||
c[ 7] = 56.00 d[ 7] = 56.00
|
||||
c[ 8] = 77.00 d[ 8] = 77.00
|
||||
c[ 9] = 98.00 d[ 9] = 98.00
|
||||
c[ 10] = 119.00 d[ 10] = 119.00
|
||||
c[ 11] = 140.00 d[ 11] = 140.00
|
||||
c[ 12] = 161.00 d[ 12] = 161.00
|
||||
c[ 13] = 182.00 d[ 13] = 182.00
|
||||
c[ 14] = 190.00 d[ 14] = 190.00
|
||||
c[ 15] = 184.00 d[ 15] = 184.00
|
||||
c[ 16] = 163.00 d[ 16] = 163.00
|
||||
c[ 17] = 126.00 d[ 17] = 126.00
|
||||
c[ 18] = 72.00 d[ 18] = 72.00
|
||||
\endverbatim
|
||||
|
||||
\author Sergey Bakhurin www.dsplib.org
|
||||
*******************************************************************************/
|
||||
int DSPL_API conv_fft(double* a, int na, double* b, int nb,
|
||||
fft_t* pfft, int nfft, double* c)
|
||||
{
|
||||
complex_t *pa = NULL, *pb = NULL, *pc = NULL;
|
||||
int err;
|
||||
|
||||
if(!a || !b || !c || !pfft)
|
||||
return ERROR_PTR;
|
||||
if(na<1 || nb < 1)
|
||||
return ERROR_SIZE;
|
||||
if(nfft<2)
|
||||
return ERROR_FFT_SIZE;
|
||||
|
||||
pa = (complex_t*) malloc(na*sizeof(complex_t));
|
||||
pb = (complex_t*) malloc(nb*sizeof(complex_t));
|
||||
pc = (complex_t*) malloc((na+nb-1)*sizeof(complex_t));
|
||||
|
||||
re2cmplx(a, na, pa);
|
||||
re2cmplx(b, nb, pb);
|
||||
|
||||
err = conv_fft_cmplx(pa, na, pb, nb, pfft, nfft, pc);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
|
||||
err = cmplx2re(pc, na+nb-1, c, NULL);
|
||||
|
||||
exit_label:
|
||||
if(pa) free(pa);
|
||||
if(pb) free(pb);
|
||||
if(pc) free(pc);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
\ingroup FILTER_CONV_GROUP
|
||||
\fn int conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
|
||||
fft_t* pfft, complex_t* c)
|
||||
fft_t* pfft, int nfft, complex_t* c)
|
||||
\brief Complex vectors fast linear convolution by using fast Fourier
|
||||
transform algorithms
|
||||
|
||||
|
@ -299,7 +406,7 @@ int DSPL_API conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
|
|||
fft_t* pfft, int nfft, complex_t* c)
|
||||
{
|
||||
|
||||
int La, Lb, Lc, Nz, n, shift, ind, err;
|
||||
int La, Lb, Lc, Nz, n, p0, p1, ind, err;
|
||||
complex_t *pa, *pb;
|
||||
complex_t *pt, *pA, *pB, *pC;
|
||||
|
||||
|
@ -312,7 +419,7 @@ int DSPL_API conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
|
|||
{
|
||||
La = na;
|
||||
Lb = nb;
|
||||
pa = a;
|
||||
pa = a;
|
||||
pb = b;
|
||||
}
|
||||
else
|
||||
|
@ -328,77 +435,68 @@ int DSPL_API conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
|
|||
|
||||
if(Nz <= 0)
|
||||
return ERROR_FFT_SIZE;
|
||||
|
||||
|
||||
|
||||
pt = (complex_t*)malloc(nfft*sizeof(complex_t));
|
||||
pB = (complex_t*)malloc(nfft*sizeof(complex_t));
|
||||
pA = (complex_t*)malloc(nfft*sizeof(complex_t));
|
||||
pC = (complex_t*)malloc(nfft*sizeof(complex_t));
|
||||
|
||||
|
||||
memset(pt, 0, nfft*sizeof(complex_t));
|
||||
memcpy(pt+Nz, pb, Lb*sizeof(complex_t));
|
||||
|
||||
|
||||
err = fft_cmplx(pt, nfft, pfft, pB);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
|
||||
shift = -Lb;
|
||||
p0 = -Lb;
|
||||
p1 = p0 + nfft;
|
||||
ind = 0;
|
||||
while(shift + nfft < La)
|
||||
while(ind < Lc)
|
||||
{
|
||||
if(shift < 0)
|
||||
if(p0 >=0)
|
||||
{
|
||||
memset(pt, 0, nfft*sizeof(complex_t));
|
||||
memcpy(pt-shift, pa, (nfft+shift)*sizeof(complex_t));
|
||||
|
||||
err = fft_cmplx(pt, nfft, pfft, pA);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
if(p1 < La)
|
||||
err = fft_cmplx(pa + p0, nfft, pfft, pA);
|
||||
else
|
||||
{
|
||||
memset(pt, 0, nfft*sizeof(complex_t));
|
||||
memcpy(pt, pa+p0, (nfft+La-p1)*sizeof(complex_t));
|
||||
err = fft_cmplx(pt, nfft, pfft, pA);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = fft_cmplx(pa+shift, nfft, pfft, pA);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
memset(pt, 0, nfft*sizeof(complex_t));
|
||||
if(p1 < La)
|
||||
memcpy(pt - p0, pa, (nfft+p0)*sizeof(complex_t));
|
||||
else
|
||||
memcpy(pt - p0, pa, La * sizeof(complex_t));
|
||||
err = fft_cmplx(pt, nfft, pfft, pA);
|
||||
}
|
||||
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
|
||||
for(n = 0; n < nfft; n++)
|
||||
{
|
||||
RE(pC[n]) = CMRE(pA[n], pB[n]);
|
||||
IM(pC[n]) = CMIM(pA[n], pB[n]);
|
||||
}
|
||||
|
||||
err = ifft_cmplx(pC, nfft, pfft, c+ind);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
|
||||
shift += Nz;
|
||||
ind += Nz;
|
||||
}
|
||||
|
||||
while(ind <= Lc)
|
||||
{
|
||||
memset(pt, 0, nfft*sizeof(complex_t));
|
||||
|
||||
if(shift>=0)
|
||||
memcpy(pt, pa + shift, (La-shift)*sizeof(complex_t));
|
||||
|
||||
|
||||
if(ind+nfft < Lc)
|
||||
err = ifft_cmplx(pC, nfft, pfft, c+ind);
|
||||
else
|
||||
memcpy(pt+Lb, pa, La*sizeof(complex_t));
|
||||
|
||||
err = fft_cmplx(pt, nfft, pfft, pA);
|
||||
{
|
||||
err = ifft_cmplx(pC, nfft, pfft, pt);
|
||||
memcpy(c+ind, pt, (Lc-ind)*sizeof(complex_t));
|
||||
}
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
|
||||
for(n = 0; n < nfft; n++)
|
||||
{
|
||||
RE(pC[n]) = CMRE(pA[n], pB[n]);
|
||||
IM(pC[n]) = CMIM(pA[n], pB[n]);
|
||||
}
|
||||
|
||||
err = ifft_cmplx(pC, nfft, pfft, pt);
|
||||
memcpy(c+ind, pt, (Lc-ind)*sizeof(complex_t));
|
||||
shift += Nz;
|
||||
ind += Nz;
|
||||
p0 += Nz;
|
||||
p1 += Nz;
|
||||
ind += Nz;
|
||||
}
|
||||
|
||||
exit_label:
|
||||
|
@ -410,167 +508,6 @@ exit_label:
|
|||
return err;
|
||||
}
|
||||
|
||||
/*int DSPL_API conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
|
||||
fft_t* pfft, complex_t* c)
|
||||
{
|
||||
complex_t *pa = NULL;
|
||||
complex_t *pb = NULL;
|
||||
complex_t *pc = NULL;
|
||||
complex_t *pA = NULL;
|
||||
complex_t *pB = NULL;
|
||||
complex_t *pC = NULL;
|
||||
|
||||
int nfft, nfft2, n, npos, err;
|
||||
int ma, mb;
|
||||
complex_t *ta, *tb;
|
||||
|
||||
if(!a || !b || !c)
|
||||
return ERROR_PTR;
|
||||
if(na < 1 || nb < 1)
|
||||
return ERROR_SIZE;
|
||||
|
||||
|
||||
if(na > nb)
|
||||
{
|
||||
ma = na;
|
||||
mb = nb;
|
||||
ta = a;
|
||||
tb = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
ma = nb;
|
||||
mb = na;
|
||||
ta = b;
|
||||
tb = a;
|
||||
}
|
||||
if(ma > 2*mb)
|
||||
{
|
||||
nfft = 4;
|
||||
n = mb-1;
|
||||
while(n>>=1)
|
||||
nfft <<= 1;
|
||||
nfft2 = nfft >> 1;
|
||||
|
||||
pa = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pb = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pc = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pA = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pB = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pC = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
|
||||
npos = -nfft2;
|
||||
memset(pa, 0, nfft*sizeof(complex_t));
|
||||
memset(pb, 0, nfft*sizeof(complex_t));
|
||||
|
||||
memcpy(pa + nfft2, ta, nfft2 * sizeof(complex_t));
|
||||
memcpy(pb, tb, mb * sizeof(complex_t));
|
||||
|
||||
err = fft_cmplx(pa, nfft, pfft, pA);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
|
||||
err = fft_cmplx(pb, nfft, pfft, pB);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
|
||||
for(n = 0; n < nfft; n++)
|
||||
{
|
||||
RE(pC[n]) = CMRE(pA[n], pB[n]);
|
||||
IM(pC[n]) = CMIM(pA[n], pB[n]);
|
||||
}
|
||||
|
||||
err = ifft_cmplx(pC, nfft, pfft, pc);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
|
||||
memcpy(c, pc+nfft2, nfft2*sizeof(complex_t));
|
||||
|
||||
npos = 0;
|
||||
while(npos < ma)
|
||||
{
|
||||
if(npos+nfft > ma)
|
||||
{
|
||||
memset(pa, 0, nfft * sizeof(complex_t));
|
||||
memcpy(pa, ta+npos, (ma - npos) * sizeof(complex_t));
|
||||
err = fft_cmplx(pa, nfft, pfft, pA);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
err = fft_cmplx(ta+npos, nfft, pfft, pA);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
for(n = 0; n < nfft; n++)
|
||||
{
|
||||
RE(pC[n]) = CMRE(pA[n], pB[n]);
|
||||
IM(pC[n]) = CMIM(pA[n], pB[n]);
|
||||
}
|
||||
|
||||
err = ifft_cmplx(pC, nfft, pfft, pc);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
if(npos+nfft <= ma+mb-1)
|
||||
memcpy(c+npos+nfft2, pc+nfft2,
|
||||
nfft2*sizeof(complex_t));
|
||||
else
|
||||
{
|
||||
if(ma+mb-1-npos-nfft2 > 0)
|
||||
{
|
||||
memcpy(c+npos+nfft2, pc+nfft2,(ma+mb-1-npos-nfft2)*sizeof(complex_t));
|
||||
}
|
||||
}
|
||||
npos+=nfft2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nfft = 4;
|
||||
n = ma - 1;
|
||||
while(n>>=1)
|
||||
nfft <<= 1;
|
||||
|
||||
pa = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pb = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pc = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pA = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pB = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
pC = (complex_t*)malloc(nfft * sizeof(complex_t));
|
||||
|
||||
|
||||
memset(pa, 0, nfft*sizeof(complex_t));
|
||||
memset(pb, 0, nfft*sizeof(complex_t));
|
||||
|
||||
memcpy(pa, ta, ma * sizeof(complex_t));
|
||||
memcpy(pb, tb, mb * sizeof(complex_t));
|
||||
|
||||
err = fft_cmplx(pa, nfft, pfft, pA);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
err = fft_cmplx(pb, nfft, pfft, pB);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
for(n = 0; n < nfft; n++)
|
||||
{
|
||||
RE(pC[n]) = CMRE(pA[n], pB[n]);
|
||||
IM(pC[n]) = CMIM(pA[n], pB[n]);
|
||||
}
|
||||
err = ifft_cmplx(pC, nfft, pfft, pc);
|
||||
if(err != RES_OK)
|
||||
goto exit_label;
|
||||
memcpy(c, pc, (ma+mb-1)*sizeof(complex_t));
|
||||
}
|
||||
exit_label:
|
||||
if(pa) free(pa);
|
||||
if(pb) free(pb);
|
||||
if(pc) free(pc);
|
||||
if(pA) free(pA);
|
||||
if(pB) free(pB);
|
||||
if(pB) free(pC);
|
||||
|
||||
return err;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "dspl.h"
|
||||
|
||||
#define N 13
|
||||
#define M 7
|
||||
int main()
|
||||
{
|
||||
void* handle; // DSPL handle
|
||||
handle = dspl_load(); // Load DSPL function
|
||||
double a[N], b[M], c[N+M-1], d[N+M-1];
|
||||
fft_t pfft;
|
||||
int n, err;
|
||||
|
||||
linspace(0, N, N, DSPL_PERIODIC, a);
|
||||
linspace(0, M, M, DSPL_PERIODIC, b);
|
||||
memset(&pfft, 0, sizeof(fft_t));
|
||||
|
||||
err = conv_fft(a, N, b, M, &pfft, 16, c);
|
||||
printf("conv_fft error: 0x%.8x\n", err);
|
||||
|
||||
err = conv(a, N, b, M, d);
|
||||
printf("conv error: 0x%.8x\n", err);
|
||||
|
||||
// print result
|
||||
for(n = 0; n < N+M-1; n++)
|
||||
printf("c[%3d] = %9.2f d[%3d] = %9.2f\n", n, c[n], n, d[n]);
|
||||
|
||||
fft_free(&pfft); // free fft structure memory
|
||||
dspl_free(handle); // free dspl handle
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -52,6 +52,7 @@ 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 ;
|
||||
|
@ -215,6 +216,7 @@ void* dspl_load()
|
|||
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);
|
||||
|
|
|
@ -344,6 +344,14 @@ DECLARE_FUNC(int, conv_cmplx, complex_t*
|
|||
COMMA int
|
||||
COMMA complex_t*);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, conv_fft, double* a
|
||||
COMMA int na
|
||||
COMMA double* b
|
||||
COMMA int nb
|
||||
COMMA fft_t* pfft
|
||||
COMMA int nfft
|
||||
COMMA double* c);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, conv_fft_cmplx, complex_t* a
|
||||
COMMA int na
|
||||
COMMA complex_t* b
|
||||
|
|
|
@ -52,6 +52,7 @@ 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 ;
|
||||
|
@ -215,6 +216,7 @@ void* dspl_load()
|
|||
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);
|
||||
|
|
|
@ -344,6 +344,14 @@ DECLARE_FUNC(int, conv_cmplx, complex_t*
|
|||
COMMA int
|
||||
COMMA complex_t*);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, conv_fft, double* a
|
||||
COMMA int na
|
||||
COMMA double* b
|
||||
COMMA int nb
|
||||
COMMA fft_t* pfft
|
||||
COMMA int nfft
|
||||
COMMA double* c);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, conv_fft_cmplx, complex_t* a
|
||||
COMMA int na
|
||||
COMMA complex_t* b
|
||||
|
|
Ładowanie…
Reference in New Issue