File: dst.c

package info (click to toggle)
python-ltfatpy 1.1.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 41,412 kB
  • sloc: ansic: 8,546; python: 6,470; makefile: 15
file content (114 lines) | stat: -rw-r--r-- 2,674 bytes parent folder | download | duplicates (5)
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
/* NOT PROCESSED DIRECTLY, dst_ci.c */
#ifdef LTFAT_TYPE

#include "ltfat.h"
#include "ltfat_types.h"

LTFAT_EXTERN LTFAT_FFTW(plan)
LTFAT_NAME(dst_init)( const ltfatInt L, const ltfatInt W, LTFAT_TYPE *cout,
                      const dst_kind kind)
{
    LTFAT_FFTW(iodim) dims, howmanydims;
    LTFAT_FFTW(plan) p;

#ifdef LTFAT_COMPLEXTYPE
    dims.n = L;
    dims.is = 2;
    dims.os = 2;

    howmanydims.n = W;
    howmanydims.is = 2*L;
    howmanydims.os = 2*L;

    unsigned flag = FFTW_ESTIMATE | FFTW_UNALIGNED;
#else
    dims.n = L;
    dims.is = 1;
    dims.os = 1;

    howmanydims.n = W;
    howmanydims.is = L;
    howmanydims.os = L;

    unsigned flag = FFTW_ESTIMATE;
#endif

    LTFAT_FFTW(r2r_kind) kindFftw = (LTFAT_FFTW(r2r_kind)) kind;
    p = LTFAT_FFTW(plan_guru_r2r)(1, &dims,
                                  1, &howmanydims,
                                  (LTFAT_REAL*)cout, (LTFAT_REAL*)cout,
                                  &kindFftw, flag);

    return p;
}


// f and cout cannot be equal, because creating plan can tamper with the array
LTFAT_EXTERN void
LTFAT_NAME(dst)(const LTFAT_TYPE *f, const ltfatInt L, const ltfatInt W,
                LTFAT_TYPE *cout, const dst_kind kind)
{
    LTFAT_FFTW(plan) p = LTFAT_NAME(dst_init)( L, W, cout, kind);

    LTFAT_NAME(dst_execute)(p, f,  L,  W, cout, kind);

    LTFAT_FFTW(destroy_plan)(p);
}

// f and cout can be equal, provided plan was already created
LTFAT_EXTERN void
LTFAT_NAME(dst_execute)(LTFAT_FFTW(plan) p, const LTFAT_TYPE *f,
                        const ltfatInt L, const ltfatInt W, LTFAT_TYPE *cout,
                        const dst_kind kind)
{
    // Copy input to the output
    if(cout!=f)
        memcpy(cout,f,L*W*sizeof*f);

    if(L==1)
        return;

    ltfatInt N = 2*L;
    LTFAT_REAL sqrt2 = (LTFAT_REAL) sqrt(2.0);
    LTFAT_REAL postScale = (LTFAT_REAL) 1.0/sqrt2;
    LTFAT_REAL scale = (LTFAT_REAL) sqrt2*(1.0/(double)N)*sqrt((double)L);

    if(kind==DSTIII)
    {
        for(ltfatInt ii=0; ii<W; ii++)
        {
            cout[(ii+1)*L-1] *= sqrt2;
        }
    }

    if(kind==DSTI)
    {
        N += 2;
        scale = (LTFAT_REAL) sqrt2*(1.0/((double)N))*sqrt((double)L+1);
    }

    LTFAT_REAL* c_r = (LTFAT_REAL*)cout;

    LTFAT_FFTW(execute_r2r)(p,c_r,c_r);
#ifdef LTFAT_COMPLEXTYPE
    LTFAT_REAL* c_i = c_r+1;
    LTFAT_FFTW(execute_r2r)(p,c_i,c_i);
#endif

    // Post-scaling
    for(ltfatInt ii=0; ii<L*W; ii++)
    {
        cout[ii] *= scale;
    }

    if(kind==DSTII)
    {
        // Scale AC component
        for(ltfatInt ii=0; ii<W; ii++)
        {
            cout[(ii+1)*L-1] *= postScale;
        }
    }
}

#endif