1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#include "ltfat.h"
#include "ltfat_types.h"
LTFAT_EXTERN LTFAT_NAME(dgt_shearola_plan)
LTFAT_NAME(dgt_shearola_init)(const LTFAT_COMPLEX *g, const ltfatInt gl,
const ltfatInt W, const ltfatInt a, const ltfatInt M,
const ltfatInt s0, const ltfatInt s1, const ltfatInt br,
const ltfatInt bl,
unsigned flags)
{
LTFAT_NAME(dgt_shearola_plan) plan;
plan.bl = bl;
plan.gl = gl;
plan.W = W;
const ltfatInt Lext = bl+gl;
const ltfatInt Nblocke = Lext/a;
plan.buf = ltfat_malloc(Lext*W*sizeof(LTFAT_COMPLEX));
plan.gext = ltfat_malloc(Lext*sizeof(LTFAT_COMPLEX));
plan.cbuf = ltfat_malloc(M*Nblocke*W*sizeof(LTFAT_COMPLEX));
LTFAT_NAME(fir2long_c)(g, gl, Lext, plan.gext);
/* Zero the last part of the buffer, it will always be zero. */
for (ltfatInt w=0; w<W; w++)
{
for (ltfatInt jj=bl; jj<Lext; jj++)
{
plan.buf[jj+w*Lext] = (LTFAT_COMPLEX) 0.0;
}
}
plan.plan =
LTFAT_NAME(dgt_shear_init)((const LTFAT_COMPLEX*)plan.buf,
(const LTFAT_COMPLEX*)plan.gext,
Lext, W, a, M,
s0, s1, br,
plan.cbuf, flags);
return (plan);
}
LTFAT_EXTERN void
LTFAT_NAME(dgt_shearola_execute)(const LTFAT_NAME(dgt_shearola_plan) plan,
const LTFAT_COMPLEX *f, const ltfatInt L,
LTFAT_COMPLEX *cout)
{
const ltfatInt bl = plan.bl;
const ltfatInt gl = plan.gl;
const ltfatInt a = plan.plan.a;
const ltfatInt M = plan.plan.M;
const ltfatInt N = L/a;
const ltfatInt Lext = bl+gl;
const ltfatInt Nb = L/bl;
const ltfatInt b2 = gl/a/2;
const ltfatInt Nblock = bl/a;
const ltfatInt Nblocke = Lext/a;
const ltfatInt W = plan.W;
/* Zero the output array, as we will be adding to it */
for (ltfatInt ii=0; ii<M*N*W; ii++)
{
cout[ii] = (LTFAT_COMPLEX) 0.0;
}
for (ltfatInt ii=0; ii<Nb; ii++)
{
ltfatInt s_ii;
/* Copy to working buffer. */
for (ltfatInt w=0; w<W; w++)
{
memcpy(plan.buf+Lext*w,f+ii*bl+w*L,sizeof(LTFAT_COMPLEX)*bl);
}
/* Execute the short DGT */
LTFAT_NAME(dgt_shear_execute)(plan.plan);
/* Place the results */
for (ltfatInt w=0; w<W; w++)
{
/* Place large block */
LTFAT_COMPLEX *cout_p = cout + ii*M*Nblock+w*M*N ;
LTFAT_COMPLEX *cbuf_p = plan.cbuf + w*M*Nblocke;
for (ltfatInt m=0; m<M; m++)
{
for (ltfatInt n=0; n<Nblock; n++)
{
cout_p[m+n*M] += cbuf_p[m+n*M];
}
}
/* Small block + */
s_ii=positiverem(ii+1,Nb);
cout_p = cout + s_ii*M*Nblock+w*M*N ;
cbuf_p = plan.cbuf + M*Nblock+w*M*Nblocke;
for (ltfatInt m=0; m<M; m++)
{
for (ltfatInt n=0; n<b2; n++)
{
cout_p[m+n*M] += cbuf_p[m+n*M];
}
}
/* Small block - */
s_ii=positiverem(ii-1,Nb)+1;
cout_p = cout + M*(s_ii*Nblock-b2)+w*M*N ;
cbuf_p = plan.cbuf + M*(Nblock+b2) +w*M*Nblocke;
for (ltfatInt m=0; m<M; m++)
{
for (ltfatInt n=0; n<b2; n++)
{
cout_p[m+n*M] += cbuf_p[m+n*M];
}
}
}
}
}
LTFAT_EXTERN void
LTFAT_NAME(dgt_shearola_done)(LTFAT_NAME(dgt_shearola_plan) plan)
{
LTFAT_NAME(dgt_shear_done)(plan.plan);
/* ltfat_free(plan.cbuf); */
LTFAT_SAFEFREEALL(plan.gext,plan.buf);
}
LTFAT_EXTERN void
LTFAT_NAME(dgt_shearola)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt a, const ltfatInt M,
const ltfatInt s0, const ltfatInt s1, const ltfatInt br, const ltfatInt bl,
LTFAT_COMPLEX *cout)
{
LTFAT_NAME(dgt_shearola_plan) plan = LTFAT_NAME(dgt_shearola_init)(
g,gl,W,a,M,s0,s1,br,bl,FFTW_ESTIMATE);
LTFAT_NAME(dgt_shearola_execute)(plan,f,L,cout);
LTFAT_NAME(dgt_shearola_done)(plan);
}
|