@@ -3733,7 +3733,16 @@ public:
37333733 }
37343734 else if (range.length == 1 )
37353735 {
3736- buf[0 ] = range[0 ];
3736+ static if (isNumeric! (ElementType! R))
3737+ {
3738+ buf[0 ].re = range[0 ];
3739+ buf[0 ].im = 0 ;
3740+ }
3741+ else
3742+ {
3743+ buf[0 ].re = range[0 ].re;
3744+ buf[0 ].im = range[0 ].im;
3745+ }
37373746 return ;
37383747 }
37393748 else if (range.length == 2 )
@@ -3931,6 +3940,26 @@ void inverseFft(Ret, R)(R range, Ret buf)
39313940 assert (isClose(twoInv[1 ].im, 0 , 0.0 , 1e-10 ));
39323941}
39333942
3943+ // https://github.com/dlang/phobos/issues/10796
3944+ @system unittest
3945+ {
3946+ import std.algorithm ;
3947+ import std.range ;
3948+ static struct C { float re, im; } // User-defined complex
3949+
3950+ float [8 ] arr = [1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ];
3951+ C[8 ] fft1;
3952+ fft(arr[], fft1[]);
3953+ assert (isClose(fft1[].map! " a.re" ,
3954+ [36.0 , - 4 , - 4 , - 4 , - 4 , - 4 , - 4 , - 4 ], 1e-4 ));
3955+ assert (isClose(fft1[].map! " a.im" ,
3956+ [0 , 9.6568 , 4 , 1.6568 , 0 , - 1.6568 , - 4 , - 9.6568 ], 1e-4 ));
3957+
3958+ auto inv = inverseFft(fft1[]);
3959+ assert (isClose(inv[].map! " a.re" , arr[], 1e-6 ));
3960+ assert (inv[].map! " a.im" .maxElement < 1e-10 );
3961+ }
3962+
39343963// Swaps the real and imaginary parts of a complex number. This is useful
39353964// for inverse FFTs.
39363965C swapRealImag (C)(C input)
@@ -4112,11 +4141,24 @@ struct Stride(R)
41124141// using a generic slow DFT. This seems to be the best base case. (Size 1
41134142// can be coded inline as buf[0] = range[0]).
41144143void slowFourier2 (Ret, R)(R range, Ret buf)
4144+ if (isComplexLike! (ElementType! Ret))
4145+ in (range.length == 2 )
4146+ in (buf.length == 2 )
41154147{
4116- assert (range.length == 2 );
4117- assert (buf.length == 2 );
4118- buf[0 ] = range[0 ] + range[1 ];
4119- buf[1 ] = range[0 ] - range[1 ];
4148+ static if (isNumeric! (ElementType! R))
4149+ {
4150+ buf[0 ].re = range[0 ] + range[1 ];
4151+ buf[0 ].im = 0 ;
4152+ buf[1 ].re = range[0 ] - range[1 ];
4153+ buf[1 ].im = 0 ;
4154+ }
4155+ else
4156+ {
4157+ buf[0 ].re = range[0 ].re + range[1 ].re;
4158+ buf[0 ].im = range[0 ].im + range[1 ].im;
4159+ buf[1 ].re = range[0 ].re - range[1 ].re;
4160+ buf[1 ].im = range[0 ].im - range[1 ].im;
4161+ }
41204162}
41214163
41224164// Hard-coded base case for FFT of size 4. Doesn't work as well as the size
0 commit comments