Swift中的DFT结果与MATLAB的结果不同 [英] DFT result in Swift is different than that of MATLAB

查看:86
本文介绍了Swift中的DFT结果与MATLAB的结果不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

import Cocoa
import Accelerate

let filePath = Bundle.main.path(forResource: "sinusoid", ofType: "txt")
let contentData = FileManager.default.contents(atPath: filePath!)
var content = NSString(data: contentData!, encoding: String.Encoding.utf8.rawValue) as? String

var idx = content?.characters.index(of: "\n")
idx = content?.index(after: idx!)

repeat {
    //let fromIndex = index(from: )
    content = content?.substring(from: idx!)
    idx = content?.characters.index(of: "\n")
    idx = content?.index(after: idx!)
} while content!.characters.contains("%")

let regex = try? NSRegularExpression(pattern: "[ ]+", options:[])

let delimiter = ","
var modifiedString = regex?.stringByReplacingMatches(in: content!, options: [], range: NSRange(location: 0, length: (content! as NSString).length), withTemplate: delimiter)

let lines = modifiedString?.components(separatedBy: "\n")

var s = [Double]()

for var line in lines! {
    if !line.isEmpty {
        let data = line.components(separatedBy: ",")
        s.append(Double(data[1])!)
    }
}

let length = vDSP_Length(pow(2, floor(log2(Float(s.count)))))
let L = Int(length)

// zrop or zop? 
// zrop covers real to complex, and zop covers complex
// length must be a power of 2 or specific multiples of powers of 2 if size is at least 4
let setup = vDSP_DFT_zrop_CreateSetupD(nil, length, vDSP_DFT_Direction.FORWARD)

var inputReal = UnsafeMutablePointer<Double>.allocate(capacity: L)
var inputImaginary = UnsafeMutablePointer<Double>.allocate(capacity: L)
var outputReal = UnsafeMutablePointer<Double>.allocate(capacity: L)
var outputImaginary = UnsafeMutablePointer<Double>.allocate(capacity: L)

for i in 0..<L {
    inputReal[i] = s[i]
    inputImaginary[i] = 0.0
}

vDSP_DFT_ExecuteD(setup!, inputReal, inputImaginary, outputReal, outputImaginary)

for i in 0..<L {
    print("\(outputReal[i]) + \(outputImaginary[i])i")
}

输入文件"sinusoid.txt"在以下链接中 https://dpaste.de/M1VD

The input file "sinusoid.txt" is in the following link https://dpaste.de/M1VD

输入文件数据由频率为50和120的两个正弦波组成.Matlab代码可产生以下链接中给出的正确输出:

The input file data consists of two sine waves at frequencies of 50 and 120. The Matlab code produces the correct output given in the following link:

https://dpaste.de/2mdK

对Matlab的结果进行比例缩放并取其幅度时,可以正确地显示频率为50时的振幅为0.7,频率为120时的振幅为1.

When the result from Matlab is scaled and the magnitude is taken, it correctly shows that the amplitude at a frequency of 50 is 0.7 and the amplitude at a frequency of 120 is 1.

clear all; close all; clc;
data = load('sinusoid.txt');
S = data(:,2);
Fs = 1000;
Y = fft(S);
L = length(S);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
plot(f,P1)
title('Single-Sided Amplitude Spectrum of X(t)')
xlabel('f (Hz)')
ylabel('|P1(f)|')

与Matlab输出相比,Swift代码输出完全不同且无法识别,无论应用了什么比例因子以及是否应用了实数到复杂或复杂到复杂的转换:

The Swift code output is entirely different and unrecognizable when compared to the Matlab output, regardless of whatever scaling factors are applied and whether or not a real-to-complex or complex-to-complex transformation is applied:

https://dpaste.de/MUwB

有什么想法吗?

推荐答案

您的2个FFT的长度是不同的,因此,结果当然是不匹配的.您还将向2个FFT传递不同数量的数据.

The lengths of your 2 FFT are different, and so, of course the results won't match. You are also passing different amounts of data to your 2 FFTs.

打印出FFT长度和输入数据向量以调试代码.比较结果之前,请确保输入匹配.

Print out the FFT lengths and the input data vector to debug your code. Make sure the inputs match before comparing results.

此外,Apple的Accelerate/vDSP FFT可以使用长度而不是2的幂(也可以使用3或5的​​因子).

Also, Apple's Accelerate/vDSP FFTs can use lengths other than just powers of 2 (lengths with factors of 3 or 5 are also allowed).

另外,请注意,Matlab索引的数组从1开始,而不是0,这在C和Swift函数中更为常见.

Also, note that Matlab indexes arrays starting at 1, not 0, as is more typical in C and Swift functions.

这篇关于Swift中的DFT结果与MATLAB的结果不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆