Beispiel #1
0
        public void TestFloorLog2Properties(int seed)
        {
            var rand = new Random(seed);

            for (var sample = 0; sample < 100; ++sample)
            {
                var n = rand.Next() ^ (rand.Next() << 16);
                if (n == 0)
                {
                    continue;
                }

                var log2n = FastFourierTransform.FloorLog2(n);
                var hibit = 1 << log2n;
                var mask  = hibit | (hibit - 1);
                Assert.AreEqual(0, n & ~mask, "higher bits");
                Assert.AreEqual(hibit, n & hibit, "high bit");
            }
        }
        private static float[] GenerateCloudFft(int dx, int dy, int dz)
        {
            var log2X = (byte)FastFourierTransform.FloorLog2(dx);
            var log2Y = (byte)FastFourierTransform.FloorLog2(dy);
            var log2Z = (byte)FastFourierTransform.FloorLog2(dz);

            Trace.WriteLine($"Generate random {dx} x {dy} x {dz} data...");
            var data = new Complex[dx * dy * dz];
            var rand = new Random(101);

            for (var i = 0; i < data.Length; ++i)
            {
                data[i] = rand.NextDouble();
            }

            Trace.WriteLine($"Compute multi-dimensional FFT...");
            data.MultiFft(log2X, log2Y, log2Z);

            Trace.WriteLine($"Apply 1/f^2 scaling...");
            var p = 0;

            for (var x = 0; x < dx; ++x)
            {
                var fx = Math.Min(x, dx - x);
                for (var y = 0; y < dy; ++y)
                {
                    var fy = Math.Min(y, dy - y);

                    for (var z = 0; z < dz; ++z)
                    {
                        var fz = Math.Min(z, dz - z);

                        var ff = fx * fx + fy * fy + fz * fz;
                        if (ff == 0)
                        {
                            data[p++] = 0;
                        }
                        else
                        {
                            data[p++] /= ff;
                        }
                    }
                }
            }

            Trace.WriteLine("Compute inverse multi-dimensional FFT...");
            data.InverseMultiFft(log2X, log2Y, log2Z);

            Trace.WriteLine("Convert complex real component to normalized float...");
            var minc   = data.Min(x => x.Real);
            var maxc   = data.Max(x => x.Real);
            var result = new float[data.Length];

            for (var i = 0; i < data.Length; ++i)
            {
                result[i] = (float)((data[i].Real - minc) / (maxc - minc));
            }

            Trace.WriteLine($"max( abs( R ) ) = {data.Max( c => Math.Abs( c.Real ) )}");
            Trace.WriteLine($"max( abs( I ) ) = {data.Max( c => Math.Abs( c.Imaginary ) )}");

            return(result);
        }
Beispiel #3
0
 public void TestFloorLog2(int n, int expect)
 {
     Assert.AreEqual(expect, FastFourierTransform.FloorLog2(n));
 }