{"action":"created","comment":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/50933938","id":50933938,"diff_hunk":"@@ -318,7 +318,215 @@ function sparse_IJ_sorted!{Ti<:Integer}(I::AbstractVector{Ti}, J::AbstractVector\n     return SparseMatrixCSC(m, n, colptr, I, V)\n end\n \n-## sparse() can take its inputs in unsorted order (the parent method is now in csparse.jl)\n+\"\"\"\n+    sparse(I, J, V, [m, n, combine])\n+\n+Create a sparse matrix `S` of dimensions `m` x `n` such that `S[I[k], J[k]] = V[k]`. The\n+`combine` function is used to combine duplicates. If `m` and `n` are not specified, they\n+are set to `maximum(I)` and `maximum(J)` respectively. If the `combine` function is not\n+supplied, duplicates are added by default. All elements of `I` must satisfy\n+`1 <= I[k] <= m`, and all elements of `J` must satisfy `1 <= J[k] <= n`.\n+\n+For additional documentation and an expert driver, see `Base.SparseArrays.sparse!`.\n+\"\"\"\n+function sparse{Tv,Ti<:Integer}(I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{Tv}, m::Integer, n::Integer, combine)\n+    coolen = length(I)\n+    if length(J) != coolen || length(V) != coolen\n+        throw(ArgumentError(string(\"the first three arguments' lengths must match, \",\n+              \"length(I) (=$(length(I))) == length(J) (= $(length(J))) == length(V) (= \",\n+              \"$(length(V)))\")))\n+    end\n+\n+    if m == 0 || n == 0 || coolen == 0\n+        SparseMatrixCSC(m, n, ones(Ti, n+1), Vector{Ti}(), Vector{Tv}())\n+    else\n+        # Allocate storage for CSR form\n+        csrrowptr = Vector{Ti}(m+1)\n+        csrcolval = Vector{Ti}(coolen)\n+        csrnzval = Vector{Tv}(coolen)\n+\n+        # Allocate storage for the CSC form's column pointers and a necessary workspace\n+        csccolptr = Vector{Ti}(n+1)\n+        klasttouch = Vector{Ti}(n)\n+\n+        # Allocate empty arrays for the CSC form's row and nonzero value arrays\n+        # The parent method called below automagically resizes these arrays\n+        cscrowval = Vector{Ti}()\n+        cscnzval = Vector{Tv}()\n+\n+        sparse!(I, J, V, m, n, combine, klasttouch,\n+                csrrowptr, csrcolval, csrnzval,\n+                csccolptr, cscrowval, cscnzval )\n+    end\n+end\n+\n+\"\"\"\n+    sparse!{Tv,Ti<:Integer}(\n+        I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{Tv},\n+        m::Integer, n::Integer, combine, [klasttouch::Vector{Ti},\n+        csrrowptr::Vector{Ti}, csrcolval::Vector{Ti}, csrnzval::Vector{Tv}],\n+        [csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}] )\n+\n+Parent of and expert driver for `sparse`; see `sparse` for basic usage. This method\n+allows the user to provide preallocated storage for `sparse`'s intermediate objects and\n+result as described below. This capability enables more efficient successive construction\n+of SparseMatrixCSCs from coordinate representations, and also enables extraction of an","path":"base/sparse/sparsematrix.jl","position":null,"original_position":57,"commit_id":"ad5dae2e979f86a55ea6f13239ed5b269180a590","original_commit_id":"5b14cfb872deb80964d223cbefb732f0e1add8f7","user":{"login":"Sacha0","id":5799177,"avatar_url":"https://avatars.githubusercontent.com/u/5799177?v=3","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},"body":"Fixed, thanks!","created_at":"2016-01-27T02:24:55Z","updated_at":"2016-01-27T02:24:55Z","html_url":"https://github.com/JuliaLang/julia/pull/14798#discussion_r50933938","pull_request_url":"https://api.github.com/repos/JuliaLang/julia/pulls/14798","_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/50933938"},"html":{"href":"https://github.com/JuliaLang/julia/pull/14798#discussion_r50933938"},"pull_request":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/14798"}}},"pull_request":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/14798","id":57165489,"html_url":"https://github.com/JuliaLang/julia/pull/14798","diff_url":"https://github.com/JuliaLang/julia/pull/14798.diff","patch_url":"https://github.com/JuliaLang/julia/pull/14798.patch","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/14798","number":14798,"state":"open","locked":false,"title":"MIT-licensed sparse() parent method and expert driver","user":{"login":"Sacha0","id":5799177,"avatar_url":"https://avatars.githubusercontent.com/u/5799177?v=3","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},"body":"Followup to #13001, #14631, and #14702. This pull request replaces the LGPL-licensed `sparse` parent method with an MIT-licensed version and introduces an expert driver `sparse!` underlying that method (see documentation for details on the expert driver).\r\n\r\nIn accord with discussion in #12605, #9928, #9906, and #6769, this PR's `sparse` method does not automatically purges numerical zeros. Hence this pull request comments two tests of numerical-zero purging. Rather than simply being commented, perhaps those tests should remain with `dropzeros!(sparse(...))` in place of `sparse(...)` and a reference to this PR?\r\n\r\nHats off to those who contributed to the existing implementation! Matching its performance in all tested cases was challenging. [Benchmarks results](https://gist.github.com/Sacha0/30296d6a55506d0a88a0#file-mitsparse_benchres-jl), [benchmark code](https://gist.github.com/Sacha0/30296d6a55506d0a88a0#file-mitsparse_benchcode-jl); the results should be comprehensible without reading the code. **tl;dr**: In these benchmarks, this PR's implementation ranges from matching the existing implementation's performance to reducing runtime by ~30%, and seems to allocate approximately `Vector{Ti}(m)` + `Vector{Ti}(n)` less storage. Notably the sparser the matrix, the better this PR's implementation's relative performance. Though solving #13400 requires a fundamentally different algorithm, #13400's example serves as an extreme illustration of the preceding point:\r\n```julia\r\nusing Benchmarks\r\n@benchmark sparse([1;100000000], [1;1], [1;1], 100000000, 1, Base.AddFun())\r\n@benchmark mitsparse([1;100000000], [1;1], [1;1], 100000000, 1, Base.AddFun())\r\n```\r\n(with `mitsparse` this PR's implementation) yields\r\n```julia\r\n================ Benchmark Results ========================\r\n     Time per evaluation: 1.94 s [1.90 s, 1.98 s]\r\nProportion of time in GC: 9.71% [9.01%, 10.40%]\r\n        Memory allocated: 2.24 gb\r\n   Number of allocations: 13 allocations\r\n       Number of samples: 4\r\n   Number of evaluations: 4\r\n Time spent benchmarking: 9.67 s\r\n\r\n================ Benchmark Results ========================\r\n     Time per evaluation: 735.76 ms [723.62 ms, 747.89 ms]\r\nProportion of time in GC: 6.50% [5.98%, 7.03%]\r\n        Memory allocated: 762.94 mb\r\n   Number of allocations: 11 allocations\r\n       Number of samples: 12\r\n   Number of evaluations: 12\r\n Time spent benchmarking: 9.73 s\r\n```\r\nWhen editing base/sparse/csparse.jl to remove the existing methods, I folded all blocks to avoid peaking at the LGPL code. So someone should check that the removal was graceful given it was blind but for method signatures.\r\n\r\nApologies for responding slowly elsewhere while working on this!","created_at":"2016-01-26T03:16:52Z","updated_at":"2016-01-27T02:24:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f5edbaea6c566951e54f64c0d570e180ea7fae96","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/JuliaLang/julia/pulls/14798/commits","review_comments_url":"https://api.github.com/repos/JuliaLang/julia/pulls/14798/comments","review_comment_url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments{/number}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/14798/comments","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/ad5dae2e979f86a55ea6f13239ed5b269180a590","head":{"label":"Sacha0:mitsparse","ref":"mitsparse","sha":"ad5dae2e979f86a55ea6f13239ed5b269180a590","user":{"login":"Sacha0","id":5799177,"avatar_url":"https://avatars.githubusercontent.com/u/5799177?v=3","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},"repo":{"id":46197044,"name":"julia","full_name":"Sacha0/julia","owner":{"login":"Sacha0","id":5799177,"avatar_url":"https://avatars.githubusercontent.com/u/5799177?v=3","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},"private":false,"html_url":"https://github.com/Sacha0/julia","description":"The Julia Language: A fresh approach to technical computing.","fork":true,"url":"https://api.github.com/repos/Sacha0/julia","forks_url":"https://api.github.com/repos/Sacha0/julia/forks","keys_url":"https://api.github.com/repos/Sacha0/julia/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Sacha0/julia/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Sacha0/julia/teams","hooks_url":"https://api.github.com/repos/Sacha0/julia/hooks","issue_events_url":"https://api.github.com/repos/Sacha0/julia/issues/events{/number}","events_url":"https://api.github.com/repos/Sacha0/julia/events","assignees_url":"https://api.github.com/repos/Sacha0/julia/assignees{/user}","branches_url":"https://api.github.com/repos/Sacha0/julia/branches{/branch}","tags_url":"https://api.github.com/repos/Sacha0/julia/tags","blobs_url":"https://api.github.com/repos/Sacha0/julia/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Sacha0/julia/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Sacha0/julia/git/refs{/sha}","trees_url":"https://api.github.com/repos/Sacha0/julia/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Sacha0/julia/statuses/{sha}","languages_url":"https://api.github.com/repos/Sacha0/julia/languages","stargazers_url":"https://api.github.com/repos/Sacha0/julia/stargazers","contributors_url":"https://api.github.com/repos/Sacha0/julia/contributors","subscribers_url":"https://api.github.com/repos/Sacha0/julia/subscribers","subscription_url":"https://api.github.com/repos/Sacha0/julia/subscription","commits_url":"https://api.github.com/repos/Sacha0/julia/commits{/sha}","git_commits_url":"https://api.github.com/repos/Sacha0/julia/git/commits{/sha}","comments_url":"https://api.github.com/repos/Sacha0/julia/comments{/number}","issue_comment_url":"https://api.github.com/repos/Sacha0/julia/issues/comments{/number}","contents_url":"https://api.github.com/repos/Sacha0/julia/contents/{+path}","compare_url":"https://api.github.com/repos/Sacha0/julia/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Sacha0/julia/merges","archive_url":"https://api.github.com/repos/Sacha0/julia/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Sacha0/julia/downloads","issues_url":"https://api.github.com/repos/Sacha0/julia/issues{/number}","pulls_url":"https://api.github.com/repos/Sacha0/julia/pulls{/number}","milestones_url":"https://api.github.com/repos/Sacha0/julia/milestones{/number}","notifications_url":"https://api.github.com/repos/Sacha0/julia/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Sacha0/julia/labels{/name}","releases_url":"https://api.github.com/repos/Sacha0/julia/releases{/id}","deployments_url":"https://api.github.com/repos/Sacha0/julia/deployments","created_at":"2015-11-14T23:50:27Z","updated_at":"2015-11-14T23:50:41Z","pushed_at":"2016-01-27T02:23:12Z","git_url":"git://github.com/Sacha0/julia.git","ssh_url":"git@github.com:Sacha0/julia.git","clone_url":"https://github.com/Sacha0/julia.git","svn_url":"https://github.com/Sacha0/julia","homepage":"http://julialang.org/","size":96075,"stargazers_count":0,"watchers_count":0,"language":"Julia","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"JuliaLang:master","ref":"master","sha":"493f913431b103bc37a1b5343bcec0f154bea795","user":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"repo":{"id":1644196,"name":"julia","full_name":"JuliaLang/julia","owner":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/JuliaLang/julia","description":"The Julia Language: A fresh approach to technical computing.","fork":false,"url":"https://api.github.com/repos/JuliaLang/julia","forks_url":"https://api.github.com/repos/JuliaLang/julia/forks","keys_url":"https://api.github.com/repos/JuliaLang/julia/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JuliaLang/julia/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JuliaLang/julia/teams","hooks_url":"https://api.github.com/repos/JuliaLang/julia/hooks","issue_events_url":"https://api.github.com/repos/JuliaLang/julia/issues/events{/number}","events_url":"https://api.github.com/repos/JuliaLang/julia/events","assignees_url":"https://api.github.com/repos/JuliaLang/julia/assignees{/user}","branches_url":"https://api.github.com/repos/JuliaLang/julia/branches{/branch}","tags_url":"https://api.github.com/repos/JuliaLang/julia/tags","blobs_url":"https://api.github.com/repos/JuliaLang/julia/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JuliaLang/julia/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JuliaLang/julia/git/refs{/sha}","trees_url":"https://api.github.com/repos/JuliaLang/julia/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/{sha}","languages_url":"https://api.github.com/repos/JuliaLang/julia/languages","stargazers_url":"https://api.github.com/repos/JuliaLang/julia/stargazers","contributors_url":"https://api.github.com/repos/JuliaLang/julia/contributors","subscribers_url":"https://api.github.com/repos/JuliaLang/julia/subscribers","subscription_url":"https://api.github.com/repos/JuliaLang/julia/subscription","commits_url":"https://api.github.com/repos/JuliaLang/julia/commits{/sha}","git_commits_url":"https://api.github.com/repos/JuliaLang/julia/git/commits{/sha}","comments_url":"https://api.github.com/repos/JuliaLang/julia/comments{/number}","issue_comment_url":"https://api.github.com/repos/JuliaLang/julia/issues/comments{/number}","contents_url":"https://api.github.com/repos/JuliaLang/julia/contents/{+path}","compare_url":"https://api.github.com/repos/JuliaLang/julia/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JuliaLang/julia/merges","archive_url":"https://api.github.com/repos/JuliaLang/julia/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JuliaLang/julia/downloads","issues_url":"https://api.github.com/repos/JuliaLang/julia/issues{/number}","pulls_url":"https://api.github.com/repos/JuliaLang/julia/pulls{/number}","milestones_url":"https://api.github.com/repos/JuliaLang/julia/milestones{/number}","notifications_url":"https://api.github.com/repos/JuliaLang/julia/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JuliaLang/julia/labels{/name}","releases_url":"https://api.github.com/repos/JuliaLang/julia/releases{/id}","deployments_url":"https://api.github.com/repos/JuliaLang/julia/deployments","created_at":"2011-04-21T07:01:50Z","updated_at":"2016-01-26T23:41:21Z","pushed_at":"2016-01-27T02:23:13Z","git_url":"git://github.com/JuliaLang/julia.git","ssh_url":"git@github.com:JuliaLang/julia.git","clone_url":"https://github.com/JuliaLang/julia.git","svn_url":"https://github.com/JuliaLang/julia","homepage":"http://julialang.org/","size":120316,"stargazers_count":6631,"watchers_count":6631,"language":"Julia","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1483,"mirror_url":null,"open_issues_count":1610,"forks":1483,"open_issues":1610,"watchers":6631,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/14798"},"html":{"href":"https://github.com/JuliaLang/julia/pull/14798"},"issue":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/14798"},"comments":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/14798/comments"},"review_comments":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/14798/comments"},"review_comment":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/14798/commits"},"statuses":{"href":"https://api.github.com/repos/JuliaLang/julia/statuses/ad5dae2e979f86a55ea6f13239ed5b269180a590"}}}}