Skip to content

Commit ac4b5b9

Browse files
author
Simon Gladman
committed
Merge remote-tracking branch 'origin/accelerate-vDSP-integration' into Accelerate_Swift-vDSP-Overlays
2 parents 8b76ff5 + f5afb0d commit ac4b5b9

File tree

3 files changed

+337
-0
lines changed

3 files changed

+337
-0
lines changed

stdlib/public/Darwin/Accelerate/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ add_swift_target_library(swiftAccelerate ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES
2222
vDSP_ClippingLimitThreshold.swift
2323
vDSP_FillClearGenerate.swift
2424

25+
Accelerate.swift
26+
ContiguousCollection.swift
27+
vDSP_Integration.swift
28+
2529
"${SWIFT_SOURCE_DIR}/stdlib/linker-support/magic-symbols-for-install-name.c"
2630

2731
GYB_SOURCES
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Accelerate
14+
15+
extension vDSP {
16+
public enum IntegrationRule {
17+
case runningSum
18+
case simpson
19+
case trapezoidal
20+
}
21+
22+
/// Integrates source vector using specified rule, single-precision.
23+
///
24+
/// - Parameter vector: The vector to integrate.
25+
/// - Parameter rule: The integration rule.
26+
/// - Parameter stepSize: The integration step size (weighting factor for running sum).
27+
/// - Returns: The integration result.
28+
@inline(__always)
29+
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
30+
public static func integrate<U>(_ vector: U,
31+
using rule: IntegrationRule,
32+
stepSize: Float = 1) -> [Float]
33+
where
34+
U: _ContiguousCollection,
35+
U.Element == Float {
36+
37+
let result = Array<Float>(unsafeUninitializedCapacity: vector.count) {
38+
buffer, initializedCount in
39+
40+
integrate(vector,
41+
using: rule,
42+
result: &buffer)
43+
44+
initializedCount = vector.count
45+
}
46+
47+
return result
48+
}
49+
50+
/// Integrates source vector using specified rule, single-precision.
51+
///
52+
/// - Parameter vector: The vector to integrate.
53+
/// - Parameter rule: The integration rule.
54+
/// - Parameter stepSize: The integration step size (weighting factor for running sum).
55+
/// - Parameter result: The destination vector to receive the result.
56+
@inline(__always)
57+
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
58+
public static func integrate<U, V>(_ vector: U,
59+
using rule: IntegrationRule,
60+
stepSize: Float = 1,
61+
result: inout V)
62+
where
63+
U: _ContiguousCollection,
64+
V: _MutableContiguousCollection,
65+
U.Element == Float, V.Element == Float {
66+
67+
let n = vDSP_Length(min(vector.count,
68+
result.count))
69+
70+
result.withUnsafeMutableBufferPointer { output in
71+
vector.withUnsafeBufferPointer { input in
72+
switch rule {
73+
case .runningSum:
74+
vDSP_vrsum(input.baseAddress!, 1,
75+
[stepSize],
76+
output.baseAddress!, 1,
77+
n)
78+
case .simpson:
79+
vDSP_vsimps(input.baseAddress!, 1,
80+
[stepSize],
81+
output.baseAddress!, 1,
82+
n)
83+
case .trapezoidal:
84+
vDSP_vtrapz(input.baseAddress!, 1,
85+
[stepSize],
86+
output.baseAddress!, 1,
87+
n)
88+
}
89+
}
90+
}
91+
}
92+
93+
/// Integrates source vector using specified rule, double-precision.
94+
///
95+
/// - Parameter vector: The vector to integrate.
96+
/// - Parameter rule: The integration rule.
97+
/// - Parameter stepSize: The integration step size (weighting factor for running sum).
98+
/// - Returns: The integration result.
99+
@inline(__always)
100+
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
101+
public static func integrate<U>(_ vector: U,
102+
using rule: IntegrationRule,
103+
stepSize: Double = 1) -> [Double]
104+
where
105+
U: _ContiguousCollection,
106+
U.Element == Double {
107+
108+
let result = Array<Double>(unsafeUninitializedCapacity: vector.count) {
109+
buffer, initializedCount in
110+
111+
integrate(vector,
112+
using: rule,
113+
result: &buffer)
114+
115+
initializedCount = vector.count
116+
}
117+
118+
return result
119+
}
120+
121+
/// Integrates source vector using specified rule, double-precision.
122+
///
123+
/// - Parameter vector: The vector to integrate.
124+
/// - Parameter rule: The integration rule.
125+
/// - Parameter stepSize: The integration step size (weighting factor for running sum).
126+
/// - Parameter result: The destination vector to receive the result.
127+
@inline(__always)
128+
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
129+
public static func integrate<U, V>(_ vector: U,
130+
using rule: IntegrationRule,
131+
stepSize: Double = 1,
132+
result: inout V)
133+
where
134+
U: _ContiguousCollection,
135+
V: _MutableContiguousCollection,
136+
U.Element == Double, V.Element == Double {
137+
138+
let n = vDSP_Length(min(vector.count,
139+
result.count))
140+
141+
result.withUnsafeMutableBufferPointer { output in
142+
vector.withUnsafeBufferPointer { input in
143+
switch rule {
144+
case .runningSum:
145+
vDSP_vrsumD(input.baseAddress!, 1,
146+
[stepSize],
147+
output.baseAddress!, 1,
148+
n)
149+
case .simpson:
150+
vDSP_vsimpsD(input.baseAddress!, 1,
151+
[stepSize],
152+
output.baseAddress!, 1,
153+
n)
154+
case .trapezoidal:
155+
vDSP_vtrapzD(input.baseAddress!, 1,
156+
[stepSize],
157+
output.baseAddress!, 1,
158+
n)
159+
}
160+
}
161+
}
162+
}
163+
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// RUN: %target-run-simple-swift
2+
// REQUIRES: executable_test
3+
4+
// REQUIRES: objc_interop
5+
// UNSUPPORTED: OS=watchos
6+
7+
import StdlibUnittest
8+
import Accelerate
9+
10+
var Accelerate_vDSPIntegrationTests = TestSuite("Accelerate_vDSPIntegration")
11+
12+
//===----------------------------------------------------------------------===//
13+
//
14+
// vDSP integration tests
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
if #available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *) {
19+
20+
let count = 1024
21+
let n = vDSP_Length(1024)
22+
23+
let sourcef: [Float] = (0 ..< 1024).map {
24+
return sin(Float($0) * 0.03) * cos(Float($0) * 0.07)
25+
}
26+
27+
let sourced: [Double] = (0 ..< 1024).map {
28+
return sin(Double($0) * 0.03) * cos(Double($0) * 0.07)
29+
}
30+
31+
Accelerate_vDSPIntegrationTests.test("vDSP/SinglePrecisionRunningSum") {
32+
var result = [Float](repeating: 0,
33+
count: count)
34+
35+
vDSP.integrate(sourcef,
36+
using: .runningSum,
37+
result: &result)
38+
39+
var legacyResult = [Float](repeating: -1,
40+
count: count)
41+
42+
vDSP_vrsum(sourcef, 1,
43+
[1],
44+
&legacyResult, 1,
45+
n)
46+
47+
let returnedResult = vDSP.integrate(sourcef,
48+
using: .runningSum)
49+
50+
expectTrue(result.elementsEqual(legacyResult))
51+
expectTrue(result.elementsEqual(returnedResult))
52+
}
53+
54+
Accelerate_vDSPIntegrationTests.test("vDSP/SinglePrecisionTrapezoidal") {
55+
var result = [Float](repeating: 0,
56+
count: count)
57+
58+
vDSP.integrate(sourcef,
59+
using: .simpson,
60+
result: &result)
61+
62+
var legacyResult = [Float](repeating: -1,
63+
count: count)
64+
65+
vDSP_vsimps(sourcef, 1,
66+
[1],
67+
&legacyResult, 1,
68+
n)
69+
70+
let returnedResult = vDSP.integrate(sourcef,
71+
using: .simpson)
72+
73+
expectTrue(result.elementsEqual(legacyResult))
74+
expectTrue(result.elementsEqual(returnedResult))
75+
}
76+
77+
Accelerate_vDSPIntegrationTests.test("vDSP/SinglePrecisionTrapezoidal") {
78+
var result = [Float](repeating: 0,
79+
count: count)
80+
81+
vDSP.integrate(sourcef,
82+
using: .trapezoidal,
83+
result: &result)
84+
85+
var legacyResult = [Float](repeating: -1,
86+
count: count)
87+
88+
vDSP_vtrapz(sourcef, 1,
89+
[1],
90+
&legacyResult, 1,
91+
n)
92+
93+
let returnedResult = vDSP.integrate(sourcef,
94+
using: .trapezoidal)
95+
96+
expectTrue(result.elementsEqual(legacyResult))
97+
expectTrue(result.elementsEqual(returnedResult))
98+
}
99+
100+
Accelerate_vDSPIntegrationTests.test("vDSP/DoublePrecisionRunningSum") {
101+
var result = [Double](repeating: 0,
102+
count: count)
103+
104+
vDSP.integrate(sourced,
105+
using: .runningSum,
106+
result: &result)
107+
108+
var legacyResult = [Double](repeating: -1,
109+
count: count)
110+
111+
vDSP_vrsumD(sourced, 1,
112+
[1],
113+
&legacyResult, 1,
114+
n)
115+
116+
let returnedResult = vDSP.integrate(sourced,
117+
using: .runningSum)
118+
119+
expectTrue(result.elementsEqual(legacyResult))
120+
expectTrue(result.elementsEqual(returnedResult))
121+
}
122+
123+
Accelerate_vDSPIntegrationTests.test("vDSP/DoublePrecisionSimpson") {
124+
var result = [Double](repeating: 0,
125+
count: count)
126+
127+
vDSP.integrate(sourced,
128+
using: .simpson,
129+
result: &result)
130+
131+
var legacyResult = [Double](repeating: -1,
132+
count: count)
133+
134+
vDSP_vsimpsD(sourced, 1,
135+
[1],
136+
&legacyResult, 1,
137+
n)
138+
139+
let returnedResult = vDSP.integrate(sourced,
140+
using: .simpson)
141+
142+
expectTrue(result.elementsEqual(legacyResult))
143+
expectTrue(result.elementsEqual(returnedResult))
144+
}
145+
146+
Accelerate_vDSPIntegrationTests.test("vDSP/DoublePrecisionTrapezoidal") {
147+
var result = [Double](repeating: 0,
148+
count: count)
149+
150+
vDSP.integrate(sourced,
151+
using: .trapezoidal,
152+
result: &result)
153+
154+
var legacyResult = [Double](repeating: -1,
155+
count: count)
156+
157+
vDSP_vtrapzD(sourced, 1,
158+
[1],
159+
&legacyResult, 1,
160+
n)
161+
162+
let returnedResult = vDSP.integrate(sourced,
163+
using: .trapezoidal)
164+
165+
expectTrue(result.elementsEqual(legacyResult))
166+
expectTrue(result.elementsEqual(returnedResult))
167+
}
168+
}
169+
170+
runAllTests()

0 commit comments

Comments
 (0)