From 9b0d5215b442728072988bf9628eb14449e9aed8 Mon Sep 17 00:00:00 2001 From: Elio Campitelli Date: Sat, 20 Jan 2024 13:23:18 -0300 Subject: [PATCH] Imrpoves FItWave documentattion Closes #184 --- NEWS.md | 1 + R/FitWave.R | 36 +++++++++++++++++++++++++++++++----- man/waves.Rd | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/NEWS.md b/NEWS.md index 7eb16cf1..161a8508 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,7 @@ - The contour functions gain a `clip` argument to only show contours in an area defined by a polygon. - The `kriging` argument of the contour functions now can be a numeric to control de number of pixels used. +- Documentation of `FitWave()` and friends improved (#184, @pascaloettli). ## Breaking changes diff --git a/R/FitWave.R b/R/FitWave.R index 36d7fbd3..3751545c 100644 --- a/R/FitWave.R +++ b/R/FitWave.R @@ -1,6 +1,7 @@ -#' Fourier transform +#' Fourier transform functions #' -#' Perform a fourier transform of the data and return the +#' Use [fft()] to fit, filter and reconstruct signals in the frequency domain, as +#' well as to compute the wave envelope. #' #' @param y numeric vector to transform #' @param k numeric vector of wave numbers @@ -28,11 +29,11 @@ #' \item{y}{the reconstructed signal of each wavenumber} #' } #' -#' `FilterWave` returns a vector of the same length as `y` +#' `FilterWave` and `WaveEnvelope` return a vector of the same length as `y` #' ` #' @details -#' `FitWave` uses [fft] to make a fourier transform of the -#' data and then returns a list of parameters for each wave number kept. +#' `FitWave` performs a fourier transform of the input vector +#' and returns a list of parameters for each wave number kept. #' The amplitude (A), phase (\eqn{\phi}) and wave number (k) satisfy: #' \deqn{y = \sum A cos((x - \phi)k)} #' The phase is calculated so that it lies between 0 and \eqn{2\pi/k} so it @@ -56,6 +57,31 @@ #' @examples #' \dontshow{data.table::setDTthreads(1)} #' +#' # Build a wave with specific wavenumber profile +#' waves <- list(k = 1:10, +#' amplitude = rnorm(10)^2, +#' phase = runif(10, 0, 2*pi/(1:10))) +#' x <- BuildWave(seq(0, 2*pi, length.out = 60)[-1], wave = waves) +#' +#' # Just fancy FFT +#' FitWave(x, k = 1:10) +#' +#' # Extract only specific wave components +#' plot(FilterWave(x, 1), type = "l") +#' plot(FilterWave(x, 2), type = "l") +#' plot(FilterWave(x, 1:4), type = "l") +#' +#' # Remove components from the signal +#' plot(FilterWave(x, -4:-1), type = "l") +#' +#' # The sum of the two above is the original signal (minus floating point errors) +#' all.equal(x, FilterWave(x, 1:4) + FilterWave(x, -4:-1)) +#' +#' # The Wave envelopes shows where the signal is the most "wavy". +#' plot(x, type = "l", col = "grey") +#' lines(WaveEnvelope(x), add = TRUE) +#' +#' # Examples with real data #' data(geopotential) #' library(data.table) #' # January mean of geopotential height diff --git a/man/waves.Rd b/man/waves.Rd index 1f223aa3..34977c46 100644 --- a/man/waves.Rd +++ b/man/waves.Rd @@ -6,7 +6,7 @@ \alias{BuildWave} \alias{FilterWave} \alias{WaveEnvelope} -\title{Fourier transform} +\title{Fourier transform functions} \usage{ FitWave(y, k = 1) @@ -57,15 +57,16 @@ vector if \code{sum} is \code{TRUE} or, instead, a list with components \item{y}{the reconstructed signal of each wavenumber} } -\code{FilterWave} returns a vector of the same length as \code{y} +\code{FilterWave} and \code{WaveEnvelope} return a vector of the same length as \code{y} ` } \description{ -Perform a fourier transform of the data and return the +Use \code{\link[=fft]{fft()}} to fit, filter and reconstruct signals in the frequency domain, as +well as to compute the wave envelope. } \details{ -\code{FitWave} uses \link{fft} to make a fourier transform of the -data and then returns a list of parameters for each wave number kept. +\code{FitWave} performs a fourier transform of the input vector +and returns a list of parameters for each wave number kept. The amplitude (A), phase (\eqn{\phi}) and wave number (k) satisfy: \deqn{y = \sum A cos((x - \phi)k)} The phase is calculated so that it lies between 0 and \eqn{2\pi/k} so it @@ -89,6 +90,31 @@ the envelope of only a restricted band, first filter it with \code{FilterWave}. \examples{ \dontshow{data.table::setDTthreads(1)} +# Build a wave with specific wavenumbers +waves <- list(k = 1:10, + amplitude = rnorm(10)^2, + phase = runif(10, 0, 2*pi/(1:10))) +x <- BuildWave(seq(0, 2*pi, length.out = 60)[-1], wave = waves) + +# Just fancy FFT +FitWave(x, k = 1:10) + +# Extract only specific wave components +plot(FilterWave(x, 1), type = "l") +plot(FilterWave(x, 2), type = "l") +plot(FilterWave(x, 1:4), type = "l") + +# Remove components from the signal +plot(FilterWave(x, -4:-1), type = "l") + +# The sum of the two above is the original signal (minus floating point errors) +all.equal(x, FilterWave(x, 1:4) + FilterWave(x, -4:-1)) + +# The Wave envelopes shows where the signal is the most "wavy". +plot(x, type = "l", col = "grey") +lines(WaveEnvelope(x), add = TRUE) + +# Examples with real data data(geopotential) library(data.table) # January mean of geopotential height