@@ -2736,15 +2736,23 @@ class RFFT {
27362736 }
27372737
27382738 const int * RESTRICT kin = KINV .data ();
2739+ for (int k = 1 ; k < N / 2 ; ++k) {
2740+ const int m = kin[k];
2741+ output[k].re = work[2 *m];
2742+ output[k].im = -work[2 *m + 1 ];
2743+ }
2744+
2745+ convert_standard_complex_to_mag_phase (output);
2746+ }
2747+
2748+ void convert_standard_complex_to_mag_phase (complex_t * RESTRICT output) const {
27392749 int k = 1 ;
27402750#if BRUUN_LEVEL >= 1
27412751 for (; k + 1 < N / 2 ; k += 2 ) {
2742- const int m0 = kin[k];
2743- const int m1 = kin[k + 1 ];
2744- const double re0 = work[2 *m0];
2745- const double im0 = -work[2 *m0 + 1 ];
2746- const double re1 = work[2 *m1];
2747- const double im1 = -work[2 *m1 + 1 ];
2752+ const double re0 = output[k].re ;
2753+ const double im0 = output[k].im ;
2754+ const double re1 = output[k + 1 ].re ;
2755+ const double im1 = output[k + 1 ].im ;
27482756 const double mag0 = std::sqrt (re0 * re0 + im0 * im0);
27492757 const double mag1 = std::sqrt (re1 * re1 + im1 * im1);
27502758 double phase0;
@@ -2757,14 +2765,41 @@ class RFFT {
27572765 }
27582766#endif
27592767 for (; k < N / 2 ; ++k) {
2760- const int m = kin[k];
2761- const double re = work[2 *m];
2762- const double im = -work[2 *m + 1 ];
2768+ const double re = output[k].re ;
2769+ const double im = output[k].im ;
27632770 const double mag = std::sqrt (re * re + im * im);
2764- double phase = bruun_phase_atan2_mag (im, re, mag);
2765- if (phase < 0.0 ) {
2766- phase += 2.0 * M_PI ;
2767- }
2771+ const double phase = bruun_phase_atan2_mag (im, re, mag);
2772+ output[k].re = mag;
2773+ output[k].im = phase;
2774+ }
2775+ }
2776+
2777+ void convert_standard_complex_to_mag_phase_f32 (complex_f32_t * RESTRICT output) const {
2778+ int k = 1 ;
2779+ #if BRUUN_LEVEL >= 1
2780+ for (; k + 1 < N / 2 ; k += 2 ) {
2781+ const float re0 = output[k].re ;
2782+ const float im0 = output[k].im ;
2783+ const float re1 = output[k + 1 ].re ;
2784+ const float im1 = output[k + 1 ].im ;
2785+ const float mag0 = std::sqrt (re0 * re0 + im0 * im0);
2786+ const float mag1 = std::sqrt (re1 * re1 + im1 * im1);
2787+ double phase0;
2788+ double phase1;
2789+ bruun_phase_atan2_mag_pair (static_cast <double >(im0), static_cast <double >(re0), static_cast <double >(mag0),
2790+ static_cast <double >(im1), static_cast <double >(re1), static_cast <double >(mag1),
2791+ &phase0, &phase1);
2792+ output[k].re = mag0;
2793+ output[k].im = static_cast <float >(phase0);
2794+ output[k + 1 ].re = mag1;
2795+ output[k + 1 ].im = static_cast <float >(phase1);
2796+ }
2797+ #endif
2798+ for (; k < N / 2 ; ++k) {
2799+ const float re = output[k].re ;
2800+ const float im = output[k].im ;
2801+ const float mag = std::sqrt (re * re + im * im);
2802+ const float phase = bruun_phase_atan2_mag_f32 (im, re, mag);
27682803 output[k].re = mag;
27692804 output[k].im = phase;
27702805 }
@@ -2812,18 +2847,18 @@ class RFFT {
28122847 }
28132848
28142849 const int * RESTRICT kin = KINV .data ();
2815- for (int k = 1 ; k < N / 2 ; ++k) {
2850+ int k = 1 ;
2851+ for (; k + 3 < N / 2 ; k += 4 ) {
2852+ pack4_residues_to_complex_f32 (output + k, work,
2853+ kin[k], kin[k + 1 ], kin[k + 2 ], kin[k + 3 ]);
2854+ }
2855+ for (; k < N / 2 ; ++k) {
28162856 const int m = kin[k];
2817- const float re = work[2 *m];
2818- const float im = -work[2 *m + 1 ];
2819- const float mag = std::sqrt (re * re + im * im);
2820- float phase = bruun_phase_atan2_mag_f32 (im, re, mag);
2821- if (phase < 0 .0f ) {
2822- phase += 2 .0f * static_cast <float >(M_PI );
2823- }
2824- output[k].re = mag;
2825- output[k].im = phase;
2857+ output[k].re = work[2 *m];
2858+ output[k].im = -work[2 *m + 1 ];
28262859 }
2860+
2861+ convert_standard_complex_to_mag_phase_f32 (output);
28272862 }
28282863
28292864 // Standard FFTW-like real -> complex interface, using caller-provided native scratch.
0 commit comments