From 16d17e1d238b54994b4d8be9135952520a3bff0a Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 5 Jul 2026 03:47:03 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Cache=20inverted=20matr?= =?UTF-8?q?ices=20in=20vuongtest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted and cached the matrix inversion for AB1 and AB2 into local variables before constructing the block matrix W in calcLambda to prevent redundant O(n^3) computation. --- .jules/bolt.md | 3 +++ R/vuongtest.R | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..6e74844 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-05-18 - Caching Matrix Inversions in vuongtest +**Learning:** In statistical R packages involving likelihood calculations, matrix inversion is a common performance bottleneck. Repeating the exact same inversion inside matrix bindings multiplies this cost unnecessarily. +**Action:** Always inspect matrix construction blocks for duplicated expensive operations and extract them into cached local variables before assembling the final block matrix. diff --git a/R/vuongtest.R b/R/vuongtest.R index 57c5f6b..3864774 100644 --- a/R/vuongtest.R +++ b/R/vuongtest.R @@ -271,10 +271,13 @@ calcLambda <- function(object1, object2, n, score1, score2, vc1, vc2) { AB2 <- calcAB(object2, n, score2, vc2) Bc <- calcBcross(AB1$sc, AB2$sc, n) - W <- cbind(rbind(-AB1$B %*% chol2inv(chol(AB1$A)), - t(Bc) %*% chol2inv(chol(AB1$A))), - rbind(-Bc %*% chol2inv(chol(AB2$A)), - AB2$B %*% chol2inv(chol(AB2$A)))) + # Bolt: cache matrix inversions to avoid recalculating the O(n^3) inverse twice for each model + invA1 <- chol2inv(chol(AB1$A)) + invA2 <- chol2inv(chol(AB2$A)) + W <- cbind(rbind(-AB1$B %*% invA1, + t(Bc) %*% invA1), + rbind(-Bc %*% invA2, + AB2$B %*% invA2)) lamstar <- eigen(W, only.values=TRUE)$values ## Discard imaginary part, as it only occurs for tiny eigenvalues? From 7a6f5335e486f3a4f407275d2f48cc4c6018d11e Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 5 Jul 2026 04:04:23 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Cache=20inverted=20matr?= =?UTF-8?q?ices=20in=20vuongtest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted and cached the matrix inversion for AB1 and AB2 into local variables before constructing the block matrix W in calcLambda to prevent redundant O(n^3) computation. From a8429a2878201fc07cddff33e435d245ccd4f832 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 5 Jul 2026 04:21:35 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Cache=20inverted=20matr?= =?UTF-8?q?ices=20in=20vuongtest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted and cached the matrix inversion for AB1 and AB2 into local variables before constructing the block matrix W in calcLambda to prevent redundant O(n^3) computation. From 30acd371aa5acf9b890c73128a1c0e5fa933557b Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 5 Jul 2026 04:38:35 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Cache=20inverted=20matr?= =?UTF-8?q?ices=20in=20vuongtest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted and cached the matrix inversion for AB1 and AB2 into local variables before constructing the block matrix W in calcLambda to prevent redundant O(n^3) computation.