Están fuertemente relacionados. Su ejemplo no es reproducible porque no incluyó sus datos, por lo que haré uno nuevo. En primer lugar, creemos una función periódica:
T <- 10
omega <- 2*pi/T
N <- 21
x <- seq(0, T, len = N)
sum_sines_cosines <- function(x, omega){
sin(omega*x)+2*cos(2*omega*x)+3*sin(4*omega*x)+4*cos(4*omega*x)
}
Yper <- sum_sines_cosines(x, omega)
Yper[N]-Yper[1] # numerically 0
x2 <- seq(0, T, len = 1000)
Yper2 <- sum_sines_cosines(x2, omega)
plot(x2, Yper2, col = "red", type = "l", xlab = "x", ylab = "Y")
points(x, Yper)
N=2k+1N−2N−3=2(k−1)k ωnorte= 3k = 1. De todos modos, si quieres comprobarlo, basta con cambiar N-2
a N
en el siguiente fragmento de código y vistazo a las últimas dos columnas: verá que en realidad son inútiles (y que crea problemas para el ajuste, debido a que la matriz de diseño ahora es singular )
# Fourier Regression with fda
library(fda)
mybasis <- create.fourier.basis(c(0,T),N-2)
basisMat <- eval.basis(x, mybasis)
FDA_regression <- lm(Yper ~ basisMat-1)
FDA_coef <-coef(FDA_regression)
barplot(FDA_coef)
Tenga en cuenta que las frecuencias son exactamente las correctas, pero las amplitudes de los componentes distintos de cero no lo son (1,2,3,4). La razón es que las fda
funciones básicas de Fourier se escalan de una manera extraña: su valor máximo no es 1, como sería para la base de Fourier habitual1 , pecadoω x ,cosω x ,.... No es1π√ tampoco, como habría sido para la base de Fourier ortonormal, 12 π√, el pecadoω xπ√, cosω xπ√, ....
# FDA basis has a weird scaling
max(abs(basisMat))
plot(mybasis)
Usted ve claramente que:
- el valor máximo es menor que 1π√
- la base de Fourier (truncada a la primera norte- 2 términos) contiene una función constante (la línea negra), senos de frecuencia creciente (las curvas que son iguales a 0 en los límites del dominio) y cosenos de frecuencia creciente (las curvas que son iguales a 1 en los límites del dominio), ya que debiera ser
Simplemente escalar la base de Fourier dada por fda
, para que se obtenga la base de Fourier habitual, conduce a coeficientes de regresión que tienen los valores esperados:
basisMat <- basisMat/max(abs(basisMat))
FDA_regression <- lm(Yper ~ basisMat-1)
FDA_coef <-coef(FDA_regression)
barplot(FDA_coef, names.arg = colnames(basisMat), main = "rescaled FDA coefficients")
Probemos fft
ahora: tenga en cuenta que, dado que Yper
es una secuencia periódica, el último punto realmente no agrega ninguna información (el DFT de una secuencia siempre es periódico). Por lo tanto, podemos descartar el último punto al calcular la FFT. Además, el FFT es solo un algoritmo numérico rápido para calcular el DFT, y el DFT de una secuencia de números reales o complejos es complejo . Por lo tanto, realmente queremos los módulos de los coeficientes FFT:
# FFT
fft_coef <- Mod(fft(Yper[1:(N-1)]))*2/(N-1)
Multiplicamos por 2norte- 1 para tener la misma escala que con la base de Fourier 1 , pecadoω x ,cosω x ,.... Si no escalamos, aún recuperaríamos las frecuencias correctas, pero todas las amplitudes serían escaladas por el mismo factor con respecto a lo que encontramos antes. Tracemos ahora los coeficientes fft:
fft_coef <- fft_coef[1:((N-1)/2)]
terms <- paste0("exp",seq(0,(N-1)/2-1))
barplot(fft_coef, names.arg = terms, main = "FFT coefficients")
Ok: las frecuencias son correctas, pero tenga en cuenta que ahora las funciones básicas ya no son senos y cosenos (son exponenciales complejos Expn i ω x, donde con yoDenote la unidad imaginaria). Tenga en cuenta también que en lugar de un conjunto de frecuencias distintas de cero (1,2,3,4) como antes, obtuvimos un conjunto (1,2,5). La razón es que un términoXnorteExpn i ω x en este complejo coeficiente de expansión (por lo tanto Xnorte es complejo) corresponde a dos términos reales unnortes i n ( n ω x ) + bnortec o s ( n ω x ) en la expansión de la base trigonométrica, debido a la fórmula de Euler Expi x =cosx +isinX. The modulus of the complex coefficient is equal to the sum in quadrature of the two real coefficients, i.e., |xn|=a2n+b2n−−−−−−√. As a matter of fact, 5=33+42−−−−−−√.