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; }
/// <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); }
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); }
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(); }