Skip to content

Commit 2ee1914

Browse files
author
Simon Gladman
committed
Merge remote-tracking branch 'origin/accelerate-vDSP-polynomialEvaluation' into Accelerate_Swift-vDSP-Overlays
2 parents 87ab1d6 + 2547585 commit 2ee1914

File tree

3 files changed

+218
-0
lines changed

3 files changed

+218
-0
lines changed

stdlib/public/Darwin/Accelerate/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ add_swift_target_library(swiftAccelerate ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES
1818
vDSP_PolarRectangularConversion.swift
1919
vDSP_DecibelConversion.swift
2020
vDSP_ComplexConversion.swift
21+
vDSP_PolynomialEvaluation.swift
2122

2223
"${SWIFT_SOURCE_DIR}/stdlib/linker-support/magic-symbols-for-install-name.c"
2324

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
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+
17+
/// Evaluates a polynomial using specified coefficients and independent variables. Single-precision.
18+
///
19+
/// - Parameter coefficients: Coefficients.
20+
/// - Parameter variables: Independent variables.
21+
/// - Returns: The polynomial evaluation result.
22+
///
23+
/// For example, given the coefficients `[10, 20, 30]`, and independent variables `[2, 5]`,
24+
/// the result is calculated as:
25+
///
26+
/// `result[0] = (10 * 2²) + (20 * 2¹) + (30 * 2⁰) // 110`
27+
///
28+
/// `result[1] = (10 * 5²) + (20 * 5¹) + (30 * 5⁰) // 380`
29+
@inline(__always)
30+
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
31+
public static func evaluatePolynomial<U>(usingCoefficients coefficients: [Float],
32+
withVariables variables: U) -> [Float]
33+
where
34+
U: _ContiguousCollection,
35+
U.Element == Float {
36+
37+
let result = Array<Float>(unsafeUninitializedCapacity: variables.count) {
38+
buffer, initializedCount in
39+
40+
evaluatePolynomial(usingCoefficients: coefficients,
41+
withVariables: variables,
42+
result: &buffer)
43+
44+
initializedCount = variables.count
45+
}
46+
47+
return result
48+
}
49+
50+
/// Evaluates a polynomial using specified coefficients and independent variables. Single-precision.
51+
///
52+
/// - Parameter coefficients: Coefficients.
53+
/// - Parameter variables: Independent variables.
54+
/// - Parameter result: Destination vector.
55+
///
56+
/// For example, given the coefficients `[10, 20, 30]`, and independent variables `[2, 5]`,
57+
/// the result is calculated as:
58+
///
59+
/// `result[0] = (10 * 2²) + (20 * 2¹) + (30 * 2⁰) // 110`
60+
///
61+
/// `result[1] = (10 * 5²) + (20 * 5¹) + (30 * 5⁰) // 380`
62+
@inline(__always)
63+
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
64+
public static func evaluatePolynomial<U, V>(usingCoefficients coefficients: [Float],
65+
withVariables variables: U,
66+
result: inout V)
67+
where
68+
U: _ContiguousCollection,
69+
V: _MutableContiguousCollection,
70+
U.Element == Float, V.Element == Float {
71+
72+
let n = vDSP_Length(min(variables.count,
73+
result.count))
74+
75+
let degreeOfPolynomial = vDSP_Length(coefficients.count - 1)
76+
77+
result.withUnsafeMutableBufferPointer { dest in
78+
variables.withUnsafeBufferPointer { src in
79+
vDSP_vpoly(coefficients, 1,
80+
src.baseAddress!, 1,
81+
dest.baseAddress!, 1,
82+
n,
83+
degreeOfPolynomial)
84+
}
85+
}
86+
}
87+
88+
/// Evaluates a polynomial using specified coefficients and independent variables. Double-precision.
89+
///
90+
/// - Parameter coefficients: Coefficients.
91+
/// - Parameter variables: Independent variables.
92+
/// - Returns: The polynomial evaluation result.
93+
///
94+
/// For example, given the coefficients `[10, 20, 30]`, and independent variables `[2, 5]`,
95+
/// the result is calculated as:
96+
///
97+
/// `result[0] = (10 * 2²) + (20 * 2¹) + (30 * 2⁰) // 110`
98+
///
99+
/// `result[1] = (10 * 5²) + (20 * 5¹) + (30 * 5⁰) // 380`
100+
@inline(__always)
101+
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
102+
public static func evaluatePolynomial<U>(usingCoefficients coefficients: [Double],
103+
withVariables variables: U) -> [Double]
104+
where
105+
U: _ContiguousCollection,
106+
U.Element == Double {
107+
108+
let result = Array<Double>(unsafeUninitializedCapacity: variables.count) {
109+
buffer, initializedCount in
110+
111+
evaluatePolynomial(usingCoefficients: coefficients,
112+
withVariables: variables,
113+
result: &buffer)
114+
115+
initializedCount = variables.count
116+
}
117+
118+
return result
119+
}
120+
121+
/// Evaluates a polynomial using specified coefficients and independent variables. Double-precision.
122+
///
123+
/// - Parameter coefficients: Coefficients.
124+
/// - Parameter variables: Independent variables.
125+
/// - Parameter result: Destination vector.
126+
///
127+
/// For example, given the coefficients `[10, 20, 30]`, and independent variables `[2, 5]`,
128+
/// the result is calculated as:
129+
///
130+
/// `result[0] = (10 * 2²) + (20 * 2¹) + (30 * 2⁰) // 110`
131+
///
132+
/// `result[1] = (10 * 5²) + (20 * 5¹) + (30 * 5⁰) // 380`
133+
@inline(__always)
134+
@available(iOS 9999, OSX 9999, tvOS 9999, watchOS 9999, *)
135+
public static func evaluatePolynomial<U, V>(usingCoefficients coefficients: [Double],
136+
withVariables variables: U,
137+
result: inout V)
138+
where
139+
U: _ContiguousCollection,
140+
V: _MutableContiguousCollection,
141+
U.Element == Double, V.Element == Double {
142+
143+
let n = vDSP_Length(min(variables.count,
144+
result.count))
145+
146+
let degreeOfPolynomial = vDSP_Length(coefficients.count - 1)
147+
148+
result.withUnsafeMutableBufferPointer { dest in
149+
variables.withUnsafeBufferPointer { src in
150+
vDSP_vpolyD(coefficients, 1,
151+
src.baseAddress!, 1,
152+
dest.baseAddress!, 1,
153+
n,
154+
degreeOfPolynomial)
155+
}
156+
}
157+
}
158+
159+
}

test/stdlib/Accelerate.swift

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,4 +427,62 @@ if #available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *) {
427427
}
428428
}
429429

430+
//===----------------------------------------------------------------------===//
431+
//
432+
// vDSP polynomial evaluation.
433+
//
434+
//===----------------------------------------------------------------------===//
435+
436+
if #available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *) {
437+
438+
AccelerateTests.test("vDSP/PolynomialEvaluationSinglePrecision") {
439+
let coefficients: [Float] = [2, 3, 4, 5, 6, 7, 8, 9, 10]
440+
let variables = (0 ... 100).map { return Float($0) }
441+
var result = [Float](repeating: 0, count: variables.count)
442+
443+
vDSP.evaluatePolynomial(usingCoefficients: coefficients,
444+
withVariables: variables,
445+
result: &result)
446+
447+
var legacyResult = [Float](repeating: -1, count: variables.count)
448+
449+
vDSP_vpoly(coefficients, 1,
450+
variables, 1,
451+
&legacyResult, 1,
452+
vDSP_Length(legacyResult.count),
453+
vDSP_Length(coefficients.count - 1))
454+
455+
let returnedResult = vDSP.evaluatePolynomial(usingCoefficients: coefficients,
456+
withVariables: variables)
457+
458+
expectTrue(result.elementsEqual(legacyResult))
459+
expectTrue(result.elementsEqual(returnedResult))
460+
}
461+
462+
AccelerateTests.test("vDSP/PolynomialEvaluationDoublePrecision") {
463+
let coefficients: [Double] = [2, 3, 4, 5, 6, 7, 8, 9, 10]
464+
let variables = (0 ... 100).map { return Double($0) }
465+
var result = [Double](repeating: 0, count: variables.count)
466+
467+
vDSP.evaluatePolynomial(usingCoefficients: coefficients,
468+
withVariables: variables,
469+
result: &result)
470+
471+
var legacyResult = [Double](repeating: -1, count: variables.count)
472+
473+
vDSP_vpolyD(coefficients, 1,
474+
variables, 1,
475+
&legacyResult, 1,
476+
vDSP_Length(legacyResult.count),
477+
vDSP_Length(coefficients.count - 1))
478+
479+
let returnedResult = vDSP.evaluatePolynomial(usingCoefficients: coefficients,
480+
withVariables: variables)
481+
482+
expectTrue(result.elementsEqual(legacyResult))
483+
expectTrue(result.elementsEqual(returnedResult))
484+
}
485+
}
486+
430487
runAllTests()
488+

0 commit comments

Comments
 (0)