Nothing
# Double-precision Morlet wavelet implementation.
#
# Public entry point is `morlet_wavelet()` (defined in R/wavelet.R), which
# dispatches here when `precision = "double"`.
wavelet_kernels2_double <- function(freqs, srate, wave_num, data_length, signature = NULL) {
freqs <- as.double(freqs)
srate <- as.double(srate)
wave_num <- as.double(wave_num)
data_length <- as.integer(data_length)
kernel_info <- wavelet_kernels(freqs = freqs, srate = srate, wave_num = wave_num)
digest <- digest::digest(list(freqs, srate, wave_num, data_length, signature = signature))
root_dir <- file.path(tempdir2(check = TRUE), "ravetools")
if (!dir.exists(root_dir)) {
dir.create(root_dir, showWarnings = FALSE, recursive = TRUE)
}
real_path <- file.path(root_dir, sprintf("wavelet-real-%s", digest))
imag_path <- file.path(root_dir, sprintf("wavelet-imag-%s", digest))
arr_dim <- c(data_length, length(kernel_info$kernels))
tryCatch({
return(list(
real = filearray::filearray_checkload(
filebase = real_path, mode = "readonly", symlink_ok = FALSE,
freqs = freqs, srate = srate, wave_num = wave_num, data_length = data_length,
arr_dim = arr_dim, rave_data_type = "rave-wavelet-kernels-double-real"
),
imag = filearray::filearray_checkload(
filebase = imag_path, mode = "readonly", symlink_ok = FALSE,
freqs = freqs, srate = srate, wave_num = wave_num, data_length = data_length,
arr_dim = arr_dim, rave_data_type = "rave-wavelet-kernels-double-imag"
)
))
}, error = function(e) {
if (getOption("ravetools.debug", FALSE)) {
print(real_path)
print(imag_path)
warning(e)
}
if (dir.exists(real_path)) { unlink(real_path, recursive = TRUE) }
if (dir.exists(imag_path)) { unlink(imag_path, recursive = TRUE) }
})
arr_real <- filearray::filearray_create(
filebase = real_path,
dimension = arr_dim,
type = "double",
partition_size = 1
)
arr_imag <- filearray::filearray_create(
filebase = imag_path,
dimension = arr_dim,
type = "double",
partition_size = 1
)
arr_real$.mode <- "readwrite"
arr_imag$.mode <- "readwrite"
tmp <- complex(data_length)
lapply(seq_along(kernel_info$kernels), function(ii) {
tmp_wavelet <- kernel_info$kernels[[ii]]
w_l <- length(tmp_wavelet)
n_pre <- ceiling(data_length / 2) - floor(w_l / 2)
n_post <- data_length - n_pre - w_l
x <- c(rep(0, n_pre), tmp_wavelet, rep(0, n_post))
fftw_c2c(data = x, inverse = 0L, ret = tmp)
conjugate(tmp)
arr_real[, ii] <- Re(tmp)
arr_imag[, ii] <- Im(tmp)
NULL
})
arr_real$.header$freqs <- freqs
arr_real$.header$srate <- srate
arr_real$.header$wave_num <- wave_num
arr_real$.header$data_length <- data_length
arr_real$.header$arr_dim <- arr_dim
arr_real$.header$freqs <- freqs
arr_real$.header$rave_data_type <- "rave-wavelet-kernels-double-real"
arr_real$.save_header()
arr_imag$.header$freqs <- freqs
arr_imag$.header$srate <- srate
arr_imag$.header$wave_num <- wave_num
arr_imag$.header$data_length <- data_length
arr_imag$.header$arr_dim <- arr_dim
arr_imag$.header$freqs <- freqs
arr_imag$.header$rave_data_type <- "rave-wavelet-kernels-double-imag"
arr_imag$.save_header()
arr_real$.mode <- "readonly"
arr_imag$.mode <- "readonly"
return(list(
real = arr_real,
imag = arr_imag
))
}
morlet_wavelet_double <- function(data, freqs, srate, wave_num,
trend = c("constant", "linear", "none"),
signature = NULL, segment_length = NULL, ...) {
trend <- match.arg(trend)
freqs <- as.double(freqs)
srate <- as.double(srate)
wave_num <- as.double(wave_num)
more_args <- list(...)
data_digest <- digest::digest(data)
f_l <- length(freqs)
d_l <- length(data)
segment_length_norm <- wavelet_normalize_segment_length(segment_length, d_l)
segmented <- !is.na(segment_length_norm)
# detrend on the full signal first; preserves legacy semantics
if (trend != "none") {
data <- as.vector(detrend(data, trend = trend, ...))
}
if (segmented) {
kern_info <- wavelet_kernels(freqs = freqs, srate = srate, wave_num = wave_num)
max_kernel_len <- max(vapply(kern_info$kernels, length, integer(1L)))
plan <- wavelet_segment_plan(d_l, segment_length_norm, max_kernel_len)
kern_data_length <- segment_length_norm
} else {
plan <- NULL
kern_data_length <- d_l
}
# Kernel cache differentiates by `data_length`; output cache deliberately
# omits `segment_length` since both paths produce the same coefficients.
fft_waves <- wavelet_kernels2_double(freqs, srate, wave_num, kern_data_length,
signature = signature)
real_path <- tempfile2(pattern = "wavelet-double-real-")
imag_path <- tempfile2(pattern = "wavelet-double-imag-")
output <- tryCatch({
list(
real = filearray::filearray_checkload(
filebase = real_path, symlink_ok = FALSE,
freqs = freqs, srate = srate, wave_num = wave_num,
data_digest = data_digest, trend = trend,
more_args = more_args,
rave_data_type = "rave-wavelet-coefficients-real",
precision = "double"
),
imag = filearray::filearray_checkload(
filebase = imag_path, symlink_ok = FALSE,
freqs = freqs, srate = srate, wave_num = wave_num,
data_digest = data_digest, trend = trend,
more_args = more_args,
rave_data_type = "rave-wavelet-coefficients-imag",
precision = "double"
)
)
}, error = function(e) {
if (getOption("ravetools.debug", FALSE)) {
print(real_path)
print(imag_path)
warning(e)
}
if (dir.exists(real_path)) { unlink(real_path, recursive = TRUE) }
if (dir.exists(imag_path)) { unlink(imag_path, recursive = TRUE) }
NULL
})
if (length(output) == 2) { return(output) }
output_real <- filearray::filearray_create(
filebase = real_path, dimension = c(d_l, f_l),
type = "double", partition_size = 1
)
output_imag <- filearray::filearray_create(
filebase = imag_path, dimension = c(d_l, f_l),
type = "double", partition_size = 1
)
output_real$.mode <- "readwrite"
output_imag$.mode <- "readwrite"
wave_len <- nrow(fft_waves$real)
ind <- seq_len(ceiling(wave_len / 2))
norm_factor <- wave_len * sqrt(srate / 2)
if (segmented) {
seg_mat <- wavelet_build_segment_matrix(data, plan)
fft_seg <- mvfftw_r2c(seg_mat, HermConj = 1L)
n_seg <- plan$n_seg
local_starts <- plan$local_starts
local_ends <- plan$local_ends
new_ind <- seq_len(plan$segment_length)
new_ind <- c(new_ind[-ind], new_ind[ind])
# Pre-allocated buffer avoids a full segment_length * n_seg complex alloc
# per frequency. mvfftw_c2c writes in-place via `ret`; norm_factor division
# is deferred to the small per-segment subsets.
buffer <- array(0 + 0i, dim = c(plan$segment_length, n_seg))
ii <- 1L
fmap_fun <- function(input) {
kern <- input[[1]] + 1i * input[[2]]
mvfftw_c2c(kern * fft_seg, inverse = 1L, ret = buffer)
col_vec <- unlist(lapply(seq_len(n_seg), function(k) {
buffer[new_ind[local_starts[k]:local_ends[k]], k] / norm_factor
}))
output_real[, ii] <- Re(col_vec)
output_imag[, ii] <- Im(col_vec)
ii <<- ii + 1L
NULL
}
} else {
fft_data <- fftw_r2c(data)
tmp <- complex(length(fft_data))
ii <- 1L
fmap_fun <- function(input) {
kern <- input[[1]] + 1i * input[[2]]
fftw_c2c(data = kern * fft_data, inverse = 1L, ret = tmp)
shifted <- c(tmp[-ind], tmp[ind]) / norm_factor
output_real[, ii] <- Re(shifted)
output_imag[, ii] <- Im(shifted)
ii <<- ii + 1L
NULL
}
}
filearray::fmap2(
x = fft_waves,
fun = fmap_fun,
.buffer_count = f_l,
.simplify = FALSE
)
output_real$.header$freqs <- freqs
output_real$.header$srate <- srate
output_real$.header$wave_num <- wave_num
output_real$.header$data_digest <- data_digest
output_real$.header$trend <- trend
output_real$.header$more_args <- more_args
output_real$.header$rave_data_type <- "rave-wavelet-coefficients-real"
output_real$.header$precision <- "double"
output_real$.save_header()
output_imag$.header$freqs <- freqs
output_imag$.header$srate <- srate
output_imag$.header$wave_num <- wave_num
output_imag$.header$data_digest <- data_digest
output_imag$.header$trend <- trend
output_imag$.header$more_args <- more_args
output_imag$.header$rave_data_type <- "rave-wavelet-coefficients-imag"
output_imag$.header$precision <- "double"
output_imag$.save_header()
output_real$.mode <- "readonly"
output_imag$.mode <- "readonly"
list(
real = output_real,
imag = output_imag
)
}
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.