Nothing
"adjMatrix" <-
function(A) {
### From the edge matrix to the adjacency matrix
E <- t(A)
diag(E) <- 0
E
}
"allEdges" <-
function(amat) {
### Finds all the edges of a graph with edge matrix amat.
nn <- 1:nrow(amat)
E <- c()
if (all(amat == t(amat))) {
amat[lower.tri(amat)] <- 0
}
for (i in nn) {
e <- nn[amat[i, ] == 1]
if (length(e) == 0) next
li <- cbind(i, e)
dimnames(li) <- list(rep("", length(e)), rep("", 2))
E <- rbind(E, li)
}
E
}
"basiSet" <-
function(amat) {
### Basis set of a DAG with adjacency matrix amat.
amat <- topSort(amat)
nod <- rownames(amat)
dv <- length(nod)
ind <- NULL
## NOTE. This is correct if the adj mat is upper triangular.
for (r in 1:dv) {
for (s in r:dv) {
if ((amat[r, s] != 0) | (s == r)) {
next
} else {
ed <- nod[c(r, s)]
pa.r <- nod[amat[, r] == 1]
pa.s <- nod[amat[, s] == 1]
dsep <- union(pa.r, pa.s)
dsep <- setdiff(dsep, ed)
b <- list(c(ed, dsep))
ind <- c(ind, b)
}
}
}
## ind <- lapply(ind, function(x) nn[x])
ind
}
"bd" <-
function(nn, amat) {
### Boundary of the nodes nn for a graph with adjacency matrix amat.
nod <- rownames(amat)
if (is.null(nod)) stop("The edge matrix must have dimnames!")
if (!all(is.element(nn, nod))) stop("Some of the nodes are not among the vertices.")
b <- vector(length(nn), mode = "list")
diag(amat) <- 0 # As you do not want the node itself in the list
k <- length(nn)
for (i in 1:k) {
b[[i]] <- c(nod[amat[nn[i], ] == 1], nod[amat[, nn[i]] == 1])
}
b <- unique(unlist(b))
setdiff(b, nn)
}
"ch" <-
function(nn, amat) {
### List of the children of nodes nn for a given with adjacency matrix amat.
nod <- rownames(amat)
if (is.null(nod)) stop("The adjacency matrix must have dimnames!")
if (!all(is.element(nn, nod))) stop("Some of the nodes are not among the vertices.")
k <- length(nn)
p <- vector(k, mode = "list")
A <- 0 + ((amat != t(amat)) & (amat == 1)) # Select the directed edges
for (i in 1:k) {
p[[i]] <- nod[A[nn[i], ] == 1]
}
setdiff(unique(unlist(p)), nn)
}
"pa" <-
function(nn, amat) {
### List of the parents of nodes nn for a given with adjacency matrix amat.
nod <- rownames(amat)
if (is.null(nod)) stop("The adjacency matrix must have dimnames!")
if (!all(is.element(nn, nod))) stop("Some of the nodes are not among the vertices.")
k <- length(nn)
p <- vector(k, mode = "list")
A <- 0 + ((amat != t(amat)) & (amat == 1)) # Select the directed edges
for (i in 1:k) {
p[[i]] <- nod[A[, nn[i]] == 1]
}
setdiff(unique(unlist(p)), nn)
}
"bfsearch" <-
function(amat, v = 1) {
### Breadth-first search of a connected UG with adjacency matrix amat.
n <- nrow(amat)
indices <- 1:n
if (n == 1) {
return(NULL)
}
visited <- rep(0, n)
Q <- c()
tree <- matrix(0, n, n)
dimnames(tree) <- dimnames(amat)
E <- c()
visited[v] <- 1
Q <- c(v, Q)
while (!all(visited == 1)) {
x <- Q[1]
Q <- Q[-1]
## b <- bd(x, amat)
b <- indices[amat[x, ] == 1] # Boundary of x. Assumes that amat is symmetric
for (y in b) {
if (visited[y] == 0) {
visited[y] <- 1
Q <- c(Q, y)
tree[x, y] <- 1
tree[y, x] <- 1
E <- rbind(E, c(x, y))
}
}
}
cross <- amat - tree
V <- allEdges(cross)
dimnames(E) <- list(rep("", nrow(E)), rep("", 2))
list(tree = tree, branches = E, chords = V)
}
`checkIdent` <- function(amat, latent) {
### Checks SW sufficient conditions for identifiability of a DAG
### with adjacency matrix edge amat and one latent variable.
"allSubsets" <-
function(n) {
## Returns all subsets of n
p <- length(n)
H <- data.matrix(expand.grid(rep(list(1:2), p))) - 1
H <- split(H == 1, row(H))
lapply(H, function(i) n[i])
}
nod <- rownames(amat)
if (is.null(nod)) stop("The adjacency matrix must have dimnames.")
gcov <- inducedCovGraph(amat, sel = nod, cond = NULL)
gcov <- sign(gcov)
L <- latent
if (length(L) > 1) {
stop("I have an answer only for one latent variable.")
}
O <- setdiff(nod, L)
m <- bd(L, gcov)
## Theorem 1
if (length(m) > 2) {
G <- inducedCovGraph(amat, sel = O, cond = L)
G <- sign(G)
cond.i <- isGident(G[m, m, drop = FALSE])
} else {
cond.i <- FALSE
}
gcon <- inducedConGraph(amat, sel = nod, cond = NULL)
gcon <- sign(gcon)
cc <- bd(L, gcon)
if (length(cc) > 2) {
cond.ii <- isGident(gcon[cc, cc, drop = FALSE])
} else {
cond.ii <- FALSE
}
## Theorem 2 (revised)
a <- union(pa(L, amat), ch(L, amat))
if (length(a) > 2) {
Oa <- setdiff(O, a) # O \ a
S.a <- inducedCovGraph(amat, sel = union(Oa, L), cond = a)
S.a <- sign(S.a)
first <- S.a[Oa, L]
first <- Oa[first == 0] # variables that satisfy condition (i) of thm. 2.
if (length(first) == 0) {
cond.iii <- FALSE
} else {
cond.iii <- FALSE
H <- allSubsets(first) # in all subsets of these variables
for (h in H) { # look for a G-identifiable cov. or con. graph
isgid <- isGident(sign(inducedCovGraph(amat, sel = a, cond = union(L, h))))
if (isgid) {
cond.iii <- TRUE
break
} else {
isgid <- isGident(sign(inducedConGraph(amat, sel = a, cond = union(L, h))))
if (isgid) {
cond.iii <- TRUE
break
}
}
}
}
second <- setdiff(O, m) # variables that satisfy condition (ii) of thm. 2.
if (length(second) == 0) {
cond.iv <- FALSE
} else {
cond.iv <- FALSE
H <- allSubsets(second) # in all subsets of these variables
for (h in H) { # look for a G-identifiable cov. or con. graph
isgid <- isGident(sign(inducedCovGraph(amat, sel = a, cond = union(L, h))))
if (isgid) {
cond.iv <- TRUE
break
} else {
isgid <- isGident(sign(inducedConGraph(amat, sel = a, cond = union(L, h))))
if (isgid) {
cond.iv <- TRUE
break
}
}
}
}
} else {
cond.iii <- FALSE
cond.iv <- FALSE
}
c(
T1.i = cond.i, T1.ii = cond.ii,
T2.i = cond.iii, T2.ii = cond.iv
)
}
"cmpGraph" <-
function(amat) {
### Adjacency matrix of the complementary graph
g <- 1 * !amat
diag(g) <- 0
g
}
`conComp` <- function(amat, method = 1)
### Finds the connected components of an UG graph from its adjacency matrix amat.
{
if (!all(amat == t(amat))) {
stop("Not an undirected graph.")
}
if (method == 2) {
u <- clusters(graph.adjacency(amat, mode = "undirected"))$membership + 1
return(u)
} else if (method == 1) {
A <- transClos(amat)
diag(A) <- 1
n <- nrow(A)
A <- sign(A + t(A))
u <- A %*% 2^((n - 1):0)
return(match(u, unique(u)))
} else {
stop("Wrong method.")
}
}
"correlations" <-
function(x) {
### Marginal correlations (lower half) and
### partial correlations given all remaining variables (upper half).
if (is.data.frame(x)) {
r <- cor(x)
} else { # Recomputes the corr matrix
Dg <- 1 / sqrt(diag(x))
r <- x * outer(Dg, Dg)
}
rp <- parcor(r)
r[upper.tri(r)] <- rp[upper.tri(rp)]
r
}
"cycleMatrix" <-
function(amat) {
### Fundamental Cycle matrix of the UG amat.
fc <- fundCycles(amat) # Edges of the fundamental cycles
E <- allEdges(amat) # All the edges of the graph
n <- nrow(E) # Number of edges
k <- length(fc) # Number of FC
if (k == 0) {
return(NULL)
}
cmat <- matrix(0, k, n)
for (cy in 1:k) {
M <- fc[[cy]] # Edges in cycle cy
for (j in 1:nrow(M)) {
e <- sort(M[j, ])
for (i in 1:n) {
cmat[cy, i] <- cmat[cy, i] | all(E[i, ] == e)
}
}
}
dimnames(cmat) <- list(1:k, paste(E[, 1], E[, 2]))
cmat
}
"DAG" <-
function(..., order = FALSE) {
### Defines a DAG from a set of equations (defined with model formulae).
f <- list(...)
nb <- length(f) # nb is the number of model formulae (of blocks)
nod <- c() # Counts the number of nodes
for (k in 1:nb) {
tt <- terms(f[[k]], specials = "I")
vars <- dimnames(attr(tt, "factors"))[[1]]
skip <- attr(tt, "specials")$I
if (!is.null(skip)) {
vars <- vars[-skip]
}
nod <- c(nod, vars)
}
N <- unique(nod) # set of nodes
dN <- length(N) # number of nodes
amat <- matrix(0, dN, dN)
for (k in 1:nb) {
tt <- terms(f[[k]], specials = "I")
vars <- dimnames(attr(tt, "factors"))[[1]]
if (attr(tt, "response") == 1) {
j <- match(vars[1], N)
i <- match(vars[-1], N)
amat[i, j] <- 1
} else if (attr(tt, "response") == 0) {
stop("Some equations have no response")
}
}
if (!isAcyclic(amat)) {
warning("The graph contains directed cycles!")
}
dimnames(amat) <- list(N, N)
if (order) {
amat <- topSort(amat)
}
amat
}
`drawGraph` <- function(amat, coor = NULL, adjust = FALSE, alpha = 1.5, beta = 3,
lwd = 1, ecol = "blue", bda = 0.1, layout = layout.auto) {
if (is.null(dimnames(amat))) {
rownames(a) <- 1:ncol(amat)
colnames(a) <- 1:ncol(amat)
}
if (all(amat == t(amat)) & all(amat[amat != 0] == 1)) {
amat <- amat * 10
}
`lay` <- function(a, directed = TRUE, start = layout) {
if (class(a)[1] == "igraph" || class(a)[1] == "graphNEL" || class(a)[1] ==
"character") {
a <- grMAT(a)
}
if (is(a, "matrix")) {
if (nrow(a) == ncol(a)) {
if (length(rownames(a)) != ncol(a)) {
rownames(a) <- 1:ncol(a)
colnames(a) <- 1:ncol(a)
}
if (!directed) {
if (all(a == t(a)) & all(a[a != 0] == 1)) {
a <- a * 10
}
}
l1 <- c()
l2 <- c()
for (i in 1:nrow(a)) {
for (j in i:nrow(a)) {
if (a[i, j] == 1) {
l1 <- c(l1, i, j)
l2 <- c(l2, 2)
}
if (a[j, i] %% 10 == 1) {
l1 <- c(l1, j, i)
l2 <- c(l2, 2)
}
if (a[i, j] == 10) {
l1 <- c(l1, i, j)
l2 <- c(l2, 0)
}
if (a[i, j] == 11) {
l1 <- c(l1, i, j, i, j)
l2 <- c(l2, 2, 0)
}
if (a[i, j] == 100) {
l1 <- c(l1, i, j)
l2 <- c(l2, 3)
}
if (a[i, j] == 101) {
l1 <- c(l1, i, j, i, j)
l2 <- c(l2, 2, 3)
}
if (a[i, j] == 110) {
l1 <- c(l1, i, j, i, j)
l2 <- c(l2, 0, 3)
}
if (a[i, j] == 111) {
l1 <- c(l1, i, j, i, j, i, j)
l2 <- c(l2, 2, 0, 3)
}
}
}
} else {
stop("'object' is not in a valid adjacency matrix form")
}
if (length(l1) > 0) {
## l1 <- l1 - 1 # igraph0
agr <- graph(l1, n = nrow(a), directed = TRUE)
}
} else {
stop("'object' is not in a valid format")
}
x <- start(agr)
x[, 1] <- 10 + 80 * (x[, 1] - min(x[, 1])) / (max(x[, 1]) - min(x[, 1]))
x[, 2] <- 10 + 80 * (x[, 2] - min(x[, 2])) / (max(x[, 2]) - min(x[, 2]))
x
}
plot.dots <- function(xy, v, dottype, n, beta) {
for (i in 1:n) {
if (dottype[i] == 1) {
points(xy[i, 1], xy[i, 2],
pch = 1, cex = 1.2,
lwd = lwd
)
} else if (dottype[i] == 2) {
points(xy[i, 1], xy[i, 2], pch = 16, cex = 1.2)
}
}
text(xy[, 1] - beta, xy[, 2] + 2 * beta, v, cex = 1.2)
}
angle <- function(v, alpha = pi / 2) {
theta <- Arg(complex(real = v[1], imaginary = v[2]))
z <- complex(argument = theta + alpha)
c(Re(z), Im(z))
}
double.edges <- function(x1, x2, y1, y2, lwd, ecol) {
d <- 50
n <- 30
dd <- 2
k <- length(x1)
if (is.na(x1)) {
return()
}
for (i in 1:k) {
x <- c(x1[i], x2[i])
y <- c(y1[i], y2[i])
m <- (x + y) / 2
cen <- m + d * angle(y - x)
xm <- x - cen
ym <- y - cen
thetax <- Arg(complex(real = xm[1], imaginary = xm[2]))
thetay <- Arg(complex(real = ym[1], imaginary = ym[2]))
theta <- seq(thetax, thetay, len = n)
l <- crossprod(y - m)
delta <- sqrt(d^2 + l)
lx <- cen[1] + delta * cos(theta)
ly <- cen[2] + delta * sin(theta)
lines(lx, ly, lty = 2, col = ecol, lwd = lwd)
vy <- angle(y - cen)
vx <- angle(x - cen)
vx1 <- x + dd * angle(vx, alpha = pi / 12)
vx2 <- x + dd * angle(vx, alpha = -pi / 12)
vy1 <- y + dd * angle(vy, alpha = 11 * pi / 12)
vy2 <- y + dd * angle(vy, alpha = -11 * pi / 12)
segments(x[1], x[2], vx1[1], vx1[2],
col = ecol,
lwd = lwd
)
segments(x[1], x[2], vx2[1], vx2[2],
col = ecol,
lwd = lwd
)
segments(y[1], y[2], vy1[1], vy1[2],
col = ecol,
lwd = lwd
)
segments(y[1], y[2], vy2[1], vy2[2],
col = ecol,
lwd = lwd
)
ex <- x + 0.05 * (y - x)
ey <- x + 0.95 * (y - x)
arrows(ex[1], ex[2], ey[1], ey[2],
lty = 1, code = 1,
angle = 20, length = 0.1, lwd = lwd, col = ecol
)
}
}
draw.edges <- function(coor, u, alpha, type, lwd, ecol, bda) {
for (k in 1:nrow(u)) {
a <- coor[u[k, 1], ]
b <- coor[u[k, 2], ]
ba <- b - a
ba <- ba / sqrt(sum(ba * ba))
x <- a + ba * alpha
y <- b - ba * alpha
switch(type + 1,
segments(x[1], x[2], y[1], y[2],
lty = 1, lwd = lwd, col = ecol
),
arrows(x[1],
x[2], y[1], y[2],
code = 2, angle = 20, length = 0.1,
lty = 1, lwd = lwd, col = ecol
),
arrows(x[1],
x[2], y[1], y[2],
code = 3, angle = 20, length = bda,
lty = 5, lwd = lwd, col = ecol
),
double.edges(x[1],
x[2], y[1], y[2],
lwd = lwd, ecol
)
)
}
}
# def.coor <- function(ce, k, h, w) {
# if (k == 1)
# return(ce)
# else if (k == 2) {
# r1 <- c(ce[1], ce[1])
# r2 <- c(ce[2] + h * 0.3, ce[2] - h * 0.3)
# }
# else if (k == 3) {
# r1 <- c(ce[1], ce[1], ce[1])
# r2 <- c(ce[2] + h * 0.25, ce[2], ce[2] - h * 0.25)
# }
# else if (k == 4) {
# r1 <- c(ce[1] - w * 0.3, ce[1] + w * 0.3, ce[1] +
# w * 0.3, ce[1] - w * 0.3)
# r2 <- c(ce[2] - h * 0.3, ce[2] - h * 0.3, ce[2] +
# h * 0.3, ce[2] + h * 0.3)
# }
# else {
# a <- 1
# z <- seq(a, a + 2 * pi, len = k + 1)
# z <- z[-1]
# r1 <- ce[1] + w/2.5 * cos(z)
# r2 <- ce[2] + h/2.5 * sin(z)
# }
# cbind(r1, r2)
# }
# def.coor.dag <- function(amat, w, h, left) {
# nod <- rownames(amat)
# o <- topOrder(amat)
# if (left)
# o <- rev(o)
# k <- length(nod)
# x <- seq(0, 100, len = k)
# y <- rep(c(20, 40, 60, 80), ceiling(k/4))[1:k]
# xy <- cbind(x, y)
# rownames(xy) <- nod[o]
# xy[nod, ]
# }
v <- parse(text = rownames(amat))
n <- length(v)
dottype <- rep(1, n)
old <- par(mar = c(0, 0, 0, 0))
on.exit(par(old))
plot(c(0, 100), c(0, 100),
type = "n", axes = FALSE, xlab = "",
ylab = ""
)
center <- matrix(c(50, 50), ncol = 2)
if (is.null(coor)) {
coor <- lay(amat)
# isdag <- isAcyclic(amat)
# if (isdag)
# coor <- def.coor.dag(amat, 100, 100, left = left)
# else coor <- def.coor(center, n, 100, 100)
}
g0 <- amat * ((amat == 10) & (t(amat) == 10))
g0[lower.tri(g0)] <- 0
g1 <- amat * ((amat == 1) & !((amat > 0) & (t(amat) > 0)))
g2 <- amat * ((amat == 100) & (t(amat) == 100))
g2[lower.tri(g2)] <- 0
g3 <- (amat == 101) + 0
i <- expand.grid(1:n, 1:n)
u0 <- i[g0 > 0, ]
u1 <- i[g1 > 0, ]
u2 <- i[g2 > 0, ]
u3 <- i[g3 > 0, ]
if (nrow(coor) != length(v)) {
stop("Wrong coordinates of the vertices.")
}
plot.dots(coor, v, dottype, n, beta)
draw.edges(coor, u0, alpha, type = 0, lwd = lwd, ecol, bda)
draw.edges(coor, u1, alpha, type = 1, lwd = lwd, ecol, bda)
draw.edges(coor, u2, alpha, type = 2, lwd = lwd, ecol, bda)
draw.edges(coor, u3, alpha, type = 3, lwd = lwd, ecol, bda)
if (adjust) {
repeat {
xnew <- unlist(locator(1))
if (length(xnew) == 0) {
break
}
d2 <- (xnew[1] - coor[, 1])^2 + (xnew[2] - coor[
,
2
])^2
i <- (1:n)[d2 == min(d2)]
coor[i, 1] <- xnew[1]
coor[i, 2] <- xnew[2]
plot(c(0, 100), c(0, 100),
type = "n", axes = FALSE,
xlab = "", ylab = ""
)
plot.dots(coor, v, dottype, n, beta)
draw.edges(coor, u0, alpha,
type = 0, lwd = lwd,
ecol, bda
)
draw.edges(coor, u1, alpha,
type = 1, lwd = lwd,
ecol, bda
)
draw.edges(coor, u2, alpha,
type = 2, lwd = lwd,
ecol, bda
)
draw.edges(coor, u3, alpha,
type = 3, lwd = lwd,
ecol, bda
)
}
}
colnames(coor) <- c("x", "y")
return(invisible(coor))
}
"dSep" <-
function(amat, first, second, cond) {
### Are first and second d-Separated by cond in a DAG?
e <- inducedCovGraph(amat, sel = c(first, second), cond = cond)
all(e[first, second] == 0)
}
"edgematrix" <-
function(E, inv = FALSE) {
### From the adjacency matrix to the edge matrix
E <- sign(E)
if (inv) {
ord <- topOrder(E)
ord <- rev(ord) # Inverse topological order: Nanny ordering.
E <- E[ord, ord]
}
A <- t(E)
diag(A) <- 1
A
}
"essentialGraph" <-
function(dagx) {
### Converts a DAG into Essential Graph.
### Is implemented by the algorithm by D.M.Chickering (1995).
### A transformational characterization of equivalent Bayesian network
### structures. Proceedings of Eleventh Conference on Uncertainty in
### Artificial Intelligence, Montreal, QU, pages 87-98. Morgan Kaufmann
### http://research.microsoft.com/~dmax/publications/uai95.pdf
### Implemented in Matlab by Tomas Kocka, AAU.
### Translated in R by Giovanni Marchetti, University of Florence.
ord <- topOrder(dagx) # get the topological order of nodes
n <- nrow(dagx) # gets the number of nodes
i <- expand.grid(1:n, 1:n) # finds all nonzero elements in the adj matrix
IJ <- i[dagx == 1, ] # sort the arcs from lowest possible y
I <- IJ[, 1]
J <- IJ[, 2] # and highest possible x, arcs are x->y
e <- 1
for (y in 1:n) {
for (x in n:1) {
if (dagx[ord[x], ord[y]] == 1) {
I[e] <- ord[x]
J[e] <- ord[y]
e <- e + 1
}
}
}
## Now we have to decide which arcs are part of the essential graph and
## which are undirected edges in the essential graph.
## Undecided arc in the DAG are 1, directed in EG are 2 and undirected in EG are 3.
for (e in 1:length(I)) {
if (dagx[I[e], J[e]] == 1) {
cont <- TRUE
for (w in 1:n) {
if (dagx[w, I[e]] == 2) {
if (dagx[w, J[e]] != 0) {
dagx[w, J[e]] <- 2
} else {
for (ww in 1:n) {
if (dagx[ww, J[e]] != 0) {
dagx[ww, J[e]] <- 2
}
} # skip the rest and start with another arc from the list
w <- n
cont <- FALSE
}
}
}
if (cont) {
exists <- FALSE
for (z in 1:n) {
if ((dagx[z, J[e]] != 0) & (z != I[e]) & (dagx[z, I[e]] == 0)) {
exists <- TRUE
for (ww in 1:n) {
if (dagx[ww, J[e]] == 1) {
dagx[ww, J[e]] <- 2
}
}
}
}
if (!exists) {
for (ww in 1:n) {
if (dagx[ww, J[e]] == 1) {
dagx[ww, J[e]] <- 3
}
}
}
}
}
}
(dagx == 2) + (dagx == 3) + t(dagx == 3)
}
"findPath" <-
function(amat, st, en, path = c()) {
### Find a path between nodes st and en in a UG with adjacency mat. amat.
indices <- 1:nrow(amat)
if (st == en) { # st is 'node' in recursive calls
return(c(path, st))
}
if (sum(amat[st, ]) == 0) {
return(NULL)
}
## ne <- bd(st,amat)
ne <- indices[amat[st, ] == 1] # Boundary of x. Assumes that amat is symmetric
for (node in ne) {
if (!is.element(node, c(path, st))) {
newpath <- findPath(amat, node, en, c(path, st))
if (!is.null(newpath)) {
return(newpath)
}
}
}
}
`fitAncestralGraph` <-
function(amat, S, n, tol = 1e-06) {
### Fit Ancestral Graphs. Mathias Drton, 2003 2009. It works for ADMGs
nam <- rownames(S)
nod <- rownames(amat)
## permute graph to have same layout as S
if (is.null(nod)) {
stop("The adjacency matrix has no labels!")
}
if (!all(is.element(nod, nam))) {
stop("The nodes of the graph do not match the names of the variables")
} else {
sek <- intersect(nam, nod)
}
S <- S[sek, sek, drop = FALSE] # Resizes eventually S
amat <- amat[sek, sek, drop = FALSE] # and reorders amat
temp <- icfmag(amat, S, tol)
p <- ncol(S)
df <- p * (p - 1) / 2 - sum(In(amat + t(amat))) / 2 # Degrees of freedom
dev <- likGau(solve(temp$Sigmahat), S, n, p)
if (is.null(temp$Bhat)) {
Beta <- NULL
} else {
## Beta <- diag(1,p)-temp$Bhat
Beta <- temp$Bhat
}
return(list(
Shat = temp$Sigmahat, Lhat = temp$Lambdahat, Bhat = Beta,
Ohat = temp$Omegahat, dev = dev, df = df, it = temp$iterations
))
}
`fitConGraph` <- function(amat, S, n, cli = NULL, alg = 3, pri = FALSE, tol = 1e-06) {
### Fits a concentration graph G.
### Now it does not compute the cliques of the graph.
nam <- rownames(S)
nod <- rownames(amat)
if (is.null(nod)) {
stop("The adjacency matrix has no labels.")
}
if (!all(is.element(nod, nam))) {
stop("The nodes of the graph do not match the names of the variables.")
} else {
sek <- intersect(nam, nod)
}
S <- S[sek, sek, drop = FALSE] # Resizes eventually S
amat <- amat[sek, sek, drop = FALSE] # and reorders amat
nod <- rownames(amat)
if (all(amat == 0)) {
alg <- 2
cli <- as.list(nod)
}
if (is.null(cli)) {
alg <- 3
} else {
alg <- 2
nc <- length(cli)
if (nc == 1) {
return(list(Shat = S, dev = 0, df = 0, it = 1))
}
}
k <- ncol(S)
if (alg == 1) { # First algorithm by Whittaker (needs the cliques)
it <- 0
W <- diag(diag(S)) # Starting value
dimnames(W) <- dimnames(S)
repeat {
W.old <- W
it <- it + 1
for (i in 1:nc) {
a <- cli[[i]]
b <- setdiff(nod, a)
Saa <- S[a, a]
Waa <- W[a, a]
Wba <- W[b, a]
Wbb <- W[b, b]
B <- Wba %*% solve(Waa)
Spar <- Wbb - B %*% Waa %*% t(B)
BV <- B %*% Saa
W[b, a] <- BV
W[a, b] <- t(BV)
W[a, a] <- Saa
W[b, b] <- Spar + BV %*% t(B)
}
if (sum(abs(W - W.old)) < tol) break
}
} else if (alg == 2) { # Second algorithm by Whittaker (needs the cliques)
it <- 0
K <- solve(diag(diag(S))) # Starting value
dimnames(K) <- dimnames(S)
repeat {
K.old <- K
it <- it + 1
for (i in 1:nc) {
a <- cli[[i]]
b <- setdiff(nod, a)
K[a, a] <- solve(S[a, a]) + K[a, b] %*% solve(K[b, b]) %*% K[b, a]
if (pri) {
dev <- likGau(K, S, n, k)
cat(dev, "\n")
}
}
if (sum(abs(K - K.old)) < tol) break
}
W <- solve(K)
} else if (alg == 3) { # Hastie Friedman Tibshirani p. 791
W0 <- S
W <- S
it <- 0
converge <- FALSE
while (!converge) {
it <- it + 1
for (j in 1:k) {
W11 <- W[-j, -j, drop = FALSE]
w12 <- W[-j, j]
s12 <- S[-j, j, drop = FALSE]
paj <- amat[j, ] == 1 # neighbors
paj <- paj[-j]
beta <- rep(0, k - 1)
if (all(!paj)) {
w <- rep(0, k - 1)
} else {
beta[paj] <- solve(W11[paj, paj], s12[paj, ])
w <- W11 %*% beta
}
W[-j, j] <- w
W[j, -j] <- w
}
di <- norm(W0 - W)
if (pri) {
cat(di, "\n")
}
if (di < tol) {
converge <- TRUE
} else {
W0 <- W
}
}
}
df <- (sum(1 - amat) - k) / 2
Kh <- solve(W)
dev <- likGau(Kh, S, n, k)
list(Shat = W, dev = dev, df = df, it = it)
}
`fitCovGraph` <-
function(amat, S, n, alg = "icf", dual.alg = 2, start.icf = NULL, tol = 1e-06) {
### Fits a Covariance Graph. Mathias Drton, 2003
### amat: adjacency matrix; S: covariance matrix; n: sample size.
amat <- In(amat) # Forces the ones in a bidirected graph defined with makeMG
nam <- rownames(S)
nod <- rownames(amat)
if (is.null(nod)) {
stop("The adjacency matrix has no labels.")
}
if (!all(is.element(nod, nam))) {
stop("The nodes of the graph do not match the names of the variables.")
} else {
sek <- intersect(nam, nod)
}
S <- S[sek, sek, drop = FALSE] # Resizes eventually S
amat <- amat[sek, sek, drop = FALSE] # and reorders amat
if (alg == "icf") {
temp <- icf(amat, S, start.icf, tol)
} else {
if (alg == "dual") {
Sinv <- solve(S)
temp <- fitConGraph(amat, Sinv, n, pri = FALSE, alg = dual.alg, tol = 1e-06)
temp <- list(Sigmahat = zapsmall(solve(temp$Shat)), iterations = temp$it)
} else {
stop("Algorithm misspecified!")
}
}
df <- sum(amat[upper.tri(amat)] == 0) # Degrees of freedom
k <- ncol(S)
dev <- likGau(solve(temp$Sigmahat), S, n, k)
return(list(Shat = temp$Sigmahat, dev = dev, df = df, it = temp$iterations))
}
"fitDag" <-
function(amat, S, n) {
### Fits linear recursive regressions with independent residuals.
### amat: the adjacency matrix of the DAG. S: cov matrix. n: sample size.
if (missing(amat)) { # saturated model
amat <- lower.tri(diag(ncol(S)), diag = FALSE) * 1
dimnames(amat) <- dimnames(S)
}
nam <- rownames(S)
nod <- rownames(amat)
if (is.null(nod)) {
stop("The adjacency matrix has no labels.")
}
if (!all(is.element(nod, nam))) {
stop("The nodes of the graph do not match the names of the variables.")
} else {
sek <- intersect(nam, nod)
}
S <- S[sek, sek] # Resizes eventually S
amat <- amat[sek, sek] # and reorders amat
Delta <- rep(length(sek), 0)
emat <- edgematrix(amat)
A <- emat
p <- ncol(S)
ip <- 1:p
for (i in 1:p) {
u <- emat[i, ]
v <- ip[u == 1 & ip != i]
M <- swp(S, v)[i, ]
A[i, ] <- -A[i, ] * M
A[i, i] <- 1
k <- sum(A[i, ])
Delta[i] <- M[i]
}
names(Delta) <- sek
B <- solve(A)
Shat <- B %*% diag(Delta) %*% t(B)
dimnames(Shat) <- dimnames(S)
Khat <- solve(Shat)
H <- S %*% Khat
trace <- function(A) sum(diag(A))
dev <- (trace(H) - log(det(H)) - p) * n
df <- p * (p + 1) / 2 - sum(amat == 1) - p
list(Shat = Shat, Ahat = A, Dhat = Delta, dev = dev, df = df)
}
"fitDagLatent" <-
function(amat, Syy, n, latent, norm = 1, seed, maxit = 9000, tol = 1e-6, pri = FALSE) {
### Fits linear recursive regressions with independent residuals and one latent variable.
### Syy: covariance matrix, n: sample size, amat: adjacency matrix.
### NOTE: both amat and Syy must have rownames.
### latent is the "name" of the latent in the rownames of Syy. norm = normalisation type.
## Local functions
setvar1 <- function(V, z, paz, norm)
## paz are the parents of the latent (needed if norm=2)
{
## Normalizes V
if (norm == 1) {
## Rescales V forcing V[z,z] = 1
a <- 1 / sqrt(V[z, z])
} else if (norm == 2) {
## Rescales V forcing Delta[z,z] = 1
if (sum(paz) > 0) {
sig <- V[z, z] - V[z, paz] %*% solve(V[paz, paz]) %*% V[paz, z]
} else {
sig <- V[z, z]
}
a <- 1 / sqrt(sig)
}
V[z, ] <- V[z, ] * a
V[, z] <- V[, z] * a
V
}
cmqi <- function(Syy, Sigma, z) {
## Computes the matrix C(M | Q) by Kiiveri (1987), Psychometrika.
## It is a slight generalization in which Z is not the last element.
## z is a Boolean vector indicating the position of the latent variable in X.
y <- !z
Q <- solve(Sigma)
Qzz <- Q[z, z]
Qzy <- Q[z, y]
B <- -solve(Qzz) %*% Qzy
BSyy <- B %*% Syy
E <- Sigma * 0
E[y, y] <- Syy
E[y, z] <- t(BSyy)
E[z, y] <- BSyy
E[z, z] <- BSyy %*% t(B) + solve(Qzz)
dimnames(E) <- dimnames(Sigma)
E
}
fitdag <- function(amat, S, n, constr = NULL) {
## Fits linear recursive regressions with independent residuals (fast version).
## NOTE. amat and S must have the same size and variables. constr is a matrix
## indicating the edges that must be constrained to 1.
emat <- edgematrix(amat)
A <- emat
p <- ncol(S)
Delta <- rep(p, 0)
ip <- 1:p
for (i in ip) {
u <- emat[i, ]
v <- ip[(u == 1) & (ip != i)] # Parents
if (length(v) == 0) { # If pa is empty
Delta[i] <- S[i, i]
next
}
M <- lmfit(S, y = i, x = v, z = (constr[i, ] == 1))
A[i, ] <- -A[i, ] * M
A[i, i] <- 1
k <- sum(A[i, ])
Delta[i] <- M[i]
}
Khat <- t(A) %*% diag(1 / Delta) %*% A
Shat <- solve(Khat)
list(A = A, Delta = Delta, Shat = Shat, Khat = Khat)
}
lmfit <- function(S, y, x, z = NULL) {
## Regression coefficients of y given x eventually with z constrained to 1.
## Residual variance in position y.
Sxy <- S[x, y, drop = FALSE] - apply(S[x, z, drop = FALSE], 1, sum)
Sxx <- S[x, x, drop = FALSE]
bxy <- solve(Sxx, Sxy)
out <- rep(0, nrow(S))
out[x] <- bxy
out[z] <- 1
names(out) <- rownames(S)
xz <- c(x, z)
b <- out[xz, drop = FALSE]
res <- S[y, y] + t(b) %*% (S[xz, xz, drop = FALSE] %*% b - 2 * S[xz, y, drop = FALSE])
out[y] <- res
out
}
lik <- function(K, S, n, p) {
## Computes the deviance
trace <- function(a) sum(diag(a))
SK <- S %*% K
(trace(SK) - log(det(SK)) - p) * n
}
## Beginning of the main function
nam <- rownames(Syy) # Names of the variables (they can be more than the nodes)
nod <- rownames(amat) # Names of the nodes of the DAG (that contains the latent)
if (is.null(nod)) {
stop("The adjacency matrix has no labels.")
}
if (!all(is.element(setdiff(nod, latent), nam))) {
stop("The observed nodes of the graph do not match the names of the variables.")
} else {
sek <- intersect(nam, nod)
}
Syy <- Syy[sek, sek, drop = FALSE] # Resizes eventually S
sek <- c(sek, latent)
amat <- amat[sek, sek, drop = FALSE] # and reorders amat
nod <- rownames(amat)
paz <- pa(latent, amat) # Parents of the latent
paz <- is.element(nod, paz)
dn <- list(nod, nod)
wherez <- is.element(nod, latent) # Index of the latent
if (is.null(wherez)) {
stop("Wrong name of the latent variable!")
}
wherey <- !wherez
p <- ncol(Syy)
df <- p * (p + 1) / 2 - sum(amat == 1) - p # Degrees of freedom
if (df <= 0) {
warning(paste("The degrees of freedom are ", df))
}
if (!missing(seed)) set.seed(seed) # For random starting value
Sigma.old <- rcorr(p + 1)
Sigma.old <- setvar1(Sigma.old, wherez, paz, norm = norm)
dimnames(Sigma.old) <- dn
it <- 0
repeat{
it <- it + 1
if (it > maxit) {
warning("Maximum number of iterations reached.")
break
}
Q <- cmqi(Syy, Sigma.old, wherez) # E-step. See Kiiveri, 1987
fit <- fitdag(amat, Q, n) # M-step
Sigma.new <- fit$Shat
if (pri) {
dev <- lik(fit$Khat, Q, n, (p + 1)) # Monitoring progress of iterations
cat(dev, "\n")
} else {
if (0 == (it %% 80)) {
cat("\n")
} else {
cat(".")
}
}
if (sum(abs(Sigma.new - Sigma.old)) < tol) break # Test convergence
Sigma.old <- Sigma.new
}
cat("\n")
dev <- lik(fit$Khat, Q, n, (p + 1))
Shat <- setvar1(Sigma.new, wherez, paz, norm = norm) # Normalize Shat
dimnames(Shat) <- dn
Khat <- solve(Shat)
fit <- fitDag(amat, Shat, n)
list(Shat = Shat, Ahat = fit$Ahat, Dhat = fit$Dhat, dev = dev, df = df, it = it)
}
"fundCycles" <-
function(amat) {
### Finds a set of fundamental cycles for an UG with adj. matrix amat.
fc <- c()
tr <- bfsearch(amat) # Spanning tree
if (is.null(tr)) {
return(NULL)
}
if (is.null(tr$chords)) {
return(NULL)
}
co <- tr$chords # edges of the cospanning tree
for (i in 1:nrow(co)) {
e <- co[i, ]
g <- tr$tree # edge matrix of the spanning tree
cy <- findPath(g, st = e[1], en = e[2])
splitCycle <- function(v) {
## Splits a cycle v into a matrix of edges.
v <- c(v, v[1])
cbind(v[-length(v)], v[-1])
}
cy <- splitCycle(cy)
fc <- c(fc, list(cy))
}
fc
}
"icf" <-
function(bi.graph, S, start = NULL, tol = 1e-06) {
### Iterative conditional fitting for bidirected graphs. Mathias Drton, 2003
if (!is.matrix(S)) {
stop("Second argument is not a matrix!")
}
if (dim(S)[1] != dim(S)[2]) {
stop("Second argument is not a square matrix!")
}
if (min(eigen(S)[[1]]) <= 0) {
stop("Second argument is not a positive definite matrix!")
}
p <- nrow(S)
i <- 0
## prep spouses and non-spouses
pa.each.node <- function(amat) {
## List of the parents of each node.
## If amat is symmetric it returns the boundaries.
p <- nrow(amat)
b <- vector(p, mode = "list")
ip <- 1:p
for (i in 1:p) {
b[[i]] <- ip[amat[, i] == 1]
}
b
}
spo <- pa.each.node(bi.graph)
nsp <- pa.each.node(cmpGraph(bi.graph))
number.spouses <- unlist(lapply(spo, length))
no.spouses <- (1:p)[number.spouses == 0]
all.spouses <- (1:p)[number.spouses == (p - 1)]
nontrivial.vertices <- setdiff((1:p), no.spouses)
if (length(nontrivial.vertices) == 0) {
if (p == 1) {
Sigma <- S
} else {
Sigma <- diag(diag(S))
dimnames(Sigma) <- dimnames(S)
}
return(list(Sigmahat = Sigma, iterations = 1))
}
if (is.null(start)) {
Sigma <- as.matrix(diag(diag(S))) # starting value
} else {
temp <- diag(start)
start[bi.graph == 0] <- 0
diag(start) <- temp
diag(start)[no.spouses] <- diag(S)[no.spouses]
Sigma <- as.matrix(start)
if (min(eigen(Sigma)$values) <= 0) {
stop("Starting value is not feasible!")
}
}
repeat{
i <- i + 1
Sigma.old <- Sigma
for (v in nontrivial.vertices) {
if (is.element(v, all.spouses)) {
B <- S[v, -v] %*% solve(S[-v, -v])
lambda <- S[v, v] - B %*% S[-v, v]
} else {
B.spo.nsp <-
Sigma[spo[[v]], nsp[[v]]] %*% solve(Sigma[nsp[[v]], nsp[[v]]])
YZ <- S[v, spo[[v]]] - S[v, nsp[[v]]] %*% t(B.spo.nsp)
B.spo <-
YZ %*%
solve(S[spo[[v]], spo[[v]]]
- S[spo[[v]], nsp[[v]]] %*% t(B.spo.nsp)
- B.spo.nsp %*% S[nsp[[v]], spo[[v]]]
+ B.spo.nsp %*% S[nsp[[v]], nsp[[v]]] %*% t(B.spo.nsp))
lambda <- S[v, v] - B.spo %*% t(YZ)
B.nsp <- -B.spo %*% B.spo.nsp
B <- rep(0, p)
B[spo[[v]]] <- B.spo
B[nsp[[v]]] <- B.nsp
B <- B[-v]
}
## here I can improve by only using B[spo[[v]]]!
Sigma[v, -v] <- B %*% Sigma[-v, -v]
Sigma[v, nsp[[v]]] <- 0
Sigma[-v, v] <- t(Sigma[v, -v])
Sigma[v, v] <- lambda + B %*% Sigma[-v, v]
}
if (sum(abs(Sigma.old - Sigma)) < tol) break
}
dimnames(Sigma) <- dimnames(S)
return(list(Sigmahat = Sigma, iterations = i))
}
`icfmag` <-
function(mag, S, tol = 1e-06) {
## Iterative conditional fitting for ancestral and mixed graphs. Mathias Drton, 2003, 2009.
if (!is.matrix(S)) {
stop("Second argument is not a matrix!")
}
if (dim(S)[1] != dim(S)[2]) {
stop("Second argument is not a square matrix!")
}
if (min(eigen(S)[[1]]) <= 0) {
stop("Second argument is not a positive definite matrix!")
}
p <- nrow(S) # Dimensionality
temp <- unmakeMG(mag)
mag.ug <- temp$ug
mag.dag <- temp$dg
mag.bg <- temp$bg
## Catch trivial case
if (p == 1) {
return(list(Sigmahat = S, Omegahat = S, Bhat = NULL, Lambdahat = NULL, iterations = 1))
}
## Starting value
Omega <- diag(diag(S))
dimnames(Omega) <- dimnames(S)
B <- diag(p)
dimnames(B) <- dimnames(S)
## IPS for UG
UG.part <- (1:p)[0 == apply(mag.dag + mag.bg, 2, sum)]
if (length(UG.part) > 0) {
Lambda.inv <-
fitConGraph(mag.ug[UG.part, UG.part, drop = FALSE],
S[UG.part, UG.part, drop = FALSE], p + 1,
tol = tol
)$Shat
Omega[UG.part, UG.part] <- Lambda.inv
}
## Prepare list of spouses, parents, etc.
pa.each.node <- function(amat) {
## List of the parents of each node.
## If the adjacency matrix is symmetric it gives the boundary.
p <- nrow(amat)
b <- vector(p, mode = "list")
ip <- 1:p
for (i in 1:p) {
b[[i]] <- ip[amat[, i] == 1]
}
b
}
spo <- pa.each.node(mag.bg)
nsp <- pa.each.node(cmpGraph(mag.bg))
pars <- pa.each.node(mag.dag)
i <- 0
repeat{
i <- i + 1
Omega.old <- Omega
B.old <- B
for (v in setdiff(1:p, UG.part)) {
parv <- pars[[v]]
spov <- spo[[v]]
if (length(spov) == 0) {
if (length(parv) != 0) {
if (i == 1) { # do it only once
## attention: B = - beta
B[v, parv] <- -S[v, parv] %*% solve(S[parv, parv])
Omega[v, v] <- S[v, v] + B[v, parv] %*% S[parv, v]
}
}
} else {
if (length(parv) != 0) {
O.inv <- matrix(0, p, p)
O.inv[-v, -v] <- solve(Omega[-v, -v])
Z <- O.inv[spov, -v] %*% B[-v, ]
lpa <- length(parv)
lspo <- length(spov)
XX <- matrix(0, lpa + lspo, lpa + lspo)
XX[1:lpa, 1:lpa] <- S[parv, parv]
XX[1:lpa, (lpa + 1):(lpa + lspo)] <- S[parv, ] %*% t(Z)
XX[(lpa + 1):(lpa + lspo), 1:lpa] <- t(XX[1:lpa, (lpa + 1):(lpa + lspo)])
XX[(lpa + 1):(lpa + lspo), (lpa + 1):(lpa + lspo)] <- Z %*% S %*% t(Z)
YX <- c(S[v, parv], S[v, ] %*% t(Z))
temp <- YX %*% solve(XX)
B[v, parv] <- -temp[1:lpa]
Omega[v, spov] <- temp[(lpa + 1):(lpa + lspo)]
Omega[spov, v] <- Omega[v, spov]
temp.var <- S[v, v] - temp %*% YX
Omega[v, v] <- temp.var +
Omega[v, spov] %*% O.inv[spov, spov] %*% Omega[spov, v]
} else {
O.inv <- matrix(0, p, p)
O.inv[-v, -v] <- solve(Omega[-v, -v])
Z <- O.inv[spov, -v] %*% B[-v, ]
XX <- Z %*% S %*% t(Z)
YX <- c(S[v, ] %*% t(Z))
Omega[v, spov] <- YX %*% solve(XX)
Omega[spov, v] <- Omega[v, spov]
temp.var <- S[v, v] - Omega[v, spov] %*% YX
Omega[v, v] <- temp.var +
Omega[v, spov] %*% O.inv[spov, spov] %*%
Omega[spov, v]
}
}
}
if (sum(abs(Omega.old - Omega)) + sum(abs(B.old - B)) < tol) break
}
Sigma <- solve(B) %*% Omega %*% solve(t(B))
## Corrections by Thomas Richardson of the following:
## Lambda <- Omega
## Lambda[-UG.part,-UG.part] <- 0
Lambda <- matrix(0, p, p)
if (length(UG.part) > 0) {
Lambda[-UG.part, -UG.part] <- Omega[-UG.part, -UG.part]
}
Omega[UG.part, UG.part] <- 0
return(list(
Sigmahat = Sigma, Bhat = B, Omegahat = Omega, Lambdahat = Lambda,
iterations = i
))
}
`In` <-
function(A) {
### Indicator matrix of structural zeros.
abs(sign(A))
}
`isAcyclic` <-
function(amat, method = 2) {
### Tests if the graph is acyclic.
if (method == 1) {
G <- graph.adjacency(amat)
return(max(clusters(G, mode = "strong")$csize) == 1)
} else if (method == 2) {
B <- transClos(amat)
l <- B[lower.tri(B)]
u <- t(B)[lower.tri(t(B))]
com <- (l & u)
return(all(!com))
} else {
stop("Wrong method.")
}
}
"isGident" <-
function(amat) {
### Is the UG with adjacency matrix amat G-identifiable?
is.odd <- function(x) (x %% 2) == 1
cmpGraph <- function(amat) {
## Adjacency matrix of the complementary graph.
g <- 0 + (!amat)
diag(g) <- 0
g
}
cgr <- cmpGraph(amat)
cc <- conComp(cgr)
l <- unique(cc)
k <- length(l)
g <- rep(k, 0)
for (i in 1:k) {
subg <- cgr[cc == i, cc == i, drop = FALSE]
m <- cycleMatrix(subg)
if (is.null(m)) {
rt <- 0
} else {
rt <- apply(m, 1, sum)
}
g[i] <- any(is.odd(rt))
}
all(g)
}
"parcor" <-
function(S) {
### Finds the partial correlation matrix of the variables given the rest.
### S is the covariance matrix.
p <- ncol(S)
K <- solve(S)
a <- 1 / sqrt(diag(K))
K <- K * outer(a, a)
out <- 2 * diag(p) - K
dimnames(out) <- dimnames(S)
out
}
"pcor" <-
function(u, S) {
### Partial correlation between u[1:2], given th rest of u. S: cov matrix.
k <- solve(S[u, u])
-k[1, 2] / sqrt(k[1, 1] * k[2, 2])
}
"pcor.test" <-
function(r, q, n) {
df <- n - 2 - q
tval <- r * sqrt(df) / sqrt(1 - r * r)
pv <- 2 * pt(-abs(tval), df)
list(tval = tval, df = df, pvalue = pv)
}
"rcorr" <-
function(d) {
# Generates a random correlation matrix of dimension d
# with the method of Marsaglia and Olkin (1984).
h <- rsphere(d, d)
h %*% t(h)
}
"rnormDag" <-
function(n, A, Delta) {
### Generates n observations from a multivariate normal with mean 0
### and a covariance matrix A^-1 Delta (A^-1)'.
p <- length(Delta)
E <- matrix(0, n, p)
for (j in 1:p) {
E[, j] <- rnorm(n, 0, sqrt(Delta[j]))
}
B <- solve(A)
Y <- E %*% t(B)
colnames(Y) <- colnames(A)
Y
}
"rsphere" <-
function(n, d) {
## Generates n random vectors uniformly dist. on the
## surface of a sphere, in d dimensions.
X <- matrix(rnorm(n * d), n, d)
d <- apply(X, 1, function(x) sqrt(sum(x * x)))
sweep(X, 1, d, "/")
}
"shipley.test" <-
function(amat, S, n) {
### Overall d-separation test. See Shipley (2000).
### amat: adjacency matrix; S: covariance matrix; n: observations.
pval <- function(r, q, n) {
## See pcor
df <- n - 2 - q
tval <- r * sqrt(df) / sqrt(1 - r * r)
2 * pt(-abs(tval), df)
}
l <- basiSet(amat)
k <- length(l)
p <- rep(0, k)
for (i in 1:k) {
r <- pcor(l[[i]], S)
q <- length(l[[i]]) - 2
p[i] <- pval(r, q, n)
}
ctest <- -2 * sum(log(p))
df <- 2 * k
pv <- 1 - pchisq(ctest, df)
list(ctest = ctest, df = df, pvalue = pv)
}
"swp" <-
function(V, b) {
### SWP operator. V is the covariance matrix, b is a subset of indices.
p <- ncol(V)
u <- is.na(match(1:p, b))
a <- (1:p)[u]
out <- 0 * V
dimnames(out) <- dimnames(V)
if (length(a) == 0) {
return(-solve(V))
} else if (length(a) == p) {
return(V)
} else {
Saa <- V[a, a, drop = FALSE]
Sab <- V[a, b, drop = FALSE]
Sbb <- V[b, b, drop = FALSE]
B <- Sab %*% solve(Sbb)
out[a, a] <- Saa - B %*% t(Sab)
out[a, b] <- B
out[b, a] <- t(B)
out[b, b] <- -solve(Sbb)
return(out)
}
## list(swept = out, coef = out[a, b], rss = out[a, a, drop = F])
}
"topOrder" <-
function(amat) {
### Return the nodes in topological order (parents before children).
### Translated from: Kevin Murphy's BNT.
if (!isAcyclic(amat)) stop("The graph is not acyclic!")
n <- nrow(amat)
nod <- 1:n
indeg <- rep(0, n)
up <- !amat[lower.tri(amat)]
if (all(up)) {
return(nod)
}
zero.indeg <- c() # a stack of nodes with no parents
for (i in nod) {
indeg[i] <- sum(amat[, i])
if (indeg[i] == 0) {
zero.indeg <- c(i, zero.indeg)
}
}
s <- 1
ord <- rep(0, n)
while (length(zero.indeg) > 0) {
v <- zero.indeg[1] # pop v
zero.indeg <- zero.indeg[-1]
ord[s] <- v
s <- s + 1
cs <- nod[amat[v, ] == 1]
if (length(cs) == 0) next
for (j in 1:length(cs)) {
k <- cs[j]
indeg[k] <- indeg[k] - 1
if (indeg[k] == 0) {
zero.indeg <- c(k, zero.indeg)
} # push k
}
}
ord
}
"topSort" <-
function(amat) {
### Topological sort of the DAG with adjacency matrix amat.
ord <- topOrder(amat)
amat[ord, ord]
}
`transClos` <-
function(amat) {
### Transitive closure of the relation with adjacency matrix amat.
if (nrow(amat) == 1) {
return(amat)
}
A <- amat
diag(A) <- 1
repeat {
B <- sign(A %*% A)
if (all(B == A)) {
break
} else {
A <- B
}
}
diag(A) <- 0
A
}
"triDec" <-
function(Sigma) {
### Triangular decomposition of covariance matrix Sigma.
R <- chol(solve(Sigma))
dimnames(R) <- dimnames(Sigma)
D <- diag(R)
A <- diag(1 / D) %*% R
dimnames(A) <- dimnames(Sigma)
B <- solve(A)
list(A = A, B = B, Delta = 1 / (D^2))
}
"UG" <-
function(f) {
### Defines an UG from a model formula. Returns the adj. matrix.
tt <- terms(f)
if (attr(tt, "response") == 1) {
stop("You should not specify a response!")
}
nod <- dimnames(attr(tt, "factors"))[[1]]
N <- unique(nod) # set of nodes
dN <- length(N) # number of nodes
amat <- matrix(0, dN, dN)
o <- attr(tt, "order") <= 2
v <- attr(tt, "factors")[, o, drop = FALSE]
m <- match(dimnames(v)[[1]], N)
for (i in 1:sum(o)) {
ij <- m[v[, i] == 1]
amat[ij[1], ij[2]] <- 1
amat[ij[2], ij[1]] <- 1
}
dimnames(amat) <- list(N, N)
amat
}
`makeMG` <- function(dg = NULL, ug = NULL, bg = NULL) {
dg.nodes <- rownames(dg)
ug.nodes <- rownames(ug)
bg.nodes <- rownames(bg)
ver <- unique(c(dg.nodes, ug.nodes, bg.nodes))
d <- length(ver)
amat <- matrix(0, d, d)
dimnames(amat) <- list(ver, ver)
amat.dg <- amat
amat.ug <- amat
amat.bg <- amat
if (!is.null(dg)) {
amat.dg[dg.nodes, dg.nodes] <- dg
}
if (!is.null(ug)) {
amat.ug[ug.nodes, ug.nodes] <- ug * 10
}
if (!is.null(bg)) {
amat.bg[bg.nodes, bg.nodes] <- bg * 100
}
amat.dg + amat.ug + amat.bg
}
`unmakeMG` <- function(amat) {
### Returns a list with the three components of a loopless MG.
d <- nrow(amat)
ug <- dg <- bg <- amat
M <- expand.grid(dg = 0:1, ug = 0:1, bg = 0:1)
i <- strtoi(as.character(amat), 2)
GG <- M[i + 1, ]
ug[, ] <- GG[, 2]
dg[, ] <- GG[, 1]
bg[, ] <- GG[, 3]
if (any(ug != t(ug))) stop("Undirected edges are wrongly coded.")
if (any(bg != t(bg))) stop("Undirected edges are wrongly coded.")
return(list(dg = dg, ug = ug, bg = bg))
}
`DG` <- function(...) {
f <- list(...)
nb <- length(f)
nod <- c()
for (k in 1:nb) {
tt <- terms(f[[k]], specials = "I")
vars <- dimnames(attr(tt, "factors"))[[1]]
skip <- attr(tt, "specials")$I
if (!is.null(skip)) {
vars <- vars[-skip]
}
nod <- c(nod, vars)
}
N <- unique(nod)
dN <- length(N)
amat <- matrix(0, dN, dN)
for (k in 1:nb) {
tt <- terms(f[[k]], specials = "I")
vars <- dimnames(attr(tt, "factors"))[[1]]
if (attr(tt, "response") == 1) {
j <- match(vars[1], N)
i <- match(vars[-1], N)
amat[i, j] <- 1
} else if (attr(tt, "response") == 0) {
stop("Some equations have no response")
}
}
dimnames(amat) <- list(N, N)
amat
}
`isAG` <- function(amat) {
### checks if a graph is an ancestral graph
comp <- unmakeMG(amat)
ug <- comp$ug
dag <- comp$dg
bg <- comp$bg
out <- TRUE
if (any(amat > 100)) {
warning("There are double edges.")
out <- FALSE
}
anteriorGraph <- function(amat) {
## Adjacency matrix of the anterior graph from an AG.
A <- 0 + ((amat == 1) | (amat == 10)) # Select the directed and undirected edges
transClos(A)
}
if (any(apply(dag, 2, sum) & apply(ug, 2, sum))) {
warning("Undirected edges meeting a directed edge.")
out <- FALSE
}
if (any(apply(bg, 2, sum) & apply(ug, 2, sum))) {
warning("Undirected edges meeting a bidirected edge.")
out <- FALSE
}
H <- anteriorGraph(amat)
if (any((H == 1) & (amat == 100))) {
warning("Spouses cannot be ancestors.")
out <- FALSE
}
out
}
`isADMG` <- function(amat) {
### check is if a graph is an ADMG
comp <- unmakeMG(amat)
ug <- comp$ug
dag <- comp$dg
bg <- comp$bg
out <- TRUE
if (any(amat > 100)) {
warning("There are double edges.")
out <- FALSE
}
if (!isAcyclic(dag)) {
warning("Not acyclic.")
out <- FALSE
}
out
}
`plotGraph` <- function(a, dashed = FALSE, tcltk = TRUE, layout = layout.auto, directed = FALSE, noframe = FALSE, nodesize = 15, vld = 0, vc = "gray", vfc = "black", colbid = "FireBrick3", coloth = "black", cex = 1.5, ...) {
if (class(a)[1] == "igraph" || class(a)[1] == "graphNEL" || class(a)[1] ==
"character") {
a <- grMAT(a)
}
if (is(a, "matrix")) {
if (nrow(a) == ncol(a)) {
if (length(rownames(a)) != ncol(a)) {
rownames(a) <- 1:ncol(a)
colnames(a) <- 1:ncol(a)
}
if (!directed) {
if (all(a == t(a)) & all(a[a != 0] == 1)) {
a <- a * 10
}
}
l1 <- c()
l2 <- c()
for (i in 1:nrow(a)) {
for (j in i:nrow(a)) {
if (a[i, j] == 1) {
l1 <- c(l1, i, j)
l2 <- c(l2, 2)
}
if (a[j, i] %% 10 == 1) {
l1 <- c(l1, j, i)
l2 <- c(l2, 2)
}
if (a[i, j] == 10) {
l1 <- c(l1, i, j)
l2 <- c(l2, 0)
}
if (a[i, j] == 11) {
l1 <- c(l1, i, j, i, j)
l2 <- c(l2, 2, 0)
}
if (a[i, j] == 100) {
l1 <- c(l1, i, j)
l2 <- c(l2, 3)
}
if (a[i, j] == 101) {
l1 <- c(l1, i, j, i, j)
l2 <- c(l2, 2, 3)
}
if (a[i, j] == 110) {
l1 <- c(l1, i, j, i, j)
l2 <- c(l2, 0, 3)
}
if (a[i, j] == 111) {
l1 <- c(l1, i, j, i, j, i, j)
l2 <- c(l2, 2, 0, 3)
}
}
}
} else {
stop("'object' is not in a valid adjacency matrix form")
}
if (length(l1) > 0) {
## l1 <- l1 - 1 # igraph0
agr <- graph(l1, n = nrow(a), directed = TRUE)
}
if (length(l1) == 0) {
agr <- graph.empty(n = nrow(a), directed = TRUE)
return(tkplot(agr, vertex.label = rownames(a)))
}
ed0 <- get.edgelist(agr)
ne <- nrow(ed0)
ed <- apply(apply(ed0, 1, sort), 2, paste, collapse = "-")
tb <- table(ed)
curve <- rep(0, ne)
if (any(tb > 1)) {
tb <- tb[tb > 1]
for (i in 1:length(tb)) {
reped <- names(tb[i]) == ed
U <- ed0[reped, ]
if (sum(reped) == 2) {
ed0[reped]
if (all(is.element(c(0, 3), l2[reped]))) {
curve[reped] <- c(0.9, -0.9)
}
if (all(U[1, ] == U[2, ])) {
curve[reped] <- c(0.6, -0.6)
} else {
curve[reped] <- c(0.6, 0.6)
}
}
if (sum(reped) == 3) {
curve[(l2 == 3) & reped] <- 0.9
curve[(l2 == 0) & reped] <- -0.9
}
if (sum(reped) == 4) {
curve[(l2 == 3) & reped] <- 0.3
curve[(l2 == 0) & reped] <- -0.3
curve[(l2 == 1) & reped] <- 0.9
curve[(l2 == 2) & reped] <- 0.9
}
}
}
col <- rep(coloth, ne)
col[l2 == 3] <- colbid
if (dashed) {
ety <- rep(1, ne)
ety[l2 == 3] <- 2
l2[l2 == 3] <- 0
} else {
ety <- rep(1, ne)
}
if (noframe) {
vfc <- "white"
vc <- "white"
}
if (tcltk == TRUE) {
id <- tkplot(agr,
layout = layout, edge.curved = curve,
vertex.label = rownames(a), edge.arrow.mode = l2,
edge.color = col, edge.lty = ety,
vertex.label.family = "sans",
edge.width = 1.5, vertex.size = nodesize,
vertex.frame.color = vfc, vertex.color = vc,
vertex.label.cex = cex, edge.arrow.width = 1,
edge.arrow.size = 1.2, vertex.label.dist = vld, ...
)
} else {
id <- plot(agr,
layout = layout, edge.curved = curve,
vertex.label = rownames(a), edge.arrow.mode = l2,
edge.color = col, edge.lty = ety,
vertex.label.family = "sans",
edge.width = 2, vertex.size = nodesize * 1.5,
vertex.frame.color = vfc, vertex.color = vc,
vertex.label.cex = cex * 0.8, edge.arrow.width = 2,
edge.arrow.size = .5, vertex.label.dist = vld, ...
)
}
V(agr)$name <- rownames(a)
agr <- set.edge.attribute(agr, "edge.arrow.mode", index = E(agr), l2)
return(invisible(list(tkp.id = id, igraph = agr)))
} else {
stop("'object' is not in a valid format")
}
}
## Fit multivariate logistic model with individual covariates
#############################################################
`binve` <- function(eta, C, M, G, maxit = 500, print = FALSE, tol = 1e-10) {
# Inverts a marginal loglinear parameterization.
# eta has dimension t-1,
# G is the model matrix of the loglinear parameterization with no intercept.
# C and M are the matrices of the link.
# From a Matlab function by A. Forcina, University of Perugia, Italy.
## starting values
k <- nrow(C)
pmin <- 1e-100
kG <- ncol(G)
err <- 0
th0 <- matrix(1, k, 1) / 100
## prepare to iterate
it <- 0
mit <- 500
p <- exp(G %*% th0)
p <- p / sum(p)
t <- M %*% p
d <- eta - C %*% log(t)
div0 <- crossprod(d)
hh <- 0
s <- c(.1, .6, 1.2)
div <- div0 + 1
while ((it < maxit) & (div > tol)) {
R0 <- C %*% diagv(1 / t, M) %*% diagv(p, G)
rco <- rcond(R0) > tol
ub <- 0
while (rco == FALSE) {
cat("Rank: ", qr(R0)$rank, "\n")
R0 <- R0 + diag(k)
rco <- rcond(R0) > tol
}
de <- solve(R0) %*% d
dem <- max(abs(de))
de <- (dem <= 4) * de + (dem > 4) * 4 * de / dem
th <- th0 + de
p <- exp(G %*% th)
p <- p / sum(p)
p <- p + pmin * (p < pmin)
p <- p / sum(p)
t <- M %*% p
d <- eta - C %*% log(t)
div <- crossprod(d)
rid <- (.01 + div0) / (.01 + div)
iw <- 0
while ((rid < 0.96) & (iw < 10)) {
th <- th0 + de %*% (rid^(iw + 1))
p <- exp(G %*% th)
p <- p / sum(p)
p <- p + pmin * (p < pmin)
p <- p / sum(p)
t <- M %*% p
d <- (eta - C %*% log(M %*% p))
div <- crossprod(d)
rid <- (.01 + div) / (.01 + div0)
iw <- iw + 1
it <- it + 1
}
if (rid < 0.96) {
it <- mit
} else {
it <- it + 1
th0 <- th
}
}
if (div > tol) {
warning("div > tolerance.", call. = FALSE)
}
if (any(is.nan(p))) {
warning("Some NaN in the vector of probabilities.", call. = FALSE)
}
if (it > maxit) {
warning("Maximum number of iteration reached.", call. = FALSE)
}
if (print) {
cat("Iterations: ", it, ", Div = ", div, ".\n")
}
as.vector(p)
}
# The following function has been generalized and called mlogit.param
`mat.mlogit` <- function(d, P = powerset(1:d)) {
## Find matrices C and M of binary mlogit parameterization for a table 2^d.
## The output will be in the ordering of P.
## Here for 3 variables is: 1 2 3 12 13 23 123.
`margmat` <- function(bi, mar) {
### Defines the marginalization matrix
if (mar == FALSE) {
matrix(1, 1, bi)
} else {
diag(bi)
}
}
`contrmat` <- function(bi, i) {
### Contrast matrix
if (i == FALSE) {
1
} else {
cbind(-1, diag(bi - 1))
}
}
V <- 1:d
C <- matrix(0, 0, 0)
L <- c()
for (mar in P) {
K <- 1
H <- 1
for (i in V) {
w <- is.element(i, mar)
K <- contrmat(2, w) %x% K
H <- margmat(2, w) %x% H
}
C <- blkdiag(C, K)
L <- rbind(L, H)
}
list(C = C, L = L)
}
`powerset` <- function(set, sort = TRUE, nonempty = TRUE) {
## Power set P(set). If nonempty = TRUE, the empty set is excluded.
d <- length(set)
if (d == 0) {
if (nonempty) {
stop("The set is empty.")
}
return(list(c()))
}
out <- expand.grid(rep(list(c(FALSE, TRUE)), d))
out <- as.matrix(out)
out <- apply(out, 1, function(x) set[x])
if (nonempty) {
out <- out[-1]
}
if (sort) {
i <- order(unlist(lapply(out, length)))
} else {
i <- 1:length(out)
}
names(out) <- NULL
out[i]
}
`null` <- function(M) {
tmp <- qr(M)
set <- if (tmp$rank == 0L) {
1L:ncol(M)
} else {
-(1L:tmp$rank)
}
qr.Q(tmp, complete = TRUE)[, set, drop = FALSE]
}
`diagv` <- function(v, M) {
# Computes N = diag(v) %*% M avoiding the diag operator.
as.vector(v) * M
}
`blodiag` <- function(x, blo) {
# Split a vector x into a block diagonal matrix bith components blo.
# Used by fitmlogit.
k <- length(blo)
B <- matrix(0, k, sum(blo))
u <- cumsum(c(1, blo))
for (i in 1:k) {
sub <- u[i]:(u[i + 1] - 1)
B[i, sub] <- x[sub]
}
B
}
##### The main function fitmlogit ##########
`fitmlogit` <- function(..., C = c(), D = c(), data, mit = 100, ep = 1e-80, acc = 1e-4) {
# Fits a logistic regression model to multivariate binary responseses.
# Preliminaries
loglin2 <- function(d) {
# Finds the matrix G for a set o d binary variables in inv lex order.
G <- 1
K <- matrix(c(1, 1, 0, 1), 2, 2)
for (i in 1:d) {
G <- G %x% K
}
G[, -1]
}
mods <- list(...)
# mods should have 2^q - 1 components
nm <- length(mods)
be <- c()
# Starting values
resp <- c()
Xbig <- c()
blo <- c()
for (k in 1:nm) {
mf <- model.frame(mods[[k]], data = data)
res <- model.response(mf)
Xsmall <- model.matrix(mods[[k]], data = data)
Xbig <- cbind(Xbig, Xsmall)
blo <- c(blo, ncol(Xsmall))
nr <- 1
if (is.vector(res)) {
b <- glm(mods[[k]], family = binomial, data = data)
be <- c(be, coef(b))
} else {
be2 <- rep(0.1, ncol(Xsmall))
be <- c(be, be2)
nc <- ncol(res)
if (nc > nr) {
nr <- nc
Y <- res
}
}
}
q <- nr # number of responses
b <- rep(2, q) # Assuming all binary variables
# Transforms the binary observation into a cell number
y <- 1 + (Y %*% 2^(0:(q - 1)))
# Finds the matrices C, M and G
mml <- mat.mlogit(q)
Co <- mml$C
Ma <- mml$L
Co <- as.matrix(Co)
G <- loglin2(q)
b0 <- be
n <- length(y) # le righe di y sono le unita'
t <- max(y) # Questo e' semplicemente 2^q
k <- length(be) # number of parameters
rc <- nrow(C)
cc <- ncol(C)
rd <- nrow(D)
cd <- ncol(D)
# if (k != cc){
# warning('check col C')
# }
# if( k != cd){
# warning('check col D')
# }
if (!is.null(C)) { # se C non ha zero righe trova il null space di C
U <- null(C)
}
seta <- nrow(Co) # e' la dimensione di eta
mg <- t(G) %*% matrix(1 / t, t, t) # NB troppi t!
H <- solve(crossprod(G) - mg %*% G) %*% (t(G) - mg)
# initialize
P <- matrix(0, t, n)
cat("Initial probabilities\n")
for (iu in 1:n) { # initialize P iu = index of a unit
# X = .bdiag(lapply(mods, function(x) model.matrix(x, data = data[iu,]))) ### Change this
# X = as.matrix(X)
X <- blodiag(Xbig[iu, ], blo)
eta <- X %*% be
eta <- as.matrix(eta)
p <- binve(eta, Co, Ma, G)
p <- pmax(p, ep)
p <- p / sum(p)
P[, iu] <- p
}
# Iterate
it <- 0
test <- 0
diss <- 1
LL0 <- 0
dis <- 1
dm <- 1
while (it < mit && (dis + diss) > acc) {
LL <- 0
s <- matrix(0, k, 1)
S <- matrix(0, k, k)
dis <- 0
for (iu in 1:n) {
# X = .bdiag(lapply(mods, function(x) model.matrix(x, data = data[iu,])))
# X = as.matrix(X)
X <- blodiag(Xbig[iu, ], blo)
p <- P[, iu]
if (it > 0) {
Op <- diag(p) - p %*% t(p)
R <- Co %*% diagv(1 / (Ma %*% p), Ma) %*% Op %*% G # This is the inverse Jacobian
while (rcond(R) < 1e-12) {
R <- R + diag(seta)
}
R <- solve(R)
delta <- X %*% be - Co %*% log(Ma %*% p)
th <- H %*% log(p) + R %*% delta
dm <- max(th) - min(th)
p <- exp(G %*% th)
p <- p / sum(p)
p <- pmax(p, ep)
p <- p / sum(p)
P[, iu] <- p
}
LL <- LL + log(p[y[iu]])
Op <- diag(as.vector(p)) - p %*% t(p)
R <- Co %*% diagv(1 / (Ma %*% p), Ma) %*% Op %*% G # Check
while (rcond(R) < 1e-12) {
R <- R + diag(seta)
}
R <- solve(R)
eta <- Co %*% log(Ma %*% p)
delta <- X %*% be - eta
dis <- dis + sum(abs(delta))
A <- G %*% R %*% X
B <- t(R) %*% t(G) %*% Op %*% A
S <- S + t(B) %*% X
# attivare una delle due
s <- s + (t(A[y[iu], , drop = FALSE]) - t(A) %*% p) + t(B) %*% eta # versione 1
# s = s +( t(A[y[iu],]) - t(A)%*% p) # versione 2
}
while (rcond(S) < 1e-10) {
S <- S + mean(abs(diag(S))) * diag(k)
}
# attivare 1 delle due
b0 <- be
v <- solve(S, s) # versione 1
# b0=be; v = b0 + solve(S) %*% s # versione 2
if (is.null(rc) & is.null(rd)) {
de <- v - b0
} else if (is.null(rc)) { # only inequalities
Si <- solve(S)
Li <- t(chol(Si))
Di <- D %*% Li
de <- NULL
# de = v - b0 + Li %*% ldp(Di,-D %*% v) # Needs ldp
} else if (is.null(rd)) { # only equalities
Ai <- solve(t(U) %*% S %*% U)
de <- U %*% Ai %*% t(U) %*% S %*% v - b0
} else { # both equalities and inequalities
Ai <- solve(t(U) %*% S %*% U)
Li <- t(chol(Ai))
Dz <- D %*% U
ta <- Ai %*% t(U) %*% S %*% v
# de = U %*% (ta + Li %*% ldp(Dz %*% Li, -Dz %*% ta)) - b0 # Needs ldp
de <- NULL
}
dm0 <- dm
dm <- max(de) - min(de) # shorten step
dd <- (dm > 1.5)
de <- de / (1 + dd * (dm^(.85)))
be <- b0 + de
diss <- sum(abs(de))
LL0 <- LL
it <- it + 1
cat(c(it, LL / 100, dis / n, diss), "\n")
# cat(t(be), "\n")
}
list(LL = LL, beta = be, S = solve(S), P = P)
}
`marg.param` <- function(lev, type)
# Creates matrices C and M for the marginal parametrization
# of the probability vector for a vector of categorical variables.
# INPUT:
# lev: vector containing the number of levels of each variable
# type: vector with elements 'l', 'g', 'c', 'r' indicating the type of logit
# 'g' for global,
# 'c' for continuation,
# 'r' for reverse continuation,
# 'l' for local.
# OUTPUT:
# C: matrix of constrats (the first sum(lev)-length(r) elements are
# referred to univariate logits)
# M: marginalization matrix with elements 0 and 1
# G: corresponding design matrix for the corresponding log-linear model
# Translated from a Matlab function by Bartolucci and Forcina.
# NOTE: assumes that the vector of probabilities is in inv lex order.
# The interactions are returned in order of dimension, like e.g., 1 2 3 12 13 23 123.
{
# preliminaries
`powset` <- function(d)
# Power set P(d).
{
P <- expand.grid(rep(list(1:2), d))
P[order(apply(P, 1, sum)), ] - 1
}
r <- length(lev)
# create sets of parameters
S <- powset(r)
S <- S[-1, ] # drop the empty set
C <- c()
M <- c()
G <- c()
for (i in 1:nrow(S)) {
si <- S[i, ]
Ci <- 1 # to update matrix C
for (h in 1:r) {
if (si[h] == 1) {
I <- diag(lev[h] - 1)
Ci <- cbind(-I, I) %x% Ci
}
}
C <- blkdiag(C, Ci)
Mi <- 1 # to update matrix M
for (h in 1:r) {
lh <- lev[h] - 1
if (si[h] == 1) {
I <- diag(lh)
T <- 0 + lower.tri(matrix(1, lh, lh), diag = TRUE)
ze <- matrix(0, lh, 1)
Mi <- switch(type[h],
l = rbind(cbind(I, ze), cbind(ze, I)) %x% Mi,
g = rbind(cbind(T, ze), cbind(ze, t(T))) %x% Mi,
c = rbind(cbind(I, ze), cbind(ze, t(T))) %x% Mi,
r = rbind(cbind(T, ze), cbind(ze, I)) %x% Mi
)
} else {
Mi <- matrix(1, 1, lev[h]) %x% Mi
}
}
M <- rbind(M, Mi)
Gi <- 1 # for the design matrix
for (h in 1:r) {
lh <- lev[h]
if (si[h] == 1) {
T <- 0 + lower.tri(matrix(1, lh, lh), diag = TRUE)
T <- T[, -1]
Gi <- T %x% Gi
} else {
Gi <- matrix(1, lh, 1) %x% Gi
}
}
G <- cbind(G, Gi)
}
list(C = C, M = M, G = G)
}
`blkdiag` <- function(...) {
### Block diagonal concatenation of input arguments.
a <- list(...)
Y <- matrix(0, 0, 0)
for (M in a) {
if (is.null(M)) {
M <- matrix(0, 0, 0)
}
M <- as.matrix(M)
dY <- dim(Y)
dM <- dim(M)
zeros1 <- matrix(0, dY[1], dM[2])
zeros2 <- matrix(0, dM[1], dY[2])
Y <- rbind(cbind(Y, zeros1), cbind(zeros2, M))
}
Y
}
# source("~/Documents/R/graphical_models/fitmlogit.R")
# fitmlogit(A ~X, B ~ Z, cbind(A, B) ~ 1, data = datisim)
# source("~/Documents/R/graphical_models/ilaria/sim-blogit.R")
#### Functions by Kayvan Sadeghi 2011-2012
## May 2012 Changed the return values of some functions to TRUE FALSE
`rem` <- function(a, r) { # this is setdiff (a, r)
k <- 0
b <- a
for (i in a) {
k <- k + 1
for (j in r) {
if (i == j) {
b <- b[-k]
k <- k - 1
break
}
}
}
return(b)
}
# SPl<-function(a,alpha){
# a<-sort(a)
# alpha<-sort(alpha)
# r<-c()
# if (length(alpha)>0){
# for(i in 1:length(a)){
# for(j in 1:length(alpha)){
# if(a[i]==alpha[j]){
# r<-c(r,i)
# break}}}}
# return(r)
# }
###############################################################################
# Finds indices of b in sorted a
`SPl` <- function(a, b) (seq_along(a))[is.element(sort(a), b)]
##############################################################################
`RR` <- function(a) { ## This is unique(a)
a <- sort(a)
r <- a[1]
i <- 1
while (i < length(a)) {
if (a[i] == a[i + 1]) {
i <- i + 1
} else {
r <- c(r, a[i + 1])
i <- i + 1
}
}
return(r)
}
`likGau` <- function(K, S, n, k) {
# deviance of the Gaussian model.
SK <- S %*% K
tr <- function(A) sum(diag(A))
(tr(SK) - log(det(SK)) - k) * n
}
`grMAT` <- function(agr) {
if (class(agr)[1] == "graphNEL") {
agr <- igraph.from.graphNEL(agr)
}
if (class(agr)[1] == "igraph") {
return(get.adjacency(agr, sparse = FALSE))
}
if (class(agr)[1] == "character") {
if (length(agr) %% 3 != 0) {
stop("'The character object' is not in a valid form")
}
seqt <- seq(1, length(agr), 3)
b <- agr[seqt]
agrn <- agr[-seqt]
bn <- c()
for (i in 1:length(b)) {
if (b[i] != "a" && b[i] != "l" && b[i] != "b") {
stop("'The numeric object' is not in a valid form")
}
if (b[i] == "l") {
bn[i] <- 10
}
if (b[i] == "a") {
bn[i] <- 1
}
if (b[i] == "b") {
bn[i] <- 100
}
}
Ragr <- RR(agrn)
ma <- length(Ragr)
mat <- matrix(rep(0, (ma)^2), ma, ma)
for (i in seq(1, length(agrn), 2)) {
if ((bn[(i + 1) / 2] == 1 && mat[SPl(Ragr, agrn[i]), SPl(Ragr, agrn[i + 1])] %% 10 != 1) || (bn[(i + 1) / 2] == 10 && mat[SPl(Ragr, agrn[i]), SPl(Ragr, agrn[i + 1])] %% 100 < 10) || (bn[(i + 1) / 2] == 100 && mat[SPl(Ragr, agrn[i]), SPl(Ragr, agrn[i + 1])] < 100)) {
mat[SPl(Ragr, agrn[i]), SPl(Ragr, agrn[i + 1])] <- mat[SPl(Ragr, agrn[i]), SPl(Ragr, agrn[i + 1])] + bn[(i + 1) / 2]
if (bn[(i + 1) / 2] == 10 || bn[(i + 1) / 2] == 100) {
mat[SPl(Ragr, agrn[i + 1]), SPl(Ragr, agrn[i])] <- mat[SPl(Ragr, agrn[i + 1]), SPl(Ragr, agrn[i])] + bn[(i + 1) / 2]
}
}
}
rownames(mat) <- Ragr
colnames(mat) <- Ragr
}
return(mat)
}
`RG` <- function(amat, M = c(), C = c(), showmat = TRUE, plot = FALSE, plotfun = plotGraph, ...) {
if (class(amat)[1] == "igraph" || class(amat)[1] == "graphNEL" || class(amat)[1] == "character") {
amat <- grMAT(amat)
}
if (is(amat, "matrix")) {
if (nrow(amat) == ncol(amat)) {
if (length(rownames(amat)) != ncol(amat)) {
rownames(amat) <- 1:ncol(amat)
colnames(amat) <- 1:ncol(amat)
}
} else {
stop("'object' is not in a valid adjacency matrix form")
}
}
if (!is(amat, "matrix")) {
stop("'object' is not in a valid form")
}
S <- C
St <- c()
while (identical(S, St) == FALSE) {
St <- S
for (j in S) {
for (i in rownames(amat)) {
if (amat[i, j] %% 10 == 1) {
S <- c(i, S[S != i])
}
}
}
}
amatr <- amat
amatt <- 2 * amat
while (identical(amatr, amatt) == FALSE) {
amatt <- amatr
############################################################ 1
amat21 <- amatr
for (kk in M) {
for (kkk in 1:ncol(amatr)) {
amat31 <- amatr
if (amatr[kkk, kk] %% 10 == 1 || amatr[kk, kkk] %% 10 == 1) {
amat31[kk, kkk] <- amatr[kkk, kk]
amat31[kkk, kk] <- amatr[kk, kkk]
}
idx <- which(amat31[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1 && amat31[kkk, kk] %% 10 == 1)) {
for (ii in 1:(lenidx)) {
# for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], kkk] %% 10 == 0 && idx[ii] != kkk) {
amat21[idx[ii], kkk] <- TRUE
}
}
}
}
}
amatr <- amat21
################################################################ 2
amat22 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in S) {
idx <- which(amatr[, kk] %% 10 == 1)
idy <- which(amatr[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 10 == 0 && idx[ii] != idy[jj]) {
amat22[idx[ii], idy[jj]] <- 1
}
}
}
}
}
amatr <- amat22 + amatr
################################################################# 3
amat33 <- t(amatr)
amat23 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amat33[, kk] %% 10 == 1)
idy <- which(amat33[, kk] %% 100 > 9)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idy[jj], idx[ii]] %% 10 == 0 && idx[ii] != idy[jj]) {
amat23[idy[jj], idx[ii]] <- 1
}
}
}
}
}
amatr <- amat23 + amatr
################################################################## 4
amat24 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amatr[, kk] %% 100 > 9)
idy <- which(amatr[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 10 == 0 && idx[ii] != idy[jj]) {
amat24[idx[ii], idy[jj]] <- 1
}
}
}
}
}
amatr <- amat24 + amatr
#################################################################### 5
amat35 <- t(amatr)
amat25 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amat35[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] < 100) {
amat25[idx[ii], idx[jj]] <- 100
}
}
}
}
}
amatr <- amat25 + t(amat25) + amatr
###################################################################### 6
amat36 <- t(amatr)
amat26 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amat36[, kk] %% 10 == 1)
idy <- which(amat36[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idy[jj], idx[ii]] < 100 && idx[ii] != idy[jj]) {
amat26[idy[jj], idx[ii]] <- 100
}
}
}
}
}
amatr <- amat26 + t(amat26) + amatr
################################################################# 7
amat27 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in S) {
idx <- which(amatr[, kk] > 99)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] < 100) {
amat27[idx[ii], idx[jj]] <- 100
}
}
}
}
}
amatr <- amat27 + t(amat27) + amatr
################################################################ 8
amat28 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in S) {
idx <- which(amatr[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] %% 100 < 10) {
amat28[idx[ii], idx[jj]] <- 10
}
}
}
}
}
amatr <- amat28 + t(amat28) + amatr
################################################################# 9
amat29 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amatr[, kk] %% 10 == 1)
idy <- which(amatr[, kk] %% 100 > 9)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 100 < 10 && idx[ii] != idy[jj]) {
amat29[idx[ii], idy[jj]] <- 10
}
}
}
}
}
amatr <- amat29 + t(amat29) + amatr
################################################################## 10
amat20 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amatr[, kk] %% 100 > 9)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] %% 100 < 10) {
amat20[idx[ii], idx[jj]] <- 10
}
}
}
}
}
amatr <- amat20 + t(amat20) + amatr
}
Mn <- c()
Cn <- c()
for (i in M) {
Mn <- c(Mn, which(rownames(amat) == i))
}
for (i in C) {
Cn <- c(Cn, which(rownames(amat) == i))
}
if (length(Mn) > 0 && length(Cn) > 0) {
fr <- amatr[-c(Mn, Cn), -c(Mn, Cn)]
}
if (length(Mn) > 0 && length(Cn) == 0) {
fr <- amatr[-c(Mn), -c(Mn)]
}
if (length(Mn) == 0 && length(Cn) > 0) {
fr <- amatr[-c(Cn), -c(Cn)]
}
if (length(Mn) == 0 && length(Cn) == 0) {
fr <- amatr
}
if (plot == TRUE) {
plotfun(fr, ...)
}
if (showmat == FALSE) {
invisible(fr)
} else {
return(fr)
}
}
##############################################################################
##############################################################################
`SG` <- function(amat, M = c(), C = c(), showmat = TRUE, plot = FALSE, plotfun = plotGraph, ...) {
if (class(amat)[1] == "igraph" || class(amat)[1] == "graphNEL" || class(amat)[1] == "character") {
amat <- grMAT(amat)
}
if (is(amat, "matrix")) {
if (nrow(amat) == ncol(amat)) {
if (length(rownames(amat)) != ncol(amat)) {
rownames(amat) <- 1:ncol(amat)
colnames(amat) <- 1:ncol(amat)
}
} else {
stop("'object' is not in a valid adjacency matrix form")
}
}
if (!is(amat, "matrix")) {
stop("'object' is not in a valid form")
}
S <- C
St <- c()
while (identical(S, St) == FALSE) {
St <- S
for (j in S) {
for (i in rownames(amat)) {
if (amat[i, j] %% 10 == 1) {
S <- c(i, S[S != i])
}
}
}
}
amatr <- amat
amatt <- 2 * amat
while (identical(amatr, amatt) == FALSE) {
amatt <- amatr
############################################################ 1
amat21 <- amatr
for (kk in M) {
for (kkk in 1:ncol(amatr)) {
amat31 <- amatr
if (amatr[kkk, kk] %% 10 == 1 || amatr[kk, kkk] %% 10 == 1) {
amat31[kk, kkk] <- amatr[kkk, kk]
amat31[kkk, kk] <- amatr[kk, kkk]
}
idx <- which(amat31[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1 && amat31[kkk, kk] %% 10 == 1)) {
for (ii in 1:(lenidx)) {
# for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], kkk] %% 10 == 0 && idx[ii] != kkk) {
amat21[idx[ii], kkk] <- TRUE
}
}
}
}
}
amatr <- amat21
################################################################ 2
amat22 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in S) {
idx <- which(amatr[, kk] %% 10 == 1)
idy <- which(amatr[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 10 == 0 && idx[ii] != idy[jj]) {
amat22[idx[ii], idy[jj]] <- 1
}
}
}
}
}
amatr <- amat22 + amatr
################################################################# 3
amat33 <- t(amatr)
amat23 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amat33[, kk] %% 10 == 1)
idy <- which(amat33[, kk] %% 100 > 9)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idy[jj], idx[ii]] %% 10 == 0 && idx[ii] != idy[jj]) {
amat23[idy[jj], idx[ii]] <- 1
}
}
}
}
}
amatr <- amat23 + amatr
################################################################## 4
amat24 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amatr[, kk] %% 100 > 9)
idy <- which(amatr[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 10 == 0 && idx[ii] != idy[jj]) {
amat24[idx[ii], idy[jj]] <- 1
}
}
}
}
}
amatr <- amat24 + amatr
#################################################################### 5
amat35 <- t(amatr)
amat25 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amat35[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] < 100) {
amat25[idx[ii], idx[jj]] <- 100
}
}
}
}
}
amatr <- amat25 + t(amat25) + amatr
###################################################################### 6
amat36 <- t(amatr)
amat26 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amat36[, kk] %% 10 == 1)
idy <- which(amat36[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idy[jj], idx[ii]] < 100 && idx[ii] != idy[jj]) {
amat26[idy[jj], idx[ii]] <- 100
}
}
}
}
}
amatr <- amat26 + t(amat26) + amatr
################################################################# 7
amat27 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in S) {
idx <- which(amatr[, kk] > 99)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] < 100) {
amat27[idx[ii], idx[jj]] <- 100
}
}
}
}
}
amatr <- amat27 + t(amat27) + amatr
################################################################ 8
amat28 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in S) {
idx <- which(amatr[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] %% 100 < 10) {
amat28[idx[ii], idx[jj]] <- 10
}
}
}
}
}
amatr <- amat28 + t(amat28) + amatr
################################################################# 9
amat29 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amatr[, kk] %% 10 == 1)
idy <- which(amatr[, kk] %% 100 > 9)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 100 < 10 && idx[ii] != idy[jj]) {
amat29[idx[ii], idy[jj]] <- 10
}
}
}
}
}
amatr <- amat29 + t(amat29) + amatr
################################################################## 10
amat20 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amatr[, kk] %% 100 > 9)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] %% 100 < 10) {
amat20[idx[ii], idx[jj]] <- 10
}
}
}
}
}
amatr <- amat20 + t(amat20) + amatr
}
for (i in 1:ncol(amatr)) {
for (j in 1:ncol(amatr)) {
if (amatr[i, j] %% 100 > 9) {
amatr[i, j] <- 10
for (k in 1:ncol(amatr)) {
if (amatr[k, j] == 100) {
amatr[j, k] <- 1
amatr[k, j] <- 0
}
}
}
}
}
SS <- S
SSt <- c()
while (identical(SS, SSt) == FALSE) {
SSt <- SS
for (j in SS) {
for (i in rownames(amat)) {
if (amatr[i, j] %% 10 == 1) {
SS <- c(i, SS[SS != i])
}
}
}
}
for (i in SS) {
for (j in SS) {
if (amatr[i, j] %% 10 == 1) {
amatr[i, j] <- 10
amatr[j, i] <- 10
}
}
}
Mn <- c()
Cn <- c()
for (i in M) {
Mn <- c(Mn, which(rownames(amat) == i))
}
for (i in C) {
Cn <- c(Cn, which(rownames(amat) == i))
}
if (length(Mn) > 0 && length(Cn) > 0) {
fr <- amatr[-c(Mn, Cn), -c(Mn, Cn)]
}
if (length(Mn) > 0 && length(Cn) == 0) {
fr <- amatr[-c(Mn), -c(Mn)]
}
if (length(Mn) == 0 && length(Cn) > 0) {
fr <- amatr[-c(Cn), -c(Cn)]
}
if (length(Mn) == 0 && length(Cn) == 0) {
fr <- amatr
}
if (plot == TRUE) {
plotfun(fr, ...)
}
if (showmat == FALSE) {
invisible(fr)
} else {
return(fr)
}
}
##############################################################################
##############################################################################
`AG` <- function(amat, M = c(), C = c(), showmat = TRUE, plot = FALSE, plotfun = plotGraph, ...) {
if (class(amat)[1] == "igraph" || class(amat)[1] == "graphNEL" || class(amat)[1] == "character") {
amat <- grMAT(amat)
}
if (is(amat, "matrix")) {
if (nrow(amat) == ncol(amat)) {
if (length(rownames(amat)) != ncol(amat)) {
rownames(amat) <- 1:ncol(amat)
colnames(amat) <- 1:ncol(amat)
}
} else {
stop("'object' is not in a valid adjacency matrix form")
}
}
if (!is(amat, "matrix")) {
stop("'object' is not in a valid form")
}
S <- C
St <- c()
while (identical(S, St) == FALSE) {
St <- S
for (j in S) {
for (i in rownames(amat)) {
if (amat[i, j] %% 10 == 1) {
S <- c(i, S[S != i])
}
}
}
}
amatr <- amat
amatt <- 2 * amat
while (identical(amatr, amatt) == FALSE) {
amatt <- amatr
############################################################ 1
amat21 <- amatr
for (kk in M) {
for (kkk in 1:ncol(amatr)) {
amat31 <- amatr
if (amatr[kkk, kk] %% 10 == 1 || amatr[kk, kkk] %% 10 == 1) {
amat31[kk, kkk] <- amatr[kkk, kk]
amat31[kkk, kk] <- amatr[kk, kkk]
}
idx <- which(amat31[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1 && amat31[kkk, kk] %% 10 == 1)) {
for (ii in 1:(lenidx)) {
# for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], kkk] %% 10 == 0 && idx[ii] != kkk) {
amat21[idx[ii], kkk] <- TRUE
}
}
}
}
}
amatr <- amat21
################################################################ 2
amat22 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in S) {
idx <- which(amatr[, kk] %% 10 == 1)
idy <- which(amatr[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 10 == 0 && idx[ii] != idy[jj]) {
amat22[idx[ii], idy[jj]] <- 1
}
}
}
}
}
amatr <- amat22 + amatr
################################################################# 3
amat33 <- t(amatr)
amat23 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amat33[, kk] %% 10 == 1)
idy <- which(amat33[, kk] %% 100 > 9)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idy[jj], idx[ii]] %% 10 == 0 && idx[ii] != idy[jj]) {
amat23[idy[jj], idx[ii]] <- 1
}
}
}
}
}
amatr <- amat23 + amatr
################################################################## 4
amat24 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amatr[, kk] %% 100 > 9)
idy <- which(amatr[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 10 == 0 && idx[ii] != idy[jj]) {
amat24[idx[ii], idy[jj]] <- 1
}
}
}
}
}
amatr <- amat24 + amatr
#################################################################### 5
amat35 <- t(amatr)
amat25 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amat35[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] < 100) {
amat25[idx[ii], idx[jj]] <- 100
}
}
}
}
}
amatr <- amat25 + t(amat25) + amatr
###################################################################### 6
amat36 <- t(amatr)
amat26 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amat36[, kk] %% 10 == 1)
idy <- which(amat36[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idy[jj], idx[ii]] < 100 && idx[ii] != idy[jj]) {
amat26[idy[jj], idx[ii]] <- 100
}
}
}
}
}
amatr <- amat26 + t(amat26) + amatr
################################################################# 7
amat27 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in S) {
idx <- which(amatr[, kk] > 99)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] < 100) {
amat27[idx[ii], idx[jj]] <- 100
}
}
}
}
}
amatr <- amat27 + t(amat27) + amatr
################################################################ 8
amat28 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in S) {
idx <- which(amatr[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] %% 100 < 10) {
amat28[idx[ii], idx[jj]] <- 10
}
}
}
}
}
amatr <- amat28 + t(amat28) + amatr
################################################################# 9
amat29 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amatr[, kk] %% 10 == 1)
idy <- which(amatr[, kk] %% 100 > 9)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 100 < 10 && idx[ii] != idy[jj]) {
amat29[idx[ii], idy[jj]] <- 10
}
}
}
}
}
amatr <- amat29 + t(amat29) + amatr
################################################################## 10
amat20 <- matrix(rep(0, length(amat)), dim(amat))
for (kk in M) {
idx <- which(amatr[, kk] %% 100 > 9)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] %% 100 < 10) {
amat20[idx[ii], idx[jj]] <- 10
}
}
}
}
}
amatr <- amat20 + t(amat20) + amatr
}
for (i in 1:ncol(amatr)) {
for (j in 1:ncol(amatr)) {
if (amatr[i, j] %% 100 > 9) {
amatr[i, j] <- 10
for (k in 1:ncol(amatr)) {
if (amatr[k, j] == 100) {
amatr[j, k] <- 1
amatr[k, j] <- 0
}
}
}
}
}
SS <- S
SSt <- c()
while (identical(SS, SSt) == FALSE) {
SSt <- SS
for (j in SS) {
for (i in rownames(amat)) {
if (amatr[i, j] %% 10 == 1) {
SS <- c(i, SS[SS != i])
}
}
}
}
for (i in SS) {
for (j in SS) {
if (amatr[i, j] %% 10 == 1) {
amatr[i, j] <- 10
amatr[j, i] <- 10
}
}
}
amatn <- amatr
for (kk in 1:ncol(amatr)) {
for (kkk in 1:ncol(amatr)) {
amat3n <- amatr
if (amatr[kkk, kk] %% 10 == 1 || amatr[kk, kkk] %% 10 == 1) {
amat3n[kk, kkk] <- amatr[kkk, kk]
amat3n[kkk, kk] <- amatr[kk, kkk]
}
idx <- which(amat3n[, kk] %% 10 == 1)
lenidx <- length(idx)
if ((lenidx > 1 && amat3n[kkk, kk] %% 10 == 1)) {
for (ii in 1:(lenidx)) {
# for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], kkk] %% 10 == 0 && idx[ii] != kkk) {
amatn[idx[ii], kkk] <- TRUE
}
}
}
}
}
amatt <- 2 * amat
while (identical(amatr, amatt) == FALSE) {
amatt <- amatr
amat27n <- matrix(rep(0, length(amat)), dim(amat))
for (kk in 1:ncol(amatr)) {
idx <- which(amatn[, kk] > 99)
lenidx <- length(idx)
if ((lenidx > 1)) {
for (ii in 1:(lenidx - 1)) {
for (jj in (ii + 1):lenidx) {
if (amatr[idx[ii], idx[jj]] < 100 && (amatn[kk, idx[ii]] %% 10 == 1 || amatn[kk, idx[jj]] %% 10 == 1)) {
amat27n[idx[ii], idx[jj]] <- 100
}
}
}
}
}
amatn <- amat27n + t(amat27n) + amatn
amatr <- amat27n + t(amat27n) + amatr
amat22n <- matrix(rep(0, length(amat)), dim(amat))
for (kk in 1:ncol(amatr)) {
idx <- which(amatn[, kk] %% 10 == 1)
idy <- which(amatn[, kk] > 99)
lenidx <- length(idx)
lenidy <- length(idy)
if ((lenidx > 0 && lenidy > 0)) {
for (ii in 1:(lenidx)) {
for (jj in 1:lenidy) {
if (amatr[idx[ii], idy[jj]] %% 10 == 0 && idx[ii] != idy[jj] && amatn[kk, idy[jj]] %% 10 == 1) {
amat22n[idx[ii], idy[jj]] <- 1
}
}
}
}
}
amatn <- amat22n + amatn
amatr <- amat22n + amatr
}
for (i in 1:ncol(amatr)) {
for (j in 1:ncol(amatr)) {
if (amatr[i, j] == 101) {
amatr[i, j] <- 1
amatr[j, i] <- 0
}
}
}
Mn <- c()
Cn <- c()
for (i in M) {
Mn <- c(Mn, which(rownames(amat) == i))
}
for (i in C) {
Cn <- c(Cn, which(rownames(amat) == i))
}
if (length(Mn) > 0 && length(Cn) > 0) {
fr <- amatr[-c(Mn, Cn), -c(Mn, Cn)]
}
if (length(Mn) > 0 && length(Cn) == 0) {
fr <- amatr[-c(Mn), -c(Mn)]
}
if (length(Mn) == 0 && length(Cn) > 0) {
fr <- amatr[-c(Cn), -c(Cn)]
}
if (length(Mn) == 0 && length(Cn) == 0) {
fr <- amatr
}
if (plot == TRUE) {
plotfun(fr, ...)
}
if (showmat == FALSE) {
invisible(fr)
} else {
return(fr)
}
}
##############################################################################
##############################################################################
Max <- function(amat) {
if (class(amat)[1] == "igraph" || class(amat)[1] == "graphNEL" || class(amat)[1] == "character") {
amat <- grMAT(amat)
}
if (is(amat, "matrix")) {
if (nrow(amat) == ncol(amat)) {
if (length(rownames(amat)) != ncol(amat)) {
rownames(amat) <- 1:ncol(amat)
colnames(amat) <- 1:ncol(amat)
}
} else {
stop("'object' is not in a valid adjacency matrix form")
}
}
if (!is(amat, "matrix")) {
stop("'object' is not in a valid form")
}
na <- ncol(amat)
at <- which(amat + t(amat) + diag(na) == 0, arr.ind = TRUE)
if (dim(at)[1] > 0) {
for (i in 1:dim(at)[1]) {
S <- at[i, ]
St <- c()
while (identical(S, St) == FALSE) {
St <- S
for (j in S) {
for (k in 1:na) {
if (amat[k, j] %% 10 == 1) {
S <- c(k, S[S != k])
}
}
}
}
one <- at[i, 1]
two <- at[i, 2]
onearrow <- c()
onearc <- c()
twoarrow <- c()
twoarc <- c()
Sr <- S
Sr <- Sr[Sr != at[i, 1]]
Sr <- Sr[Sr != at[i, 2]]
if (length(Sr) > 0) {
for (j in Sr) {
if (amat[one, j] %% 10 == 1) {
onearrow <- c(onearrow, j)
}
if (amat[one, j] > 99) {
onearc <- c(onearc, j)
}
}
for (j in Sr) {
if (amat[two, j] %% 10 == 1) {
for (k in onearc) {
if (j == k || amat[j, k] > 99) {
amat[at[i, 2], at[i, 1]] <- 1
}
}
twoarrow <- c(twoarrow, j)
}
if (amat[two, j] > 99) {
for (k in onearrow) {
if (j == k || amat[j, k] > 99) {
amat[at[i, 1], at[i, 2]] <- 1
}
}
for (k in onearc) {
if (j == k || amat[j, k] > 99) {
amat[at[i, 1], at[i, 2]] <- 100
amat[at[i, 2], at[i, 1]] <- 100
}
}
twoarc <- c(twoarc, j)
}
}
}
if (length(c(onearc, onearrow, twoarc, twoarrow)) > 0) {
for (j in c(onearc, onearrow, twoarc, twoarrow)) {
Sr <- Sr[Sr != j]
}
onearcn <- c()
twoarcn <- c()
onearrown <- c()
twoarrown <- c()
while (length(Sr) > 0) {
for (l in onearc) {
for (j in Sr) {
if (amat[l, j] > 99) {
onearcn <- c(onearcn, j)
}
}
}
for (l in onearrow) {
for (j in Sr) {
if (amat[l, j] > 99) {
onearrown <- c(onearrown, j)
}
}
}
for (l in twoarc) {
for (j in Sr) {
if (amat[l, j] > 99) {
for (k in onearrow) {
if (j == k || amat[j, k] > 99) {
amat[at[i, 1], at[i, 2]] <- 1
}
}
for (k in onearc) {
if (j == k || amat[j, k] > 99) {
amat[at[i, 1], at[i, 2]] <- 100
amat[at[i, 2], at[i, 1]] <- 100
}
}
twoarcn <- c(twoarcn, j)
}
}
}
for (l in twoarrow) {
for (j in Sr) {
if (amat[l, j] > 99) {
for (k in onearc) {
if (j == k || amat[j, k] > 99) {
amat[at[i, 1], at[i, 2]] <- 100
amat[at[i, 2], at[i, 1]] <- 100
}
}
twoarrown <- c(twoarrown, j)
}
}
}
if (length(c(onearcn, onearrown, twoarcn, twoarrown)) == 0) {
break
}
for (j in c(onearcn, onearrown, twoarcn, twoarrown)) {
Sr <- Sr[Sr != j]
}
onearc <- onearcn
twoarc <- twoarcn
onearrow <- onearrown
twoarrow <- twoarrown
onearcn <- c()
twoarcn <- c()
onearrown <- c()
twoarrown <- c()
}
}
}
}
return(amat)
}
#####################################################################################################
######################################################################################################
msep <- function(a, alpha, beta, C = c()) {
if (class(a)[1] == "igraph" || class(a)[1] == "graphNEL" || class(a)[1] == "character") {
a <- grMAT(a)
}
if (is(a, "matrix")) {
if (nrow(a) == ncol(a)) {
if (length(rownames(a)) != ncol(a)) {
rownames(a) <- 1:ncol(a)
colnames(a) <- 1:ncol(a)
}
} else {
stop("'object' is not in a valid adjacency matrix form")
}
}
if (!is(a, "matrix")) {
stop("'object' is not in a valid form")
}
M <- rem(rownames(a), c(alpha, beta, C))
ar <- Max(RG(a, M, C))
# aralpha<-as.matrix(ar[SPl(c(alpha,beta),alpha),SPl(c(alpha,beta),beta)])
# arbeta<-as.matrix(ar[SPl(c(alpha,beta),beta),SPl(c(alpha,beta),alpha)])
# for(i in 1:length(alpha)){
# for(j in 1:length(beta)){
# if(aralpha[j,i]!=0 || arbeta[j,i]!=0){
# return("NOT separated")
# break
# break}}}
if (max(ar[as.character(beta), as.character(alpha)] + ar[as.character(alpha), as.character(beta)] != 0)) {
return(FALSE)
}
return(TRUE)
}
############################################################################
############################################################################
`MRG` <- function(amat, M = c(), C = c(), showmat = TRUE, plot = FALSE, plotfun = plotGraph, ...) {
return(Max(RG(amat, M, C, showmat, plot, plotfun = plotGraph, ...)))
}
##########################################################################
##########################################################################
`MSG` <- function(amat, M = c(), C = c(), showmat = TRUE, plot = FALSE, plotfun = plotGraph, ...) {
return(Max(SG(amat, M, C, showmat, plot, plotfun = plotGraph, ...)))
}
############################################################################
###########################################################################
`MAG` <- function(amat, M = c(), C = c(), showmat = TRUE, plot = FALSE, plotfun = plotGraph, ...) {
return(Max(AG(amat, M, C, showmat, plot, plotfun = plotGraph, ...)))
}
############################################################################
############################################################################
# Plot<-function(a)
# {
# if(class(a)[1] == "igraph" || class(a)[1] == "graphNEL" || class(a)[1] == "character") {
# a<-grMAT(a)}
# if(is(a,"matrix")){
# if(nrow(a)==ncol(a)){
# if(length(rownames(a))!=ncol(a)){
# rownames(a)<-1:ncol(a)
# colnames(a)<-1:ncol(a)}
# l1<-c()
# l2<-c()
# for (i in 1:nrow(a)){
# for (j in i:nrow(a)){
# if (a[i,j]==1){
# l1<-c(l1,i,j)
# l2<-c(l2,2)}
# if (a[j,i]%%10==1){
# l1<-c(l1,j,i)
# l2<-c(l2,2)}
# if (a[i,j]==10){
# l1<-c(l1,i,j)
# l2<-c(l2,0)}
# if (a[i,j]==11){
# l1<-c(l1,i,j,i,j)
# l2<-c(l2,2,0)}
# if (a[i,j]==100){
# l1<-c(l1,i,j)
# l2<-c(l2,3)}
# if (a[i,j]==101){
# l1<-c(l1,i,j,i,j)
# l2<-c(l2,2,3)}
# if (a[i,j]==110){
# l1<-c(l1,i,j,i,j)
# l2<-c(l2,0,3)}
# if (a[i,j]==111){
# l1<-c(l1,i,j,i,j,i,j)
# l2<-c(l2,2,0,3)}
# }
# }
# }
# else {
# stop("'object' is not in a valid adjacency matrix form")
# }
# if(length(l1)>0){
# l1<-l1-1
# agr<-graph(l1,n=nrow(a),directed=TRUE)}
# if(length(l1)==0){
# agr<-graph.empty(n=nrow(a), directed=TRUE)
# return(plot(agr,vertex.label=rownames(a)))}
# return( tkplot(agr, layout=layout.kamada.kawai, edge.curved=FALSE:TRUE, vertex.label=rownames(a),edge.arrow.mode=l2))
# }
# else {
# stop("'object' is not in a valid format")}
# }
############################################################################
############################################################################
MarkEqRcg <- function(amat, bmat) {
if (class(amat)[1] == "igraph") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "graphNEL") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "character") {
amat <- grMAT(amat)
}
if (length(rownames(amat)) != ncol(amat) || length(colnames(amat)) != ncol(amat)) {
rownames(amat) <- 1:ncol(amat)
colnames(amat) <- 1:ncol(amat)
}
if (class(bmat)[1] == "igraph") {
bmat <- grMAT(bmat)
}
if (class(bmat)[1] == "graphNEL") {
bmat <- grMAT(bmat)
}
if (class(bmat)[1] == "character") {
bmat <- grMAT(bmat)
}
if (length(rownames(bmat)) != ncol(bmat) || length(colnames(bmat)) != ncol(bmat)) {
rownames(bmat) <- 1:ncol(bmat)
colnames(bmat) <- 1:ncol(bmat)
}
bmat <- bmat[rownames(amat), colnames(amat), drop = FALSE]
na <- ncol(amat)
nb <- ncol(bmat)
if (na != nb) {
return(FALSE)
}
at <- which(amat + t(amat) + diag(na) == 0, arr.ind = TRUE)
bt <- which(bmat + t(bmat) + diag(na) == 0, arr.ind = TRUE)
if (identical(at, bt) == FALSE) {
return(FALSE)
}
ai <- c()
bi <- c()
if (dim(at)[1] != 0) {
for (i in 1:dim(at)[1]) {
for (j in 1:na) {
if ((amat[at[i, 1], j] %% 10 == 1 || amat[at[i, 1], j] > 99) && (amat[at[i, 2], j] %% 10 == 1 || amat[at[i, 2], j] > 99)) {
ai <- c(ai, j)
}
if ((bmat[bt[i, 1], j] %% 10 == 1 || bmat[bt[i, 1], j] > 99) && (bmat[bt[i, 2], j] %% 10 == 1 || bmat[bt[i, 2], j] > 99)) {
bi <- c(bi, j)
}
}
if (identical(ai, bi) == FALSE) {
return(FALSE)
}
ai <- c()
bi <- c()
}
}
return(TRUE)
}
########################################################################################
########################################################################################
`MarkEqMag` <- function(amat, bmat) {
if (class(amat)[1] == "igraph") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "graphNEL") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "character") {
amat <- grMAT(amat)
}
if (length(rownames(amat)) != ncol(amat) || length(colnames(amat)) != ncol(amat)) {
rownames(amat) <- 1:ncol(amat)
colnames(amat) <- 1:ncol(amat)
}
if (class(bmat)[1] == "igraph") {
bmat <- grMAT(bmat)
}
if (class(bmat)[1] == "graphNEL") {
bmat <- grMAT(bmat)
}
if (class(bmat)[1] == "character") {
bmat <- grMAT(bmat)
}
if (length(rownames(bmat)) != ncol(bmat) || length(colnames(bmat)) != ncol(bmat)) {
rownames(bmat) <- 1:ncol(bmat)
colnames(bmat) <- 1:ncol(bmat)
}
bmat <- bmat[rownames(amat), colnames(amat), drop = FALSE]
na <- ncol(amat)
nb <- ncol(bmat)
if (na != nb) {
return(FALSE)
}
at <- which(amat + t(amat) + diag(na) == 0, arr.ind = TRUE)
bt <- which(bmat + t(bmat) + diag(na) == 0, arr.ind = TRUE)
if (identical(at, bt) == FALSE) {
return(FALSE)
}
a <- c()
b <- c()
if (length(at) > 0) {
for (i in 1:dim(at)[1]) {
for (j in 1:na) {
if ((amat[at[i, 1], j] %% 10 == 1 || amat[at[i, 1], j] > 99) && (amat[at[i, 2], j] %% 10 == 1 || amat[at[i, 2], j] > 99)) {
a <- rbind(a, c(at[i, 1], j, at[i, 2]))
}
if ((bmat[bt[i, 1], j] %% 10 == 1 || bmat[bt[i, 1], j] > 99) && (bmat[bt[i, 2], j] %% 10 == 1 || bmat[bt[i, 2], j] > 99)) {
b <- rbind(b, c(bt[i, 1], j, bt[i, 2]))
}
}
}
if (identical(a, b) == FALSE) {
return(FALSE)
}
}
ar <- which(amat %% 10 == 1, arr.ind = TRUE)
br <- which(bmat %% 10 == 1, arr.ind = TRUE)
ap <- c()
bp <- c()
if (length(ar) > 0) {
for (i in 1:dim(ar)[1]) {
for (j in 1:na) {
if ((amat[ar[i, 1], j] > 99) && (amat[ar[i, 2], j] > 99)) {
ap <- rbind(ap, c(ar[i, 1], j, ar[i, 2]))
}
}
}
}
if (length(br) > 0) {
for (i in 1:dim(br)[1]) {
for (j in 1:nb) {
if ((bmat[br[i, 1], j] > 99) && (bmat[br[i, 2], j] > 99)) {
bp <- rbind(bp, c(br[i, 1], j, br[i, 2]))
}
}
}
}
if (length(ap) > 0) {
aptt <- ap
apt <- c(ap, 1)
Qonen <- c()
Qtwon <- c()
while (length(apt) - length(aptt) > 0) {
apt <- aptt
for (i in (1:dim(ap)[1])) {
Qone <- ap[i, 1]
Qtwo <- ap[i, 2]
while (length(Qone) > 0) {
for (l in (1:length(Qone))) {
J <- which(((amat + t(amat) + diag(na))[ap[i, 3], ] == 0) & ((amat[Qone[l], ] > 99) | (amat[, Qone[l]] %% 100 == 1)))
for (j in J) {
for (k in 1:dim(a)[1]) {
if (min(a[k, ] == c(j, Qone[l], Qtwo[l])) == 1) {
a <- rbind(a, ap[i, ])
aptt <- aptt[(1:dim(aptt)[1])[-i], ]
break
break
break
break
}
}
}
Q <- which((amat[, ap[i, 3]] %% 10 == 1) & (amat[Qone[l], ] > 99))
for (q in Q) {
for (k in 1:dim(a)[1]) {
if (min(a[k, ] == c(q, Qone[l], Qtwo[l])) == 1) {
Qtwon <- c(Qtwon, Qone[l])
Qonen <- c(Qonen, q)
}
}
}
}
Qtwo <- Qtwon
Qone <- Qonen
Qonen <- c()
Qtwon <- c()
}
}
}
}
if (length(bp) > 0) {
bptt <- bp
bpt <- c(bp, 1)
Qbonen <- c()
Qbtwon <- c()
while (length(bpt) - length(bptt) > 0) {
bpt <- bptt
for (i in (1:dim(bp)[1])) {
Qbone <- bp[i, 1]
Qbtwo <- bp[i, 2]
while (length(Qbone) > 0) {
for (l in (1:length(Qbone))) {
J <- which(((bmat + t(bmat) + diag(nb))[bp[i, 3], ] == 0) & ((bmat[Qbone[l], ] > 99) | (bmat[, Qbone[l]] %% 100 == 1)))
for (j in J) {
for (k in 1:dim(b)[1]) {
if (min(b[k, ] == c(j, Qbone[l], Qbtwo[l])) == 1) {
b <- rbind(b, bp[i, ])
bptt <- bptt[(1:dim(bptt)[1])[-i], ]
break
break
break
break
}
}
}
Qb <- which((bmat[, bp[i, 3]] %% 10 == 1) & (bmat[Qbone[l], ] > 99))
for (q in Qb) {
for (k in 1:dim(b)[1]) {
if (min(b[k, ] == c(q, Qbone[l], Qbtwo[l])) == 1) {
Qbtwon <- c(Qbtwon, Qbone[l])
Qbonen <- c(Qbonen, q)
}
}
}
}
Qbtwo <- Qbtwon
Qbone <- Qbonen
Qbonen <- c()
Qbtwon <- c()
}
}
}
}
if (length(a) != length(b)) {
return(FALSE)
}
f <- c()
if ((length(a) > 0) && (length(b) > 0)) {
for (i in 1:dim(a)[1]) {
for (j in 1:dim(b)[1]) {
f <- c(f, min(a[i, ] == b[j, ]))
}
if (max(f) == 0) {
return(FALSE)
}
}
}
return(TRUE)
}
RepMarUG <- function(amat) {
if (class(amat)[1] == "igraph") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "graphNEL") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "character") {
amat <- grMAT(amat)
}
if (length(rownames(amat)) != ncol(amat) || length(colnames(amat)) != ncol(amat)) {
rownames(amat) <- 1:ncol(amat)
colnames(amat) <- 1:ncol(amat)
}
na <- ncol(amat)
at <- which(amat + t(amat) + diag(na) == 0, arr.ind = TRUE)
if (dim(at)[1] != 0) {
for (i in 1:dim(at)[1]) {
for (j in 1:na) {
if ((amat[at[i, 1], j] %% 10 == 1 || amat[at[i, 1], j] > 99) && (amat[at[i, 2], j] %% 10 == 1 || amat[at[i, 2], j] > 99)) {
return(list(verify = FALSE, amat = NA))
}
}
}
}
for (i in 1:na) {
for (j in 1:na) {
if (amat[i, j] == 100) {
amat[i, j] <- 10
}
if (amat[i, j] == 1) {
amat[i, j] <- 10
amat[j, i] <- 10
}
}
}
return(list(verify = TRUE, amat = amat))
}
RepMarBG <- function(amat) {
if (class(amat)[1] == "igraph") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "graphNEL") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "character") {
amat <- grMAT(amat)
}
if (length(rownames(amat)) != ncol(amat) || length(colnames(amat)) != ncol(amat)) {
rownames(amat) <- 1:ncol(amat)
colnames(amat) <- 1:ncol(amat)
}
na <- ncol(amat)
at <- which(amat + t(amat) + diag(na) == 0, arr.ind = TRUE)
if (dim(at)[1] != 0) {
for (i in 1:dim(at)[1]) {
for (j in 1:na) {
if (amat[at[i, 1], j] %% 100 > 9 || amat[j, at[i, 1]] %% 10 == 1 || amat[at[i, 2], j] %% 100 > 9 || amat[j, at[i, 2]] %% 10 == 1) {
return(list(verify = FALSE, amat = NA))
}
}
}
}
for (i in 1:na) {
for (j in 1:na) {
if (amat[i, j] == 10) {
amat[i, j] <- 100
}
if (amat[i, j] == 1) {
amat[i, j] <- 100
amat[j, i] <- 100
}
}
}
return(list(verify = TRUE, amat = amat))
}
`RepMarDAG` <- function(amat) {
if (class(amat)[1] == "igraph") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "graphNEL") {
amat <- grMAT(amat)
}
if (class(amat)[1] == "character") {
amat <- grMAT(amat)
}
if (length(rownames(amat)) != ncol(amat) || length(colnames(amat)) != ncol(amat)) {
rownames(amat) <- 1:ncol(amat)
colnames(amat) <- 1:ncol(amat)
}
na <- ncol(amat)
full <- sort(unique(which(amat %% 100 > 9, arr.ind = TRUE)[, 1]))
arc <- sort(unique(which(amat > 99, arr.ind = TRUE)[, 1]))
arrow <- sort(unique(as.vector(which(amat %% 10 == 1, arr.ind = TRUE))))
S <- full[full != full[1]]
Ma <- full[1]
while (length(S) > 0) {
dim <- c()
for (i in S) {
dim <- c(dim, length(which(amat[i, Ma] %% 100 > 9, arr.ind = TRUE)))
}
s <- S[which(dim == max(dim))[1]]
ns <- which(amat[s, Ma] %% 100 > 9, arr.ind = TRUE)
if (min(amat[ns, ns] + diag(length(ns))) == 0) {
return(FALSE)
}
Ma <- c(Ma, s)
S <- S[S != s]
}
at <- which(amat + t(amat) == 0, arr.ind = TRUE)
ai <- c()
if (length(at[, 1]) != 0) {
for (i in (1:length(at[, 1]))) {
for (j in 1:na) {
if ((amat[at[i, 1], j] %% 10 == 1 || amat[at[i, 1], j] > 99) && (amat[at[i, 2], j] %% 10 != 1) && (amat[at[i, 2], j] < 100)) {
ai <- c(ai, j)
}
}
if (length(ai) == 0) {
break
}
for (j in ((1:na)[-ai])) {
if ((max(amat[ai, j] > 99) == 1) && (amat[at[i, 2], j] %% 10 == 1 || amat[at[i, 2], j] > 99) && (amat[at[i, 1], j] %% 10 != 1) && (amat[at[i, 1], j] < 100)) {
return(list(verify = FALSE, amat = NA))
}
}
ai <- c()
}
}
for (i in Ma) {
v <- which(amat[i, ] %% 100 > 9)
for (j in v) {
amat[i, j] <- 1
amat[j, i] <- 0
}
}
at <- which(amat + t(amat) + diag(na) == 0, arr.ind = TRUE)
if (length(at[, 1]) != 0) {
for (i in (1:length(at[, 1]))) {
for (j in 1:na) {
if ((amat[at[i, 1], j] %% 10 == 1 || amat[at[i, 1], j] > 99) && (amat[at[i, 2], j] %% 10 == 1 || amat[at[i, 2], j] > 99)) {
amat[at[i, 1], j] <- 1
amat[at[i, 2], j] <- 1
}
}
}
}
O <- c()
Oc <- arrow
while (length(Oc) > 0) {
for (i in Oc) {
if (max(amat[i, Oc] %% 10) == 0) {
O <- c(O, i)
break
}
}
Oc <- Oc[Oc != i]
}
for (i in arc) {
if (length(which(arrow == i)) == 0) {
O <- c(O, i)
}
}
aarc <- which(amat > 99, arr.ind = TRUE)
if (length(aarc)[1] > 0) {
for (i in 1:(length(aarc[, 1]))) {
# if(length(O)==0){
# amat[aarc[i,1],aarc[i,2]]<-0
if (which(O == aarc[i, 1]) > which(O == aarc[i, 2])) {
amat[aarc[i, 1], aarc[i, 2]] <- 1
} else {
amat[aarc[i, 1], aarc[i, 2]] <- 0
}
}
}
return(list(verify = TRUE, amat = amat))
}
`inducedChainGraph` <-
function(amat, cc = rownames(amat), cond = NULL, type = "LWF") {
### Induced chain graph with chain components cc.
inducedBlockGraph <- function(amat, sel, cond) {
S <- inducedConGraph(amat, sel = union(cond, sel), cond = NULL)
In(S[cond, sel, drop = FALSE])
}
nod <- rownames(amat)
nam <- c(list(cond), cc)
if (!all(unlist(nam) %in% nod)) {
stop("The chain components or the conditioning set are wrong.")
}
for (h in nam) {
for (k in nam) {
h <- unlist(h)
k <- unlist(k)
if (setequal(h, k)) {
next
}
if (length(intersect(h, k) > 0)) {
stop("The sets are not disjoint!")
}
}
}
nam <- unlist(nam)
cg <- matrix(0, length(nam), length(nam))
dimnames(cg) <- list(nam, nam)
kc <- length(cc)
if (type == "AMP") {
for (i in 1:kc) {
past <- unlist(cc[0:(i - 1)])
Past <- union(cond, past)
g <- cc[[i]]
Sgg.r <- inducedConGraph(amat, sel = g, cond = Past)
cg[g, g] <- Sgg.r
if (length(past) != 0) {
Pgr <- inducedRegGraph(amat, sel = g, cond = Past)
cg[Past, g] <- Pgr
}
}
} else if (type == "LWF") {
for (i in 1:kc) {
past <- unlist(cc[0:(i - 1)])
Past <- union(cond, past)
g <- cc[[i]]
Sgg.r <- inducedConGraph(amat, sel = g, cond = Past)
cg[g, g] <- Sgg.r
if (length(past) != 0) {
Cgr <- inducedBlockGraph(amat, sel = g, cond = Past)
cg[Past, g] <- Cgr
}
}
} else if (type == "MRG") {
for (i in 1:kc) {
past <- unlist(cc[0:(i - 1)])
Past <- union(cond, past)
g <- cc[[i]]
Sgg.r <- inducedCovGraph(amat, sel = g, cond = Past)
cg[g, g] <- Sgg.r
if (length(past) != 0) {
Pgr <- inducedRegGraph(amat, sel = g, cond = Past)
cg[Past, g] <- Pgr
}
}
} else {
stop("Wrong type.")
}
n <- unlist(cc)
cg[n, n, drop = FALSE]
}
"inducedConGraph" <-
function(amat, sel = rownames(amat), cond = NULL) {
### Induced concentration graph for a set of nodes given a conditioning set.
ancGraph <- function(A) {
## Edge matrix of the overall ancestor graph.
if (sum(dim(A)) == 0) {
return(A)
} else {
return(In(solve(2 * diag(nrow(A)) - A)))
}
}
trclos <- function(M) {
## Transitive closure of an UG with edge matrix M. See Wermuth and Cox (2004).
edgematrix(transClos(adjMatrix(M)))
}
A <- edgematrix(amat) # From the adjacency matrix to edge matrix
nod <- rownames(A)
if (!all(cond %in% nod)) {
stop("Conditioning nodes are not among the vertices.")
}
if (!all(sel %in% nod)) {
stop("Selected nodes are not among the vertices.")
}
if (length(intersect(sel, cond) > 0)) {
stop("The sets are not disjoint!")
}
l <- setdiff(nod, union(sel, cond)) # Marginal nodes
g <- sel
r <- cond
L <- union(l, g)
R <- union(g, r)
Al <- ancGraph(A[l, l, drop = FALSE])
ARR.l <- In(A[R, R, drop = FALSE] +
A[R, l, drop = FALSE] %*% Al %*% A[l, R, drop = FALSE])
TRl <- In(A[R, l, drop = FALSE] %*% Al)
DRl <- In(diag(length(R)) + TRl %*% t(TRl))
out <- In(t(ARR.l) %*% trclos(DRl) %*% ARR.l)
out <- out[g, g, drop = FALSE]
adjMatrix(out) * 10
}
"inducedCovGraph" <-
function(amat, sel = rownames(amat), cond = NULL) {
### Induced covariance graph for a set of nodes given a conditioning set.
ancGraph <- function(A) {
## Edge matrix of the overall ancestor graph.
if (sum(dim(A)) == 0) {
return(A)
} else {
return(In(solve(2 * diag(nrow(A)) - A)))
}
}
trclos <- function(M) {
## Transitive closure of an UG with edge matrix M. See Wermuth and Cox (2004).
edgematrix(transClos(adjMatrix(M)))
}
A <- edgematrix(amat) # From the adjacency matrix to edge matrix
nod <- rownames(A)
if (!all(cond %in% nod)) {
stop("Conditioning nodes are not among the vertices.")
}
if (!all(sel %in% nod)) {
stop("Selected nodes are not among the vertices.")
}
if (length(intersect(sel, cond) > 0)) {
stop("The sets are not disjoint!")
}
l <- setdiff(nod, union(sel, cond)) # Marginalized over nodes
g <- sel
r <- cond
L <- union(l, g)
R <- union(g, r)
AL <- ancGraph(A[L, L, drop = FALSE]) # In(solve(2*diag(length(L)) - A[L,L]))
TrL <- In(A[r, L, drop = FALSE] %*% AL)
DLr <- In(diag(length(L)) + t(TrL) %*% TrL)
cl <- trclos(DLr)
out <- In(AL %*% cl %*% t(AL))
out <- out[g, g, drop = FALSE]
adjMatrix(out) * 100
}
"inducedDAG" <-
function(amat, order, cond = NULL) {
### Induced DAG in a new ordering.
cc <- as.list(order)
inducedChainGraph(amat, cc = cc, cond = cond)
}
"inducedRegGraph" <-
function(amat, sel = rownames(amat), cond = NULL) {
### Induced regression graph for a set of nodes given a conditioning set.
ancGraph <- function(A) {
## Edge matrix of the overall ancestor graph.
if (sum(dim(A)) == 0) {
return(A)
} else {
return(In(solve(2 * diag(nrow(A)) - A)))
}
}
trclos <- function(M) {
## Transitive closure of an UG with edge matrix M. See Wermuth and Cox (2004).
edgematrix(transClos(adjMatrix(M)))
}
A <- edgematrix(amat) # From the adjacency matrix to edge matrix
nod <- rownames(A)
if (!all(cond %in% nod)) {
stop("Conditioning nodes are not among the vertices.")
}
if (!all(sel %in% nod)) {
stop("Selected nodes are not among the vertices.")
}
if (length(intersect(sel, cond) > 0)) {
stop("The sets are not disjoint!")
}
l <- setdiff(nod, union(sel, cond)) # Nodes marginalized over
g <- sel
r <- cond
L <- union(l, g)
R <- union(g, r)
AL <- ancGraph(A[L, L, drop = FALSE]) # A^{LL}
TrL <- In(A[r, L, drop = FALSE] %*% AL) # T_{rL}
DrL <- In(diag(length(r)) + TrL %*% t(TrL)) # D_{rr-L}
Arr.L <- In(A[r, r, drop = FALSE] + A[r, L, drop = FALSE] %*% AL
%*% A[L, r, drop = FALSE]) # A_{rr.L}
FLr <- In(AL %*% A[L, r, drop = FALSE]) # F_{Lr}
out <- In(AL %*% t(TrL) %*% trclos(DrL) %*% Arr.L + FLr)
t(out[g, r, drop = FALSE])
}
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.