mirror of
https://github.com/jkl1337/SwiftPFFFT.git
synced 2026-01-02 03:34:31 -06:00
Attempt Swift 5.9 compatibility.
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"originHash" : "d50b9049eb671b1ad14bc8ba592c78735f9e357a6b59835343af6e20e8be4701",
|
|
||||||
"pins" : [
|
"pins" : [
|
||||||
{
|
{
|
||||||
"identity" : "swift-numerics",
|
"identity" : "swift-numerics",
|
||||||
@@ -11,5 +10,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version" : 3
|
"version" : 2
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// swift-tools-version: 6.0
|
// swift-tools-version: 5.9
|
||||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||||
|
|
||||||
import PackageDescription
|
import PackageDescription
|
||||||
@@ -22,12 +22,12 @@ let package = Package(
|
|||||||
.define("PFFFT_SCALVEC_ENABLED", to: "1"),
|
.define("PFFFT_SCALVEC_ENABLED", to: "1"),
|
||||||
.define("_USE_MATH_DEFINES"),
|
.define("_USE_MATH_DEFINES"),
|
||||||
.define("NDEBUG"),
|
.define("NDEBUG"),
|
||||||
.unsafeFlags(["-O3"]),
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
.target(
|
.target(
|
||||||
name: "PFFFT",
|
name: "PFFFT",
|
||||||
dependencies: ["PFFFTLib", .product(name: "Numerics", package: "swift-numerics")]
|
dependencies: ["PFFFTLib", .product(name: "Numerics", package: "swift-numerics")],
|
||||||
|
swiftSettings: [.enableExperimentalFeature("AccessLevelOnImport")]
|
||||||
),
|
),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "PFFFTTests",
|
name: "PFFFTTests",
|
||||||
|
|||||||
@@ -159,14 +159,20 @@ public struct FFT<T: FFTElement>: ~Copyable {
|
|||||||
|
|
||||||
let ptr: OpaquePointer
|
let ptr: OpaquePointer
|
||||||
let n: Int
|
let n: Int
|
||||||
let work: Buffer<ScalarType>?
|
let work: Buffer<ScalarType>
|
||||||
let setup: Setup
|
let setup: Setup
|
||||||
|
|
||||||
public init(setup: Setup) {
|
public init(setup: Setup) {
|
||||||
self.setup = setup
|
self.setup = setup
|
||||||
ptr = setup.ptr
|
ptr = setup.ptr
|
||||||
n = setup.n
|
n = setup.n
|
||||||
work = n > 4096 ? Buffer<ScalarType>(capacity: T.self == ComplexType.self ? 2 * n : n) : nil
|
|
||||||
|
let workCapacity = if n > 4096 {
|
||||||
|
T.self == ComplexType.self ? 2 * n : n
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
work = Buffer(capacity: workCapacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the FFT implementation with the given size and type.
|
/// Initialize the FFT implementation with the given size and type.
|
||||||
@@ -202,10 +208,11 @@ public struct FFT<T: FFTElement>: ~Copyable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
func toAddress(_ work: borrowing Buffer<ScalarType>?) -> UnsafeMutablePointer<ScalarType>? {
|
var workPtr: UnsafeMutablePointer<ScalarType>? {
|
||||||
switch work {
|
if work.count > 0 {
|
||||||
case let .some(b): return b.baseAddress
|
return work.baseAddress
|
||||||
case .none: return nil
|
} else {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,12 +278,12 @@ public struct FFT<T: FFTElement>: ~Copyable {
|
|||||||
/// - sign: The direction of the FFT.
|
/// - sign: The direction of the FFT.
|
||||||
public func forward(signal: borrowing Buffer<T>, spectrum: borrowing Buffer<ComplexType>) {
|
public func forward(signal: borrowing Buffer<T>, spectrum: borrowing Buffer<ComplexType>) {
|
||||||
checkFftBufferCounts(signal: signal, spectrum: spectrum)
|
checkFftBufferCounts(signal: signal, spectrum: spectrum)
|
||||||
ScalarType.pffftTransformOrdered(ptr, rebind(signal), rebind(spectrum), toAddress(work), .forward)
|
ScalarType.pffftTransformOrdered(ptr, rebind(signal), rebind(spectrum), workPtr, .forward)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func inverse(spectrum: borrowing Buffer<ComplexType>, signal: borrowing Buffer<T>) {
|
public func inverse(spectrum: borrowing Buffer<ComplexType>, signal: borrowing Buffer<T>) {
|
||||||
checkFftBufferCounts(signal: signal, spectrum: spectrum)
|
checkFftBufferCounts(signal: signal, spectrum: spectrum)
|
||||||
ScalarType.pffftTransformOrdered(ptr, rebind(spectrum), rebind(signal), toAddress(work), .backward)
|
ScalarType.pffftTransformOrdered(ptr, rebind(spectrum), rebind(signal), workPtr, .backward)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a forward FFT on the input buffer, with implementation defined order.
|
/// Perform a forward FFT on the input buffer, with implementation defined order.
|
||||||
@@ -290,12 +297,12 @@ public struct FFT<T: FFTElement>: ~Copyable {
|
|||||||
/// - sign: The direction of the FFT.
|
/// - sign: The direction of the FFT.
|
||||||
public func forwardToInternalLayout(signal: borrowing Buffer<T>, spectrum: borrowing Buffer<ScalarType>) {
|
public func forwardToInternalLayout(signal: borrowing Buffer<T>, spectrum: borrowing Buffer<ScalarType>) {
|
||||||
checkFftInternalLayoutBufferCounts(signal: signal, spectrum: spectrum)
|
checkFftInternalLayoutBufferCounts(signal: signal, spectrum: spectrum)
|
||||||
ScalarType.pffftTransform(ptr, rebind(signal), spectrum.baseAddress, toAddress(work), .forward)
|
ScalarType.pffftTransform(ptr, rebind(signal), spectrum.baseAddress, workPtr, .forward)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func inverseFromInternalLayout(spectrum: borrowing Buffer<ScalarType>, signal: borrowing Buffer<T>) {
|
public func inverseFromInternalLayout(spectrum: borrowing Buffer<ScalarType>, signal: borrowing Buffer<T>) {
|
||||||
checkFftInternalLayoutBufferCounts(signal: signal, spectrum: spectrum)
|
checkFftInternalLayoutBufferCounts(signal: signal, spectrum: spectrum)
|
||||||
ScalarType.pffftTransform(ptr, spectrum.baseAddress, rebind(signal), toAddress(work), .backward)
|
ScalarType.pffftTransform(ptr, spectrum.baseAddress, rebind(signal), workPtr, .backward)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func reorder(spectrum: borrowing Buffer<ScalarType>, output: borrowing Buffer<ComplexType>) {
|
public func reorder(spectrum: borrowing Buffer<ScalarType>, output: borrowing Buffer<ComplexType>) {
|
||||||
|
|||||||
@@ -1,50 +1,51 @@
|
|||||||
import Testing
|
|
||||||
import ComplexModule
|
import ComplexModule
|
||||||
@testable import PFFFT
|
@testable import PFFFT
|
||||||
|
import XCTest
|
||||||
|
|
||||||
@Test func fftFloat() async throws {
|
final class FFTTests: XCTestCase {
|
||||||
|
func testFftFloat() throws {
|
||||||
|
let fft = try FFT<Complex<Float>>(n: 16)
|
||||||
|
let signal = fft.makeSignalBuffer()
|
||||||
|
let spectrum = fft.makeSpectrumBuffer()
|
||||||
|
|
||||||
let fft = try FFT<Complex<Float>>(n: 16)
|
signal.mapInPlace { i, v in
|
||||||
let signal = fft.makeSignalBuffer()
|
v = Complex(Float(i) + 1.0, Float(i) - 2.0)
|
||||||
let spectrum = fft.makeSpectrumBuffer()
|
}
|
||||||
|
|
||||||
signal.mutateEach { (i, v) in
|
fft.forward(signal: signal, spectrum: spectrum)
|
||||||
v = Complex(Float(i) + 1.0, Float(i) - 2.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fft.forward(signal: signal, spectrum: spectrum)
|
let result = spectrum.map { $0 }
|
||||||
|
let expected: [Complex<Float>] = [
|
||||||
|
.init(136.0, 88.0),
|
||||||
|
.init(-48.218716, 32.218716),
|
||||||
|
.init(-27.31371, 11.313708),
|
||||||
|
.init(-19.972847, 3.972846),
|
||||||
|
.init(-16.0, 0.0),
|
||||||
|
.init(-13.345428, -2.6545706),
|
||||||
|
.init(-11.313709, -4.6862917),
|
||||||
|
.init(-9.591298, -6.408703),
|
||||||
|
.init(-8.0, -8.0),
|
||||||
|
.init(-6.408703, -9.591298),
|
||||||
|
.init(-4.6862917, -11.313708),
|
||||||
|
.init(-2.6545706, -13.345429),
|
||||||
|
.init(0.0, -16.0),
|
||||||
|
.init(3.972845, -19.972847),
|
||||||
|
.init(11.313707, -27.31371),
|
||||||
|
.init(32.218716, -48.218716),
|
||||||
|
]
|
||||||
|
for (r, e) in zip(result, expected) {
|
||||||
|
XCTAssert(r.isApproximatelyEqual(to: e))
|
||||||
|
}
|
||||||
|
|
||||||
let result = spectrum.map { $0 }
|
fft.inverse(spectrum: spectrum, signal: signal)
|
||||||
let expected: [Complex<Float>] = [
|
|
||||||
.init(136.0, 88.0),
|
|
||||||
.init(-48.218716, 32.218716),
|
|
||||||
.init(-27.31371, 11.313708),
|
|
||||||
.init(-19.972847, 3.972846),
|
|
||||||
.init(-16.0, 0.0),
|
|
||||||
.init(-13.345428, -2.6545706),
|
|
||||||
.init(-11.313709, -4.6862917),
|
|
||||||
.init(-9.591298, -6.408703),
|
|
||||||
.init(-8.0, -8.0),
|
|
||||||
.init(-6.408703, -9.591298),
|
|
||||||
.init(-4.6862917, -11.313708),
|
|
||||||
.init(-2.6545706, -13.345429),
|
|
||||||
.init(0.0, -16.0),
|
|
||||||
.init(3.972845, -19.972847),
|
|
||||||
.init(11.313707, -27.31371),
|
|
||||||
.init(32.218716, -48.218716),
|
|
||||||
]
|
|
||||||
zip(result, expected).forEach { r, e in
|
|
||||||
#expect(r.isApproximatelyEqual(to: e))
|
|
||||||
}
|
|
||||||
|
|
||||||
fft.inverse(spectrum: spectrum, signal: signal)
|
let signalResult = signal.map { $0 }
|
||||||
|
let signalExpected = (0 ..< 16).map { i in
|
||||||
|
Complex(Float(i) + 1.0, Float(i) - 2.0) * 16
|
||||||
|
}
|
||||||
|
|
||||||
let signalResult = signal.map { $0 }
|
for (r, e) in zip(signalResult, signalExpected) {
|
||||||
let signalExpected = (0..<16).map { i in
|
XCTAssert(r.isApproximatelyEqual(to: e))
|
||||||
Complex(Float(i) + 1.0, Float(i) - 2.0) * 16
|
}
|
||||||
}
|
|
||||||
|
|
||||||
zip(signalResult, signalExpected).forEach { r, e in
|
|
||||||
#expect(r.isApproximatelyEqual(to: e))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user