# Transform the phylogenetic matrix from positive semidefinite to positive definite

I’m working on construct a phylogenetic model using brms.
Previously, the below model was converged, but now it became to produce an error, “Within-group covariance matrices must be positive definite”. I feel the part of code `tree_vcvc_new <- tree_vcvc + 0.000001 * tree_vcvc` is not appropriate. How is the right way to transform the matrix to positive definite?

``````tree_vcvc <- ape::vcv(tree.c\$scenario.1, corr = FALSE)
tree_vcvc_new <- tree_vcvc + 0.000001 * tree_vcvc
colnames(tree_vcvc_new)<-colnames(tree_vcvc)
rownames(tree_vcvc_new)<-rownames(tree_vcvc)

#model constructing

bmodel<- brm(example ~ Temperature + Precipitation +
(1 +Temperature + Precipitation  |gr(sn, cov = tree_vcvc_new)),
data      = d,
family    = cumulative(link = "logit", threshold = "flexible"),
data2 = list(tree_vcvc_new = tree_vcvc_new),
prior   = c(set_prior("normal(0,10)", class = "b")),
warmup    = 300,
iter      = 1000,
chains    = 4,
cores     = 4,
save_all_pars = TRUE,
backend = "cmdstanr",
control = list(adapt_delta = 0.99, max_treedepth=15),
save_model = "all_vcvcn_stanscript",
file = "all_vcvcn")
``````

Thanks,

Hey,

You could try to use the nearest positive definite matrix:

``````library(Matrix)
tree_vcvc_new <- as.matrix(nearPD(tree_vcvc)\$mat)
``````

HTH!

Try adding a small constant to the diagonal rather than multiplying the entire matrix by a value slightly larger than one. Indeed, multiplying a matrix by a positive scalar is guaranteed not to change whether the matrix is positive definite.

2 Likes

Thank you for a comment.
I added a small number to the diagonal like below, the calculation seemed to start.

`tree_vcvc_new ← diag(diag(tree_vcvc + 0.000001))

Many thanks,

Your code would set all off-diagonal elements to zero.

I guess you meant:

``````diag(tree_vcvc_new) <- diag(tree_vcvc) + 0.000001
``````
1 Like