{"action":"created","issue":{"url":"https://api.github.com/repos/odlgroup/odl/issues/115","labels_url":"https://api.github.com/repos/odlgroup/odl/issues/115/labels{/name}","comments_url":"https://api.github.com/repos/odlgroup/odl/issues/115/comments","events_url":"https://api.github.com/repos/odlgroup/odl/issues/115/events","html_url":"https://github.com/odlgroup/odl/pull/115","id":120162813,"number":115,"title":"Issue 80  ufuncs","user":{"login":"adler-j","id":2202312,"avatar_url":"https://avatars.githubusercontent.com/u/2202312?v=3","gravatar_id":"","url":"https://api.github.com/users/adler-j","html_url":"https://github.com/adler-j","followers_url":"https://api.github.com/users/adler-j/followers","following_url":"https://api.github.com/users/adler-j/following{/other_user}","gists_url":"https://api.github.com/users/adler-j/gists{/gist_id}","starred_url":"https://api.github.com/users/adler-j/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adler-j/subscriptions","organizations_url":"https://api.github.com/users/adler-j/orgs","repos_url":"https://api.github.com/users/adler-j/repos","events_url":"https://api.github.com/users/adler-j/events{/privacy}","received_events_url":"https://api.github.com/users/adler-j/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":11,"created_at":"2015-12-03T12:46:16Z","updated_at":"2015-12-06T14:19:19Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/odlgroup/odl/pulls/115","html_url":"https://github.com/odlgroup/odl/pull/115","diff_url":"https://github.com/odlgroup/odl/pull/115.diff","patch_url":"https://github.com/odlgroup/odl/pull/115.patch"},"body":"Fixed the things suggested in issue #80.\r\n\r\nBasically we can call (almost) all [UFuncs](http://docs.scipy.org/doc/numpy-1.10.0/reference/ufuncs.html) using the following syntax\r\n\r\n```python\r\n>>> x = vector([1.0, 2.0])\r\n>>> x.ufunc.sin()\r\nRn(2).element([0.8414709848078965, 0.90929742682568171])\r\n>>> y = x.copy()\r\n>>> z = x.ufunc.sin(out=y)\r\nRn(2).element([0.8414709848078965, 0.90929742682568171])\r\n>>> z is y\r\nTrue\r\n```\r\n\r\nThis works for any element that inherits from `NtuplesBaseVector`. \r\n\r\nEncapsulation\r\n-------------\r\nI opted to encapsulate this feature inside `x.ufunc` so that we wont have collisions such as `x.multiply` and also so that users know exactly what is happening.\r\n\r\nWith this users can do things like broadcasting addition etc:\r\n\r\n```python\r\n>>> x.ufunc.add(1, out=x)\r\nRn(2).element([2.0, 3.0])\r\n```\r\n\r\nSince we don't know the data storage, the `out` parameter is (by default) handled by calculating the result and then using assignment. However, for the spaces inheriting from `Ntuples` I have added a optimization, so this is as fast as numpy. I'm planning on adding this optimization for `CudaNtuples` as well, but users will only notice it in performance, the functionality is already there.\r\n\r\nMissing ufuncs\r\n--------------\r\nMost ufuncs are in, the only ones missing are:\r\n\r\n* `isreal` -> requires bool output, we don't really support it.\r\n* `iscomplex` -> requires bool output, we don't really support it.\r\n* `ldexp` -> requires integer input.\r\n* `frexp` ->requires integer output.\r\n\r\nTODO:\r\n-----\r\n\r\n- [ ] Possibly add missing ufuncs (if anyone needs them)\r\n- [ ] Add CUDA support\r\n- [x] Add optimization in `DiscreteLp`"},"comment":{"url":"https://api.github.com/repos/odlgroup/odl/issues/comments/162320624","html_url":"https://github.com/odlgroup/odl/pull/115#issuecomment-162320624","issue_url":"https://api.github.com/repos/odlgroup/odl/issues/115","id":162320624,"user":{"login":"adler-j","id":2202312,"avatar_url":"https://avatars.githubusercontent.com/u/2202312?v=3","gravatar_id":"","url":"https://api.github.com/users/adler-j","html_url":"https://github.com/adler-j","followers_url":"https://api.github.com/users/adler-j/followers","following_url":"https://api.github.com/users/adler-j/following{/other_user}","gists_url":"https://api.github.com/users/adler-j/gists{/gist_id}","starred_url":"https://api.github.com/users/adler-j/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adler-j/subscriptions","organizations_url":"https://api.github.com/users/adler-j/orgs","repos_url":"https://api.github.com/users/adler-j/repos","events_url":"https://api.github.com/users/adler-j/events{/privacy}","received_events_url":"https://api.github.com/users/adler-j/received_events","type":"User","site_admin":false},"created_at":"2015-12-06T14:19:19Z","updated_at":"2015-12-06T14:19:19Z","body":"I added the already existing ufuncs to follow the protocol. A comparsion between `sin` which is optimized, and `tan` which is not, shows runtimes (when used in-place)\r\n\r\n```\r\n                           sin :      0.021 \r\n                           tan :      2.891 \r\n```\r\n\r\nAnd out of place:\r\n\r\n```\r\n                           sin :      0.057 \r\n                           tan :      3.026 \r\n```\r\n\r\nQuite an improvement. Im pulling now."}}