Nothing
elementary_symmetric_functions <- function(par,
order = 0L, log = TRUE, diff = FALSE, engine = NULL)
{
## check order, set poly and engine
stopifnot(order %in% 0L:2L)
poly <- is.list(par)
if (is.null(engine)) engine <- if (order < 2L && log && !(.Platform$OS.type == "windows" && .Platform$r_arch == "i386")) "C" else "R"
## if necessary: create ncat and unlist par
if (engine == "C" || poly) {
ncat <- sapply(par, length)
par <- unlist(par)
## sanity checks
stopifnot(log)
if(order == 2L) {
if (poly) stop("Second order ESFs are not available for polytomous items.")
else {
warning("Second order ESFs are not available in C, changed to R.")
engine <- "R"
}
}
}
if(engine == "R" & !poly) {
## Michelle Liou (1994). More on the Computation of Higher-Order
## Derivatives of the Elementary Symmetric Functions in the
## Rasch Model. Applied Psychological Measurement, 18(1), 53-62.
## Use difference algorithm for orders > 0?
diff <- rep(diff, length.out = 2L)
## derivatives up to order
order <- round(order)[1L]
rval <- list()[1L:(order+1L)]
names(rval) <- 0L:order
## transformations
par <- as.vector(par)
beta <- if(log) par else -log(par)
eps <- exp(-beta)
n <- length(eps)
stopifnot(n > 1L)
## Order: 0
## initialization: gamma_1(eps_1) = eps_1
gamma <- c(eps[1L], numeric(n-1L))
## recursion: Equation 3
for(i in 2L:n) gamma[1L:i] <- c(eps[i] + gamma[1L],
eps[i] * gamma[(2L:i) - 1L] + gamma[2L:i])
## gamma_0 = 1
gamma <- c(1, gamma)
## return value
rval[[1L]] <- gamma
if(order < 1L) return(rval)
## Order: 1
if(diff[1L]) {
## initialization: gamma_1^(j) = 1
gamma1 <- matrix(0, nrow = n+1, ncol = n)
gamma1[2L,] <- 1
## recursion: Equation 4
for(q in 3L:(n+1)) gamma1[q,] <- gamma[q-1L] - eps * gamma1[q-1L,]
} else {
## re-call self, omitting i-th parameter
gamma1 <- sapply(1L:n, function(i)
c(0, elementary_symmetric_functions(eps[-i], order = 0L, log = FALSE, engine = "R")[[1L]]))
}
## if input on log scale: include inner derivative
if(log) gamma1 <- exp(t(t(log(gamma1)) - beta))
## return value
rval[[2L]] <- gamma1
if(order < 2L) return(rval)
## Order: 2
if(diff[2L]) {
## initialization: gamma_2^(i,j) = 1
gamma2 <- array(0, c(n+1L, n, n))
gamma2[3L,,] <- 1
## auxiliary variables
eps_plus_eps <- outer(eps, eps, "+")
eps_times_eps <- exp(-outer(beta, beta, "+"))
## recursion: Jansen's Equation (Table 1, Forward, Second-Order)
if(n > 2L) for(q in 4L:(n+1L)) gamma2[q,,] <- gamma[q-2L] -
(eps_plus_eps * gamma2[q-1L,,] + eps_times_eps * gamma2[q-2L,,])
} else {
## re-call self, omitting i-th and j-th parameter
gamma2 <- array(0, c(n + 1L, n, n))
for(i in 1L:(n-1L)) {
for(j in (i+1L):n) {
gamma2[, i, j] <- gamma2[, j, i] <- c(0, 0,
elementary_symmetric_functions(eps[-c(i, j)], order = 0L, log = FALSE, engine = "R")[[1L]])
}
}
if(log) eps_times_eps <- exp(-outer(beta, beta, "+"))
}
## if input on log scale: include inner derivative
if(log) for(q in 1L:(n+1L)) gamma2[q,,] <- eps_times_eps * gamma2[q,,]
## each diagonal is simply first derivative
for(q in 2L:(n+1L)) diag(gamma2[q,,]) <- gamma1[q,]
## return value
rval[[3L]] <- gamma2
return(rval)
}
if(engine == "R" && poly) {
## ESF summation/difference algorithm for polytmous items.
## See: Fischer & Ponocny (FP), 1994 and 1995
## construct item parameter list and result vector
m <- length(ncat)
par <- split.default(par, rep.int(1L:m, ncat))
eps <- lapply(par, function (x) {
x <- c(1, exp(-x))
x[is.na(x)] <- 0
x
})
rval <- vector("list", (1L+order))
names(rval) <- 0L:order
## zero derivative, summation algorithm
## setup result list, possible scores (r) with i items (i=2, ..., m) and categories (ncat, including zero)
r <- cumsum(ncat) + 1L
rmax <- r[m] - 1L
ncat <- ncat + 1L
rxncat <- r*ncat
rval[[1L]] <- vector("list", m)
## initialization: gamma_r(Item1) = eps_r, r = 0, ..., o_1
rval[[1L]][[1L]] <- eps[[1L]]
## FP (1994), EQ (11); FP (1995) EQ (19.19)
for (i in 2L:m) {
gamma <- rep.int(c(rval[[1L]][[i-1L]], rep.int(0, ncat[i])), ncat[i])[1L:rxncat[i]]
dim(gamma) <- c(r[i], ncat[i])
rval[[1L]][[i]] <- gamma %*% eps[[i]]
}
## first derivative, preparations, setup result list: derivatives of first parameter for all items (m)
if (order) {
## create result object
rval[[2L]] <- lapply(1L:m, function (x) vector("list", x))
if (!diff) {
## helper variables
## nOld: number of items in previous round
## r: possible scores with 2:m Items (cols) without item j (row)
nOld <- 0L:(m-1L)
r <- vapply(r, "-", numeric(m) , ncat) + 1L
## initialization, gamma^(1)_0(I1) = 1
rval[[2L]][[1L]] <- 1
## FP (1994), EQ (12)/FP (1995) EQ (19.21)
for (i in 2L:m) {
for (j in 1L:nOld[i]) { #derivivatives of 'old' items
gamma1 <- rep.int(c(rval[[2L]][[j]], rep.int(0, ncat[i])), ncat[i])[1L:(ncat[i] * r[j,i])]
dim(gamma1) <- c(r[j,i], ncat[i])
rval[[2L]][[j]] <- gamma1 %*% eps[[i]]
}
rval[[2L]][[i]] <- rval[[1L]][[nOld[i]]] #derivative of newly added item
}
} else{
## helper variables
## maximum score with all Items but without item j (+1 because zero is first element)
r <- r[m] - ncat + 1L
## initialization, gamma^(i)_0(I1) = 1, i = 1, ..., m
rval[[2L]][1L:m] <- 1
## FP (1994), EQ (14/13); FP (1995) EQ (19.22/19.23/19.24)
for (j in 1L:m) {
for (i in 2L:r[j]) {
rval[[2L]][[j]] <- c(rval[[2L]][[j]], rval[[1L]][[m]][i] - sum(rval[[2L]][[j]][(i-1L) : (i-min(i-1L, ncat[j]-1L))]
* eps[[j]][2L:min(i, ncat[j])]))
}
}
}
## include inner derivative (only for identified parameters) & construct result matrix
eps_indent <- lapply(eps, function (x) x[-1L])
rval[[2L]] <- lapply(rval[[2L]], function (x) if (length(x) < rmax) c(0, x, rep.int(0, rmax-length(x))) else c(0, x))
rval[[2L]] <- mapply("%o%", rval[[2L]], eps_indent, SIMPLIFY=FALSE)
rval[[2L]] <- do.call("cbind", rval[[2L]])
## shift derivatives to the correct position with helper function
shift_val <- unlist(lapply(ncat - 2L, seq, from = 0L))
shift_row <- function (x, y) if (y) c(rep.int(0, y), x[1L:(length(x)-y)]) else x
for (j in seq_len(rmax)) rval[[2L]][, j] <- shift_row(rval[[2L]][, j], shift_val[j])
}
## over and out
rval[[1L]] <- rval[[1L]][[m]][, , drop=TRUE] # return only full zero gammas, rest was only for first order derivatives needed
return(rval)
}
if(engine == "C") {
rval <- .Call(esf, as.double(par), as.integer(ncat), as.integer(order), as.integer(diff))
names(rval) <- 0L:order
return(rval)
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.