You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// If the number of radix factors is `1`, the only twiddle factor we need is `W_N^0 = 1`, which the main transform kernels already hard-code, so nothing to pre-compute...
112
+
if(nf-1===0){
113
+
return;
114
+
}
112
115
// Compute the master angular step (i.e., the basic angle that generates all twiddles):
113
-
argh=TWO_PI/n;
114
-
115
-
// Initialize the index into the twiddle factor array:
116
-
is=0;
116
+
argh=TWO_PI/N;
117
117
118
-
// Compute the number of factors minus one:
119
-
nfm1=nf-1;
118
+
// Define the location of the first sine term we want to compute:
119
+
im=1;
120
120
121
121
// Initialize a running product of factors already processed:
122
122
l1=1;
123
123
124
-
// If the number of radix factors is `1`, the only twiddle factor we need is `W_N^0 = 1`, which the main transform kernels already hard-code, so nothing to pre-compute...
125
-
if(nfm1===0){
126
-
return;
127
-
}
128
-
// Generate twiddle factors for each radix factor...
129
-
for(k1=0;k1<nfm1;k1++){
130
-
// Resolve the next radix factor (C code: ifac[k1+2] with 1-based, JS: ifac[k1+2] with 0-based):
131
-
ip=ifac[offsetF+((k1+2)*strideF)];
124
+
// Compute the index of the first radix factor:
125
+
fidx=offsetF+(2*strideF);
132
126
133
-
// Initialize a running offset used to step the angle:
134
-
ld=0;
127
+
// Compute the stride length for each cosine/sine pair:
128
+
st=2*strideT;
129
+
130
+
// Generate twiddle factors...
131
+
for(k=0;k<nf-1;k++){
132
+
// Resolve the next radix factor:
133
+
factor=factors[fidx];
135
134
136
135
// Compute the length of the transform after including the current radix:
137
-
l2=l1*ip;
136
+
l2=factor*l1;
138
137
139
-
// Compute the number of data points in each sub-transform:
140
-
ido=floor(n/l2);
138
+
// Compute the number of the "butterfly wings" (at this stage, the data is viewed as a `factor`-point transform of sub-vectors of length `l1`; `M` describes how many such vectors fit in the full array of length `N`):
139
+
M=floor(N/l2);
141
140
142
-
// Compute the number of iterations for the inner loop:
143
-
ipm=ip-1;
141
+
// Initialize a running offset used to step the angle:
142
+
ld=0;
144
143
145
144
// Iterate over each butterfly column within the current radix...
146
-
for(j=0;j<ipm;j++){
145
+
for(j=1;j<factor;j++){
147
146
// Advance to the next column:
148
147
ld+=l1;
149
148
150
-
// Initialize the index into the twiddle factor array:
151
-
i=is;
152
-
153
149
// Compute the angle step for this column:
154
-
argld=ld*argh;
150
+
argld=ld*argh;// 2π ⋅ j ⋅ li / N, which is the j-th column's base angle
155
151
156
-
// Initialize the harmonic counter:
157
-
fi=0.0;
152
+
// Initialize a counter which counts from `1` to `(M/2)-1` (i.e., all non-trivial harmonics):
153
+
fi=1.0;
158
154
159
-
// Iterate over each non-trivial harmonic in the column...
160
-
for(ii=2;ii<ido;ii+=2){
161
-
// Advance the index by 2 (for cosine and sine):
162
-
i+=2;
155
+
// Compute the index of the sine term:
156
+
it=offsetT+((im+1)*strideT);
163
157
164
-
// Update the harmonic counter:
165
-
fi+=1.0;
158
+
// Iterate over each non-trivial harmonic in the column (note: we skip the `m=0` and `m=1` (i.e., the first cosine/sine pair, the first harmonic `W_N^0 = cos(0) + j sin(0) = 1 + j⋅0` is trivial and hard-coded by transform kernels)...
159
+
for(m=2;m<M;m+=2){
160
+
// Compute `(cos(fi*argld), sin(fi*argld))`:
161
+
sincos(fi*argld,twiddles,-strideT,it);// note: `sincos` returns the sine and cosine, in that order, so we need to use a negative stride when assigning the values to `twiddles` to ensure that cosine comes before sine in the twiddles table
166
162
167
-
// Compute the angle for this harmonic:
168
-
arg=fi*argld;
163
+
// Update for the next harmonic:
164
+
fi+=1.0;
169
165
170
-
// Store the cosine and sine values:
171
-
wa[offsetW+((i-1)*strideW)]=cos(arg);
172
-
wa[offsetW+(i*strideW)]=sin(arg);
166
+
// Resolve the index of the next sine term:
167
+
it+=st;
173
168
}
174
-
// Advance the index by the number of data points in each sub-transform:
175
-
is+=ido;
169
+
// Advance `im` by the size of the current block, skipping the cosine/sine pairs we have just written:
170
+
im+=M;
176
171
}
177
172
// Update the running product of factors already processed:
0 commit comments