From a matrix m
, construct a "close" positive definite
one.
posdefify(m, method = c("someEVadd", "allEVadd"),
symmetric = TRUE, eigen.m = eigen(m, symmetric= symmetric),
eps.ev = 1e-07)
a matrix of the same dimensions and the “same” diagonal
(i.e. diag
) as m
but with the property to
be positive definite.
a numeric (square) matrix.
a string specifying the method to apply; can be abbreviated.
logical, simply passed to eigen
(unless
eigen.m
is specified); currently, we do not see any reason
for not using TRUE
.
the eigen
value decomposition of
m
, can be specified in case it is already available.
number specifying the tolerance to use, see Details below.
Martin Maechler, July 2004
We form the eigen decomposition $$m = V \Lambda V'$$ where \(\Lambda\) is the diagonal matrix of eigenvalues, \(\Lambda_{j,j} = \lambda_j\), with decreasing eigenvalues \(\lambda_1 \ge \lambda_2 \ge \ldots \ge \lambda_n\).
When the smallest eigenvalue \(\lambda_n\) are less than
Eps <- eps.ev * abs(lambda[1])
, i.e., negative or “almost
zero”, some or all eigenvalues are replaced by positive
(>= Eps
) values,
\(\tilde\Lambda_{j,j} = \tilde\lambda_j\).
Then, \(\tilde m = V \tilde\Lambda V'\) is computed
and rescaled in order to keep the original diagonal (where that is
>= Eps
).
Section 4.4.2 of Gill, P.~E., Murray, W. and Wright, M.~H. (1981) Practical Optimization, Academic Press.
Cheng, Sheung Hun and Higham, Nick (1998) A Modified Cholesky Algorithm Based on a Symmetric Indefinite Factorization; SIAM J. Matrix Anal.\ Appl., 19, 1097--1110.
Knol DL, ten Berge JMF (1989) Least-squares approximation of an improper correlation matrix by a proper one. Psychometrika 54, 53--61.
Highham (2002) Computing the nearest correlation matrix - a problem from finance; IMA Journal of Numerical Analysis 22, 329--343.
Lucas (2001) Computing nearest covariance and correlation matrices. A thesis submitted to the University of Manchester for the degree of Master of Science in the Faculty of Science and Engeneering.
set.seed(12)
m <- matrix(round(rnorm(25),2), 5, 5); m <- 1+ m + t(m); diag(m) <- diag(m) + 4
m
posdefify(m)
1000 * zapsmall(m - posdefify(m))
Run the code above in your browser using DataLab