41
41
"""
42
42
positive_semidefinite(X::AbstractMatrix{<:Real})
43
43
44
- Produce a parameter whose `value` is constrained to be a positive-semidefinite 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 positive-semidefinite matrix. The
45
+ argument `X` needs to be a positive-definite matrix
46
+ (see https://en.wikipedia.org/wiki/Definite_matrix).
46
47
47
48
The unconstrained parameter is a `LowerTriangular` matrix, stored as a vector.
48
49
@@ -57,6 +58,23 @@ function positive_semidefinite(X::AbstractMatrix{<:Real})
57
58
return PositiveSemiDefinite (tril_to_vec (cholesky (X). L))
58
59
end
59
60
61
+ """
62
+ positive_definite(X::AbstractMatrix{<:Real}, ε = eps(T))
63
+
64
+ Produce a parameter whose `value` is constrained to be a strictly positive-semidefinite
65
+ matrix. The argument `X` minus `ε` times the identity needs to be a positive-definite matrix
66
+ (see https://en.wikipedia.org/wiki/Definite_matrix). The optional second argument `ε` must
67
+ be a positive real number.
68
+
69
+ The unconstrained parameter is a `LowerTriangular` matrix, stored as a vector.
70
+ """
71
+ function positive_definite (X:: AbstractMatrix{T} , ε = eps (T)) where T <: Real
72
+ ε > 0 || throw (ArgumentError (" ε is not positive. Use `positive_semidefinite` instead." ))
73
+ _X = X - ε * I
74
+ isposdef (_X) || throw (ArgumentError (" X-ε*I is not positive-definite for ε=$ε " ))
75
+ return PositiveDefinite (tril_to_vec (cholesky (_X). L), ε)
76
+ end
77
+
60
78
struct PositiveSemiDefinite{TL<: AbstractVector{<:Real} } <: AbstractParameter
61
79
L:: TL
62
80
end
@@ -73,6 +91,21 @@ function flatten(::Type{T}, X::PositiveSemiDefinite) where {T<:Real}
73
91
return v, unflatten_PositiveSemiDefinite
74
92
end
75
93
94
+ struct PositiveDefinite{TL<: AbstractVector{<:Real} , Tε<: Real } <: AbstractParameter
95
+ L:: TL
96
+ ε:: T ε
97
+ end
98
+
99
+ Base.:(== )(X:: PositiveDefinite , Y:: PositiveDefinite ) = X. L == Y. L
100
+
101
+ value (X:: PositiveDefinite ) = A_At (vec_to_tril (X. L)) + X. ε * I
102
+
103
+ function flatten (:: Type{T} , X:: PositiveDefinite ) where {T<: Real }
104
+ v, unflatten_v = flatten (T, X. L)
105
+ unflatten_PositiveDefinite (v_new:: Vector{T} ) = PositiveDefinite (unflatten_v (v_new), X. ε)
106
+ return v, unflatten_PositiveDefinite
107
+ end
108
+
76
109
# Convert a vector to lower-triangular matrix
77
110
function vec_to_tril (v:: AbstractVector{T} ) where {T}
78
111
n_vec = length (v)
0 commit comments