From bd49fe4dbfbf316767fa5dd169e4ca42636c54b7 Mon Sep 17 00:00:00 2001 From: Pierre Santagostini <pierre.santagostini@agrocampus-ouest.fr> Date: Mon, 8 Jul 2024 19:25:20 +0200 Subject: [PATCH] Modifications to reduce the execution time. --- R/dlauricella.R | 181 +++++++++++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 79 deletions(-) diff --git a/R/dlauricella.R b/R/dlauricella.R index ede99d1..dcb6784 100644 --- a/R/dlauricella.R +++ b/R/dlauricella.R @@ -1,9 +1,7 @@ -#' @importFrom data.table rbindlist - dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { - + p <- length(lambda) - + buildMlist <- function(j, isupp, k, k1, p = p) { jsupp <- isupp[, j] Ml <- rep(list(0:k), p) @@ -11,7 +9,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { Ml[[j]] <- k1 return(expand.grid(Ml)) } - + buildxlist <- function(j, isupp, x, xsupp, p = p) { jsupp <- isupp[, j] xl <- rep(list(x), p) @@ -19,29 +17,29 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { xl[-jsupp] <- x[-jsupp] return(expand.grid(xl)) } - + prodlambda <- prod(lambda) - + lambdanu <- lambda*nu1/nu2 prodlambdanu <- prod(lambdanu) - + k <- 5 - + # M: data.frame of the indices for the nested sums # (i.e. all arrangements of n elements from {0:k}) M <- expand.grid(rep(list(0:k), p)) M <- M[-1, , drop = FALSE] - + Munique <- 0:k - + # Sum of the indices Msum <- rowSums(M) - # Msumunique <- 0:max(Msum) - + Msumunique <- 0:max(Msum) + kstep <- 5 - + if (lambdanu[p] <= 1) { # lambda[1] < ... < lambda[p] < 1 - + if (p > 1 & lambda[p] == 1) { lambda <- lambda[1:(p-1)] p1 <- p-1 @@ -52,25 +50,25 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { } else { p1 <- p } - + Mpoch <- sapply(Munique, function(j) lnpochhammer(0.5, j)) matpoch <- matrix(rep(Mpoch, p1), ncol = p1, byrow = FALSE) matM <- matrix(rep(Munique, p1), ncol = p1, byrow = FALSE) matlabmda <- matrix(rep(log(1 - lambdanu[1:p1]), length(Munique)), ncol = p1, byrow = TRUE) lambdaM <- matlabmda*matM matfact <- matrix(rep(lfactorial(Munique), p1), ncol = p1, byrow = FALSE) - + # matcommun <- exp(matpoch + lambdaM - matfact) matcommun <- as.data.frame(matpoch + lambdaM - matfact) # matcommun <- as.data.frame(apply(matcommun, 2, Re)) matcommunsupp <- as.data.frame(matrix(nrow = 0, ncol = ncol(matcommun))) colnames(matcommunsupp) <- colnames(matcommun) - + gridcommun <- expand.grid(matcommun) gridcommun <- gridcommun[-1, , drop = FALSE] # commun <- apply(gridcommun, 1, prod) commun <- rowSums(gridcommun) - + # d <- sum( # commun * sapply(Msum, function(i) { # pochhammer(1, i) / ( pochhammer((nu1 + p)/2, i) * i ) @@ -81,7 +79,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { lnpochhammer(1, i) - ( lnpochhammer((nu1 + p)/2, i) + log(i) ) }) ))) - + # Next elements of the sum, until the expected precision k1 <- 1:k derive <- 0 @@ -90,7 +88,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { k <- k1[length(k1)] k1 <- k + (1:kstep) derive <- derive + d - + # M: data.frame of the indices for the nested sums # M <- expand.grid(rep(list(k1), p1)) # if (p1 > 1) { @@ -117,12 +115,13 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { } M <- data.frame(rbindlist(Mlist)) } - + # Sum of the indices Msum <- rowSums(M) - + Munique <- (max(Munique)+1):max(M) - # Msumunique <- (max(Msumunique)+1):max(Msum) + Msumunique <- unique(Msum) + names(Msumunique) <- as.character(Msumunique) Mpoch <- sapply(Munique, function(j) lnpochhammer(0.5, j)) matpoch <- matrix(rep(Mpoch, p1), ncol = p1, byrow = FALSE) @@ -130,13 +129,13 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { matlabmda <- matrix(rep(log(1 - lambdanu[1:p1]), length(Munique)), ncol = p1, byrow = TRUE) lambdaM <- matlabmda*matM matfact <- matrix(rep(lfactorial(Munique), p1), ncol = p1, byrow = FALSE) - + matcommun <- rbind(matcommun, matcommunsupp) # matcommunsupp <- exp(matpoch + lambdaM - matfact) matcommunsupp <- as.data.frame(matpoch + lambdaM - matfact) # matcommunsupp <- as.data.frame(apply(matcommunsupp, 2, Re)) colnames(matcommunsupp) <- colnames(matcommun) - + communlist <- list(expand.grid(matcommunsupp)) if (p1 == 1) { gridcommun <- communlist[[1]] @@ -152,49 +151,53 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { } # commun <- apply(gridcommun, 1, prod) commun <- rowSums(gridcommun) - + # d <- sum( # commun * sapply(Msum, function(i) { # pochhammer(1, i) / ( pochhammer((nu1 + p)/2, i) * i ) # }) # ) - d <- Re(sum(exp( - commun + sapply(Msum, function(i) { - lnpochhammer(1, i) - ( lnpochhammer((nu1 + p)/2, i) + log(i) ) - }) - ))) - + # d <- Re(sum(exp( + # commun + sapply(Msum, function(i) { + # lnpochhammer(1, i) - ( lnpochhammer((nu1 + p)/2, i) + log(i) ) + # }) + # ))) + pochMsum <- sapply(Msumunique, function(i) { + lnpochhammer(1, i) - ( lnpochhammer((nu1 + p)/2, i) + log(i) ) + }) + names(pochMsum) <- as.character(Msumunique) + d <- Re(sum(exp(commun + pochMsum[as.character(Msum)]))) } - + derive <- as.numeric(-0.5 * log(prodlambda) - (nu2 + p)/2 * derive) - + } else if (lambdanu[1] > 1) { # 1 < lambda[1] < ... < lambda[p] - + Mpoch <- sapply(Munique, function(j) lnpochhammer(0.5, j)) matpoch <- matrix(rep(Mpoch, p), ncol = p, byrow = FALSE) matM <- matrix(rep(Munique, p), ncol = p, byrow = FALSE) matlabmda <- matrix(rep(log(1 - 1/lambdanu), length(Munique)), ncol = p, byrow = TRUE) lambdaM <- matlabmda*matM matfact <- matrix(rep(lfactorial(Munique), p), ncol = p, byrow = FALSE) - + # matcommun <- exp(matpoch + lambdaM - matfact) matcommun <- as.data.frame(matpoch + lambdaM - matfact) # matcommun <- as.data.frame(apply(matcommun, 2, Re)) matcommunsupp <- as.data.frame(matrix(nrow = 0, ncol = ncol(matcommun))) colnames(matcommunsupp) <- colnames(matcommun) - + gridcommun <- expand.grid(matcommun) gridcommun <- gridcommun[-1, , drop = FALSE] # commun <- apply(gridcommun, 1, prod) commun <- rowSums(gridcommun) - + d <- 0 for (i in 1:length(Msum)) { A <- sum(1/(0:(Msum[i]-1) + (nu1+p)/2)) d <- d - exp(commun[i]) * A } d <- Re(d) - + # Next elements of the sum, until the expected precision k1 <- 1:k derive <- 0 @@ -205,7 +208,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { k1 <- k + (1:kstep) derive <- derive + d # vd <- c(vd, d); vderive <- c(vderive, derive) - + # # M: data.frame of the indices for the nested sums # M <- as.data.frame(matrix(nrow = 0, ncol = p)) # if (p > 1) { @@ -219,7 +222,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { # } # } # M <- rbind( M, expand.grid(rep(list(k1), p)) ) - + # M: data.frame of the indices for the nested sums # M <- expand.grid(rep(list(k1), p)) # if (p > 1) { @@ -246,12 +249,13 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { } M <- data.frame(rbindlist(Mlist)) } - + Msum <- rowSums(M) - + Munique <- (max(Munique) + 1):max(M) - # Msumunique <- (max(Msumunique) + 1):max(Msum) - + Msumunique <- unique(Msum) + names(Msumunique) <- as.character(Msumunique) + # d <- 0 # for (i in 1:length(Msum)) { # commun <- prod( @@ -262,20 +266,20 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { # A <- sum(1/(0:(Msum[i]-1) + (1+p)/2)) # d <- d - commun * A # / pochhammer((1 + p)/2, Msum[i]) # } - + Mpoch <- sapply(Munique, function(j) lnpochhammer(0.5, j)) matpoch <- matrix(rep(Mpoch, p), ncol = p, byrow = FALSE) matM <- matrix(rep(Munique, p), ncol = p, byrow = FALSE) matlabmda <- matrix(rep(log(1 - 1/lambdanu), length(Munique)), ncol = p, byrow = TRUE) lambdaM <- matlabmda*matM matfact <- matrix(rep(lfactorial(Munique), p), ncol = p, byrow = FALSE) - + matcommun <- rbind(matcommun, matcommunsupp) # matcommunsupp <- exp(matpoch + lambdaM - matfact) matcommunsupp <- as.data.frame(matpoch + lambdaM - matfact) # matcommunsupp <- as.data.frame(apply(matcommunsupp, 2, Re)) colnames(matcommunsupp) <- colnames(matcommun) - + communlist <- list(expand.grid(matcommunsupp)) if (p == 1) { gridcommun <- communlist[[1]] @@ -291,22 +295,29 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { } # commun <- apply(gridcommun, 1, prod) commun <- rowSums(gridcommun) - + # d <- 0 # for (i in 1:length(Msum)) { # A <- sum(1/(0:(Msum[i]-1) + (1+p)/2)) # d <- d - commun[i] * A # } - A <- sapply(Msum, function (i) sum(1/(0:(i-1) + (nu1+p)/2))) + # d <- commun + pochMsum[Msum] + # A <- sapply(Msum, function (i) sum(1/(0:(i-1) + (nu1+p)/2))) + pochMsum <- sapply(Msumunique, function(i) { + sum(1/(0:(i-1) + (nu1+p)/2)) + }) + names(pochMsum) <- as.character(Msumunique) + A <- pochMsum[as.character(Msum)] + d <- Re(-sum(exp(commun)*A)) - + } - + derive <- as.numeric(-0.5 * log(prodlambda) - (nu2 + p)/2 * prod(1/sqrt(lambdanu)) * derive) - + } else { # lambda[1] < ... < 1 < ... < lambda[p] - + Mpoch <- sapply(Munique, function(j) lnpochhammer(0.5, j)) matpoch <- cbind(matrix(rep(Mpoch, p-1), ncol = p-1, byrow = FALSE), 0) # Mpochp <- sapply(Munique, function(j) lnpochhammer(nu1/2, j)) @@ -315,18 +326,18 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { matlabmda <- matrix(rep(log(1 - c(lambdanu[-p], 1)/lambdanu[p]), length(Munique)), ncol = p, byrow = TRUE) lambdaM <- matlabmda*matM matfact <- matrix(rep(lfactorial(Munique), p), ncol = p, byrow = FALSE) - + # matcommun <- exp(matpoch + lambdaM - matfact) matcommun <- as.data.frame(matpoch + lambdaM - matfact) # matcommun <- as.data.frame(apply(matcommun, 2, Re)) matcommunsupp <- as.data.frame(matrix(nrow = 0, ncol = ncol(matcommun))) colnames(matcommunsupp) <- colnames(matcommun) - + gridcommun <- expand.grid(matcommun) gridcommun <- gridcommun[-1, , drop = FALSE] # commun <- apply(gridcommun, 1, prod) commun <- rowSums(gridcommun) - + # d <- sum( # commun * sapply(1:length(Msum), function(i) { # pochhammer(0.5, M[i, p]) * pochhammer(1, Msum[i]) / ( pochhammer((nu1 + p)/2, Msum[i]) * Msum[i] ) @@ -338,7 +349,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { ( lnpochhammer((nu1 + p)/2, Msum[i]) + log(Msum[i]) ) }) ))) - + # Next elements of the sum, until the expected precision k1 <- 1:k derive <- 0 @@ -347,7 +358,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { k <- k1[length(k1)] k1 <- k + (1:kstep) derive <- derive + d - + # # M: data.frame of the indices for the nested sums # M <- as.data.frame(matrix(nrow = 0, ncol = p)) # if (p > 1) { @@ -361,7 +372,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { # } # } # M <- rbind( M, expand.grid(rep(list(k1), p)) ) - + # M <- expand.grid(rep(list(k1), p)) # if (p > 1) { # for (i in 1:(p-1)) { @@ -375,7 +386,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { # } # } # } - + # M: data.frame of the indices for the nested sums Mlist <- list(expand.grid(rep(list(k1), p))) if (p == 1) { @@ -389,12 +400,13 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { } M <- data.frame(rbindlist(Mlist)) } - + Msum <- rowSums(M) - + Munique <- (max(Munique)+1):max(M) - # Msumunique <- (max(Msumunique)+1):max(Msum) - + Msumunique <- unique(Msum) + names(Msumunique) <- as.character(Msumunique) + # d <- 0 # for (i in 1:length(Msum)) { # commun <- prod( @@ -405,7 +417,7 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { # commun <- commun*(1 - 1/lambda[p])^M[i, p]/factorial(M[i, p]) # d <- d + commun * pochhammer(0.5, M[i, p])*pochhammer(1, Msum[i]) / ( pochhammer((1 + p)/2, Msum[i]) * Msum[i] ) # } - + Mpoch <- sapply(Munique, function(j) lnpochhammer(0.5, j)) matpoch <- cbind(matrix(rep(Mpoch, p-1), ncol = p-1, byrow = FALSE), 0) # Mpochp <- sapply(Munique, function(j) lnpochhammer(nu1/2, j)) @@ -414,13 +426,13 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { matlabmda <- matrix(rep(log(1 - c(lambdanu[-p], 1)/lambdanu[p]), length(Munique)), ncol = p, byrow = TRUE) lambdaM <- matlabmda*matM matfact <- matrix(rep(lfactorial(Munique), p), ncol = p, byrow = FALSE) - + matcommun <- rbind(matcommun, matcommunsupp) # matcommunsupp <- exp(matpoch + lambdaM - matfact) matcommunsupp <- as.data.frame(matpoch + lambdaM - matfact) # matcommunsupp <- as.data.frame(apply(matcommunsupp, 2, Re)) colnames(matcommunsupp) <- colnames(matcommun) - + communlist <- list(expand.grid(matcommunsupp)) if (p == 1) { gridcommun <- communlist[[1]] @@ -436,27 +448,38 @@ dlauricella <- function(nu1, nu2, lambda, eps = 1e-6) { } # commun <- apply(gridcommun, 1, prod) commun <- rowSums(gridcommun) - + # d <- sum( # commun * sapply(1:length(Msum), function(i) { # pochhammer(0.5, M[i, p]) * pochhammer(1, Msum[i]) / ( pochhammer((nu1 + p)/2, Msum[i]) * Msum[i] ) # }) # ) + # d <- Re(sum(exp( + # commun + sapply(1:length(Msum), function(i) { + # lnpochhammer(nu1/2, M[i, p]) + lnpochhammer(1, Msum[i]) - + # ( lnpochhammer((nu1 + p)/2, Msum[i]) + log(Msum[i]) ) + # }) + # ))) + pochnup <- sapply(0:max(M), function(i) { + lnpochhammer(nu1/2, i) + }) + names(pochnup) <- as.character(0:max(M)) + pochMsum <- sapply(Msumunique, function(i) { + lnpochhammer(1, i) - ( lnpochhammer((nu1 + p)/2, i) + log(i) ) + }) + names(pochMsum) <- as.character(Msumunique) d <- Re(sum(exp( - commun + sapply(1:length(Msum), function(i) { - lnpochhammer(nu1/2, M[i, p]) + lnpochhammer(1, Msum[i]) - - ( lnpochhammer((nu1 + p)/2, Msum[i]) + log(Msum[i]) ) - }) + commun + pochMsum[as.character(Msum)] + pochnup[as.character(M[, p])] ))) - + } - + derive <- as.numeric(-0.5 * log(prodlambda) + (nu2 + p)/2 * (log(lambdanu[p]) - derive)) - + } - + attr(derive, "epsilon") <- eps attr(derive, "k") <- k - + return(derive) } -- GitLab