--- title: "Profiling `biwavelet` package" author: "Viliam Simko" date: "February 27, 2016" output: html_document vignette: > %\VignetteIndexEntry{Profiling `biwavelet` package} %\VignetteEngine{knitr::rmarkdown} \usepackage[utf8]{inputenc} --- ```{r Setup, include=FALSE} library(biwavelet) if (!require("profvis")) install.packages("profvis") library(profvis) ``` This document contains some attempts to perform code profiling and benchmarking. ## Profiling `wtc.sig` function We need some parameters that the `wtc.sig` function expects. ```{r Input data for wtc.sig} d1 <- cbind(1:100, rnorm(100)) d2 <- cbind(1:100, rnorm(100)) d1.ar1 <- arima(d1[, 2], order = c(1, 0, 0))$coef[1] d2.ar1 <- arima(d2[, 2], order = c(1, 0, 0))$coef[1] checked <- check.data(y = d1, x1 = d2) dt <- checked$y$dt n <- checked$y$n.obs s0 <- 2 * dt ``` Now, we can start profiling the code. The results are shown using an interactive HTML widget. ```{r Profiling wtc.sig} profvis({ wtcsig <- wtc.sig(nrands = 100, lag1 = c(d1.ar1, d2.ar1), dt = dt, ntimesteps = n, pad = TRUE, dj = 1 / 12, s0 = s0, J1 = NULL, max.scale = NULL, quiet = TRUE) }, height = 300) ``` It looks like the function `smooth.wavelet` might be the best candidate for speed improvements. ## Some microbenchmarks ```{r} library(microbenchmark) out2 <- matrix(nrow = 10, ncol = 10) out3 <- matrix(nrow = 10, ncol = 10) apply_with_quantile <- function() { apply(ts, MARGIN = c(1, 2), quantile, 0.95, na.rm = TRUE) return } row_quantile_per_row <- function() { for (i in 1:10) { out2[i, ] <- row_quantile(ts[i, , ], 0.95) } } row_quantile_per_col <- function() { for (i in 1:10) { out3[, i] <- row_quantile(ts[, i, ], 0.95) } } apply_with_row_quantile <- function() { apply(ts, 2, row_quantile, 0.95) } microbenchmark( apply_with_quantile, row_quantile_per_row, row_quantile_per_col, apply_with_row_quantile, times = 100000 ) ``` ## TODO: some old stuff The following code is not executed. ```{r, eval=FALSE} library(foreach) library(parallel) cl <- makeCluster(4, outfile = "") # number of cores. Notice 'outfile' library(doParallel) registerDoParallel(cl) wtcsig <- wtc_sig_parallel(nrands = 4, lag1 = c(d1.ar1, d2.ar1), dt = dt, ntimesteps = n, pad = TRUE, dj = 1 / 12, s0 = s0, J1 = NULL, max.scale = NULL) wtcsig <- wtc_sig_parallel(nrands = 400, lag1 = c(d1.ar1, d2.ar1), dt = dt, ntimesteps = n, pad = TRUE, dj = 1 / 12, s0 = s0, J1 = NULL, max.scale = NULL) nrands <- 4 foreach(r = seq_len(nrands), .init = array(dim = c(3, 3, nrands)), .combine = function(y, x){ y[, , x$r] <- x$a return(y) }) %dopar% { list(r = r, a = array(dim = c(3, 3), (1:9) * r)) } stopCluster(cl) image(wtcsig) Rprof(interval = 0.001) wtcsig <- wtc.sig(nrands = 100, lag1 = c(d1.ar1, d2.ar1), dt = dt, ntimesteps = n, pad = TRUE, dj = 1 / 12, s0 = s0, J1 = NULL, max.scale = NULL, quiet = FALSE) Rprof(NULL) summaryRprof()$by.self library(microbenchmark) microbenchmark( {seq_len(1000000)}, {1:1000000}, times = 1000 ) load("inst/benchmarks/data1.Rd") out2 <- matrix(nrow = 10, ncol = 10) out3 <- matrix(nrow = 10, ncol = 10) microbenchmark( function() { out1 <- apply(ts, MARGIN = c(1, 2), quantile, 0.95, na.rm = TRUE) }, function() { for (i in 1:10) { out2[i, ] <- row_quantile(ts[i, , ], 0.95) } }, function() { # this version is the best for (i in 1:10) { out3[, i] <- row_quantile(ts[, i, ], 0.95) } }, function() { out4 <- apply(ts, 2, row_quantile, 0.95) }, times = 1000 ) ntimesteps <- 100 lag1 <- c(-0.0693, 0.1581) mr1 <- get_minroots(lag1[1]) mr2 <- get_minroots(lag1[2]) ntseq <- seq_len(ntimesteps) microbenchmark( function() { d1 <- cbind(1:ntimesteps, arima.sim(model = list(ar = lag1[1], ma = 0), n = ntimesteps)) d2 <- cbind(1:ntimesteps, arima.sim(model = list(ar = lag1[2], ma = 0), n = ntimesteps)) }, function() { d1 <- cbind(ntseq, ar1_ma0_sim(mr1, lag1[1], ntimesteps)) d2 <- cbind(ntseq, ar1_ma0_sim(mr2, lag1[2], ntimesteps)) }, times = 100000 ) ts1 <- arima.sim(model = list(ar = lag1[1], ma = 0), n = ntimesteps) ar <- lag1[1] minroots <- get_minroots(ar) ts2 <- ar1_ma0_sim(minroots, ar = ar, ntimesteps) n <- ntimesteps get_minroots <- function(ar) { min(Mod(polyroot(c(1, -ar)))) } ar1_ma0_sim <- function(minroots, ar, n) { if (minroots <= 1) { stop("'ar' part of model is not stationary") } n.start <- 2 + ceiling(6 / log(minroots)) x <- ts(data = rnorm(n + n.start), start = 1 - n.start) x <- filter(x, ar, method = "recursive") x[-seq_len(n.start)] # maybe as.ts(x) } ts2 <- ar1_ma0_sim(minroots, ar = ar, 10) twave <- matrix(nrow = 100, ncol = 10, 1) ker <- 1:3 ```