@@ -39,31 +39,36 @@ function flatten(::Type{T}, X::Orthogonal) where {T<:Real}
39
39
end
40
40
41
41
"""
42
- positive_definite(X::AbstractMatrix{<:Real})
42
+ positive_definite(X::AbstractMatrix{<:Real}, ε = eps(T) )
43
43
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.
46
48
47
49
The unconstrained parameter is a `LowerTriangular` matrix, stored as a vector.
48
50
"""
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), ε)
52
56
end
53
57
54
- struct PositiveDefinite{TL<: AbstractVector{<:Real} } <: AbstractParameter
58
+ struct PositiveDefinite{TL<: AbstractVector{<:Real} ,Tε <: Real } <: AbstractParameter
55
59
L:: TL
60
+ ε:: T ε
56
61
end
57
62
58
- Base.:(== )(X:: PositiveDefinite , Y:: PositiveDefinite ) = X. L == Y. L
59
-
60
63
A_At (X) = X * X'
61
64
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
63
68
64
69
function flatten (:: Type{T} , X:: PositiveDefinite ) where {T<: Real }
65
70
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 . ε )
67
72
return v, unflatten_PositiveDefinite
68
73
end
69
74
0 commit comments