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