kopia lustrzana https://github.com/Dsplib/libdspl-2.0
fixed conv_fft_cmplx
rodzic
8fd70fa80a
commit
c3a60ae256
125
dspl/src/conv.c
125
dspl/src/conv.c
|
|
@ -133,11 +133,34 @@ int DSPL_API conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
|
||||||
complex_t *pB = NULL;
|
complex_t *pB = NULL;
|
||||||
complex_t *pC = NULL;
|
complex_t *pC = NULL;
|
||||||
|
|
||||||
int nfft, nfft2, n, npos;
|
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;
|
nfft = 4;
|
||||||
n = nb-1;
|
n = mb-1;
|
||||||
while(n>>=1)
|
while(n>>=1)
|
||||||
nfft <<= 1;
|
nfft <<= 1;
|
||||||
nfft2 = nfft >> 1;
|
nfft2 = nfft >> 1;
|
||||||
|
|
@ -153,50 +176,106 @@ int DSPL_API conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
|
||||||
memset(pa, 0, nfft*sizeof(complex_t));
|
memset(pa, 0, nfft*sizeof(complex_t));
|
||||||
memset(pb, 0, nfft*sizeof(complex_t));
|
memset(pb, 0, nfft*sizeof(complex_t));
|
||||||
|
|
||||||
memcpy(pa + nfft2, a, nfft2*sizeof(complex_t));
|
memcpy(pa + nfft2, ta, nfft2 * sizeof(complex_t));
|
||||||
memcpy(pb, b, nb*sizeof(complex_t));
|
memcpy(pb, tb, mb * sizeof(complex_t));
|
||||||
|
|
||||||
fft_cmplx(pa, nfft, pfft, pA);
|
err = fft_cmplx(pa, nfft, pfft, pA);
|
||||||
fft_cmplx(pb, nfft, pfft, pB);
|
if(err != RES_OK)
|
||||||
for(n = 0; n < nfft2; n++)
|
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]);
|
RE(pC[n]) = CMRE(pA[n], pB[n]);
|
||||||
IM(pC[n]) = -CMIM(pA[n], pB[n]);
|
IM(pC[n]) = CMIM(pA[n], pB[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ifft_cmplx(pC, nfft, pfft, pc);
|
err = ifft_cmplx(pC, nfft, pfft, pc);
|
||||||
|
if(err != RES_OK)
|
||||||
|
goto exit_label;
|
||||||
|
|
||||||
memcpy(c, pc+nfft2, nfft2*sizeof(complex_t));
|
memcpy(c, pc+nfft2, nfft2*sizeof(complex_t));
|
||||||
|
|
||||||
npos = 0;
|
npos = 0;
|
||||||
while(npos < na)
|
while(npos < ma)
|
||||||
{
|
{
|
||||||
if(npos+nfft > na)
|
if(npos+nfft > ma)
|
||||||
{
|
{
|
||||||
memset(pa, 0, nfft * sizeof(complex_t));
|
memset(pa, 0, nfft * sizeof(complex_t));
|
||||||
memcpy(pa, a+npos, (na - npos) * sizeof(complex_t));
|
memcpy(pa, ta+npos,
|
||||||
fft_cmplx(pa, nfft, pfft, pA);
|
(ma - npos) * sizeof(complex_t));
|
||||||
|
err = fft_cmplx(pa, nfft, pfft, pA);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fft_cmplx(a+npos, nfft, pfft, pA);
|
err = fft_cmplx(ta+npos, nfft, pfft, pA);
|
||||||
|
if(err != RES_OK)
|
||||||
for(n = 0; n < nfft2; n++)
|
goto exit_label;
|
||||||
|
for(n = 0; n < nfft; n++)
|
||||||
{
|
{
|
||||||
RE(pC[n]) = CMRE(pA[n], pB[n]);
|
RE(pC[n]) = CMRE(pA[n], pB[n]);
|
||||||
IM(pC[n]) = -CMIM(pA[n], pB[n]);
|
IM(pC[n]) = CMIM(pA[n], pB[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ifft_cmplx(pC, nfft, pfft, pc);
|
err = ifft_cmplx(pC, nfft, pfft, pc);
|
||||||
|
if(err != RES_OK)
|
||||||
if(npos+nfft <= na+nb-1)
|
goto exit_label;
|
||||||
memcpy(c+npos+nfft2, pc+nfft2, nfft2*sizeof(complex_t));
|
if(npos+nfft <= ma+mb-1)
|
||||||
|
memcpy(c+npos+nfft2, pc+nfft2,
|
||||||
|
nfft2*sizeof(complex_t));
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if(ma+mb-1-npos-nfft2 > 0)
|
||||||
{
|
{
|
||||||
memcpy(c+npos+nfft2, pc+nfft2,
|
memcpy(c+npos+nfft2, pc+nfft2,
|
||||||
(na+nb-1-npos-nfft2)*sizeof(complex_t));
|
(ma+mb-1-npos-nfft2)*sizeof(complex_t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
npos+=nfft2;
|
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(pa) free(pa);
|
||||||
if(pb) free(pb);
|
if(pb) free(pb);
|
||||||
if(pc) free(pc);
|
if(pc) free(pc);
|
||||||
|
|
@ -204,7 +283,7 @@ int DSPL_API conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
|
||||||
if(pB) free(pB);
|
if(pB) free(pB);
|
||||||
if(pB) free(pC);
|
if(pB) free(pC);
|
||||||
|
|
||||||
return RES_OK;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "dspl.h"
|
||||||
|
|
||||||
|
#define N 15
|
||||||
|
#define M 5
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
void* handle; // DSPL handle
|
||||||
|
handle = dspl_load(); // Load DSPL function
|
||||||
|
complex_t a[N], b[M], c[N+M-1];
|
||||||
|
fft_t pfft;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
linspace(0, 2*N, 2*N, DSPL_PERIODIC, (double*)a);
|
||||||
|
linspace(0, 2*M, 2*M, DSPL_PERIODIC, (double*)b);
|
||||||
|
memset(&pfft, 0, sizeof(fft_t));
|
||||||
|
|
||||||
|
conv_fft_cmplx(a, N, b, M, &pfft, c);
|
||||||
|
|
||||||
|
for(n = 0; n < N+M-1; n++)
|
||||||
|
printf("c[%3d] = %9.2f%+9.2fj\n", n, RE(c[n]), IM(c[n]));
|
||||||
|
|
||||||
|
fft_free(&pfft);
|
||||||
|
dspl_free(handle); // free dspl handle
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Ładowanie…
Reference in New Issue