-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmakeDufam.R
88 lines (77 loc) · 3.12 KB
/
makeDufam.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
makeDufam <- function(pedigree, parallel = FALSE,
ncores = getOption("mc.cores", 2L), invertD = TRUE,
returnA = FALSE, det = TRUE, verbose = TRUE){
N <- nrow(pedigree)
pedigree <- cbind(pedigree, gen = genAssign(pedigree), oseq = seq.int(N))
pedigree <- pedigree[order(pedigree$gen, pedigree[, 2], pedigree[, 3]), ]
numeric.pedigree <- numPed(pedigree[, 1:3])
A <- makeA(pedigree[, 1:3])
dA <- diag(A)
if(parallel){
if(length(A@x)/ncores < 10){
warning("pedigree too small - 'parallel' set to FALSE instead")
parallel <- FALSE
}
}
if(!parallel){
if(verbose) cat(paste("starting to make D..."))
Cout <- .C("dijjskip", PACKAGE = "nadiv",
as.integer(numeric.pedigree[, 2] - 1),
as.integer(numeric.pedigree[, 3] - 1),
as.integer(A@i),
as.integer(A@p),
as.double(A@x/2),
as.integer(N),
as.double(rep(0, length(A@x))),
as.integer(rep(0, length(A@i))),
as.integer(rep(0, N)),
as.integer(0))
D <- sparseMatrix(i = Cout[[8]][1:Cout[[10]]],
p = c(Cout[[9]], Cout[[10]]),
x = Cout[[7]][1:Cout[[10]]],
dims = c(N, N), dimnames = list(as.character(pedigree[, 1]), NULL),
symmetric = TRUE, index1 = FALSE)
diag(D) <- 2 - dA
if(!returnA) A <- NULL
rm("Cout")
} else{
listA <- data.frame(Row = as.integer(rep(1:length(A@p[-1]), diff(A@p))), Column = as.integer(A@i + 1))
wrap_dij <- function(x){
sub_lA <- listA[min(x):max(x), 1:2]
lA_r <- dim(sub_lA)[1]
Cout <- .C("dijp", PACKAGE = "nadiv",
as.integer(numeric.pedigree[, 2] - 1),
as.integer(numeric.pedigree[, 3] - 1),
as.integer(lA_r),
as.integer(sub_lA[, 1] - 1),
as.integer(sub_lA[, 2] - 1),
as.integer(A@i),
as.integer(A@p),
as.double(A@x/2),
as.double(rep(0, lA_r)))
Cout[[9]]
}
if(verbose) cat(paste("starting to make D..."))
Dijs <- parallel::pvec(seq(1, dim(listA)[1], 1), FUN = wrap_dij, mc.set.seed = FALSE, mc.silent = FALSE, mc.cores = ncores, mc.cleanup = TRUE)
D <- sparseMatrix(i = A@i,
p = A@p,
x = Dijs,
dims = c(N, N), dimnames = list(as.character(pedigree[, 1]), NULL),
symmetric = TRUE, index1 = FALSE)
if(!returnA) A <- NULL
D <- drop0(D)
diag(D) <- 2 - dA
}
if(verbose) cat(paste(".done", "\n"))
D <- D[pedigree$oseq, pedigree$oseq]
if(returnA) A <- A[pedigree$oseq, pedigree$oseq]
if(det) logDet <- determinant(D, logarithm = TRUE)$modulus[1] else logDet <- NULL
if(invertD){
Dinv <- as(solve(D), "dgCMatrix")
Dinv@Dimnames <- list(as.character(pedigree[pedigree$oseq, 1]), NULL)
listDinv <- sm2list(Dinv, rownames = pedigree[pedigree$oseq, 1], colnames=c("row", "column", "Dinverse"))
return(list(A = A, D = D, logDet = logDet, Dinv=Dinv, listDinv=listDinv))
} else{
return(list(A = A, D = D, logDet = logDet))
}
}