{"action":"created","issue":{"url":"https://api.github.com/repos/scipy/scipy/issues/8465","repository_url":"https://api.github.com/repos/scipy/scipy","labels_url":"https://api.github.com/repos/scipy/scipy/issues/8465/labels{/name}","comments_url":"https://api.github.com/repos/scipy/scipy/issues/8465/comments","events_url":"https://api.github.com/repos/scipy/scipy/issues/8465/events","html_url":"https://github.com/scipy/scipy/issues/8465","id":299612437,"number":8465,"title":"Unexpected behavior with reflect mode of ndimage.rotate","user":{"login":"not522","id":1255726,"avatar_url":"https://avatars0.githubusercontent.com/u/1255726?v=4","gravatar_id":"","url":"https://api.github.com/users/not522","html_url":"https://github.com/not522","followers_url":"https://api.github.com/users/not522/followers","following_url":"https://api.github.com/users/not522/following{/other_user}","gists_url":"https://api.github.com/users/not522/gists{/gist_id}","starred_url":"https://api.github.com/users/not522/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/not522/subscriptions","organizations_url":"https://api.github.com/users/not522/orgs","repos_url":"https://api.github.com/users/not522/repos","events_url":"https://api.github.com/users/not522/events{/privacy}","received_events_url":"https://api.github.com/users/not522/received_events","type":"User","site_admin":false},"labels":[{"id":38890106,"url":"https://api.github.com/repos/scipy/scipy/labels/query","name":"query","color":"d4c5f9","default":false},{"id":37342586,"url":"https://api.github.com/repos/scipy/scipy/labels/scipy.ndimage","name":"scipy.ndimage","color":"207de5","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":15,"created_at":"2018-02-23T06:31:27Z","updated_at":"2018-03-08T12:51:14Z","closed_at":null,"author_association":"NONE","body":"`scipy.ndimage.rotate` with `reflect` mode causes unexpected behavior.\r\nFollowing code is expected to generate a symmetric image, but the output is asymmetric.\r\n\r\nIt seems wrong when the coordinates become negative. I think the behavior on the larger coordinate side is correct.\r\n\r\n### Reproducing code example:\r\n```\r\nimport numpy\r\nimport scipy.ndimage\r\nimport matplotlib.pyplot as plt\r\n\r\na = numpy.zeros((7, 7))\r\nfor i in range(7):\r\n    for j in range(7):\r\n        if (i + j) % 2 == 0:\r\n            a[i, j] = 1\r\n\r\na = scipy.ndimage.rotate(a, 1, mode='reflect')\r\n\r\nplt.axes().set_aspect('equal')\r\nplt.pcolor(a, cmap=plt.cm.binary)\r\nplt.savefig('reflect.png', bbox_inches='tight')\r\n```\r\n![reflect](https://user-images.githubusercontent.com/1255726/36581040-469f0a00-18ae-11e8-937e-a5414dcd0408.png)\r\n\r\n### Error message:\r\nNo error message.\r\n\r\n### Scipy/Numpy/Python version information:\r\n```\r\n1.0.0 1.13.1 sys.version_info(major=3, minor=6, micro=2, releaselevel='final', serial=0)\r\n```\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/scipy/scipy/issues/comments/371478037","html_url":"https://github.com/scipy/scipy/issues/8465#issuecomment-371478037","issue_url":"https://api.github.com/repos/scipy/scipy/issues/8465","id":371478037,"user":{"login":"jaimefrio","id":3343990,"avatar_url":"https://avatars1.githubusercontent.com/u/3343990?v=4","gravatar_id":"","url":"https://api.github.com/users/jaimefrio","html_url":"https://github.com/jaimefrio","followers_url":"https://api.github.com/users/jaimefrio/followers","following_url":"https://api.github.com/users/jaimefrio/following{/other_user}","gists_url":"https://api.github.com/users/jaimefrio/gists{/gist_id}","starred_url":"https://api.github.com/users/jaimefrio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jaimefrio/subscriptions","organizations_url":"https://api.github.com/users/jaimefrio/orgs","repos_url":"https://api.github.com/users/jaimefrio/repos","events_url":"https://api.github.com/users/jaimefrio/events{/privacy}","received_events_url":"https://api.github.com/users/jaimefrio/received_events","type":"User","site_admin":false},"created_at":"2018-03-08T12:51:14Z","updated_at":"2018-03-08T12:51:14Z","author_association":"MEMBER","body":"I have put this mini-library together to experiment with different ways of handling the bounds:\r\n\r\nhttps://gist.github.com/jaimefrio/79ee7a9f8d7ff6ca10ae72633ec68c80\r\n\r\nWhen I run the following code using functions from there, this is what I obtain:\r\n\r\n```\r\nf = np.array([-5.,-2, -1, 0, 1, 2, 5])\r\nfiltered_f = ndimage.spline_filter1d(f)\r\nx = np.linspace(-6, 12, 1000)\r\nplt.plot(f, 'o')\r\nplt.plot(x, interpolate(x, filtered_f, reflect_bounds, mirror_bounds))\r\n```\r\n![image](https://user-images.githubusercontent.com/3343990/37151576-527dd4dc-22d6-11e8-8e22-0152fca513dd.png)\r\n\r\nWhich shows the break in derivative continuity that I was talking about.\r\n\r\nAs the code I've put together makes explicit, there are two types of boundary handling we need to consider:\r\n\r\n 1. To map interpolated points outside of the bounds of the image to either inside or reasonably close, e.g. within 1 pixel. This is properly done by your code, as far as I can tell.\r\n 2. To map input array entries needed for interpolation that lay outside the image boundaries to a point wihin the boundaries. There is no reasonably close clause here: if you need a datapoint you need a valid index. It is very important here that you use the exact same boundary conditions for this as you used to determine the spline coefficients, which means that for now we must always use mirror for this.\r\n\r\nThe double bump is caused by that mismatch between \"reflect\" boundaries for the xs and \"mirror\" boundaries for the inner nodes. But as stated before, making both \"reflect\" doesn't work either:\r\n\r\n```\r\nplt.plot(f, 'o')\r\nplt.plot(x, interpolate(x, filtered_f, reflect_bounds, reflect_bounds))\r\n```\r\n![image](https://user-images.githubusercontent.com/3343990/37151787-48a7663e-22d7-11e8-9367-3b98ba0503bd.png)\r\n\r\nNow we have a smooth behavior, are no longer properly reproducing the image at the knots, which is not good at all.\r\n\r\nI haven't had a chance to test it yet, but am pretty sure that if the spline coefficients had been calculated with proper reflect boundary conditions, not the mirror ones that `spline_filter1d` implements, this last image would have been exactly what we are after."}}
{"actor":{"display_login":"jaimefrio"}}