# Isn't it very unintuitive that \`cholesky()\` stores data in the \*upper\* triangular part?

**URL:** https://discourse.julialang.org/t/isnt-it-very-unintuitive-that-cholesky-stores-data-in-the-upper-triangular-part/114123
**Category:** General Usage
**Tags:** linearalgebra
**Created:** [May 10, 2024, 8:46pm UTC](https://discourse.julialang.org/t/isnt-it-very-unintuitive-that-cholesky-stores-data-in-the-upper-triangular-part/114123 "2024-05-10T20:46:52Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![biona001](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/biona001/32/16497_2.png) [@biona001](https://discourse.julialang.org/u/biona001)
#### Post date: [May 10, 2024, 8:46pm UTC](https://discourse.julialang.org/t/isnt-it-very-unintuitive-that-cholesky-stores-data-in-the-upper-triangular-part/114123/1 "2024-05-10T20:46:52Z")

</div>

A cholesky factor for a symmetric matrix `A` is usually described as a **lower triangular** matrix `L` such that `A = LL'`. But in Julia, the actual numerical value of `L` is stored in the **upper triangular** portion of `cholesky(A).factors`, that is, it is transposed.

Why?

This makes it awkward to actually access `L`. For example, how do I write an efficient [half-vectorization](https://en.wikipedia.org/wiki/Vectorization_(mathematics)#Half-vectorization) routine? It feels like I need to throw around a bunch of transposes and `UpperTriangular` calls, and even then it’s still not clear how to access data in column major form.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [May 10, 2024, 9:05pm UTC](https://discourse.julialang.org/t/isnt-it-very-unintuitive-that-cholesky-stores-data-in-the-upper-triangular-part/114123/2 "2024-05-10T21:05:32Z")

</div>

> [@biona001](#):
>
> This makes it awkward to actually access `L`

You can ask for `cholesky(A).L`. More generally, `Cholesky` supports storing its factors either way — see the `uplo` field.

---

<div class="post-metadata">

### Author: ![biona001](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/biona001/32/16497_2.png) [@biona001](https://discourse.julialang.org/u/biona001)
#### Post date: [May 11, 2024, 7:01am UTC](https://discourse.julialang.org/t/isnt-it-very-unintuitive-that-cholesky-stores-data-in-the-upper-triangular-part/114123/3 "2024-05-11T07:01:14Z")

</div>

Thank you, but `cholesky(A).L` seems to be [copying data](https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/cholesky.jl#L522) internally, which is something I want to avoid.

I now see the `uplo` field, but have no idea how to actually change that. For example,

```julia
using LinearAlgebra
x = randn(5, 5);
sigma = x'*x;
L = cholesky(Symmetric(sigma));
L.uplo # returns 'U'

```

I guess `L.uplo == 'U'` means the data is actually stored in `UpperTriangular(L.factors)`, but the [documentation](https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/#LinearAlgebra.cholesky) does not mention how to create a Cholesky type with `L.uplo == 'L'`.

The [cholesky.jl](https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/cholesky.jl) file just seems a bit too complicated for me to just manually call the constructor of `Cholesky <: Factorization` directly.

---

<div class="post-metadata">

### Author: ![anonymous\_shrew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anonymous_shrew/32/210646_2.png) [@anonymous\_shrew](https://discourse.julialang.org/u/anonymous_shrew)
#### Post date: [May 11, 2024, 7:15am UTC](https://discourse.julialang.org/t/isnt-it-very-unintuitive-that-cholesky-stores-data-in-the-upper-triangular-part/114123/4 "2024-05-11T07:15:07Z")

</div>

```julia
julia> C = cholesky(Hermitian([2 1; 1 2], :L))
Cholesky{Float64, Matrix{Float64}}
L factor:
2×2 LowerTriangular{Float64, Matrix{Float64}}:
 1.41421 ⋅ 
 0.707107 1.22474

julia> C.uplo
'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)

```
