# Sparse transpose

**URL:** https://discourse.julialang.org/t/sparse-transpose/12869
**Category:** General Usage
**Created:** [August 3, 2018, 9:34pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869 "2018-08-03T21:34:12Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)
#### Post date: [August 3, 2018, 9:34pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869/1 "2018-08-03T21:34:12Z")

</div>

In regard to 0.7.0-beta2, the transpose of a `SparseMatrixCSC` is no longer a `SparseMatrixCSC`; instead it is some other object. How do I convert it to `SparseMatrixCSC`? Below are a couple of obvious things I tried. Both work fine for small matrices, but both take a really long time on big matrices, so I guess there must be a better way? I suppose I could manually pick apart the is,js,es, but that wasn’t necessary in 0.6.

```julia
julia> import SparseArrays.sparse

julia> import SparseArrays.spzeros

julia> x = spzeros(10000,10000)
10000×10000 SparseArrays.SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> y = sparse(x')
10000×10000 SparseArrays.SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> x = spzeros(100000,100000)
100000×100000 SparseArrays.SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> y = sparse(x')
100000×100000 SparseArrays.SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> import SparseArrays.SparseMatrixCSC

julia> x = spzeros(100000,100000)
100000×100000 SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> y = convert(SparseMatrixCSC{Float64,Int}, x')
100000×100000 SparseMatrixCSC{Float64,Int64} with 0 stored entries

```

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 3, 2018, 9:49pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869/2 "2018-08-03T21:49:55Z")

</div>

```julia
julia> @time SparseMatrixCSC(x')
  0.001013 seconds (11 allocations: 781.797 KiB)
100000×100000 SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> @time copy(x')
  0.001040 seconds (11 allocations: 781.797 KiB)
100000×100000 SparseMatrixCSC{Float64,Int64} with 0 stored entries

```

Seems like there is some problem with dispatch that makes the explicit parameter constructor slow.

---

<div class="post-metadata">

### Author: ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)
#### Post date: [August 3, 2018, 9:57pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869/3 "2018-08-03T21:57:32Z")

</div>

Here’s another sparse-transpose performance problem/regression. (The first `hcat` call is fast, the second is really slow.) EDIT: I can fix the second invocation to `hcat` by replacing `y'` with `SparseMatrixCSC(y')`.

```julia
julia> import SparseArrays.spzeros

julia> x = spzeros(100000,100000)
100000×100000 SparseArrays.SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> y = spzeros(100000,100000)
100000×100000 SparseArrays.SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> m = hcat(x,y)
100000×200000 SparseArrays.SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> n = hcat(x,y')
100000×200000 SparseArrays.SparseMatrixCSC{Float64,Int64} with 0 stored entries

```

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 3, 2018, 10:08pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869/4 "2018-08-03T22:08:18Z")

</div>

Yes, lazy adjoint creates a lot more methods that need to be dispatched to optimized versions. Failing to do so will lead to slow execution (brutally slow for very sparse matrices). The curse of the correct but slow fallback. You can always materialize the adjoint though which is what you do when you add `SparseMatrixCSC` (or `copy`).

---

<div class="post-metadata">

### Author: ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)
#### Post date: [August 3, 2018, 10:13pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869/5 "2018-08-03T22:13:15Z")

</div>

In my opinion, this tradeoff has been decided in the wrong way. (I encountered related problems and bugs when porting my code from 0.5 to 0.6 last year.) Sparse matrix methods should never silently fall back to dense matrix methods unless the user explicitly calls convert-to-dense. For other aspects of Julia, correct-but-slow may be acceptable, but in the case of sparse matrices, the whole point of using them is performance!

Should I open an issue?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 3, 2018, 10:14pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869/6 "2018-08-03T22:14:43Z")

</div>

> [@Stephen\_Vavasis](#):
>
> Should I open an issue?

About what? To make `SparseMatrixCSC` not an `AbstractMatrix`? To remove `getindex` from it?

---

<div class="post-metadata">

### Author: ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)
#### Post date: [August 3, 2018, 10:17pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869/7 "2018-08-03T22:17:18Z")

</div>

I meant: an issue asking someone to provide the missing methods.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 3, 2018, 10:21pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869/8 "2018-08-03T22:21:51Z")

</div>

Yes, that is definitely a good idea.

---

<div class="post-metadata">

### Author: ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)
#### Post date: [August 3, 2018, 10:49pm UTC](https://discourse.julialang.org/t/sparse-transpose/12869/9 "2018-08-03T22:49:29Z")

</div>

Done.  
[https://github.com/JuliaLang/julia/issues/28432](https://github.com/JuliaLang/julia/issues/28432)
