@@ -39,31 +39,36 @@ function flatten(::Type{T}, X::Orthogonal) where {T<:Real}
3939end
4040
4141"""
42- positive_definite(X::AbstractMatrix{<:Real})
42+ positive_definite(X::AbstractMatrix{<:Real}, ε = eps(T) )
4343
44- Produce a parameter whose `value` is constrained to be a positive-definite matrix. The argument `X` needs to
45- be a positive-definite matrix (see https://en.wikipedia.org/wiki/Definite_matrix).
44+ Produce a parameter whose `value` is constrained to be a strictly positive-definite
45+ matrix. The argument `X` minus `ε` times the identity needs to be a positive-definite matrix
46+ (see https://en.wikipedia.org/wiki/Definite_matrix). The optional second argument `ε` must
47+ be a positive real number.
4648
4749The unconstrained parameter is a `LowerTriangular` matrix, stored as a vector.
4850"""
49- function positive_definite (X:: AbstractMatrix{<:Real} )
50- isposdef (X) || throw (ArgumentError (" X is not positive-definite" ))
51- return PositiveDefinite (tril_to_vec (cholesky (X). L))
51+ function positive_definite (X:: AbstractMatrix{T} , ε= eps (T)) where {T<: Real }
52+ ε > 0 || throw (ArgumentError (" ε must be positive." ))
53+ _X = X - ε * I
54+ isposdef (_X) || throw (ArgumentError (" X-ε*I is not positive-definite for ε=$ε " ))
55+ return PositiveDefinite (tril_to_vec (cholesky (_X). L), ε)
5256end
5357
54- struct PositiveDefinite{TL<: AbstractVector{<:Real} } <: AbstractParameter
58+ struct PositiveDefinite{TL<: AbstractVector{<:Real} ,Tε <: Real } <: AbstractParameter
5559 L:: TL
60+ ε:: T ε
5661end
5762
58- Base.:(== )(X:: PositiveDefinite , Y:: PositiveDefinite ) = X. L == Y. L
59-
6063A_At (X) = X * X'
6164
62- value (X:: PositiveDefinite ) = A_At (vec_to_tril (X. L))
65+ Base.:(== )(X:: PositiveDefinite , Y:: PositiveDefinite ) = X. L == Y. L && X. ε == Y. ε
66+
67+ value (X:: PositiveDefinite ) = A_At (vec_to_tril (X. L)) + X. ε * I
6368
6469function flatten (:: Type{T} , X:: PositiveDefinite ) where {T<: Real }
6570 v, unflatten_v = flatten (T, X. L)
66- unflatten_PositiveDefinite (v_new:: Vector{T} ) = PositiveDefinite (unflatten_v (v_new))
71+ unflatten_PositiveDefinite (v_new:: Vector{T} ) = PositiveDefinite (unflatten_v (v_new), X . ε )
6772 return v, unflatten_PositiveDefinite
6873end
6974
0 commit comments