PrevPrev Go to previous topic
NextNext Go to next topic
Last Post 23 Apr 2021 11:49 AM by  Jonathan Joseph
Bug in smooth function
 0 Replies
You are not authorized to post a reply.
Author Messages

Jonathan Joseph

New Member

New Member

23 Apr 2021 11:49 AM
    I've run across what seems to be an annoying bug in the "smooth" function when operating on 2d arrays. It presents under certain conditions when operating on an array that contains NaN entries and when using the /nan keyword in tandem with one of the /edge_ keywords. I can reproduce this problem at will using randomly generated data. When using one of the /edge_ keywords, smooth seems to get the wrong value in elements for which the kernel contains a NaN.

    I noticed this in a setting where I was setting every other value in the array to NaN (like the black squares on a chess board). Strangely, in this scenario if I used findgen() instead of randomu() to generate the test array, in this particular case, it seemed to produce correct results for all elements. Using random() in this case showed the problem.

    The smooth function seems to be getting the wrong value for elements that are NOT near the edges (i.e. elements that should not be affected by the /edge_ keywords), when one of the /edge_ keywords is specified.

    I have reproduced this problem with "IDL 8.7.2 (darwin x86_64 m64)" on a MacBook pro running OS 10.14.6 (Mojave), as well as with "IDL 8.6.1 (linux x86_64 m64" on a linux box running "4.15.0-136-generic #140-Ubuntu"

    Here is an example creating a 7x7 array of random values between 0 and 100, setting the middle element (3,3) to NaN, and then doing smoothing with a 3x3 kernel with and without /edge_truncate. I then print the absolute difference and percent difference between the value calculated using /edge_truncate and not using it (which appears to give the correct values) for the array values not along the edges [1:5,1:5]

    ; 7x7 array of random values from 0 to 100
    a=randomu(0,7,7) * 100
    ; set a couple of values to NaN
    a[3,3] = !values.f_nan
    a[4,4] = !values.f_nan
    ; smooth using /nan
    as1 = smooth(a,3,/nan)
    ; smooth using /nan and /edge_truncate
    as2 = smooth(a,3,/nan,/edge_truncate)
    ; print absolute difference between non-edge pixels
    print, reform(string((abs(as1-as2))[1:5,1:5], format='(f5.2)'),5,5)
    ; print % difference between non-edge pixels
    print, reform(string(100 * (abs(as1-as2))[1:5,1:5] / as1[1:5,1:5], format='(f5.2)'),5,5)


    Absolute difference:
    0.00 0.00 0.00 0.00 0.00
    0.00 0.06 0.91 1.88 0.00
    0.00 0.92 1.31 1.96 0.28
    0.00 0.23 2.14 3.07 1.21
    0.00 0.00 2.00 2.29 0.41

    % difference
    0.00 0.00 0.00 0.00 0.00
    0.00 0.11 1.76 3.84 0.00
    0.00 2.18 2.85 3.96 0.45
    0.00 0.47 4.30 4.25 1.71
    0.00 0.00 3.65 3.21 0.65

    I think the results are the same for regardless of which /edge_ keyword is used. Using the" mean" function, I can confirm that the correct results are attained when not using a /edge_ keyword
    You are not authorized to post a reply.