Example #1
0
        public void ComplexMax()
        {
            Complex <double> complex1 = new Complex <double>(-1, -3);
            Complex <double> complex2 = new Complex <double>(1, 10);

            Complex <double> result = Complex <double> .Max(complex1, complex2);

            Complex <double> expected = new Complex <double>(1, 10);

            Assert.AreEqual(expected, result);
        }
        public static Image DrawSpectrumData(Complex[] data)
        {
            Image img = new Bitmap(data.Length * 2, 200);
            Graphics graph = Graphics.FromImage(img);
            graph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
            Brush brush = new SolidBrush(Color.Blue);
            double max = data.Max(value => value.Real);

            for (int i = 0; i < data.Length; i++)
            {
                int newValue = Convert.ToInt32(Scaler.Scaler.ScaleToDoubleGraphVersion(data[i].Real, max, 0, 200, 0));
                graph.FillRectangle(brush, i * 2, 200 - newValue, 2, newValue);
            }
            return img;
        }
Example #3
0
        /// <summary>
        /// Returns the maximum value of the elements of an array.
        /// </summary>
        /// <param name="v">An array of complex numbers.</param>
        /// <returns>The maximum value of the elements of v.</returns>
        public static Complex Max(IList <Complex> v)
        {
            if (v.Count == 0)
            {
                return(Complex.Zero);
            }

            Complex max = v[0];

            for (int i = 1; i < v.Count; i++)
            {
                max = Complex.Max(max, v[i]);
            }

            return(max);
        }
Example #4
0
        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);
        }
Example #5
0
        private void Convert(bool _centralValue, float _signX, float _signY)
        {
            // Initialize gradient filter
            Complex[,]      dx = new Complex[m_size, m_size];
            Complex[,]      dy = new Complex[m_size, m_size];
            Array.Clear(dx, 0, (int)(m_size * m_size));
            Array.Clear(dy, 0, (int)(m_size * m_size));

            if (_centralValue)
            {
                // Central-difference
                dx[m_size - 1, 0].Set(-_signX, 0);
                dx[1, 0].Set(_signX, 0);
                dy[0, m_size - 1].Set(_signY, 0);
                dy[0, 1].Set(-_signY, 0);
            }
            else
            {
                // One-sided difference
                dx[0, 0].Set(-_signX, 0);
                dx[1, 0].Set(_signX, 0);
                dy[0, 0].Set(_signY, 0);
                dy[0, 1].Set(-_signY, 0);
            }

            // Apply forward Fourier transform to obtain spectrum
            SharpMath.FFT.FFT2D_GPU FFT = new SharpMath.FFT.FFT2D_GPU(m_device, m_size);
            Complex[,]      NX = FFT.FFT_Forward(nx);
            Complex[,]      NY = FFT.FFT_Forward(ny);
            Complex[,]      DX = FFT.FFT_Forward(dx);
            Complex[,]      DY = FFT.FFT_Forward(dy);

            // Compute de-convolution
            float factor = m_imageNormal.Width * m_imageNormal.Height;

            Complex[,]      H = new Complex[m_size, m_size];
            Complex temp = new Complex(), sqrtTemp;

            for (uint Y = 0; Y < m_size; Y++)
            {
                for (uint X = 0; X < m_size; X++)
                {
#if !F**K
                    double sqNX = NX[X, Y].SquareMagnitude;
                    double sqNY = NY[X, Y].SquareMagnitude;
                    double num  = sqNX + sqNY;

                    double sqDX = DX[X, Y].SquareMagnitude;
                    double sqDY = DY[X, Y].SquareMagnitude;
                    double den  = factor * (sqDX + sqDY);

                    temp.Set(Math.Abs(den) > 0.0 ? num / den : 0.0, 0.0);
                    sqrtTemp = temp.Sqrt();

                    H[X, Y] = sqrtTemp;
#else
                    Complex Nx  = NX[X, Y];
                    Complex Ny  = NY[X, Y];
                    Complex Dx  = DX[X, Y];
                    Complex Dy  = DY[X, Y];
                    double  den = factor * (DX[X, Y].SquareMagnitude + DY[X, Y].SquareMagnitude);
                    if (Math.Abs(den) > 0.0)
                    {
                        temp    = -(Dx * Nx + Dy * Ny) / den;
                        H[X, Y] = temp;
                    }
                    else
                    {
                        H[X, Y].Zero();
                    }
#endif
                }
            }

            // Apply inverse transform
            Complex[,]      h = FFT.FFT_Inverse(H);

            Complex heightMin = new Complex(double.MaxValue, double.MaxValue);
            Complex heightMax = new Complex(-double.MaxValue, -double.MaxValue);
            for (uint Y = 0; Y < m_size; Y++)
            {
                for (uint X = 0; X < m_size; X++)
                {
                    Complex height = h[X, Y];
                    heightMin.Min(height);
                    heightMax.Max(height);
                }
            }

            // Render result
            if (m_imageHeight != null)
            {
                m_imageHeight.Dispose();
                m_imageHeight = null;
            }

            factor = 1.0f / (float)(heightMax.r - heightMin.r);
// heightMin.r = -1.0f;
// factor = 0.5f;

            m_imageHeight = new ImageFile(m_imageNormal.Width, m_imageNormal.Height, PIXEL_FORMAT.R16, new ColorProfile(ColorProfile.STANDARD_PROFILE.sRGB));
//			m_imageHeight.WritePixels( ( uint X, uint Y, ref float4 _color ) => { _color.x = 1e3f * (float) H[X,Y].Magnitude; } );
//			m_imageHeight.WritePixels( ( uint X, uint Y, ref float4 _color ) => { _color.x = 1e5f * (float) DX[X,Y].Magnitude; } );
            m_imageHeight.WritePixels((uint X, uint Y, ref float4 _color) => { _color.x = factor * (float)(h[X, Y].r - heightMin.r); });

            imagePanelHeight.Bitmap = m_imageHeight.AsBitmap;

            FFT.Dispose();
        }