# Introduction

I was doing some thinking about how best to work with rotating spectra in R,
and wanted to drop all the way down to using `fft()`

instead of `spectrum()`

.
For a while, I was confused about some of the results, because the lengths of
spectra created with `fft`

were not what I expected. Then I saw that the
problem was that I was using the default value of `fast`

in the `spectrum()`

function. The content of this post illustrates this.

# Results and discussion

By default, the R `spectrum()`

function sets the argument `fast=TRUE`

. This
causes R to increase the speed of processing, but it also leads to spectrum
lengths that can be surprising.

The following illustrates how the length of spectra computed with `spectrum`

vary from the expected value of `floor(length(data)/2)`

.

1
2
3
4
5
6
7
8
9
10
11
12
13

## below shows that spectrum() does some tricky things
par(mfrow=c(2, 1), mar=c(3, 3, 1, 1), mgp=c(2, 0.7, 0))
set.seed(123)
x <- 12:200
## fast=TRUE is the default
speclenT <- unlist(lapply(x, function(n) length(spec.pgram(rnorm(n),plot=FALSE,fast=TRUE)$freq)))
plot(x, speclenT, type="s", xlab="x length", ylab="spectrum length")
legend("topleft", lwd=par("lwd"), col=1:2, legend=c("spectrum() with fast=TRUE", "2:1 line"))
abline(0, 1/2, col=2)
speclenF <- unlist(lapply(x, function(n) length(spec.pgram(rnorm(n),plot=FALSE,fast=FALSE)$freq)))
plot(x, speclenF, type="s", xlab="x length", ylab="spectrum length")
legend("topleft", lwd=par("lwd"), col=1:2, legend=c("spectrum() with fast=FALSE", "2:1 line"))
abline(0, 1/2, col=2)

1

print(head(speclenT))

1

print(head(speclenF))

1

all.equal(speclenF, floor(x/2))

# Conclusion

If the results of `spectrum`

and `fft`

are to be put on an equal footing, e.g. for numerical
comparisons, then it makes sense to call the former as e.g. `spectrum(..., fast=FALSE)`

.

# Reference and resources

- Jekyll source code for this blog entry: 2017-12-21-spectrum-length.Rmd