# Vector of upper triangle

**URL:** <https://discourse.julialang.org/t/vector-of-upper-triangle/7764>\
**Category:** General Usage\
**Tags:** question\
**Created:** [December 14, 2017, 3:13pm UTC](https://discourse.julialang.org/t/vector-of-upper-triangle/7764 "2017-12-14T15:13:54Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 14, 2017, 3:13pm UTC](https://discourse.julialang.org/t/vector-of-upper-triangle/7764/1 "2017-12-14T15:13:54Z")

</div>

Is there an elegant way of extracting the upper triangle of a matrix as a vector using `Base`? Besides, of course, writing something like

```julia
function vec_triu(M::AbstractMatrix{T}) where T
    m, n = size(M)
    m == n || throw(error("not square"))
    l = n*(n+1) ÷ 2
    v = Vector{T}(l)
    k = 0
    for i in 1:n
        v[k + (1:i)] = M[1:i, i]
        k += i
    end
    v
end

```

so that

```julia
julia> vec_triu(reshape(1:9, 3, :))
6-element Array{Int64,1}:
 1
 4
 5
 7
 8
 9

```

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [December 14, 2017, 3:57pm UTC](https://discourse.julialang.org/t/vector-of-upper-triangle/7764/2 "2017-12-14T15:57:46Z")

</div>

`M[triu(trues(M))]`

See also [Half Vectorization](https://discourse.julialang.org/t/half-vectorization/7399)

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [December 14, 2017, 3:58pm UTC](https://discourse.julialang.org/t/vector-of-upper-triangle/7764/3 "2017-12-14T15:58:20Z")

</div>

Not that I know, but just FYI, you need to write out the loop; your function allocates (on 0.7 from this week). This does not even make your code longer or harder to read.

```julia
@inbounds for ell=1:i v[k + ell] = M[ell, i] end

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 14, 2017, 6:23pm UTC](https://discourse.julialang.org/t/vector-of-upper-triangle/7764/4 "2017-12-14T18:23:17Z")

</div>

`[A[i, j] for j in indices(A, 1) for i in 1:j]`

It’s allocating a little more than expected, though.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 14, 2017, 7:07pm UTC](https://discourse.julialang.org/t/vector-of-upper-triangle/7764/5 "2017-12-14T19:07:01Z")

</div>

Thanks everyone for the replies. Results below, related code in [gist](https://gist.github.com/tpapp/87e5675b87dbdd7a9a840e546eb20fae).

| function | time (ns) | allocation |
| --- | --- | --- |
| `vec_triu` | 232 | 528 |
| `vec_triu_collect` | 278 | 848 |
| `vec_triu_inbounds` | 201 | 528 |
| `vec_triu_loop` | 37 | 128 |

---

<div class="post-metadata">

**Author:** ![Algopaul](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algopaul/32/37603_2.png) [@Algopaul](https://discourse.julialang.org/u/Algopaul)\
**Post date:** [January 27, 2023, 3:39pm UTC](https://discourse.julialang.org/t/vector-of-upper-triangle/7764/6 "2023-01-27T15:39:19Z")

</div>

Hi everyone, I needed this functionality a lot recently and extracted my code for this into a separate package (I hope this is not overkill) but I removed the allocations in my implementation.  
I hope it helps someone else as well and feedback is much appreciated.

> **[GitHub - Algopaul/TriangularReshapes.jl](https://github.com/Algopaul/TriangularReshapes.jl)**
>
> Contribute to Algopaul/TriangularReshapes.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 27, 2023, 4:35pm UTC](https://discourse.julialang.org/t/vector-of-upper-triangle/7764/7 "2023-01-27T16:35:37Z")

</div>

It seems risky to use `@inbounds` together with one-based indexing, while accepting `AbstracArray`s.

I think it would be wise to either restrict inputs to one-based, _or_ use general indexing, _or_ remove `@inbounds`/`@turbo`.

Simplest solution may be to sprinkle some `require_one_based_indexing` calls in there.

---

<div class="post-metadata">

**Author:** ![Algopaul](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algopaul/32/37603_2.png) [@Algopaul](https://discourse.julialang.org/u/Algopaul)\
**Post date:** [January 30, 2023, 4:17pm UTC](https://discourse.julialang.org/t/vector-of-upper-triangle/7764/8 "2023-01-30T16:17:13Z")

</div>

Thank you very much for your feedback. I have added calls to `require_one_based_indexing` in (hopefully) appropriate places.
