mirror of
https://github.com/jkl1337/SwiftPFFFT.git
synced 2026-01-02 11:44:36 -06:00
Rename buffer mapInPlace to enumerateInPlace.
Document and simplify some methods.
This commit is contained in:
5
.sourcekit-lsp/config.json
Normal file
5
.sourcekit-lsp/config.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"swiftPM": {
|
||||||
|
"cCompilerFlags:" ["-DPFFFT_SCALVEC_ENABLED=1", "-DPFFFT_ENABLE_NEON", "_USE_MATH_DEFINES", "NDEBUG"],
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ performance with much simpler usage and a permissive 3 clause BSD license.
|
|||||||
let fft = try FFT<Complex<Float>>(n: 16)
|
let fft = try FFT<Complex<Float>>(n: 16)
|
||||||
let signal = fft.makeSignalBuffer()
|
let signal = fft.makeSignalBuffer()
|
||||||
|
|
||||||
signal.mapInPlace { (i, v) in
|
signal.enumerateInPlace { (i, v) in
|
||||||
v = Complex(Float(i) + 1.0, Float(i) - 2.0)
|
v = Complex(Float(i) + 1.0, Float(i) - 2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import RealModule
|
|||||||
|
|
||||||
let bufferAlignment = 32
|
let bufferAlignment = 32
|
||||||
|
|
||||||
|
/// Thin wrapper around `UnsafeMutableBufferPointer` providing correct alignment.
|
||||||
|
/// PFFFT internally assumes all buffers passed are aligned to 16 or 32 bytes
|
||||||
|
/// depending on the platform. Thie type provides correctly aligned buffers
|
||||||
|
/// and provides some in place mutating methods.
|
||||||
@frozen
|
@frozen
|
||||||
public struct Buffer<T>: ~Copyable {
|
public struct Buffer<T>: ~Copyable {
|
||||||
public let buffer: UnsafeMutableBufferPointer<T>
|
public let buffer: UnsafeMutableBufferPointer<T>
|
||||||
@@ -32,11 +36,19 @@ public struct Buffer<T>: ~Copyable {
|
|||||||
try body(UnsafeMutableRawBufferPointer(buffer))
|
try body(UnsafeMutableRawBufferPointer(buffer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return an array with results of mapping given closure over buffer elements.
|
||||||
|
/// - Parameter transform: A mapping closure. `transform` accepts an element of the buffer
|
||||||
|
/// as its parameter and returns a transformed value of any type.
|
||||||
|
/// - Returns: An array containing the transformed elements of the buffer.
|
||||||
@inlinable public func map<U>(_ transform: (T) throws -> U) rethrows -> [U] {
|
@inlinable public func map<U>(_ transform: (T) throws -> U) rethrows -> [U] {
|
||||||
try buffer.map(transform)
|
try buffer.map(transform)
|
||||||
}
|
}
|
||||||
|
|
||||||
@inlinable public func mapInPlace(_ body: (Int, inout T) throws -> Void) rethrows {
|
/// Calls the given closure on each element in the buffer for mutation in place.
|
||||||
|
/// - Parameter body: A closure that accepts a zero-based index and mutable element of the
|
||||||
|
/// buffer as a parameter. `body` may throw and the error will be propagated to the
|
||||||
|
/// caller. Any return value of the closure is discarded.
|
||||||
|
@inlinable public func enumerateInPlace(_ body: (Int, inout T) throws -> Void) rethrows {
|
||||||
for i in 0 ..< buffer.count {
|
for i in 0 ..< buffer.count {
|
||||||
try body(i, &buffer[i])
|
try body(i, &buffer[i])
|
||||||
}
|
}
|
||||||
@@ -52,7 +64,21 @@ public protocol ComplexType {
|
|||||||
extension Complex: ComplexType {}
|
extension Complex: ComplexType {}
|
||||||
|
|
||||||
public extension Buffer where T: ComplexType {
|
public extension Buffer where T: ComplexType {
|
||||||
@inlinable func mapInPlaceSwapLast(_ body: (Int, inout T) throws -> Void) rethrows {
|
/// Calls the given closure on each element in the buffer for mutation in place with
|
||||||
|
/// Nyquist replacement at the end.
|
||||||
|
///
|
||||||
|
/// When operating on Complex->Real transforms PFFFT internally uses a slightly more compact
|
||||||
|
/// but less common encoding of the DC (0) and Nyquist (n/2) components. Since these two
|
||||||
|
/// spectral components are always real, PFFFT places the DC (0) component
|
||||||
|
/// in the real part of the 0th element as expected, but places the Nyquist `(n/2)` component
|
||||||
|
/// in the imaginary part of the 0th element.
|
||||||
|
/// This enumerator works like `enumerateInPlace` but at the end places the real part of the
|
||||||
|
/// n/2 component into the imaginary part of the 0th element. In normal use it is expected
|
||||||
|
/// that a spectral buffer of 1 extra element is created suct that `count == (n/2 + 1)`.
|
||||||
|
/// - Parameter body: A closure that accepts a zero-based index and mutable element of the
|
||||||
|
/// buffer as a parameter. `body` may throw and the error will be propagated to the
|
||||||
|
/// caller. Any return value of the closure is discarded.
|
||||||
|
@inlinable func enumerateInPlaceSwapLast(_ body: (Int, inout T) throws -> Void) rethrows {
|
||||||
for i in 0 ..< buffer.count {
|
for i in 0 ..< buffer.count {
|
||||||
try body(i, &buffer[i])
|
try body(i, &buffer[i])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import ComplexModule
|
|||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
final class FFTTests: XCTestCase {
|
final class FFTTests: XCTestCase {
|
||||||
func testFftFloat() throws {
|
func testFftComplexFloat() throws {
|
||||||
let fft = try FFT<Complex<Float>>(n: 16)
|
let fft = try FFT<Complex<Float>>(n: 16)
|
||||||
let signal = fft.makeSignalBuffer()
|
let signal = fft.makeSignalBuffer()
|
||||||
let spectrum = fft.makeSpectrumBuffer()
|
let spectrum = fft.makeSpectrumBuffer()
|
||||||
|
|
||||||
signal.mapInPlace { i, v in
|
signal.enumerateInPlace { i, v in
|
||||||
v = Complex(Float(i) + 1.0, Float(i) - 2.0)
|
v = Complex(Float(i) + 1.0, Float(i) - 2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user