Skip to main content
parallel
Source Link
dfhwze
  • 14.2k
  • 3
  • 40
  • 101

If you use a certain pattern time and again, you might want to make a utility method for it. As suggested by Roland in the comments, we could implement a possible performance gain here. I would opt to call AsParallel() on the items. You could also try calling Parallel.For instead.

static void Walk(int height, int width, Action<int, int> visit) 
{
    foreach (var point in (
             from j in Enumerable.Range(0, height)
             from i in Enumerable.Range(0, width) 
             select (i, j)).AsParallel())
    {
        visit(point.i, point.j);
    }
}

If you use a certain pattern time and again, you might want to make a utility method for it.

static void Walk(int height, int width, Action<int, int> visit) 
{
    foreach (var point in (
             from j in Enumerable.Range(0, height)
             from i in Enumerable.Range(0, width) 
             select (i, j)))
    {
        visit(point.i, point.j);
    }
}

If you use a certain pattern time and again, you might want to make a utility method for it. As suggested by Roland in the comments, we could implement a possible performance gain here. I would opt to call AsParallel() on the items. You could also try calling Parallel.For instead.

static void Walk(int height, int width, Action<int, int> visit) 
{
    foreach (var point in (
             from j in Enumerable.Range(0, height)
             from i in Enumerable.Range(0, width) 
             select (i, j)).AsParallel())
    {
        visit(point.i, point.j);
    }
}
added 548 characters in body
Source Link
dfhwze
  • 14.2k
  • 3
  • 40
  • 101

If you use a certain pattern time and again, you might want to make a utility method for it.

for (int j = 0; j < imageHeight; j++)
{
    for (int i = 0; i < imageWidth; i++)
    {
        // do something ..
    }
}
static void Walk(int height, int width, Action<int, int> visit) 
{
    foreach (var point in (
             from j in Enumerable.Range(0, height)
             from i in Enumerable.Range(0, width) 
             select (i, j)))
    {
        visit(point.i, point.j);
    }
}
public static Complex[,] Convolve(Complex[,] image, Complex[,] mask)
{
    image = image ?? throw new ArgumentNullException(nameof(image));
    mask = mask ?? throw new ArgumentNullException(nameof(mask));

    var imageWidth = image.GetLength(0);
    var imageHeight = image.GetLength(1);
    var maskWidth = mask.GetLength(0);
    var maskHeight = mask.GetLength(1);

    if (!(imageWidth == maskWidth && imageHeight == maskHeight))
    {
        throw new Exception("padding needed");
    }

    var imageTransform = new FourierTransform(image);
    var maskTransform = new FourierTransform(mask);

    imageTransform.ForwardFFT();
    maskTransform.ForwardFFT();

    var imageComplex = imageTransform.FourierImageComplex;
    var maskComplex = maskTransform.FourierImageComplex;
    var convolvedComplex = new Complex[imageWidth, imageHeight];

    for Walk(int j = 0; j < imageHeight; j++)
  imageHeight, imageWidth, {
        for (int i = 0; i < imageWidth;, i++j)
        {
           => convolvedComplex[i, j] = imageComplex[i, j] * maskComplex[i, j];
        }
    }j]);

    var convolvedTransform = new FourierTransform();
    convolvedTransform.InverseFFT(convolvedComplex);
    var convolve = convolvedTransform.GrayscaleImageComplex;
    Rescale(convolve);
    convolve = FourierShifter.FFTShift(convolve);

    return convolve;
}
public static Complex[,] Convolve(Complex[,] image, Complex[,] mask)
{
    image = image ?? throw new ArgumentNullException(nameof(image));
    mask = mask ?? throw new ArgumentNullException(nameof(mask));

    var imageWidth = image.GetLength(0);
    var imageHeight = image.GetLength(1);
    var maskWidth = mask.GetLength(0);
    var maskHeight = mask.GetLength(1);

    if (!(imageWidth == maskWidth && imageHeight == maskHeight))
    {
        throw new Exception("padding needed");
    }

    var imageTransform = new FourierTransform(image);
    var maskTransform = new FourierTransform(mask);

    imageTransform.ForwardFFT();
    maskTransform.ForwardFFT();

    var imageComplex = imageTransform.FourierImageComplex;
    var maskComplex = maskTransform.FourierImageComplex;
    var convolvedComplex = new Complex[imageWidth, imageHeight];

    for (int j = 0; j < imageHeight; j++)
    {
        for (int i = 0; i < imageWidth; i++)
        {
            convolvedComplex[i, j] = imageComplex[i, j] * maskComplex[i, j];
        }
    }

    var convolvedTransform = new FourierTransform();
    convolvedTransform.InverseFFT(convolvedComplex);
    var convolve = convolvedTransform.GrayscaleImageComplex;
    Rescale(convolve);
    convolve = FourierShifter.FFTShift(convolve);

    return convolve;
}

If you use a certain pattern time and again, you might want to make a utility method for it.

for (int j = 0; j < imageHeight; j++)
{
    for (int i = 0; i < imageWidth; i++)
    {
        // do something ..
    }
}
static void Walk(int height, int width, Action<int, int> visit) 
{
    foreach (var point in (
             from j in Enumerable.Range(0, height)
             from i in Enumerable.Range(0, width) 
             select (i, j)))
    {
        visit(point.i, point.j);
    }
}
public static Complex[,] Convolve(Complex[,] image, Complex[,] mask)
{
    image = image ?? throw new ArgumentNullException(nameof(image));
    mask = mask ?? throw new ArgumentNullException(nameof(mask));

    var imageWidth = image.GetLength(0);
    var imageHeight = image.GetLength(1);
    var maskWidth = mask.GetLength(0);
    var maskHeight = mask.GetLength(1);

    if (!(imageWidth == maskWidth && imageHeight == maskHeight))
    {
        throw new Exception("padding needed");
    }

    var imageTransform = new FourierTransform(image);
    var maskTransform = new FourierTransform(mask);

    imageTransform.ForwardFFT();
    maskTransform.ForwardFFT();

    var imageComplex = imageTransform.FourierImageComplex;
    var maskComplex = maskTransform.FourierImageComplex;
    var convolvedComplex = new Complex[imageWidth, imageHeight];

    Walk(imageHeight, imageWidth, 
       (i, j) => convolvedComplex[i, j] = imageComplex[i, j] * maskComplex[i, j]);

    var convolvedTransform = new FourierTransform();
    convolvedTransform.InverseFFT(convolvedComplex);
    var convolve = convolvedTransform.GrayscaleImageComplex;
    Rescale(convolve);
    convolve = FourierShifter.FFTShift(convolve);

    return convolve;
}
performance
Source Link
dfhwze
  • 14.2k
  • 3
  • 40
  • 101
  • Check arguments against null to avoid the nasty NullReferenceException.
  • Give meaningful names to variables. Do not use ft and fft prefixes. This kills readability.
  • Exit early on invalid state of the arguments. This simplifies the number of nested code blocks. Invert if (imageWidth == maskWidth && imageHeight == maskHeight) and throw error.
  • Don't put multiple statements on a single line; FourierTransform ftForMask = new FourierTransform(mask); ftForMask.ForwardFFT();.
  • Don't introduce unnecessary white lines between simple statements.
  • Prefer the use of var for declaring variables.
  • I presume maskeHeight has a typo in it -> maskHeight
  • I don't see much room for optimizing the performance, since each step requires intermediate results from the previous one; perhaps as suggested in another answer, making one of the loops use Parallel, would benefit you.
  • Check arguments against null to avoid the nasty NullReferenceException.
  • Give meaningful names to variables. Do not use ft and fft prefixes. This kills readability.
  • Exit early on invalid state of the arguments. This simplifies the number of nested code blocks. Invert if (imageWidth == maskWidth && imageHeight == maskHeight) and throw error.
  • Don't put multiple statements on a single line; FourierTransform ftForMask = new FourierTransform(mask); ftForMask.ForwardFFT();.
  • Don't introduce unnecessary white lines between simple statements.
  • Prefer the use of var for declaring variables.
  • Check arguments against null to avoid the nasty NullReferenceException.
  • Give meaningful names to variables. Do not use ft and fft prefixes. This kills readability.
  • Exit early on invalid state of the arguments. This simplifies the number of nested code blocks. Invert if (imageWidth == maskWidth && imageHeight == maskHeight) and throw error.
  • Don't put multiple statements on a single line; FourierTransform ftForMask = new FourierTransform(mask); ftForMask.ForwardFFT();.
  • Don't introduce unnecessary white lines between simple statements.
  • Prefer the use of var for declaring variables.
  • I presume maskeHeight has a typo in it -> maskHeight
  • I don't see much room for optimizing the performance, since each step requires intermediate results from the previous one; perhaps as suggested in another answer, making one of the loops use Parallel, would benefit you.
added 16 characters in body
Source Link
dfhwze
  • 14.2k
  • 3
  • 40
  • 101
Loading
Source Link
dfhwze
  • 14.2k
  • 3
  • 40
  • 101
Loading