# Near positive definite (NearPD) of a symmetric matrix in Julia

**URL:** <https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793>\
**Category:** Performance\
**Created:** [August 30, 2020, 3:35pm UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793 "2020-08-30T15:35:16Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kokora](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kokora/32/7867_2.png) [@Kokora](https://discourse.julialang.org/u/Kokora)\
**Post date:** [August 30, 2020, 3:35pm UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/1 "2020-08-30T15:35:16Z")

</div>

Hi all,

Is there a package in Julia which can be used to find a near positive definite matrix to a symmetric matrix?  
In R there is a function nearPD that I can use or the function LaplacesDemon::as.positive.definite.

Thanks

---

<div class="post-metadata">

**Author:** ![lostella](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lostella/32/356_2.png) [@lostella](https://discourse.julialang.org/u/lostella)\
**Post date:** [August 30, 2020, 3:50pm UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/2 "2020-08-30T15:50:33Z")

</div>

[ProximalOperators](https://github.com/kul-forbes/ProximalOperators.jl) exposes the `IndPSD` type, whose proximal operator is the projection onto the positive semidefinite cone (with the Frobenius norm taken as distance).

More info [here](https://kul-forbes.github.io/ProximalOperators.jl/stable/functions/#ProximalOperators.IndPSD).

Is this what you’re looking for?

Edit: an example snippet

```julia
using ProximalOperators

# X is your symmetric matrix
P, _ = prox(IndPSD(), X)

```

---

<div class="post-metadata">

**Author:** ![Kokora](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kokora/32/7867_2.png) [@Kokora](https://discourse.julialang.org/u/Kokora)\
**Post date:** [August 30, 2020, 4:07pm UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/3 "2020-08-30T16:07:58Z")

</div>

> [@lostella](#):
>
> `using ProximalOperators`

@lostella This perfect! Exactly what I was looking for! This is awesome. Thank you very much!  
I will need to incorporate that in a inplace function since I will use this in a MCMC loop.

Also, inv (inverse of a matrix) sometimes fails for a matrix borderline invertible. In R, there is a function as.inverse in the LaplacesDemon package which quickly replaces the smallest eigen values by an epsilon.  
Are you aware of any function that can do that in Julia?

Thanks

---

<div class="post-metadata">

**Author:** ![lostella](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lostella/32/356_2.png) [@lostella](https://discourse.julialang.org/u/lostella)\
**Post date:** [August 30, 2020, 4:23pm UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/4 "2020-08-30T16:23:30Z")

</div>

> [@Kokora](#):
>
> I will need to incorporate that in a inplace function since I will use this in a MCMC loop.

You should be able to use the in-place version

```julia
prox!(P, IndPSD(), X)

```

which will write directly on a preallocated `P`.

I don’t know of anything built-in that takes care of the singularity issue: you could either modify the code from ProximalOperators to account for that (instead of projecting eigenvalues to nonnegative values, you project them to a strictly positive region) or just add `epsilon*I` to `P`.

---

<div class="post-metadata">

**Author:** ![Kokora](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kokora/32/7867_2.png) [@Kokora](https://discourse.julialang.org/u/Kokora)\
**Post date:** [August 30, 2020, 4:49pm UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/5 "2020-08-30T16:49:45Z")

</div>

Great! Indeed adding epsilon\*I to P seems to do the trick. This works just perfect for me now!  
I greatly appreciated your help.  
Thank you!

---

<div class="post-metadata">

**Author:** ![lostella](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lostella/32/356_2.png) [@lostella](https://discourse.julialang.org/u/lostella)\
**Post date:** [August 31, 2020, 9:46am UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/6 "2020-08-31T09:46:00Z")

</div>

Feel free to mark my answer as a solution, so that other people can easily spot it. And of course if a better solution is given, feel free to mark that instead 😉

---

<div class="post-metadata">

**Author:** ![Kokora](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kokora/32/7867_2.png) [@Kokora](https://discourse.julialang.org/u/Kokora)\
**Post date:** [August 31, 2020, 10:23pm UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/7 "2020-08-31T22:23:36Z")

</div>

indeed your answer works for me! How do I do mark your answer as the solution?  
I am new to this.

---

<div class="post-metadata">

**Author:** ![PGS62](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pgs62/32/207030_2.png) [@PGS62](https://discourse.julialang.org/u/PGS62)\
**Post date:** [October 2, 2024, 9:28am UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/8 "2024-10-02T09:28:18Z")

</div>

This is an old thread, to which Google directed me when I was looking for something equivalent to R’s `nearPD`. But these days I think a simpler solution is:

> **[GitHub - adknudson/NearestCorrelationMatrix.jl: Compute the nearest correlation matrix using a...](https://github.com/adknudson/NearestCorrelationMatrix.jl)**
>
> Compute the nearest correlation matrix using a pure Julia implementation

---

<div class="post-metadata">

**Author:** ![jonasaugust](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonasaugust/32/11942_2.png) [@jonasaugust](https://discourse.julialang.org/u/jonasaugust)\
**Post date:** [October 2, 2024, 11:05am UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/9 "2024-10-02T11:05:48Z")

</div>

These implementations differ on whether they constrain the resulting matrix to have 1’s along the diagonal, as required for a correlation matrix. General positive definite matrices such as covariance matrices need not have unit diagonal.

From what I can tell:

NearestCorrelationMatrix.jl seems to require unit diagonal, without an option to turn that constraint off.

ProximalOperators.jl’s IndPSD has no option to enforce unit diagonal.

R’s nearPD gives a selectable option.

If the unit diagonal constraint isn’t required and the input is symmetric (as for OP), basically one merely needs to clip the eigenvalues at zero (or `epsilon`).

---

<div class="post-metadata">

**Author:** ![Nikos\_Gianniotis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nikos_gianniotis/32/11487_2.png) [@Nikos\_Gianniotis](https://discourse.julialang.org/u/Nikos_Gianniotis)\
**Post date:** [October 15, 2024, 7:57am UTC](https://discourse.julialang.org/t/near-positive-definite-nearpd-of-a-symmetric-matrix-in-julia/45793/10 "2024-10-15T07:57:21Z")

</div>

For what it’s worth, here is my own working solution (probably suboptimal in performance) following the excellent sources (hope it’s available) of [https://nhigham.com/2021/01/26/what-is-the-nearest-positive-semidefinite-matrix/](https://nhigham.com/2021/01/26/what-is-the-nearest-positive-semidefinite-matrix/):

```julia
# Needs LinearAlgebra
function nearestposdef(A; minimumeigenvalue = 1e-6)

    Evalues, Evector = eigen(A)

    newA = Evector * Diagonal(max.(Evalues, minimumeigenvalue)) * Evector'

    Symmetric(newA)

end

```
