{"action":"created","issue":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/23857","repository_url":"https://api.github.com/repos/JuliaLang/julia","labels_url":"https://api.github.com/repos/JuliaLang/julia/issues/23857/labels{/name}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/23857/comments","events_url":"https://api.github.com/repos/JuliaLang/julia/issues/23857/events","html_url":"https://github.com/JuliaLang/julia/issues/23857","id":260049448,"number":23857,"title":"Division of a sparse matrix by row vector causes 0's to become NaN","user":{"login":"jsams","id":36820,"avatar_url":"https://avatars0.githubusercontent.com/u/36820?v=4","gravatar_id":"","url":"https://api.github.com/users/jsams","html_url":"https://github.com/jsams","followers_url":"https://api.github.com/users/jsams/followers","following_url":"https://api.github.com/users/jsams/following{/other_user}","gists_url":"https://api.github.com/users/jsams/gists{/gist_id}","starred_url":"https://api.github.com/users/jsams/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsams/subscriptions","organizations_url":"https://api.github.com/users/jsams/orgs","repos_url":"https://api.github.com/users/jsams/repos","events_url":"https://api.github.com/users/jsams/events{/privacy}","received_events_url":"https://api.github.com/users/jsams/received_events","type":"User","site_admin":false},"labels":[{"id":97636,"url":"https://api.github.com/repos/JuliaLang/julia/labels/bug","name":"bug","color":"e10c02","default":true},{"id":94575532,"url":"https://api.github.com/repos/JuliaLang/julia/labels/sparse","name":"sparse","color":"fad8c7","default":false}],"state":"closed","locked":false,"assignee":{"login":"Sacha0","id":5799177,"avatar_url":"https://avatars0.githubusercontent.com/u/5799177?v=4","gravatar_id":"","url":"https://api.github.com/users/Sacha0","html_url":"https://github.com/Sacha0","followers_url":"https://api.github.com/users/Sacha0/followers","following_url":"https://api.github.com/users/Sacha0/following{/other_user}","gists_url":"https://api.github.com/users/Sacha0/gists{/gist_id}","starred_url":"https://api.github.com/users/Sacha0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sacha0/subscriptions","organizations_url":"https://api.github.com/users/Sacha0/orgs","repos_url":"https://api.github.com/users/Sacha0/repos","events_url":"https://api.github.com/users/Sacha0/events{/privacy}","received_events_url":"https://api.github.com/users/Sacha0/received_events","type":"User","site_admin":false},"assignees":[{"login":"Sacha0","id":5799177,"avatar_url":"https://avatars0.githubusercontent.com/u/5799177?v=4","gravatar_id":"","url":"https://api.github.com/users/Sacha0","html_url":"https://github.com/Sacha0","followers_url":"https://api.github.com/users/Sacha0/followers","following_url":"https://api.github.com/users/Sacha0/following{/other_user}","gists_url":"https://api.github.com/users/Sacha0/gists{/gist_id}","starred_url":"https://api.github.com/users/Sacha0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sacha0/subscriptions","organizations_url":"https://api.github.com/users/Sacha0/orgs","repos_url":"https://api.github.com/users/Sacha0/repos","events_url":"https://api.github.com/users/Sacha0/events{/privacy}","received_events_url":"https://api.github.com/users/Sacha0/received_events","type":"User","site_admin":false}],"milestone":null,"comments":6,"created_at":"2017-09-24T01:13:37Z","updated_at":"2018-04-25T22:10:57Z","closed_at":"2018-04-23T23:05:16Z","author_association":"NONE","body":"I think the title about says it all. This example creates a sparse CSC matrix with 7 stored entries, but then the division creates 12 stored entries, with the 5 extra being NaN. None of the column means are 0 or near 0, so this should not be happening.\r\n\r\n\r\n```\r\njulia> srand(2);\r\njulia> X = sprand(3, 4, 0.6);\r\njulia> Xmeandiv = X  ./ mean(X, 1)\r\n3×4 SparseMatrixCSC{Float64,Int64} with 12 stored entries:\r\n  [1, 1]  =  1.37231\r\n  [2, 1]  =  1.20439\r\n  [3, 1]  =  0.423301\r\n  [1, 2]  =  1.91425\r\n  [2, 2]  =  NaN\r\n  [3, 2]  =  1.08575\r\n  [1, 3]  =  NaN\r\n  [2, 3]  =  3.0\r\n  [3, 3]  =  NaN\r\n  [1, 4]  =  3.0\r\n  [2, 4]  =  NaN\r\n  [3, 4]  =  NaN\r\n```\r\n\r\ndivision by a column vector doesn't create NaNs, but it does cause explicit 0s to be stored:\r\n```\r\njulia> X ./ mean(X, 2)\r\n3×4 SparseMatrixCSC{Float64,Int64} with 12 stored entries:\r\n  [1, 1]  =  1.90584\r\n  [2, 1]  =  1.91323\r\n  [3, 1]  =  1.50071\r\n  [1, 2]  =  1.72613\r\n  [2, 2]  =  0.0\r\n  [3, 2]  =  2.49929\r\n  [1, 3]  =  0.0\r\n  [2, 3]  =  2.08677\r\n  [3, 3]  =  0.0\r\n  [1, 4]  =  0.36803\r\n  [2, 4]  =  0.0\r\n  [3, 4]  =  0.0\r\n```\r\n\r\nscalar division works as expected\r\n\r\n```\r\njulia> X ./ 3.3\r\n3×4 SparseMatrixCSC{Float64,Int64} with 7 stored entries:\r\n  [1, 1]  =  0.237995\r\n  [2, 1]  =  0.208872\r\n  [3, 1]  =  0.0734115\r\n  [1, 2]  =  0.215552\r\n  [3, 2]  =  0.12226\r\n  [2, 3]  =  0.227818\r\n  [1, 4]  =  0.0459582\r\n```\r\n\r\n(even if this was correct behavior, does it make sense to allow the result of an operation on a sparse matrix to return a dense matrix if the storage requirements will be lower or close to the same?)\r\n\r\n```\r\njulia> versioninfo()\r\nJulia Version 0.6.0\r\nCommit 9036443 (2017-06-19 13:05 UTC)\r\nPlatform Info:\r\n  OS: Linux (x86_64-pc-linux-gnu)\r\n  CPU: Intel(R) Core(TM) i5-7300U CPU @ 2.60GHz\r\n  WORD_SIZE: 64\r\n  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Prescott)\r\n  LAPACK: libopenblas64_\r\n  LIBM: libopenlibm\r\n  LLVM: libLLVM-3.9.1 (ORCJIT, broadwell)\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/comments/384450254","html_url":"https://github.com/JuliaLang/julia/issues/23857#issuecomment-384450254","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/23857","id":384450254,"user":{"login":"jsams","id":36820,"avatar_url":"https://avatars0.githubusercontent.com/u/36820?v=4","gravatar_id":"","url":"https://api.github.com/users/jsams","html_url":"https://github.com/jsams","followers_url":"https://api.github.com/users/jsams/followers","following_url":"https://api.github.com/users/jsams/following{/other_user}","gists_url":"https://api.github.com/users/jsams/gists{/gist_id}","starred_url":"https://api.github.com/users/jsams/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsams/subscriptions","organizations_url":"https://api.github.com/users/jsams/orgs","repos_url":"https://api.github.com/users/jsams/repos","events_url":"https://api.github.com/users/jsams/events{/privacy}","received_events_url":"https://api.github.com/users/jsams/received_events","type":"User","site_admin":false},"created_at":"2018-04-25T22:10:57Z","updated_at":"2018-04-25T22:10:57Z","author_association":"NONE","body":"There were two parts to this bug: The NaNs and the creation of, i believe the term is, 'non-structural zeros' (i.e. zeros stored in the array rather than being implied by the structure of the object). Based on a quick test of the lastest nightly, only the NaNs are fixed. But the NaNs, at least in some instances, have been replaced by these non-structural zeros.\r\n\r\nAs a user, I would not expect broadcast operations to add structural zeros when unnecessary. It might be reasonable to expect them to remove generated zeros, but I understand that can get iffy with floating point comparisons to zero. That said, it looks like non-structural zeros are being pruned in at least some circumstances. So that's nice, but the system isn't perfect. Here's an example set of tests:\r\n\r\n```julia\r\nusing SparseArrays\r\nusing Test\r\n\r\n@test size(sparse([1.0; 0.0]).nzval, 1) == 1\r\n@test_broken size((sparse([1.0; 0.0]) ./ [1.0]).nzval, 1) == 1 # is 2, should be 1\r\n@test size((sparse([1.0; 0.0]) .* [1.0]).nzval, 1) == 1 # expected\r\n@test size((sparse([1.0; 0.0]) .+ [0.0]).nzval, 1) == 1 # expected\r\n@test size((sparse([2.0; 1.0]) .- [1.0]).nzval, 1) == 1 # nice, pruning!\r\n```"}}
{"actor":{"display_login":"jsams"}}