Я несу в несоответствующем результате в реализации Surge функции DFT; Я использую реализацию Surge, которая кажется мне простой.Результат DFT с использованием vDSP от Swift от реального значения входа (реализация всплеска)
Когда я вычислить величины для фиктивных данных я получаю:
var xx = [1.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]
{0,6, 0,082842712474619, 0,2, 0,482842712474619, 0,2, 0,482842712474619, 0,2, 0,082842712474619, 0,0, 0,2}
Который как раз кажется неправильным следуя «если он реальный в одном домене, он сопряжен симметрично в другом»
Когда я делаю то же самое:
В Mathematica:
x = {1., 0., 1., 0., 0., 1., 0., 0., 0., 1.}
Norm /@ Fourier[x, FourierParameters -> {-1, 1}]
{0,4, 0,117557, 0,154336, 0,190211, 0,214896, 0, 0,214896, 0,190211, 0,154336 , 0,117557}
В R:
x = c(1,0,1,0,0,1,0,0,0,1)
abs(fft(x)/length(x))
"0,400000" "0,117557" "0,154336" "0,190211" "0,214896" "0,000000" "0,214896" "0,190211" "0.154336" "0.117557"
Также с помощью JTransforms:
double[] x = { 1., 0., 1., 0., 0., 1., 0., 0., 0., 1. };
double[] output = new double[x.length];
DoubleFFT_1D fftDo = new DoubleFFT_1D(x.length);
double[] fft = new double[x.length * 2];
System.arraycopy(x, 0, fft, 0, x.length);
fftDo.realForwardFull(fft);
0,4 0,11755705045849463 0,1543361918426817 0,19021130325903074 0,21489611417496346 0,0 0,21489611417496346 0,19021130325903074 0,1543361918426817 0,11755705045849463
Свифт реализация в нагон:
public func fft(_ input: [Double]) -> [Double] {
var real = [Double](input)
var imaginary = [Double](repeating: 0.0, count: input.count)
var splitComplex = DSPDoubleSplitComplex(realp: &real, imagp: &imaginary)
let length = vDSP_Length(floor(log2(Float(input.count))))
let radix = FFTRadix(kFFTRadix2)
let weights = vDSP_create_fftsetupD(length, radix)
vDSP_fft_zipD(weights!, &splitComplex, 1, length, FFTDirection(FFT_FORWARD))
var magnitudes = [Double](repeating: 0.0, count: input.count)
vDSP_zvmagsD(&splitComplex, 1, &magnitudes, 1, vDSP_Length(input.count))
var normalizedMagnitudes = [Double](repeating: 0.0, count: input.count)
vDSP_vsmulD(sqrt(magnitudes), 1, [2.0/Double(input.count)], &normalizedMagnitudes, 1, vDSP_Length(input.count))
vDSP_destroy_fftsetupD(weights)
return normalizedMagnitudes
}
Я пропускаю что-то очевидное?
Спасибо
Похоже, ваш код Swift/vDSP предполагает длину, равную 2. Попробуйте работать с N = 16 вместо N = 10. –
Это действительно продвижение, спасибо! Результат равен двум. Но что, если я хочу какую-то произвольную длину ввода? –
Многие реализации FFT поддерживают только мощности 2 длины - когда вам нужно использовать другой размер, тогда типичный метод состоит в том, чтобы набивать ваши входные данные нулями до следующего значения 2. Это дает достоверные результаты, хотя данные в частотной области эффективно интерполируется по большему количеству точек. –