Merge remote-tracking branch 'origin/accelerate-vDSP-linearInterpolation' into Accelerate_Swift-vDSP-Overlays

This commit is contained in:
Simon Gladman
2019-04-20 09:35:07 +01:00
3 changed files with 458 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ add_swift_target_library(swiftAccelerate ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES
ContiguousCollection.swift
vForce_Operations.swift
vDSP_SlidingWindow.swift
vDSP_Interpolation.swift
"${SWIFT_SOURCE_DIR}/stdlib/linker-support/magic-symbols-for-install-name.c"

View File

@@ -0,0 +1,312 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import Accelerate
extension vDSP {
/// Vector linear interpolation between vectors; single-precision.
///
/// - Parameter vectorA: The `A` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter vectorB: The `B` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter interpolationConstant: The `C` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Returns: The `D` in `D[n] = A[n] + C * (B[n] - A[n])`.
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
@inline(__always)
public static func linearInterpolate<T, U>(_ vectorA: T,
_ vectorB: U,
using interpolationConstant: Float) -> [Float]
where
T: _ContiguousCollection,
U: _ContiguousCollection,
T.Element == Float, U.Element == Float{
let result = Array<Float>(unsafeUninitializedCapacity: vectorA.count) {
buffer, initializedCount in
linearInterpolate(vectorA,
vectorB,
using: interpolationConstant,
result: &buffer)
initializedCount = vectorA.count
}
return result
}
/// Vector linear interpolation between vectors; single-precision.
///
/// - Parameter vectorA: The `A` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter vectorB: The `B` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter interpolationConstant: The `C` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter result: The `D` in `D[n] = A[n] + C * (B[n] - A[n])`.
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
@inline(__always)
public static func linearInterpolate<T, U, V>(_ vectorA: T,
_ vectorB: U,
using interpolationConstant: Float,
result: inout V)
where
T: _ContiguousCollection,
U: _ContiguousCollection,
V: _MutableContiguousCollection,
T.Element == Float, U.Element == Float, V.Element == Float {
precondition(vectorA.count == result.count)
precondition(vectorB.count == result.count)
let n = vDSP_Length(result.count)
vectorA.withUnsafeBufferPointer { a in
vectorB.withUnsafeBufferPointer { b in
result.withUnsafeMutableBufferPointer { dest in
vDSP_vintb(a.baseAddress!, 1,
b.baseAddress!, 1,
[interpolationConstant],
dest.baseAddress!, 1,
n)
}
}
}
}
/// Vector linear interpolation between vectors; double-precision.
///
/// - Parameter vectorA: The `A` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter vectorB: The `B` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter interpolationConstant: The `C` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Returns: The `D` in `D[n] = A[n] + C * (B[n] - A[n])`.
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
@inline(__always)
public static func linearInterpolate<T, U>(_ vectorA: T,
_ vectorB: U,
using interpolationConstant: Double) -> [Double]
where
T: _ContiguousCollection,
U: _ContiguousCollection,
T.Element == Double, U.Element == Double{
let result = Array<Double>(unsafeUninitializedCapacity: vectorA.count) {
buffer, initializedCount in
linearInterpolate(vectorA,
vectorB,
using: interpolationConstant,
result: &buffer)
initializedCount = vectorA.count
}
return result
}
/// Vector linear interpolation between vectors; double-precision.
///
/// - Parameter vectorA: The `A` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter vectorB: The `B` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter interpolationConstant: The `C` in `D[n] = A[n] + C * (B[n] - A[n])`.
/// - Parameter result: The `D` in `D[n] = A[n] + C * (B[n] - A[n])`.
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
@inline(__always)
public static func linearInterpolate<T, U, V>(_ vectorA: T,
_ vectorB: U,
using interpolationConstant: Double,
result: inout V)
where
T: _ContiguousCollection,
U: _ContiguousCollection,
V: _MutableContiguousCollection,
T.Element == Double, U.Element == Double, V.Element == Double {
precondition(vectorA.count == result.count)
precondition(vectorB.count == result.count)
let n = vDSP_Length(result.count)
vectorA.withUnsafeBufferPointer { a in
vectorB.withUnsafeBufferPointer { b in
result.withUnsafeMutableBufferPointer { dest in
vDSP_vintbD(a.baseAddress!, 1,
b.baseAddress!, 1,
[interpolationConstant],
dest.baseAddress!, 1,
n)
}
}
}
}
/// Vector linear interpolation between neighboring elements; single-precision.
///
/// This function interpolates between the elements of `vector` using the following:
///
/// for (n = 0; n < N; ++n) {
/// b = trunc(B[n]);
/// a = B[n] - b;
/// C[n] = A[b] + a * (A[b+1] - A[b]);
/// }
///
/// Where `A` is the input vector, `B` is the control vector, and
/// `C` is the output vector.
///
/// - Parameter vector: Input values.
/// - Parameter controlVector: Vector that controls interpolation.
/// - Returns: Output values.
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
@inline(__always)
public static func linearInterpolate<T, U>(elementsOf vector: T,
using controlVector: U) -> [Float]
where
T: _ContiguousCollection,
U: _ContiguousCollection,
T.Element == Float, U.Element == Float {
let result = Array<Float>(unsafeUninitializedCapacity: controlVector.count) {
buffer, initializedCount in
linearInterpolate(elementsOf: vector,
using: controlVector,
result: &buffer)
initializedCount = controlVector.count
}
return result
}
/// Vector linear interpolation between neighboring elements; single-precision.
///
/// This function interpolates between the elements of `vector` using the following:
///
/// for (n = 0; n < N; ++n) {
/// b = trunc(B[n]);
/// a = B[n] - b;
/// C[n] = A[b] + a * (A[b+1] - A[b]);
/// }
///
/// Where `A` is the input vector, `B` is the control vector, and
/// `C` is the output vector.
///
/// - Parameter vector: Input values.
/// - Parameter controlVector: Vector that controls interpolation.
/// - Parameter result: Output values.
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
@inline(__always)
public static func linearInterpolate<T, U, V>(elementsOf vector: T,
using controlVector: U,
result: inout V)
where
T: _ContiguousCollection,
U: _ContiguousCollection,
V: _MutableContiguousCollection,
T.Element == Float, U.Element == Float, V.Element == Float {
precondition(controlVector.count == result.count)
let n = vDSP_Length(result.count)
let m = vDSP_Length(vector.count)
vector.withUnsafeBufferPointer { a in
controlVector.withUnsafeBufferPointer { b in
result.withUnsafeMutableBufferPointer { dest in
vDSP_vlint(a.baseAddress!,
b.baseAddress!, 1,
dest.baseAddress!, 1,
n, m)
}
}
}
}
/// Vector linear interpolation between neighboring elements; double-precision.
///
/// This function interpolates between the elements of `vector` using the following:
///
/// for (n = 0; n < N; ++n) {
/// b = trunc(B[n]);
/// a = B[n] - b;
/// C[n] = A[b] + a * (A[b+1] - A[b]);
/// }
///
/// Where `A` is the input vector, `B` is the control vector, and
/// `C` is the output vector.
///
/// - Parameter vector: Input values.
/// - Parameter controlVector: Vector that controls interpolation.
/// - Returns: Output values.
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
@inline(__always)
public static func linearInterpolate<T, U>(elementsOf vector: T,
using controlVector: U) -> [Double]
where
T: _ContiguousCollection,
U: _ContiguousCollection,
T.Element == Double, U.Element == Double {
let result = Array<Double>(unsafeUninitializedCapacity: controlVector.count) {
buffer, initializedCount in
linearInterpolate(elementsOf: vector,
using: controlVector,
result: &buffer)
initializedCount = controlVector.count
}
return result
}
/// Vector linear interpolation between neighboring elements; double-precision.
///
/// This function interpolates between the elements of `vector` using the following:
///
/// for (n = 0; n < N; ++n) {
/// b = trunc(B[n]);
/// a = B[n] - b;
/// C[n] = A[b] + a * (A[b+1] - A[b]);
/// }
///
/// Where `A` is the input vector, `B` is the control vector, and
/// `C` is the output vector.
///
/// - Parameter vector: Input values.
/// - Parameter controlVector: Vector that controls interpolation.
/// - Parameter result: Output values.
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
@inline(__always)
public static func linearInterpolate<T, U, V>(elementsOf vector: T,
using controlVector: U,
result: inout V)
where
T: _ContiguousCollection,
U: _ContiguousCollection,
V: _MutableContiguousCollection,
T.Element == Double, U.Element == Double, V.Element == Double {
precondition(controlVector.count == result.count)
let n = vDSP_Length(result.count)
let m = vDSP_Length(vector.count)
vector.withUnsafeBufferPointer { a in
controlVector.withUnsafeBufferPointer { b in
result.withUnsafeMutableBufferPointer { dest in
vDSP_vlintD(a.baseAddress!,
b.baseAddress!, 1,
dest.baseAddress!, 1,
n, m)
}
}
}
}
}

View File

@@ -109,4 +109,149 @@ if #available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *) {
}
//===----------------------------------------------------------------------===//
//
// Linear interpolation
//
//===----------------------------------------------------------------------===//
if #available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *) {
let n = 1024
AccelerateTests.test("vDSP/SinglePrecisionInterpolateBetweenVectors") {
var result = [Float](repeating: 0, count: n)
var legacyResult = [Float](repeating: -1, count: n)
let a: [Float] = (0 ..< n).map{ i in
return sin(Float(i) * 0.025)
}
let b: [Float] = (0 ..< n).map{ i in
return sin(Float(i) * 0.05)
}
let interpolationConstant: Float = 0.5
vDSP.linearInterpolate(a, b,
using: interpolationConstant,
result: &result)
vDSP_vintb(a, 1,
b, 1,
[interpolationConstant],
&legacyResult, 1,
vDSP_Length(n))
let returnedResult = vDSP.linearInterpolate(a, b,
using: interpolationConstant)
expectTrue(result.elementsEqual(legacyResult))
expectTrue(result.elementsEqual(returnedResult))
}
AccelerateTests.test("vDSP/SinglePrecisionInterpolateBetweenNeighbours") {
var result = [Float](repeating: 0, count: n)
var legacyResult = [Float](repeating: -1, count: n)
let shortSignal: [Float] = (0 ... 10).map{ i in
return sin(Float(i) * 0.1 * .pi * 4)
}
let controlVector: [Float] = {
var controlVector = [Float](repeating: 0, count: 1024)
vDSP_vgen([0],
[Float(shortSignal.count)],
&controlVector, 1,
vDSP_Length(n))
return controlVector
}()
vDSP.linearInterpolate(elementsOf: shortSignal,
using: controlVector,
result: &result)
vDSP_vlint(shortSignal,
controlVector, 1,
&legacyResult, 1,
vDSP_Length(n),
vDSP_Length(shortSignal.count))
let returnedResult = vDSP.linearInterpolate(elementsOf: shortSignal,
using: controlVector)
expectTrue(result.elementsEqual(legacyResult))
expectTrue(result.elementsEqual(returnedResult))
}
AccelerateTests.test("vDSP/DoublePrecisionInterpolateBetweenVectors") {
var result = [Double](repeating: 0, count: n)
var legacyResult = [Double](repeating: -1, count: n)
let a: [Double] = (0 ..< n).map{ i in
return sin(Double(i) * 0.025)
}
let b: [Double] = (0 ..< n).map{ i in
return sin(Double(i) * 0.05)
}
let interpolationConstant: Double = 0.5
vDSP.linearInterpolate(a, b,
using: interpolationConstant,
result: &result)
vDSP_vintbD(a, 1,
b, 1,
[interpolationConstant],
&legacyResult, 1,
vDSP_Length(n))
let returnedResult = vDSP.linearInterpolate(a, b,
using: interpolationConstant)
expectTrue(result.elementsEqual(legacyResult))
expectTrue(result.elementsEqual(returnedResult))
}
AccelerateTests.test("vDSP/DoublePrecisionInterpolateBetweenNeighbours") {
var result = [Double](repeating: 0, count: n)
var legacyResult = [Double](repeating: -1, count: n)
let shortSignal: [Double] = (0 ... 10).map{ i in
return sin(Double(i) * 0.1 * .pi * 4)
}
let controlVector: [Double] = {
var controlVector = [Double](repeating: 0, count: 1024)
vDSP_vgenD([0],
[Double(shortSignal.count)],
&controlVector, 1,
vDSP_Length(n))
return controlVector
}()
vDSP.linearInterpolate(elementsOf: shortSignal,
using: controlVector,
result: &result)
vDSP_vlintD(shortSignal,
controlVector, 1,
&legacyResult, 1,
vDSP_Length(n),
vDSP_Length(shortSignal.count))
let returnedResult = vDSP.linearInterpolate(elementsOf: shortSignal,
using: controlVector)
expectTrue(result.elementsEqual(legacyResult))
expectTrue(result.elementsEqual(returnedResult))
}
}
runAllTests()