{"action":"created","comment":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/73758665","id":73758665,"diff_hunk":"@@ -1269,134 +1269,116 @@ end\n \n ## Unary arithmetic and boolean operators\n \n-macro _unary_op_nz2z_z2z(op,A,Tv,Ti)\n-    esc(quote\n-        nfilledA = nnz($A)\n-        colptrB = Array{$Ti}($A.n+1)\n-        rowvalB = Array{$Ti}(nfilledA)\n-        nzvalB = Array{$Tv}(nfilledA)\n-\n-        nzvalA = $A.nzval\n-        colptrA = $A.colptr\n-        rowvalA = $A.rowval\n-\n-        k = 0 # number of additional zeros introduced by op(A)\n-        @inbounds for i = 1 : $A.n\n-            colptrB[i] = colptrA[i] - k\n-            for j = colptrA[i] : colptrA[i+1]-1\n-                opAj = $(op)(nzvalA[j])\n-                if opAj == 0\n-                    k += 1\n-                else\n-                    rowvalB[j - k] = rowvalA[j]\n-                    nzvalB[j - k] = opAj\n-                end\n-            end\n-        end\n-        colptrB[end] = $A.colptr[end] - k\n-        deleteat!(rowvalB, colptrB[end]:nfilledA)\n-        deleteat!(nzvalB, colptrB[end]:nfilledA)\n-        return SparseMatrixCSC($A.m, $A.n, colptrB, rowvalB, nzvalB)\n-    end) # quote\n-end\n-\n-# Operations that may map nonzeros to zero, and zero to zero\n-# Result is sparse\n-for op in (:ceil, :floor, :trunc, :round,\n-           :sin, :tan, :asin, :atan,\n-           :sinh, :tanh, :asinh, :atanh,\n-           :sinpi, :cosc,\n-           :sind, :tand, :asind, :atand)\n-    @eval begin\n-        $(op){Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}) = @_unary_op_nz2z_z2z($op,A,Tv,Ti)\n-    end # quote\n-end # macro\n-\n-for op in (:real, :imag)\n-    @eval begin\n-        ($op){Tv<:Complex,Ti}(A::SparseMatrixCSC{Tv,Ti}) = @_unary_op_nz2z_z2z($op,A,Tv.parameters[1],Ti)\n-    end # quote\n-end # macro\n-real{Tv<:Number,Ti}(A::SparseMatrixCSC{Tv,Ti}) = copy(A)\n-imag{Tv<:Number,Ti}(A::SparseMatrixCSC{Tv,Ti}) = spzeros(Tv, Ti, A.m, A.n)\n-\n-for op in (:ceil, :floor, :trunc, :round)\n-    @eval begin\n-        ($op){T,Tv,Ti}(::Type{T},A::SparseMatrixCSC{Tv,Ti}) = @_unary_op_nz2z_z2z($op,A,T,Ti)\n-    end # quote\n-end # macro\n-\n-\n-# Operations that map nonzeros to nonzeros, and zeros to zeros\n-# Result is sparse\n-for op in (:-, :log1p, :expm1)\n-    @eval begin\n-\n-        function ($op)(A::SparseMatrixCSC)\n-            B = similar(A)\n-            nzvalB = B.nzval\n-            nzvalA = A.nzval\n-            @simd for i=1:length(nzvalB)\n-                @inbounds nzvalB[i] = ($op)(nzvalA[i])\n-            end\n-            return B\n-        end\n-\n-    end\n-end\n-\n-function abs{Tv<:Complex,Ti}(A::SparseMatrixCSC{Tv,Ti})\n-    T = Tv.parameters[1]\n-    (T <: Integer) && (T = (T <: BigInt) ? BigFloat : Float64)\n-    @_unary_op_nz2z_z2z(abs,A,T,Ti)\n-end\n-abs2{Tv<:Complex,Ti}(A::SparseMatrixCSC{Tv,Ti}) = @_unary_op_nz2z_z2z(abs2,A,Tv.parameters[1],Ti)\n-for op in (:abs, :abs2)\n-    @eval begin\n-        function ($op){Tv<:Number,Ti}(A::SparseMatrixCSC{Tv,Ti})\n-            B = similar(A)\n-            nzvalB = B.nzval\n-            nzvalA = A.nzval\n-            @simd for i=1:length(nzvalB)\n-                @inbounds nzvalB[i] = ($op)(nzvalA[i])\n+\"\"\"\n+Helper macro for the unary broadcast definitions below. Takes parent method `fp` and a set\n+of desired child methods `fcs`, and builds an expression defining each of the child methods\n+such that `broadcast(::typeof(fc), A::SparseMatrixCSC) = fp(fc, A)`.\n+\"\"\"\n+macro _enumerate_childmethods(fp, fcs...)\n+    fcexps = Expr(:block)\n+    for fc in fcs\n+        push!(fcexps.args, :( broadcast(::typeof($(esc(fc))), A::SparseMatrixCSC) = $(esc(fp))($(esc(fc)), A) ) )\n+    end\n+    return fcexps\n+end\n+\n+# Operations that map zeros to zeros and may map nonzeros to zeros, yielding a sparse matrix\n+\"\"\"\n+Takes unary function `f` that maps zeros to zeros and may map nonzeros to zeros, and returns\n+a new `SparseMatrixCSC{TiA,TvB}` `B` generated by applying `f` to each nonzero entry in\n+`A` and retaining only the resulting nonzeros.\n+\"\"\"\n+function _broadcast_unary_nz2z_z2z_T{TvA,TiA,TvB}(f::Function, A::SparseMatrixCSC{TvA,TiA}, ::Type{TvB})\n+    Bcolptr = Array{TiA}(A.n + 1)\n+    Browval = Array{TiA}(nnz(A))\n+    Bnzval = Array{TvB}(nnz(A))\n+    Bk = 1\n+    @inbounds for j in 1:A.n\n+        Bcolptr[j] = Bk\n+        for Ak in nzrange(A, j)\n+            x = f(A.nzval[Ak])\n+            if x != 0\n+                Browval[Bk] = A.rowval[Ak]\n+                Bnzval[Bk] = x\n+                Bk += 1\n             end\n-            return B\n         end\n     end\n-end\n-\n+    Bcolptr[A.n + 1] = Bk\n+    resize!(Browval, Bk - 1)\n+    resize!(Bnzval, Bk - 1)\n+    return SparseMatrixCSC(A.m, A.n, Bcolptr, Browval, Bnzval)\n+end\n+function _broadcast_unary_nz2z_z2z{Tv}(f::Function, A::SparseMatrixCSC{Tv})\n+    _broadcast_unary_nz2z_z2z_T(f, A, Tv)\n+end\n+@_enumerate_childmethods(_broadcast_unary_nz2z_z2z,\n+    sin, sinh, sind, asin, asinh, asind,\n+    tan, tanh, tand, atan, atanh, atand,\n+    sinpi, cosc, ceil, floor, trunc, round)\n+broadcast(::typeof(real), A::SparseMatrixCSC) = copy(A)\n+broadcast{Tv,Ti}(::typeof(imag), A::SparseMatrixCSC{Tv,Ti}) = spzeros(Tv, Ti, A.m, A.n)\n+broadcast{TTv}(::typeof(real), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2z_z2z_T(real, A, TTv)\n+broadcast{TTv}(::typeof(imag), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2z_z2z_T(imag, A, TTv)\n+ceil{To}(::Type{To}, A::SparseMatrixCSC) = _broadcast_unary_nz2z_z2z_T(ceil, A, To)\n+floor{To}(::Type{To}, A::SparseMatrixCSC) = _broadcast_unary_nz2z_z2z_T(floor, A, To)\n+trunc{To}(::Type{To}, A::SparseMatrixCSC) = _broadcast_unary_nz2z_z2z_T(trunc, A, To)\n+round{To}(::Type{To}, A::SparseMatrixCSC) = _broadcast_unary_nz2z_z2z_T(round, A, To)\n+\n+# Operations that map zeros to zeros and map nonzeros to nonzeros, yielding a sparse matrix\n+\"\"\"\n+Takes unary function `f` that maps zeros to zeros and nonzeros to nonzeros, and returns a\n+new `SparseMatrixCSC{TiA,TvB}` `B` generated by applying `f` to each nonzero entry in `A`.\n+\"\"\"\n+function _broadcast_unary_nz2nz_z2z_T{TvA,TiA,TvB}(f::Function, A::SparseMatrixCSC{TvA,TiA}, ::Type{TvB})\n+    Bcolptr = Vector{TiA}(A.n + 1)\n+    Browval = Vector{TiA}(nnz(A))\n+    Bnzval = Vector{TvB}(nnz(A))\n+    copy!(Bcolptr, 1, A.colptr, 1, A.n + 1)\n+    copy!(Browval, 1, A.rowval, 1, nnz(A))\n+    @inbounds @simd for k in 1:nnz(A)\n+        Bnzval[k] = f(A.nzval[k])\n+    end\n+    return SparseMatrixCSC(A.m, A.n, Bcolptr, Browval, Bnzval)\n+end\n+function _broadcast_unary_nz2nz_z2z{Tv}(f::Function, A::SparseMatrixCSC{Tv})\n+    _broadcast_unary_nz2nz_z2z_T(f, A, Tv)\n+end\n+@_enumerate_childmethods(_broadcast_unary_nz2nz_z2z,\n+    log1p, expm1, abs, abs2, conj)\n+broadcast{TTv}(::typeof(abs2), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs2, A, TTv)\n+broadcast{TTv}(::typeof(abs), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs, A, TTv)\n+broadcast{TTv<:Integer}(::typeof(abs), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs, A, Float64)\n+broadcast{TTv<:BigInt}(::typeof(abs), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs, A, BigFloat)\n function conj!(A::SparseMatrixCSC)\n-    nzvalA = A.nzval\n-    @simd for i=1:length(nzvalA)\n-        @inbounds nzvalA[i] = conj(nzvalA[i])\n+    @inbounds @simd for k in 1:nnz(A)\n+        A.nzval[k] = conj(A.nzval[k])\n     end\n     return A\n end\n \n-conj(A::SparseMatrixCSC) = conj!(copy(A))\n-\n-# Operations that map nonzeros to nonzeros, and zeros to nonzeros\n-# Result is dense\n-for op in (:cos, :cosh, :acos, :sec, :csc, :cot, :acot, :sech,\n-           :csch, :coth, :asech, :acsch, :cospi, :sinc, :cosd,\n-           :cotd, :cscd, :secd, :acosd, :acotd, :log, :log2, :log10,\n-           :exp, :exp2, :exp10)\n-    @eval begin\n-\n-        function ($op){Tv}(A::SparseMatrixCSC{Tv})\n-            B = fill($(op)(zero(Tv)), size(A))\n-            @inbounds for col = 1 : A.n\n-                for j = A.colptr[col] : A.colptr[col+1]-1\n-                    row = A.rowval[j]\n-                    nz = A.nzval[j]\n-                    B[row,col] = $(op)(nz)\n-                end\n-            end\n-            return B\n+# Operations that map both zeros and nonzeros to zeros, yielding a dense matrix\n+\"\"\"\n+Takes unary function `f` that maps both zeros and nonzeros to nonzeros, and returns a new\n+`Matrix{TvB}` `B` effectively generated by applying `f` to every entry in `A`.","path":"base/sparse/sparsematrix.jl","position":null,"original_position":211,"commit_id":"d380f1a9b9a42f3fb637c33031518adb32bb6704","original_commit_id":"e2042d714dbd15461d7473ec2e27d64ffd15a9a1","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":"Good call. Clarified in docstring. Thanks! ","created_at":"2016-08-05T21:00:14Z","updated_at":"2016-08-05T21:00:14Z","html_url":"https://github.com/JuliaLang/julia/pull/17265#discussion_r73758665","pull_request_url":"https://api.github.com/repos/JuliaLang/julia/pulls/17265","_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/73758665"},"html":{"href":"https://github.com/JuliaLang/julia/pull/17265#discussion_r73758665"},"pull_request":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/17265"}}},"pull_request":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/17265","id":76103634,"html_url":"https://github.com/JuliaLang/julia/pull/17265","diff_url":"https://github.com/JuliaLang/julia/pull/17265.diff","patch_url":"https://github.com/JuliaLang/julia/pull/17265.patch","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/17265","number":17265,"state":"open","locked":false,"title":"De-eval-ify vectorized unary functions over SparseMatrixCSCs, and then transition them to compact broadcast syntax","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":"Edit: Ref. #16285 and #11474.\r\n\r\nThis PR's first commit revises the implementation of vectorized unary functions over `SparseMatrixCSC`s, leveraging higher order functions to displace a set of macros and `eval`s. Regarding performance, see below.\r\n\r\nThis PR's second commit then transitions those vectorized unary functions over `SparseMatrixCSC`s to compact broadcast syntax, accordingly revises the associated tests, expands those tests, and then adds deprecations for the vectorized calls.\r\n\r\n**Question**: Both the existing code and that in this PR separate unary functions into three classes (with disjoint logic): (1) unary functions that map zeros to zeros and may map nonzeros to zeros; (2) unary functions that map zeros to zeros and nonzeros to nonzeros; and (3) unary functions that map both zeros and nonzeros to nonzeros. In the first class, when a nonzero in the original sparse matrix miraculously maps to exact zero under, e.g., `sin`, the implementation expunges that entry. This behavior seems like a holdover from the aggressive-stored-zero-expunging era, now inconsistent with behavior elsewhere. Perhaps classes one and two should be merged? Merging those two classes would enable some code reduction and might increase the performance of operations presently falling under class one (by eliminating a branch in an inner loop, and enabling `@simd` decoration of that inner loop). Thoughts?\r\n\r\n**Perf**\r\nWith the exception of `real` and `imag`, for functions in the first class the existing and new implementations perform similarly or slightly favor the new implementation. The new implementation seems to resolve a type instability or so with `real` and `imag`, significantly improving performance: Where `real` is the existing implementation and `ho_real` this PR's, this bench\r\n```julia\r\nusing BenchmarkTools\r\n\r\nsmallN = 10^1; smallA = sprand(smallN, smallN, 5/smallN); smallC = smallA + im*smallA;\r\nlargeN = 10^6; largeA = sprand(largeN, largeN, 10/largeN); largeC = largeA + im*largeA;\r\n\r\npresmat = smallC;\r\nbenchpres = @benchmarkable real(Float64, presmat); tune!(benchpres);\r\nbenchnew = @benchmarkable ho_real(Float64, presmat); tune!(benchnew);\r\nmedianpres = median(run(benchpres));\r\nmediannew = median(run(benchnew));\r\nprintln(ratio(mediannew, medianpres))\r\n```\r\nfor `presmat = smallC` yields\r\n```julia\r\nBenchmarkTools.TrialRatio:\r\n  time:             0.07120253164556962\r\n  gctime:           1.0\r\n  memory:           0.5189873417721519\r\n  allocs:           0.06557377049180328\r\n  time tolerance:   5.00%\r\n  memory tolerance: 1.00%\r\n```\r\nand for `presmat = largeC` yields\r\n```julia\r\nBenchmarkTools.TrialRatio:\r\n  time:             0.16305659839888223\r\n  gctime:           0.16709694727350574\r\n  memory:           0.3442608362244807\r\n  allocs:           3.4976803383995736e-7\r\n  time tolerance:   5.00%\r\n  memory tolerance: 1.00%\r\n```\r\nFor functions in the second class, this PR's implementation exhibits significantly better performance on small matrices and somewhat better on large matrices, e.g. for the bench above with `presmat = smallA`, comparing `expm1` and `ho_expm1` yields\r\n```julia\r\nBenchmarkTools.TrialRatio:\r\n  time:             0.18331303288672351\r\n  gctime:           1.0\r\n  memory:           0.7735849056603774\r\n  allocs:           0.4\r\n  time tolerance:   5.00%\r\n  memory tolerance: 1.00%\r\n```\r\nand for `presmat = largeA`\r\n```julia\r\nBenchmarkTools.TrialRatio:\r\n  time:             0.8084212063475197\r\n  gctime:           0.9765840983181242\r\n  memory:           0.9999974302672074\r\n  allocs:           0.4375\r\n  time tolerance:   5.00%\r\n  memory tolerance: 1.00%\r\n```\r\nThis PR's implementation also appears to resolve a type instability or so with `abs` and `abs2`, e.g. comparing `abs2` and `ho_abs2` for `presmat = smallC` the above bench yields\r\n```julia\r\nBenchmarkTools.TrialRatio:\r\n  time:             0.05240027045300879\r\n  gctime:           1.0\r\n  memory:           0.5189873417721519\r\n  allocs:           0.06557377049180328\r\n  time tolerance:   5.00%\r\n  memory tolerance: 1.00%\r\n```\r\nand for `presmat = largeC`\r\n```julia\r\nBenchmarkTools.TrialRatio:\r\n  time:             0.11257829481710147\r\n  gctime:           0.1572109282310488\r\n  memory:           0.3442608362244807\r\n  allocs:           3.4976803383995736e-7\r\n  time tolerance:   5.00%\r\n  memory tolerance: 1.00%\r\n```\r\nFor functions in the third class, performance differences are within the noise. Best!","created_at":"2016-07-04T01:09:43Z","updated_at":"2016-08-05T21:00:14Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a2d8a9dbd80cd729c76af4e112d0cf2d27dc7a1a","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/JuliaLang/julia/pulls/17265/commits","review_comments_url":"https://api.github.com/repos/JuliaLang/julia/pulls/17265/comments","review_comment_url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments{/number}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/17265/comments","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/d380f1a9b9a42f3fb637c33031518adb32bb6704","head":{"label":"Sacha0:unarybcastspmat","ref":"unarybcastspmat","sha":"d380f1a9b9a42f3fb637c33031518adb32bb6704","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-08-05T20:59:52Z","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":96188,"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":"f9fb4dae619ce2f9e7b3aa466b27e4c4f6aff11b","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-08-05T16:27:10Z","pushed_at":"2016-08-05T20:59:52Z","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":409255,"stargazers_count":7336,"watchers_count":7336,"language":"Julia","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1704,"mirror_url":null,"open_issues_count":1871,"forks":1704,"open_issues":1871,"watchers":7336,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/17265"},"html":{"href":"https://github.com/JuliaLang/julia/pull/17265"},"issue":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/17265"},"comments":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/17265/comments"},"review_comments":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/17265/comments"},"review_comment":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/17265/commits"},"statuses":{"href":"https://api.github.com/repos/JuliaLang/julia/statuses/d380f1a9b9a42f3fb637c33031518adb32bb6704"}}}}
{"actor":{"display_login":"Sacha0"}}