1import os.path
2import numpy as np
3import itertools
4import Tools
5import scipy.fftpack
6
7# Those patterns are used for tests and benchmarks.
8# For tests, there is the need to add tests for saturation
9
10
11FFTSIZES=[16,32,64,128,256,512,1024,2048,4096]
12SINES=[0.25,0.5,0.9]
13NOISES=[0.1,0.4]
14
15
16def asReal(a):
17    #return(a.view(dtype=np.float64))
18    return(a.reshape(np.size(a)).view(dtype=np.float64))
19
20def noiseSignal(nb):
21    return(np.random.randn(nb))
22
23def sineSignal(freqRatio,nb):
24    fc = nb / 2.0
25    f = freqRatio*fc
26    time = np.arange(0,nb)
27    return(np.sin(2 * np.pi * f *  time/nb))
28
29def noisySineSignal(noiseAmp,r,nb):
30    return(noiseAmp*noiseSignal(nb) + r*sineSignal(0.25,nb))
31
32def stepSignal(r,nb):
33   n = int(nb/2)
34   return(np.concatenate((np.zeros(n), r*np.ones(n))))
35
36def writeFFTForSignal(config,sig,scaling,i,j,nb,signame):
37    fft=scipy.fftpack.fft(sig)
38    ifft = np.copy(fft)
39    if scaling:
40        fft = np.array([x/2**scaling[j] for x in fft])
41    config.writeInput(i, asReal(sig),"ComplexInputSamples_%s_%d_" % (signame,nb))
42    config.writeInput(i, asReal(fft),"ComplexFFTSamples_%s_%d_" % (signame,nb))
43    config.writeInput(i, asReal(fft),"ComplexInputIFFTSamples_%s_%d_" % (signame,nb))
44
45def writeRFFTForSignal(config,sig,scaling,i,j,nb,signame):
46    rfft=scipy.fftpack.rfft(sig)
47
48    # Changed for f32 and f64 to reproduce CMSIS behavior.
49    if not scaling:
50       rfft=np.insert(rfft, 1, rfft[-1])
51       rfft[-1]=0.0
52       rifft = np.copy(rfft)
53    else:
54        rfft=np.insert(rfft, 1, 0.0)
55        rifft = np.copy(rfft)
56
57
58    if scaling:
59        rfft = np.array([x/2**scaling[j] for x in rfft])
60        rifft = np.hstack((rfft,rfft))
61        rifft[rfft.size] = 0.0
62        rifft[rfft.size+1:2*rfft.size:2] = np.flip(rfft[0:rfft.size-1:2])
63        rifft[rfft.size+2:2*rfft.size:2] = -np.flip(rfft[1:rfft.size-1:2])
64        rifft[2*rfft.size-2] = 0
65        rifft[2*rfft.size-1] = 0
66
67    config.writeInput(i, (sig),"RealInputSamples_%s_%d_" % (signame,nb))
68    config.writeInput(i, (rfft),"RealFFTSamples_%s_%d_" % (signame,nb))
69    config.writeInput(i, (rifft),"RealInputIFFTSamples_%s_%d_" % (signame,nb))
70
71
72def writeTests(configs):
73    i = 1
74
75    # Write FFT tests for sinusoid
76    j = 0
77    for nb in FFTSIZES:
78        sig = noisySineSignal(0.05,0.7,nb)
79        sigc = np.array([complex(x) for x in sig])
80        for config,scaling in configs:
81            writeFFTForSignal(config,sigc,scaling,i,j,nb,"Noisy")
82            writeRFFTForSignal(config,sig,scaling,i,j,nb,"Noisy")
83        i = i + 1
84        j = j + 1
85
86    # Write FFT tests for step
87    j = 0
88    for nb in FFTSIZES:
89        sig = stepSignal(0.9,nb)
90        sigc = np.array([complex(x) for x in sig])
91        for config,scaling in configs:
92            writeFFTForSignal(config,sigc,scaling,i,j,nb,"Step")
93            writeRFFTForSignal(config,sig,scaling,i,j,nb,"Step")
94        i = i + 1
95        j = j + 1
96
97    # Used for benchmarks
98    data1=np.random.randn(512)
99    data1 = Tools.normalize(data1)
100    for config,scaling in configs:
101        config.writeInput(i, data1,"RealInputSamples" )
102
103
104def generatePatterns():
105    PATTERNDIR = os.path.join("Patterns","DSP","Transform","Transform")
106    PARAMDIR = os.path.join("Parameters","DSP","Transform","Transform")
107
108    configf64=Tools.Config(PATTERNDIR,PARAMDIR,"f64")
109    configf32=Tools.Config(PATTERNDIR,PARAMDIR,"f32")
110    configf16=Tools.Config(PATTERNDIR,PARAMDIR,"f16")
111    configq31=Tools.Config(PATTERNDIR,PARAMDIR,"q31")
112    configq15=Tools.Config(PATTERNDIR,PARAMDIR,"q15")
113
114
115    scalings = [4,5,6,7,8,9,10,11,12]
116    writeTests([(configf64,None),
117        (configf32,None),
118        (configf16,None)
119        ,(configq31,scalings)
120        ,(configq15,scalings)])
121
122
123
124
125if __name__ == '__main__':
126  generatePatterns()