Skip to content

Commit aacf667

Browse files
authored
Merge pull request #402 from lucdw/master
adapt for matrix operations via lavaanC
2 parents ca9455a + 5f95325 commit aacf667

File tree

3 files changed

+121
-11
lines changed

3 files changed

+121
-11
lines changed

R/lav_matrix.R

+111-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ lav_matrix_vecr <- function(A) {
2323
# faster way??
2424
# nRow <- NROW(A); nCol <- NCOL(A)
2525
# idx <- (seq_len(nCol) - 1L) * nRow + rep(seq_len(nRow), each = nCol)
26-
26+
if (lav_use_lavaanC() && is.numeric(A)) {
27+
return(lavaanC::m_vecr(A))
28+
}
2729
lav_matrix_vec(t(A))
2830
}
2931

@@ -39,6 +41,9 @@ lav_matrix_vecr <- function(A) {
3941
# M&N book: page 48-49
4042
#
4143
lav_matrix_vech <- function(S, diagonal = TRUE) {
44+
if (lav_use_lavaanC() && is.numeric(S)) {
45+
return(lavaanC::m_vech(S, diagonal))
46+
}
4247
ROW <- row(S)
4348
COL <- col(S)
4449
if (diagonal) S[ROW >= COL] else S[ROW > COL]
@@ -49,6 +54,9 @@ lav_matrix_vech <- function(S, diagonal = TRUE) {
4954
# into a vector by stacking the *rows* of the matrix one after the
5055
# other, but eliminating all supradiagonal elements
5156
lav_matrix_vechr <- function(S, diagonal = TRUE) {
57+
if (lav_use_lavaanC() && is.numeric(S)) {
58+
return(lavaanC::m_vechr(S, diagonal))
59+
}
5260
S[lav_matrix_vechr_idx(n = NCOL(S), diagonal = diagonal)]
5361
}
5462

@@ -57,26 +65,31 @@ lav_matrix_vechr <- function(S, diagonal = TRUE) {
5765
# into a vector by stacking the *columns* of the matrix one after the
5866
# other, but eliminating all infradiagonal elements
5967
lav_matrix_vechu <- function(S, diagonal = TRUE) {
68+
if (lav_use_lavaanC() && is.numeric(S)) {
69+
return(lavaanC::m_vechu(S, diagonal))
70+
}
6071
S[lav_matrix_vechu_idx(n = NCOL(S), diagonal = diagonal)]
6172
}
6273

63-
6474
# the vechru operator transforms a *symmetric* matrix
6575
# into a vector by stacking the *rows* of the matrix one after the
6676
# other, but eliminating all infradiagonal elements
6777
#
6878
# same as vech (but using upper-diagonal elements)
6979
lav_matrix_vechru <- function(S, diagonal = TRUE) {
80+
if (lav_use_lavaanC() && is.numeric(S)) {
81+
return(lavaanC::m_vechru(S, diagonal))
82+
}
7083
S[lav_matrix_vechru_idx(n = NCOL(S), diagonal = diagonal)]
7184
}
7285

73-
74-
75-
7686
# return the *vector* indices of the lower triangular elements of a
7787
# symmetric matrix of size 'n'
7888
lav_matrix_vech_idx <- function(n = 1L, diagonal = TRUE) {
7989
n <- as.integer(n)
90+
if (lav_use_lavaanC() && n > 1L) {
91+
return(lavaanC::m_vech_idx(n, diagonal))
92+
}
8093
if (n < 100L) {
8194
ROW <- matrix(seq_len(n), n, n)
8295
COL <- matrix(seq_len(n), n, n, byrow = TRUE)
@@ -101,6 +114,9 @@ lav_matrix_vech_idx <- function(n = 1L, diagonal = TRUE) {
101114
# symmetric matrix of size 'n'
102115
lav_matrix_vech_row_idx <- function(n = 1L, diagonal = TRUE) {
103116
n <- as.integer(n)
117+
if (lav_use_lavaanC() && n > 1L) {
118+
return(lavaanC::m_vech_row_idx(n, diagonal))
119+
}
104120
if (diagonal) {
105121
unlist(lapply(seq_len(n), seq.int, n))
106122
} else {
@@ -112,6 +128,9 @@ lav_matrix_vech_row_idx <- function(n = 1L, diagonal = TRUE) {
112128
# symmetric matrix of size 'n'
113129
lav_matrix_vech_col_idx <- function(n = 1L, diagonal = TRUE) {
114130
n <- as.integer(n)
131+
if (lav_use_lavaanC() && n > 1L) {
132+
return(lavaanC::m_vech_col_idx(n, diagonal))
133+
}
115134
if (!diagonal) {
116135
n <- n - 1L
117136
}
@@ -125,6 +144,9 @@ lav_matrix_vech_col_idx <- function(n = 1L, diagonal = TRUE) {
125144
# symmetric matrix of size 'n' -- ROW-WISE
126145
lav_matrix_vechr_idx <- function(n = 1L, diagonal = TRUE) {
127146
n <- as.integer(n)
147+
if (lav_use_lavaanC() && n > 1L) {
148+
return(lavaanC::m_vechr_idx(n, diagonal))
149+
}
128150
if (n < 100L) {
129151
ROW <- matrix(seq_len(n), n, n)
130152
COL <- matrix(seq_len(n), n, n, byrow = TRUE)
@@ -149,6 +171,9 @@ lav_matrix_vechr_idx <- function(n = 1L, diagonal = TRUE) {
149171
# symmetric matrix of size 'n' -- COLUMN-WISE
150172
lav_matrix_vechu_idx <- function(n = 1L, diagonal = TRUE) {
151173
n <- as.integer(n)
174+
if (lav_use_lavaanC() && n > 1L) {
175+
return(lavaanC::m_vechu_idx(n, diagonal))
176+
}
152177
if (n < 100L) {
153178
ROW <- matrix(seq_len(n), n, n)
154179
COL <- matrix(seq_len(n), n, n, byrow = TRUE)
@@ -166,6 +191,9 @@ lav_matrix_vechu_idx <- function(n = 1L, diagonal = TRUE) {
166191
# symmetric matrix of size 'n' -- ROW-WISE
167192
lav_matrix_vechru_idx <- function(n = 1L, diagonal = TRUE) {
168193
n <- as.integer(n)
194+
if (lav_use_lavaanC() && n > 1L) {
195+
return(lavaanC::m_vechru_idx(n, diagonal))
196+
}
169197
if (n < 100L) {
170198
# FIXME!! make this more efficient (without creating 3 n*n matrices!)
171199
ROW <- matrix(seq_len(n), n, n)
@@ -196,6 +224,9 @@ lav_matrix_vechru_idx <- function(n = 1L, diagonal = TRUE) {
196224
lav_matrix_vech_reverse <- lav_matrix_vechru_reverse <-
197225
lav_matrix_upper2full <-
198226
function(x, diagonal = TRUE) {
227+
if (lav_use_lavaanC()) {
228+
return(lavaanC::m_vech_reverse(x, diagonal))
229+
}
199230
# guess dimensions
200231
if (diagonal) {
201232
p <- (sqrt(1 + 8 * length(x)) - 1) / 2
@@ -218,6 +249,9 @@ lav_matrix_vech_reverse <- lav_matrix_vechru_reverse <-
218249
# reconstruct S
219250
lav_matrix_vechr_reverse <- lav_matrix_vechu_reverse <-
220251
lav_matrix_lower2full <- function(x, diagonal = TRUE) {
252+
if (lav_use_lavaanC()) {
253+
return(lavaanC::m_vechr_reverse(x, diagonal))
254+
}
221255
# guess dimensions
222256
if (diagonal) {
223257
p <- (sqrt(1 + 8 * length(x)) - 1) / 2
@@ -239,19 +273,27 @@ lav_matrix_vechr_reverse <- lav_matrix_vechu_reverse <-
239273
# matrix of size 'n'
240274
lav_matrix_diag_idx <- function(n = 1L) {
241275
# if(n < 1L) return(integer(0L))
276+
n <- as.integer(n)
277+
if (lav_use_lavaanC()) {
278+
return(lavaanC::m_diag_idx(n))
279+
}
242280
1L + (seq_len(n) - 1L) * (n + 1L)
243281
}
244282

245283

246284
# return the *vector* indices of the diagonal elements of the LOWER part
247285
# of a symmatrix matrix of size 'n'
248286
lav_matrix_diagh_idx <- function(n = 1L) {
287+
n <- as.integer(n)
249288
if (n < 1L) {
250289
return(integer(0L))
251290
}
252291
if (n == 1L) {
253292
return(1L)
254293
}
294+
if (lav_use_lavaanC()) {
295+
return(lavaanC::m_diagh_idx(n))
296+
}
255297
c(1L, cumsum(n:2L) + 1L)
256298
}
257299

@@ -262,6 +304,9 @@ lav_matrix_antidiag_idx <- function(n = 1L) {
262304
if (n < 1L) {
263305
return(integer(0L))
264306
}
307+
if (lav_use_lavaanC()) {
308+
return(lavaanC::m_antidiag_idx(n))
309+
}
265310
1L + seq_len(n) * (n - 1L)
266311
}
267312

@@ -294,6 +339,10 @@ lav_matrix_vech_which_idx <- function(n = 1L, diagonal = TRUE,
294339
return(integer(0L))
295340
}
296341
n <- as.integer(n)
342+
idx <- as.integer(idx)
343+
if (lav_use_lavaanC()) {
344+
return(lavaanC::m_vech_which_idx(n, diagonal, idx, type, add.idx.at.start))
345+
}
297346
A <- matrix(FALSE, n, n)
298347
if (type == "and") {
299348
A[idx, idx] <- TRUE
@@ -319,6 +368,10 @@ lav_matrix_vech_match_idx <- function(n = 1L, diagonal = TRUE,
319368
return(integer(0L))
320369
}
321370
n <- as.integer(n)
371+
idx <- as.integer(idx)
372+
if (lav_use_lavaanC()) {
373+
return(lavaanC::m_vech_match_idx(n, diagonal, idx))
374+
}
322375
pstar <- n * (n + 1) / 2
323376
A <- lav_matrix_vech_reverse(seq_len(pstar))
324377
B <- A[idx, idx, drop = FALSE]
@@ -329,7 +382,9 @@ lav_matrix_vech_match_idx <- function(n = 1L, diagonal = TRUE,
329382
lav_matrix_is_diagonal <- function(A = NULL) {
330383
A <- as.matrix.default(A)
331384
stopifnot(nrow(A) == ncol(A))
332-
385+
if (lav_use_lavaanC()) {
386+
return(lavaanC::m_is_diagonal(A))
387+
}
333388
diag(A) <- 0
334389
all(A == 0)
335390
}
@@ -413,6 +468,10 @@ lav_matrix_is_diagonal <- function(A = NULL) {
413468
# dup3: using col idx only
414469
# D7 <- dup(7L); x<- apply(D7, 1, function(x) which(x > 0)); matrix(x,7,7)
415470
.dup3 <- function(n = 1L) {
471+
n <- as.integer(n)
472+
if (lav_use_lavaanC()) {
473+
return(lavaanC::m_duplication(n))
474+
}
416475
if ((n < 1L) || (round(n) != n)) {
417476
lav_msg_stop(gettext("n must be a positive integer"))
418477
}
@@ -468,6 +527,10 @@ lav_matrix_duplication <- .dup3
468527
# - it returns a matrix of size p^2 * (p*(p-1))/2
469528
# - the columns corresponding to the diagonal elements have been removed
470529
lav_matrix_duplication_cor <- function(n = 1L) {
530+
n <- as.integer(n)
531+
if (lav_use_lavaanC()) {
532+
return(lavaanC::m_duplication_cor(n))
533+
}
471534
out <- lav_matrix_duplication(n = n)
472535
diag.idx <- lav_matrix_diagh_idx(n = n)
473536
out[, -diag.idx, drop = FALSE]
@@ -477,6 +540,9 @@ lav_matrix_duplication_cor <- function(n = 1L) {
477540
# sqrt(nrow(A)) is an integer
478541
# A is not symmetric, and not even square, only n^2 ROWS
479542
lav_matrix_duplication_pre <- function(A = matrix(0, 0, 0)) {
543+
if (lav_use_lavaanC()) {
544+
return(lavaanC::m_duplication_pre(A))
545+
}
480546
# number of rows
481547
n2 <- NROW(A)
482548

@@ -524,6 +590,9 @@ lav_matrix_duplication_dup_pre2 <- function(A = matrix(0, 0, 0)) {
524590
# A is not symmetric, and not even square, only n^2 ROWS
525591
# correlation version: ignoring diagonal elements
526592
lav_matrix_duplication_cor_pre <- function(A = matrix(0, 0, 0)) {
593+
if (lav_use_lavaanC()) {
594+
return(lavaanC::m_duplication_cor_pre(A))
595+
}
527596
# number of rows
528597
n2 <- NROW(A)
529598

@@ -548,6 +617,9 @@ lav_matrix_duplication_cor_pre <- function(A = matrix(0, 0, 0)) {
548617
# sqrt(ncol(A)) must be an integer
549618
# A is not symmetric, and not even square, only n^2 COLUMNS
550619
lav_matrix_duplication_post <- function(A = matrix(0, 0, 0)) {
620+
if (lav_use_lavaanC()) {
621+
return(lavaanC::m_duplication_post(A))
622+
}
551623
# number of columns
552624
n2 <- NCOL(A)
553625

@@ -573,6 +645,9 @@ lav_matrix_duplication_post <- function(A = matrix(0, 0, 0)) {
573645
# A is not symmetric, and not even square, only n^2 COLUMNS
574646
# correlation version: ignoring the diagonal elements
575647
lav_matrix_duplication_cor_post <- function(A = matrix(0, 0, 0)) {
648+
if (lav_use_lavaanC()) {
649+
return(lavaanC::m_duplication_cor_post(A))
650+
}
576651
# number of columns
577652
n2 <- NCOL(A)
578653

@@ -597,6 +672,9 @@ lav_matrix_duplication_cor_post <- function(A = matrix(0, 0, 0)) {
597672
# compute t(D) %*% A %*% D (without explicitly computing D)
598673
# A must be a square matrix and sqrt(ncol) an integer
599674
lav_matrix_duplication_pre_post <- function(A = matrix(0, 0, 0)) {
675+
if (lav_use_lavaanC()) {
676+
return(lavaanC::m_duplication_pre_post(A))
677+
}
600678
# number of columns
601679
n2 <- NCOL(A)
602680

@@ -623,6 +701,9 @@ lav_matrix_duplication_pre_post <- function(A = matrix(0, 0, 0)) {
623701
# A must be a square matrix and sqrt(ncol) an integer
624702
# correlation version: ignoring diagonal elements
625703
lav_matrix_duplication_cor_pre_post <- function(A = matrix(0, 0, 0)) {
704+
if (lav_use_lavaanC()) {
705+
return(lavaanC::m_duplication_cor_pre_post(A))
706+
}
626707
# number of columns
627708
n2 <- NCOL(A)
628709

@@ -772,6 +853,10 @@ lav_matrix_elimination_pre_post <- function(A = matrix(0, 0, 0)) {
772853

773854
# create DUP.ginv without transpose
774855
.dup_ginv2 <- function(n = 1L) {
856+
if (lav_use_lavaanC()) {
857+
n <- as.integer(n)
858+
return(lavaanC::m_duplication_ginv(n))
859+
}
775860
if ((n < 1L) || (round(n) != n)) {
776861
lav_msg_stop(gettext("n must be a positive integer"))
777862
}
@@ -840,7 +925,9 @@ lav_matrix_duplication_ginv_post <- function(A = matrix(0, 0, 0)) {
840925
# for square matrices only, with ncol = nrow = n^2
841926
lav_matrix_duplication_ginv_pre_post <- function(A = matrix(0, 0, 0)) {
842927
A <- as.matrix.default(A)
843-
928+
if (lav_use_lavaanC()) {
929+
return(lavaanC::m_duplication_ginv_pre_post(A))
930+
}
844931
# number of columns
845932
n2 <- NCOL(A)
846933

@@ -902,6 +989,12 @@ lav_matrix_duplication_ginv_cor_pre_post <- function(A = matrix(0, 0, 0)) {
902989

903990
# first attempt
904991
.com1 <- function(m = 1L, n = 1L) {
992+
if (lav_use_lavaanC()) {
993+
m <- as.integer(m)
994+
n <- as.integer(n)
995+
return(lavaanC::m_commutation(m, n))
996+
}
997+
905998
if ((m < 1L) || (round(m) != m)) {
906999
lav_msg_stop(gettext("n must be a positive integer"))
9071000
}
@@ -929,6 +1022,10 @@ lav_matrix_commutation <- .com1
9291022
# = permuting the rows of A
9301023
lav_matrix_commutation_pre <- function(A = matrix(0, 0, 0)) {
9311024
A <- as.matrix(A)
1025+
1026+
if (lav_use_lavaanC()) {
1027+
return(lavaanC::m_commutation_pre(A))
1028+
}
9321029

9331030
# number of rows of A
9341031
n2 <- nrow(A)
@@ -952,6 +1049,10 @@ lav_matrix_commutation_pre <- function(A = matrix(0, 0, 0)) {
9521049
# = permuting the columns of A
9531050
lav_matrix_commutation_post <- function(A = matrix(0, 0, 0)) {
9541051
A <- as.matrix(A)
1052+
1053+
if (lav_use_lavaanC()) {
1054+
return(lavaanC::m_commutation_post(A))
1055+
}
9551056

9561057
# number of columns of A
9571058
n2 <- ncol(A)
@@ -975,7 +1076,9 @@ lav_matrix_commutation_post <- function(A = matrix(0, 0, 0)) {
9751076
# = permuting both the rows AND columns of A
9761077
lav_matrix_commutation_pre_post <- function(A = matrix(0, 0, 0)) {
9771078
A <- as.matrix(A)
978-
1079+
if (lav_use_lavaanC()) {
1080+
return(lavaanC::m_commutation_pre_post(A))
1081+
}
9791082
# number of columns of A
9801083
n2 <- NCOL(A)
9811084

R/lav_model_information.R

+9-2
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,22 @@ lav_model_information_expected <- function(lavmodel = NULL,
153153
)
154154
Info.group[[g]] <- fg * Info.g
155155
} else {
156+
# ldw_trace(paste(sum(Delta[[g]] == 0),"/",length(Delta[[g]])))
156157
# compute information for this group
157158
if (lavmodel@estimator %in% c("DWLS", "ULS")) {
158159
# diagonal weight matrix
159160
Delta2 <- sqrt(A1[[g]]) * Delta[[g]]
160161
Info.group[[g]] <- fg * crossprod(Delta2)
161162
} else {
162163
# full weight matrix
163-
Info.group[[g]] <-
164-
fg * (crossprod(Delta[[g]], A1[[g]]) %*% Delta[[g]])
164+
if (lav_use_lavaanC()) {
165+
Info.group[[g]] <-
166+
fg * lavaanC::m_prod(
167+
lavaanC::m_crossprod(Delta[[g]], A1[[g]], "L"), Delta[[g]], "R")
168+
} else {
169+
Info.group[[g]] <-
170+
fg * (crossprod(Delta[[g]], A1[[g]]) %*% Delta[[g]])
171+
}
165172
}
166173
}
167174
} # g

R/lav_syntax_parser_cr.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ldw_parse_model_string_cr <- function(model.syntax = "",
1010
)
1111

1212
if (lav_use_lavaanC()) {
13-
flat <- lavaanC::lav_parse_model_string_c(modelsrc)
13+
flat <- lavaanC::parse_model_string(modelsrc)
1414
} else {
1515
flat <- lav_parse_model_string_r(modelsrc)
1616
}

0 commit comments

Comments
 (0)