Reorder the result so that it matches the pattern of tf.signal.rfft2d. In tf.signal.fft2d the frequency matrix of a 4x4 input is [[F(0, 0), F(0, 1/4), F(0, 2/4)], [F(1/4, 0), F(1/4, 1/4), F(1/4, 2/4)], [F(2/4, 0), F(2/4, 1/4), F(2/4, 2/4)], [F(3/4, 0), F(3/4, 1/4), F(3/4, 2/4)]] While in rdft2d, the frequency matrix of a 4x4 input is [[(F(0, 0), F(0, -2/4)) F(0, -1/4), 0], [ F(-1/4, 0),
| 215 | // Real(-3/4, 0) = Real(1/4, 0) = Real(-1/4, 0) |
| 216 | // Img(-3/4, 0) = Img(1/4, 0) = -Img(-1/4, 0) |
| 217 | void Rfft2dReorder(int fft_height, int fft_width, double** fft_input_output) { |
| 218 | int fft_height_half; |
| 219 | gemmlowp::ScopedProfilingLabel label("Rfft2dReorder"); |
| 220 | double real, img; |
| 221 | |
| 222 | fft_height_half = fft_height >> 1; |
| 223 | // Use 4x4 input as an example, reorder the frequency matrix from |
| 224 | // [[(F(0, 0), F(0, -2/4)) F(0, -1/4), 0], |
| 225 | // [ F(-1/4, 0), F(-1/4, -1/4), 0], |
| 226 | // [(F(-2/4, 0),F(-2/4, -2/4)), F(-2/4, -1/4), 0], |
| 227 | // [ j*F(-3/4, -2/4), F(-3/4, -1/4), 0]] |
| 228 | // to |
| 229 | // [[F(0, 0), F(0, -1/4), F(0, -2/4)], |
| 230 | // [F(-1/4, 0), F(-1/4, -1/4), F(-1/4, -2/4)], |
| 231 | // [F(-2/4, 0), F(-2/4, -1/4), F(-2/4, -2/4)], |
| 232 | // [F(-3/4, 0), F(-3/4, -1/4), F(-3/4, -2/4)]] |
| 233 | for (int i = fft_height_half + 1; i < fft_height; ++i) { |
| 234 | real = fft_input_output[i][0]; |
| 235 | img = fft_input_output[i][1]; |
| 236 | fft_input_output[i][fft_width] = img; |
| 237 | fft_input_output[i][fft_width + 1] = real; |
| 238 | fft_input_output[fft_height - i][fft_width] = img; |
| 239 | fft_input_output[fft_height - i][fft_width + 1] = -real; |
| 240 | fft_input_output[i][0] = fft_input_output[fft_height - i][0]; |
| 241 | fft_input_output[i][1] = -fft_input_output[fft_height - i][1]; |
| 242 | } |
| 243 | fft_input_output[0][fft_width] = fft_input_output[0][1]; |
| 244 | fft_input_output[0][fft_width + 1] = 0; |
| 245 | fft_input_output[0][1] = 0; |
| 246 | fft_input_output[fft_height_half][fft_width] = |
| 247 | fft_input_output[fft_height_half][1]; |
| 248 | fft_input_output[fft_height_half][fft_width + 1] = 0; |
| 249 | fft_input_output[fft_height_half][1] = 0; |
| 250 | |
| 251 | // Reorder the frequency matrix from |
| 252 | // [[F(0, 0), F(0, -1/4), F(0, -2/4)], |
| 253 | // [F(-1/4, 0), F(-1/4, -1/4), F(-1/4, -2/4)], |
| 254 | // [F(-2/4, 0), F(-2/4, -1/4), F(-2/4, -2/4)], |
| 255 | // [F(-3/4, 0), F(-3/4, -1/4), F(-3/4, -2/4)]] |
| 256 | // to |
| 257 | // [[F(0, 0), F(0, 1/4), F(0, 2/4)], |
| 258 | // [F(1/4, 0), F(1/4, 1/4), F(1/4, 2/4)], |
| 259 | // [F(2/4, 0), F(2/4, 1/4), F(2/4, 2/4)], |
| 260 | // [F(3/4, 0), F(3/4, 1/4), F(3/4, 2/4)]] |
| 261 | for (int i = 0; i < fft_height; ++i) { |
| 262 | for (int j = 1; j < fft_width + 2; j += 2) { |
| 263 | fft_input_output[i][j] = -fft_input_output[i][j]; |
| 264 | } |
| 265 | } |
| 266 | } |
| 267 | |
| 268 | void Rfft2dImpl(int fft_height, int fft_width, double** fft_input_output, |
| 269 | int* fft_integer_working_area_data, |