-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathcuPC.R
158 lines (139 loc) · 5.08 KB
/
cuPC.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
library(pcalg)
cu_pc <- function(suffStat, indepTest, alpha, labels, p,
fixedGaps = NULL, fixedEdges = NULL, NAdelete = TRUE, m.max = Inf,
u2pd = c("relaxed", "rand", "retry"),
skel.method = c("stable", "original", "stable.fast"),
conservative = FALSE, maj.rule = FALSE,
solve.confl = FALSE, verbose = FALSE)
{
## Initial Checks
cl <- match.call()
if(!missing(p)) stopifnot(is.numeric(p), length(p <- as.integer(p)) == 1, p >= 2)
if(missing(labels)) {
if(missing(p)) stop("need to specify 'labels' or 'p'")
labels <- as.character(seq_len(p))
} else { ## use labels ==> p from it
stopifnot(is.character(labels))
if(missing(p)) {
p <- length(labels)
} else if(p != length(labels))
stop("'p' is not needed when 'labels' is specified, and must match length(labels)")
else
message("No need to specify 'p', when 'labels' is given")
}
seq_p <- seq_len(p)
u2pd <- match.arg(u2pd)
skel.method <- match.arg(skel.method)
if(u2pd != "relaxed") {
if (conservative || maj.rule)
stop("Conservative PC and majority rule PC can only be run with 'u2pd = relaxed'")
if (solve.confl)
stop("Versions of PC using lists for the orientation rules (and possibly bi-directed edges)\n can only be run with 'u2pd = relaxed'")
}
if (conservative && maj.rule) stop("Choose either conservative PC or majority rule PC!")
## Skeleton
skel <- cu_skeleton(suffStat, indepTest, alpha, labels=labels, NAdelete=NAdelete, m.max=m.max, verbose=verbose)
skel@call <- cl # so that makes it into result
## Orient edges
if (!conservative && !maj.rule) {
switch (u2pd,
"rand" = udag2pdag(skel),
"retry" = udag2pdagSpecial(skel)$pcObj,
"relaxed" = udag2pdagRelaxed(skel, verbose=verbose))
}
else { ## u2pd "relaxed" : conservative _or_ maj.rule
## version.unf defined per default
## Tetrad CPC works with version.unf=c(2,1)
## see comment on pc.cons.intern for description of version.unf
pc. <- pc.cons.intern(skel, suffStat, indepTest, alpha,
version.unf=c(2,1), maj.rule=maj.rule, verbose=verbose)
udag2pdagRelaxed(pc.$sk, verbose=verbose,
unfVect=pc.$unfTripl)
}
}
cu_skeleton <- function(suffStat, indepTest, alpha, labels, p, m.max = Inf, NAdelete = TRUE, verbose = FALSE)
{
cl <- match.call()
if(!missing(p)) stopifnot(is.numeric(p), length(p <- as.integer(p)) == 1, p >= 2)
if(missing(labels)) {
if(missing(p)) stop("need to specify 'labels' or 'p'")
labels <- as.character(seq_len(p))
} else { ## use labels ==> p from it
stopifnot(is.character(labels))
if(missing(p)) {
p <- length(labels)
} else if(p != length(labels))
stop("'p' is not needed when 'labels' is specified, and must match length(labels)")
else
message("No need to specify 'p', when 'labels' is given")
}
seq_p <- seq_len(p)
pval <- NULL
#Convert SepsetMatrix to sepset
sepset <- lapply(seq_p, function(.) vector("list",p))# a list of lists [p x p]
# save maximal p value
pMax <- matrix(0, nrow = p, ncol = p)
number_of_levels = 50
threshold <- matrix(0, nrow = 1, ncol = number_of_levels)
for (i in 0:(min(number_of_levels, suffStat$n - 3) - 1)){
threshold[i] <- abs(qnorm((alpha/2), mean = 0, sd = 1)/sqrt(suffStat$n - i - 3))
}
G <- matrix(TRUE, nrow = p, ncol = p)
diag(G) <- FALSE
done <- TRUE
ord <- 0
G <- G * 1
if (m.max == Inf){
max_level = 14
} else{
max_level = m.max
}
sepsetMatrix <- matrix(-1, nrow = p * p, ncol = 14)
dyn.load("Skeleton.so")
start_time <- proc.time()
z <- .C("Skeleton",
C = as.double(suffStat$C),
p = as.integer(p),
G = as.integer(G),
Th = as.double(threshold),
l = as.integer(ord),
max_level = as.integer(max_level),
pmax = as.double(pMax),
sepsetmat = as.integer(sepsetMatrix))
ord <- z$l
G <- (matrix(z$G, nrow = p, ncol = p)) > 0
pMax <- (matrix(z$pmax, nrow = p, ncol = p))
pMax[which(pMax == -100000)] <- -Inf
if(ord <= 14){
sepsetMatrix <- t(matrix(z$sepsetmat, nrow = 14, ncol = p ^ 2))
index_of_cuted_edge <- row(sepsetMatrix)[which(sepsetMatrix != -1)]
for (i in index_of_cuted_edge) {
y <- floor(i / p) + 1
x <- i - ((y - 1) * p) + 1
#find index
j <- 1
for (j in 1:14){
if (sepsetMatrix[i, j] == -1){
j <- j - 1
break
}
}
sepset[[x]][[y]] <- sepset[[y]][[x]] <- sepsetMatrix[i, 1:j]
}
} else{
# TODO: Update sepset for more than 14 level
}
print(ord)
## transform matrix to graph object :
Gobject <-
if (sum(G) == 0) {
new("graphNEL", nodes = labels)
} else {
colnames(G) <- rownames(G) <- labels
as(G,"graphNEL")
}
## final object
new("pcAlgo", graph = Gobject, call = cl, n = integer(0),
max.ord = as.integer(ord - 1), n.edgetests = 0,
sepset = sepset, pMax = pMax, zMin = matrix(NA, 1, 1))
}## end{ skeleton }