# Rank 1 and rank 2 cholesky updates?

**URL:** <https://discourse.julialang.org/t/rank-1-and-rank-2-cholesky-updates/87176>\
**Category:** General Usage\
**Tags:** question, linearalgebra\
**Created:** [September 13, 2022, 1:33am UTC](https://discourse.julialang.org/t/rank-1-and-rank-2-cholesky-updates/87176 "2022-09-13T01:33:45Z")\
**Posts on this page:** 3\
**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:** [September 13, 2022, 1:33am UTC](https://discourse.julialang.org/t/rank-1-and-rank-2-cholesky-updates/87176/1 "2022-09-13T01:33:45Z")

</div>

According to the docs on [lowrankupdate!](https://docs.julialang.org/en/v1.8/stdlib/LinearAlgebra/#LinearAlgebra.lowrankupdate!), I can compute the cholesky factor of `A + vv'` in \mathcal{O}(n^2) time by updating an existing cholesky factor of `A`.

How would this syntax work if I want the cholesky factor of A + e\_i \* e\_j'? Here e\_i and e\_j are zero everywhere except it is 1 at the i or j th position. Clearly e\_i \* e\_j' is a rank 1 matrix, but I don’t think it is possible to write e\_i e\_j' = vv' for some v right?

Actually, what I really need is update according to A + e\_i \* e\_j' + e\_j \* e\_i', i.e. a rank 2 update. Is this achievable?

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [September 13, 2022, 3:04am UTC](https://discourse.julialang.org/t/rank-1-and-rank-2-cholesky-updates/87176/2 "2022-09-13T03:04:05Z")

</div>

A condition to have Cholesky decompositions is that the matrix is positive-definite which requires in particular: symmetric (real case) or Hermitian (complex case). The matrix A + e\_i e\_j^T would break this assumption.  
However, adding A + e\_i e\_j^T + e\_j e\_i^T stays at least symmetric/Hermitian. (But might fail to be positive-definite.)

You could use three steps:  
A + (e\_i + e\_j) (e\_i + e\_j)^T - e\_i e\_i^T - e\_j e\_j^T

That should correspond to one low-rank update and two downgrades, kind of like

```julia
a = randn(3,3)
A = a' * a
ei = [1.0, 0, 0]; ej = [0.0, 1, 0]
C = cholesky(A)
lowrankupdate!(C, ei + ej)
lowrankdowndate!(C, ei)
lowrankdowndate!(C, ej)

```

However, this will fail if a non-positive-definite matrix occurs as any of the results.

---

<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:** [September 13, 2022, 3:48am UTC](https://discourse.julialang.org/t/rank-1-and-rank-2-cholesky-updates/87176/3 "2022-09-13T03:48:00Z")

</div>

Beautiful. Thank you so much.
