% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pwelch.R
\name{pwelch}
\alias{pwelch}
\alias{plot.pwelch}
\alias{print.pwelch}
\title{Welch’s power spectral density estimate}
\usage{
pwelch(
  x,
  window = nextpow2(sqrt(NROW(x))),
  overlap = 0.5,
  nfft = if (isScalar(window)) window else length(window),
  fs = 1,
  detrend = c("long-mean", "short-mean", "long-linear", "short-linear", "none"),
  range = if (is.numeric(x)) "half" else "whole"
)

\method{plot}{pwelch}(
  x,
  xlab = NULL,
  ylab = NULL,
  main = NULL,
  plot.type = c("spectrum", "cross-spectrum", "phase", "coherence", "transfer"),
  yscale = c("linear", "log", "dB"),
  ...
)

\method{print}{pwelch}(
  x,
  plot.type = c("spectrum", "cross-spectrum", "phase", "coherence", "transfer"),
  yscale = c("linear", "log", "dB"),
  xlab = NULL,
  ylab = NULL,
  main = NULL,
  ...
)
}
\arguments{
\item{x}{input data, specified as a numeric vector or matrix. In case of a
vector it represents a single signal; in case of a matrix each column is a
signal.}

\item{window}{If \code{window} is a vector, each segment has the same length
as \code{window} and is multiplied by \code{window} before (optional)
zero-padding and calculation of its periodogram. If \code{window} is a
scalar, each segment has a length of \code{window} and a Hamming window is
used. Default: \code{nextpow2(sqrt(length(x)))} (the square root of the
length of \code{x} rounded up to the next power of two). The window length
must be larger than 3.}

\item{overlap}{segment overlap, specified as a numeric value expressed as a
multiple of window or segment length. 0 <= overlap < 1. Default: 0.5.}

\item{nfft}{Length of FFT, specified as an integer scalar. The default is the
length of the \code{window} vector or has the same value as the scalar
\code{window} argument.  If \code{nfft} is larger than the segment length,
(seg_len), the data segment is padded \code{nfft - seg_len} zeros. The
default is no padding. Nfft values smaller than the length of the data
segment (or window) are ignored. Note that the use of padding to increase
the frequency resolution of the spectral estimate is controversial.}

\item{fs}{sampling frequency (Hertz), specified as a positive scalar.
Default: 1.}

\item{detrend}{character string specifying detrending option; one of:
 \describe{
   \item{\code{long-mean}}{remove the mean from the data before
   splitting into segments (default)}
   \item{\code{short-mean}}{remove the mean value of each segment}
   \item{\code{long-linear}}{remove linear trend from the data before
   splitting into segments}
   \item{\code{short-linear}}{remove linear trend from each segment}
   \item{\code{none}}{no detrending}
}}

\item{range}{character string. one of:
\describe{
  \item{\code{"half"} or \code{"onesided"}}{frequency range of the spectrum
  is from zero up to but not including \code{fs / 2}. Power from negative
  frequencies is added to the positive side of the spectrum.}
  \item{\code{"whole"} or \code{"twosided"}}{frequency range of the spectrum
  is \code{-fs / 2} to \code{fs / 2}, with negative frequencies stored in
  "wrap around order" after the positive frequencies; e.g. frequencies for a
  10-point \code{"twosided"} spectrum are 0 0.1 0.2 0.3 0.4 0.5 -0.4 -0.3
  -0.2. -0.1.}
  \item{\code{"shift"} or \code{"centerdc"}}{same as \code{"whole"} but with
  the first half of the spectrum swapped with second half to put the
  zero-frequency value in the middle.}
}
  Default: If \code{x} are real, the default range is \code{"half"},
  otherwise the default range is \code{"whole"}.}

\item{xlab, ylab, main}{labels passed to plotting function. Default: NULL}

\item{plot.type}{character string specifying which plot to produce; one of
\code{"spectrum"}, \code{"cross-spectrum"}, \code{"phase"},
\code{"coherence"}, \code{"transfer"}}

\item{yscale}{character string specifying scaling of Y-axis; one of
\code{"linear"}, \code{"log"}, \code{"dB"}}

\item{...}{additional arguments passed to functions}
}
\value{
An object of class \code{"pwelch"}, which is a list containing the
  following elements:
  \describe{
    \item{\code{freq}}{vector of frequencies at which the spectral variables
    are estimated. If \code{x} is numeric, power from negative frequencies is
    added to the positive side of the spectrum, but not at zero or Nyquist
    (fs/2) frequencies. This keeps power equal in time and spectral domains.
    If \code{x} is complex, then the whole frequency range is returned.}
    \item{\code{spec}}{Vector (for univariate series) or matrix (for
    multivariate series) of estimates of the spectral density at frequencies
    corresponding to freq.}
    \item{\code{cross}}{NULL for univariate series. For multivariateseries, a
    matrix containing the cross-spectral density estimates between different
    series. Column \eqn{i + (j - 1) * (j - 2)/2 } of contains the
    cross-spectral estimates between columns \eqn{i} and \eqn{j} of \eqn{x},
    where \eqn{i < j}.}
    \item{\code{phase}}{NULL for univariate series. For multivariate series,
    a matrix containing the cross-spectrum phase between different series.
    The format is the same as \code{cross}.}
    \item{\code{coh}}{NULL for univariate series. For multivariate series, a
    matrix containing the squared coherence between different series. The
    format is the same as \code{cross}.}
    \item{\code{trans}}{NULL for univariate series. For multivariate series,
    a matrix containing estimates of the transfer function between different
    series. The format is the same as \code{cross}.}
    \item{\code{x_len}}{The length of the input series.}
    \item{\code{seg_len}}{The length of each segment making up the averages.}
    \item{\code{psd_len}}{The number of frequencies. See \code{freq}}
    \item{\code{nseries}}{The number of series}
    \item{\code{series}}{The name of the series}
    \item{\code{snames}}{For multivariate input, the names of the individual
    series}
    \item{\code{window}}{The window used to compute the modified periodogram}
    \item{\code{fs}}{The sampling frequency}
    \item{\code{detrend}}{Character string specifying detrending option}
  }
}
\description{
Compute power spectral density (PSD) using Welch's method.
}
\details{
The Welch method [1] reduces the variance of the periodogram estimate to the
PSD by splitting the signal into (usually) overlapping segments and windowing
each segment, for instance by a Hamming window. The periodogram is then
computed for each segment, and the squared magnitude is computed, which is
then averaged for all segments. See also [2].

The spectral density is the mean of the modified periodograms, scaled so that
area under the spectrum is the same as the mean square of the data.  This
equivalence is supposed to be exact, but in practice there is a mismatch of
up to 0.5% when comparing area under a periodogram with the mean square of
the data.

In case of multivariate signals, Cross-spectral density, phase, and coherence
are also returned. The input data can be demeaned or detrended, overall or
for each segment separately.
}
\note{
Unlike the 'Octave' function 'pwelch', the current implementation
  does not compute confidence intervals because they can be inaccurate in
  case of overlapping segments.
}
\examples{
fs <- 256
secs <- 10
freq <- 30
ampl <- 1
t <- seq(0, secs, length.out = fs * secs)

x <- ampl * cos(freq * 2 * pi * t) + runif(length(t))
Pxx <- pwelch(x, fs = fs)              # no plot
pwelch(x, fs = fs)                     # plot

# 90 degrees phase shift with with respect to x
y <- ampl * sin(freq * 2 * pi * t) + runif(length(t))
Pxy <- pwelch(cbind(x, y), fs = fs)
plot(Pxy, yscale = "dB")
plot(Pxy, plot.type = "phase")
# note the phase shift around 30 Hz is pi/2
plot(Pxy, plot.type = "coherence")

# Transfer function estimate example
fs <- 1000                 # Sampling frequency
t <- (0:fs) / fs           # One second worth of samples
A <- c(1, 2)               # Sinusoid amplitudes
f <- c(150, 140)           # Sinusoid frequencies
xn <- A[1] * sin(2 * pi * f[1] * t) +
      A[2] * sin(2 * pi * f[2] * t) +  0.1 * runif(length(t))
h <- Ma(rep(1L, 10) / 10)      # Moving average filter
yn <- filter(h, xn)
atfm <- freqz(h, fs = fs)
etfm <- pwelch(cbind(xn, yn), fs = fs)
op <- par(mfrow = c(2, 1))
xl <- "Frequency (Hz)"; yl <- "Magnitude"
plot(atfm$w, abs(atfm$h), type = "l", main = "Actual", xlab = xl, ylab = yl)
plot(etfm$freq, abs(etfm$trans), type = "l", main = "Estimated",
     xlab = xl, ylab = yl)
par(op)

}
\references{
[1] Welch, P.D. (1967). The use of Fast Fourier Transform for
  the estimation of power spectra: A method based on time averaging over
  short, modified periodograms. IEEE Transactions on Audio and
  Electroacoustics, AU-15 (2): 70–73.\cr

[2] \url{https://en.wikipedia.org/wiki/Welch\%27s_method}
}
\author{
Peter V. Lanspeary \email{pvl@mecheng.adelaide.edu.au}.\cr
Conversion to R by Geert van Boxtel, \email{G.J.M.vanBoxtel@gmail.com}.
}
