Rename buffer mapInPlace to enumerateInPlace.

Document and simplify some methods.
This commit is contained in:
2024-10-31 02:33:14 -05:00
parent 2ffe635962
commit 795003432e
4 changed files with 36 additions and 5 deletions

View File

@@ -0,0 +1,5 @@
{
"swiftPM": {
"cCompilerFlags:" ["-DPFFFT_SCALVEC_ENABLED=1", "-DPFFFT_ENABLE_NEON", "_USE_MATH_DEFINES", "NDEBUG"],
}
}

View File

@@ -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 signal = fft.makeSignalBuffer()
signal.mapInPlace { (i, v) in
signal.enumerateInPlace { (i, v) in
v = Complex(Float(i) + 1.0, Float(i) - 2.0)
}

View File

@@ -3,6 +3,10 @@ import RealModule
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
public struct Buffer<T>: ~Copyable {
public let buffer: UnsafeMutableBufferPointer<T>
@@ -32,11 +36,19 @@ public struct Buffer<T>: ~Copyable {
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] {
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 {
try body(i, &buffer[i])
}
@@ -52,7 +64,21 @@ public protocol ComplexType {
extension Complex: 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 {
try body(i, &buffer[i])
}

View File

@@ -3,12 +3,12 @@ import ComplexModule
import XCTest
final class FFTTests: XCTestCase {
func testFftFloat() throws {
func testFftComplexFloat() throws {
let fft = try FFT<Complex<Float>>(n: 16)
let signal = fft.makeSignalBuffer()
let spectrum = fft.makeSpectrumBuffer()
signal.mapInPlace { i, v in
signal.enumerateInPlace { i, v in
v = Complex(Float(i) + 1.0, Float(i) - 2.0)
}