digitalmars.D - One-line FFT, nice!
- Mehrdad (13/13) Sep 08 2012 I was pretty excited to figure out that a one-liner FFT is
- Walter Bright (3/16) Sep 08 2012 Awesome! Thanks for figuring this out. Any chance you can write up a bri...
- bearophile (5/7) Sep 08 2012 See also:
- Mehrdad (11/31) Sep 08 2012 Haha... I wish, but I don't have a blog or anything like that.
- Paulo Pinto (4/38) Sep 12 2012 If you provide me the text, I can publish it on my web site.
- Timon Gehr (2/15) Sep 08 2012 I usually get NaNs. Are you sure this is correct?
- Timon Gehr (2/19) Sep 08 2012 Works correctly in 32 bit mode. 64 bit code gen bug.
- Brad Roberts (2/23) Sep 08 2012 Bug number?
- Mehrdad (2/3) Sep 08 2012 Hehe, glad it was helpful. :D
- Manu (4/17) Sep 12 2012 Very curious to know how this performs. Since it's making use of lots of
- jerro (3/8) Sep 12 2012 It is computing sine and cosine in the inner loop, so the
I was pretty excited to figure out that a one-liner FFT is possible in D! creal[] dft(creal[] v) { return v.length > 1 ? (p => chain(map!(q => q[0] + q[1])(p), map!(q => q[0] - q[1])(p)))(zip(dft(v.stride(2).array()), map!(p => p[1] * expi(p[0] * -2 * PI / v.length))(zip(iota(v.length / 2), dft(v.drop(1).stride(2).array()))))).array() : v; } Of course, the Python version is still shorter: def dft(v): return (lambda e, o: map(add, e, o) + map(sub, e, o))(dft(v[0::2]), [o * rect(1, k * -2 * pi / len(v)) for k, o in enumerate(dft(v[1::2]))]) if len(v) > 1 else v but it's still cool (barring the unreadability, haha). Yay D!
Sep 08 2012
On 9/8/2012 3:56 PM, Mehrdad wrote:I was pretty excited to figure out that a one-liner FFT is possible in D! creal[] dft(creal[] v) { return v.length > 1 ? (p => chain(map!(q => q[0] + q[1])(p), map!(q => q[0] - q[1])(p)))(zip(dft(v.stride(2).array()), map!(p => p[1] * expi(p[0] * -2 * PI / v.length))(zip(iota(v.length / 2), dft(v.drop(1).stride(2).array()))))).array() : v; } Of course, the Python version is still shorter: def dft(v): return (lambda e, o: map(add, e, o) + map(sub, e, o))(dft(v[0::2]), [o * rect(1, k * -2 * pi / len(v)) for k, o in enumerate(dft(v[1::2]))]) if len(v) > 1 else v but it's still cool (barring the unreadability, haha). Yay D!Awesome! Thanks for figuring this out. Any chance you can write up a brief article on this, so we can post a link on reddit?
Sep 08 2012
Walter Bright:Awesome! Thanks for figuring this out. Any chance you can write up a brief article on this, so we can post a link on reddit?See also: http://rosettacode.org/wiki/FFT#D Bye, bearophile
Sep 08 2012
On Saturday, 8 September 2012 at 23:58:36 UTC, Walter Bright wrote:On 9/8/2012 3:56 PM, Mehrdad wrote:Haha... I wish, but I don't have a blog or anything like that. Currently I'm working on schoolwork though so I'm not sure I'd get to this in time. :\ If someone else wants to do it though, feel free to! Also, obligatory mention, sorry I didn't mention this earlier -- Bearophile is right on, I got the original code from http://rosettacode.org/wiki/FFT (Python) and then I played around with it to make it a one-liner. Credits go there for the original code, not me. :)I was pretty excited to figure out that a one-liner FFT is possible in D! creal[] dft(creal[] v) { return v.length > 1 ? (p => chain(map!(q => q[0] + q[1])(p), map!(q => q[0] - q[1])(p)))(zip(dft(v.stride(2).array()), map!(p => p[1] * expi(p[0] * -2 * PI / v.length))(zip(iota(v.length / 2), dft(v.drop(1).stride(2).array()))))).array() : v; } Of course, the Python version is still shorter: def dft(v): return (lambda e, o: map(add, e, o) + map(sub, e, o))(dft(v[0::2]), [o * rect(1, k * -2 * pi / len(v)) for k, o in enumerate(dft(v[1::2]))]) if len(v) > 1 else v but it's still cool (barring the unreadability, haha). Yay D!Awesome! Thanks for figuring this out. Any chance you can write up a brief article on this, so we can post a link on reddit?
Sep 08 2012
On Sunday, 9 September 2012 at 06:20:14 UTC, Mehrdad wrote:On Saturday, 8 September 2012 at 23:58:36 UTC, Walter Bright wrote:If you provide me the text, I can publish it on my web site. -- PauloOn 9/8/2012 3:56 PM, Mehrdad wrote:Haha... I wish, but I don't have a blog or anything like that. Currently I'm working on schoolwork though so I'm not sure I'd get to this in time. :\ If someone else wants to do it though, feel free to! Also, obligatory mention, sorry I didn't mention this earlier -- Bearophile is right on, I got the original code from http://rosettacode.org/wiki/FFT (Python) and then I played around with it to make it a one-liner. Credits go there for the original code, not me. :)I was pretty excited to figure out that a one-liner FFT is possible in D! creal[] dft(creal[] v) { return v.length > 1 ? (p => chain(map!(q => q[0] + q[1])(p), map!(q => q[0] - q[1])(p)))(zip(dft(v.stride(2).array()), map!(p => p[1] * expi(p[0] * -2 * PI / v.length))(zip(iota(v.length / 2), dft(v.drop(1).stride(2).array()))))).array() : v; } Of course, the Python version is still shorter: def dft(v): return (lambda e, o: map(add, e, o) + map(sub, e, o))(dft(v[0::2]), [o * rect(1, k * -2 * pi / len(v)) for k, o in enumerate(dft(v[1::2]))]) if len(v) > 1 else v but it's still cool (barring the unreadability, haha). Yay D!Awesome! Thanks for figuring this out. Any chance you can write up a brief article on this, so we can post a link on reddit?
Sep 12 2012
On 09/09/2012 12:56 AM, Mehrdad wrote:I was pretty excited to figure out that a one-liner FFT is possible in D! creal[] dft(creal[] v) { return v.length > 1 ? (p => chain(map!(q => q[0] + q[1])(p), map!(q => q[0] - q[1])(p)))(zip(dft(v.stride(2).array()), map!(p => p[1] * expi(p[0] * -2 * PI / v.length))(zip(iota(v.length / 2), dft(v.drop(1).stride(2).array()))))).array() : v; } Of course, the Python version is still shorter: def dft(v): return (lambda e, o: map(add, e, o) + map(sub, e, o))(dft(v[0::2]), [o * rect(1, k * -2 * pi / len(v)) for k, o in enumerate(dft(v[1::2]))]) if len(v) > 1 else v but it's still cool (barring the unreadability, haha). Yay D!I usually get NaNs. Are you sure this is correct?
Sep 08 2012
On 09/09/2012 02:57 AM, Timon Gehr wrote:On 09/09/2012 12:56 AM, Mehrdad wrote:Works correctly in 32 bit mode. 64 bit code gen bug.I was pretty excited to figure out that a one-liner FFT is possible in D! creal[] dft(creal[] v) { return v.length > 1 ? (p => chain(map!(q => q[0] + q[1])(p), map!(q => q[0] - q[1])(p)))(zip(dft(v.stride(2).array()), map!(p => p[1] * expi(p[0] * -2 * PI / v.length))(zip(iota(v.length / 2), dft(v.drop(1).stride(2).array()))))).array() : v; } Of course, the Python version is still shorter: def dft(v): return (lambda e, o: map(add, e, o) + map(sub, e, o))(dft(v[0::2]), [o * rect(1, k * -2 * pi / len(v)) for k, o in enumerate(dft(v[1::2]))]) if len(v) > 1 else v but it's still cool (barring the unreadability, haha). Yay D!I usually get NaNs. Are you sure this is correct?
Sep 08 2012
On 9/8/2012 6:01 PM, Timon Gehr wrote:On 09/09/2012 02:57 AM, Timon Gehr wrote:Bug number?On 09/09/2012 12:56 AM, Mehrdad wrote:Works correctly in 32 bit mode. 64 bit code gen bug.I was pretty excited to figure out that a one-liner FFT is possible in D! creal[] dft(creal[] v) { return v.length > 1 ? (p => chain(map!(q => q[0] + q[1])(p), map!(q => q[0] - q[1])(p)))(zip(dft(v.stride(2).array()), map!(p => p[1] * expi(p[0] * -2 * PI / v.length))(zip(iota(v.length / 2), dft(v.drop(1).stride(2).array()))))).array() : v; } Of course, the Python version is still shorter: def dft(v): return (lambda e, o: map(add, e, o) + map(sub, e, o))(dft(v[0::2]), [o * rect(1, k * -2 * pi / len(v)) for k, o in enumerate(dft(v[1::2]))]) if len(v) > 1 else v but it's still cool (barring the unreadability, haha). Yay D!I usually get NaNs. Are you sure this is correct?
Sep 08 2012
On Sunday, 9 September 2012 at 01:01:00 UTC, Timon Gehr wrote:Works correctly in 32 bit mode. 64 bit code gen bug.Hehe, glad it was helpful. :D
Sep 08 2012
On 9 September 2012 01:56, Mehrdad <wfunction hotmail.com> wrote:I was pretty excited to figure out that a one-liner FFT is possible in D! creal[] dft(creal[] v) { return v.length > 1 ? (p => chain(map!(q => q[0] + q[1])(p), map!(q => q[0] - q[1])(p)))(zip(dft(v.stride(2)**.array()), map!(p => p[1] * expi(p[0] * -2 * PI / v.length))(zip(iota(v.length / 2), dft(v.drop(1).stride(2).array(**)))))).array() : v; } Of course, the Python version is still shorter: def dft(v): return (lambda e, o: map(add, e, o) + map(sub, e, o))(dft(v[0::2]), [o * rect(1, k * -2 * pi / len(v)) for k, o in enumerate(dft(v[1::2]))]) if len(v) > 1 else v but it's still cool (barring the unreadability, haha). Yay D!Very curious to know how this performs. Since it's making use of lots of templates from the standard library, how much do they influence efficiency? How well does the compiler do its job optimising this?
Sep 12 2012
Very curious to know how this performs. Since it's making use of lots of templates from the standard library, how much do they influence efficiency? How well does the compiler do its job optimising this?It is computing sine and cosine in the inner loop, so the performance can not be good, no matter how well the compiler optimizes it.
Sep 12 2012