mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
@inline(__always) does not imply inlinable, which means that it effectively does nothing in the context of the Accelerate overlay. I have replaced all of these with @inlinable where that can be done as a one-line change. Functions that switch over open enums and more complex API (DCT, DFT, FFT) will require more sophisticated corrections, which we can undertake in later commits. For now, they have been rolled back to simply being normal public API.
436 lines
18 KiB
Swift
436 lines
18 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
extension vDSP {
|
|
|
|
// MARK Dot product
|
|
|
|
/// Returns the dot or scalar product of vectors A and B; single-precision.
|
|
///
|
|
/// - Parameter vectorA: Single-precision real input vector A.
|
|
/// - Parameter vectorB: Single-precision real input vector B.
|
|
/// - Returns: The dot product of vectors A and B.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func dot<U>(_ vectorA: U,
|
|
_ vectorB: U) -> Float
|
|
where
|
|
U: AccelerateBuffer,
|
|
U.Element == Float {
|
|
|
|
precondition(vectorA.count == vectorB.count)
|
|
|
|
let n = vDSP_Length(vectorA.count)
|
|
var result = Float.nan
|
|
|
|
vectorA.withUnsafeBufferPointer { a in
|
|
vectorB.withUnsafeBufferPointer { b in
|
|
|
|
vDSP_dotpr(a.baseAddress!, 1,
|
|
b.baseAddress!, 1,
|
|
&result, n)
|
|
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/// Returns the dot or scalar product of vectors A and B; double-precision.
|
|
///
|
|
/// - Parameter vectorA: Double-precision real input vector A.
|
|
/// - Parameter vectorB: Double-precision real input vector B.
|
|
/// - Returns: The dot product of vectors A and B.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func dot<U>(_ vectorA: U,
|
|
_ vectorB: U) -> Double
|
|
where
|
|
U: AccelerateBuffer,
|
|
U.Element == Double {
|
|
|
|
precondition(vectorA.count == vectorB.count)
|
|
|
|
let n = vDSP_Length(vectorA.count)
|
|
var result = Double.nan
|
|
|
|
vectorA.withUnsafeBufferPointer { a in
|
|
vectorB.withUnsafeBufferPointer { b in
|
|
|
|
vDSP_dotprD(a.baseAddress!, 1,
|
|
b.baseAddress!, 1,
|
|
&result, n)
|
|
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// MARK: Distance
|
|
|
|
/// Returns the hypotenuse of right-angled triangles with sides that are the lengths of
|
|
/// corresponding elements in vectors `x` and `y`; single-precision.
|
|
///
|
|
/// - Parameter x: The `x` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
/// - Parameter y: The `y` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
/// - Parameter result: The `z` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func hypot<U, V>(_ x: U,
|
|
_ y: V) -> [Float]
|
|
where
|
|
U: AccelerateBuffer,
|
|
V: AccelerateBuffer,
|
|
U.Element == Float, V.Element == Float {
|
|
|
|
precondition(x.count == y.count)
|
|
|
|
let result = Array<Float>(unsafeUninitializedCapacity: x.count) {
|
|
buffer, initializedCount in
|
|
|
|
hypot(x, y,
|
|
result: &buffer)
|
|
|
|
initializedCount = x.count
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/// Calculates the hypotenuse of right-angled triangles with sides that are the lengths of
|
|
/// corresponding elements in vectors `x` and `y`; single-precision.
|
|
///
|
|
/// - Parameter x: The `x` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
/// - Parameter y: The `y` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
/// - Parameter result: The `z` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func hypot<T, U, V>(_ x: T,
|
|
_ y: U,
|
|
result: inout V)
|
|
where
|
|
T: AccelerateBuffer,
|
|
U: AccelerateBuffer,
|
|
V: AccelerateMutableBuffer,
|
|
T.Element == Float, U.Element == Float, V.Element == Float {
|
|
|
|
precondition(x.count == y.count && y.count == result.count)
|
|
let n = vDSP_Length(result.count)
|
|
|
|
x.withUnsafeBufferPointer { a in
|
|
y.withUnsafeBufferPointer { b in
|
|
result.withUnsafeMutableBufferPointer { dest in
|
|
vDSP_vdist(a.baseAddress!, 1,
|
|
b.baseAddress!, 1,
|
|
dest.baseAddress!, 1,
|
|
n)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Returns the hypotenuse of right-angled triangles with sides that are the lengths of
|
|
/// corresponding elements in vectors `x` and `y`; double-precision.
|
|
///
|
|
/// - Parameter x: The `x` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
/// - Parameter y: The `y` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
/// - Parameter result: The `z` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func hypot<U, V>(_ x: U,
|
|
_ y: V) -> [Double]
|
|
where
|
|
U: AccelerateBuffer,
|
|
V: AccelerateBuffer,
|
|
U.Element == Double, V.Element == Double {
|
|
|
|
precondition(x.count == y.count)
|
|
|
|
let result = Array<Double>(unsafeUninitializedCapacity: x.count) {
|
|
buffer, initializedCount in
|
|
|
|
hypot(x, y,
|
|
result: &buffer)
|
|
|
|
initializedCount = x.count
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/// Calculates the hypotenuse of right-angled triangles with sides that are the lengths of
|
|
/// corresponding elements in vectors `x` and `y`; double-precision.
|
|
///
|
|
/// - Parameter x: The `x` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
/// - Parameter y: The `y` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
/// - Parameter result: The `z` in `z[i] = sqrt(x[i]² + y[i]²)`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func hypot<T, U, V>(_ x: T,
|
|
_ y: U,
|
|
result: inout V)
|
|
where
|
|
T: AccelerateBuffer,
|
|
U: AccelerateBuffer,
|
|
V: AccelerateMutableBuffer,
|
|
T.Element == Double, U.Element == Double, V.Element == Double {
|
|
|
|
precondition(x.count == y.count && y.count == result.count)
|
|
let n = vDSP_Length(result.count)
|
|
|
|
x.withUnsafeBufferPointer { a in
|
|
y.withUnsafeBufferPointer { b in
|
|
result.withUnsafeMutableBufferPointer { dest in
|
|
vDSP_vdistD(a.baseAddress!, 1,
|
|
b.baseAddress!, 1,
|
|
dest.baseAddress!, 1,
|
|
n)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: Pythagoras
|
|
|
|
/// Returns the hypotenuse of right-angled triangles with sides that are the differences of
|
|
/// corresponding values in x0 and x1, and y0 and y1. Single-precision.
|
|
///
|
|
/// - Parameter x0: The `x0` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter x1: The `x1` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter y0: The `y0` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter y1: The `y1` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter result: The `z` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func hypot<R, S, T, U>(x0: R, x1: S,
|
|
y0: T, y1: U) -> [Float]
|
|
where
|
|
R: AccelerateBuffer,
|
|
S: AccelerateBuffer,
|
|
T: AccelerateBuffer,
|
|
U: AccelerateBuffer,
|
|
R.Element == Float, S.Element == Float,
|
|
T.Element == Float, U.Element == Float {
|
|
|
|
precondition(x0.count == x1.count)
|
|
precondition(y0.count == y1.count)
|
|
precondition(x0.count == y0.count)
|
|
|
|
let result = Array<Float>(unsafeUninitializedCapacity: x0.count) {
|
|
buffer, initializedCount in
|
|
|
|
hypot(x0: x0, x1: x1,
|
|
y0: y0, y1: y1,
|
|
result: &buffer)
|
|
|
|
initializedCount = x0.count
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/// Calculates the hypotenuse of right-angled triangles with sides that are the differences of
|
|
/// corresponding values in x0 and x1, and y0 and y1. Single-precision.
|
|
///
|
|
/// - Parameter x0: The `x0` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter x1: The `x1` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter y0: The `y0` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter y1: The `y1` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter result: The `z` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func hypot<R, S, T, U, V>(x0: R, x1: S,
|
|
y0: T, y1: U,
|
|
result: inout V)
|
|
where
|
|
R: AccelerateBuffer,
|
|
S: AccelerateBuffer,
|
|
T: AccelerateBuffer,
|
|
U: AccelerateBuffer,
|
|
V: AccelerateMutableBuffer,
|
|
R.Element == Float, S.Element == Float,
|
|
T.Element == Float, U.Element == Float,
|
|
V.Element == Float {
|
|
|
|
precondition(x0.count == x1.count && x0.count == result.count)
|
|
precondition(y0.count == y1.count && y0.count == result.count)
|
|
|
|
let n = vDSP_Length(result.count)
|
|
|
|
x0.withUnsafeBufferPointer { a in
|
|
x1.withUnsafeBufferPointer { c in
|
|
y0.withUnsafeBufferPointer { b in
|
|
y1.withUnsafeBufferPointer { d in
|
|
result.withUnsafeMutableBufferPointer { dest in
|
|
vDSP_vpythg(a.baseAddress!, 1,
|
|
b.baseAddress!, 1,
|
|
c.baseAddress!, 1,
|
|
d.baseAddress!, 1,
|
|
dest.baseAddress!, 1,
|
|
n)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Returns the hypotenuse of right-angled triangles with sides that are the differences of
|
|
/// corresponding values in x0 and x1, and y0 and y1. Double-precision.
|
|
///
|
|
/// - Parameter x0: The `x0` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter x1: The `x1` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter y0: The `y0` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter y1: The `y1` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter result: The `z` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func hypot<R, S, T, U>(x0: R, x1: S,
|
|
y0: T, y1: U) -> [Double]
|
|
where
|
|
R: AccelerateBuffer,
|
|
S: AccelerateBuffer,
|
|
T: AccelerateBuffer,
|
|
U: AccelerateBuffer,
|
|
R.Element == Double, S.Element == Double,
|
|
T.Element == Double, U.Element == Double {
|
|
|
|
precondition(x0.count == x1.count)
|
|
precondition(y0.count == y1.count)
|
|
precondition(x0.count == y0.count)
|
|
|
|
let result = Array<Double>(unsafeUninitializedCapacity: x0.count) {
|
|
buffer, initializedCount in
|
|
|
|
hypot(x0: x0, x1: x1,
|
|
y0: y0, y1: y1,
|
|
result: &buffer)
|
|
|
|
initializedCount = x0.count
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/// Calculates the hypotenuse of right-angled triangles with sides that are the differences of
|
|
/// corresponding values in x0 and x1, and y0 and y1. Double-precision.
|
|
///
|
|
/// - Parameter x0: The `x0` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter x1: The `x1` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter y0: The `y0` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter y1: The `y1` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
/// - Parameter result: The `z` in `z[i] = sqrt( (x0[i] - x1[i])² + (y0[i] - y1[i])² )`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func hypot<R, S, T, U, V>(x0: R, x1: S,
|
|
y0: T, y1: U,
|
|
result: inout V)
|
|
where
|
|
R: AccelerateBuffer,
|
|
S: AccelerateBuffer,
|
|
T: AccelerateBuffer,
|
|
U: AccelerateBuffer,
|
|
V: AccelerateMutableBuffer,
|
|
R.Element == Double, S.Element == Double,
|
|
T.Element == Double, U.Element == Double,
|
|
V.Element == Double {
|
|
|
|
precondition(x0.count == x1.count && x0.count == result.count)
|
|
precondition(y0.count == y1.count && y0.count == result.count)
|
|
|
|
let n = vDSP_Length(result.count)
|
|
|
|
x0.withUnsafeBufferPointer { a in
|
|
x1.withUnsafeBufferPointer { c in
|
|
y0.withUnsafeBufferPointer { b in
|
|
y1.withUnsafeBufferPointer { d in
|
|
result.withUnsafeMutableBufferPointer { dest in
|
|
vDSP_vpythgD(a.baseAddress!, 1,
|
|
b.baseAddress!, 1,
|
|
c.baseAddress!, 1,
|
|
d.baseAddress!, 1,
|
|
dest.baseAddress!, 1,
|
|
n)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: Distance Squared
|
|
|
|
/// Returns the distance squared between two points in `n` dimensional space. Single-precision.
|
|
///
|
|
/// - Parameter pointA: First point in `n` dimensional space, where `n` is the collection count.
|
|
/// - Parameter pointB: Second point in `n` dimensional space, where `n` is the collection count.
|
|
/// - Returns: The distance squared between `pointA` and `pointB`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func distanceSquared<U, V>(_ pointA: U,
|
|
_ pointB: V) -> Float
|
|
where
|
|
U: AccelerateBuffer,
|
|
V: AccelerateMutableBuffer,
|
|
U.Element == Float, V.Element == Float {
|
|
|
|
precondition(pointA.count == pointB.count)
|
|
|
|
let n = vDSP_Length(pointA.count)
|
|
var result = Float.nan
|
|
|
|
pointA.withUnsafeBufferPointer { a in
|
|
pointB.withUnsafeBufferPointer { b in
|
|
vDSP_distancesq(a.baseAddress!, 1,
|
|
b.baseAddress!, 1,
|
|
&result,
|
|
n)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/// Returns the distance squared between two points in `n` dimensional space. Double-precision.
|
|
///
|
|
/// - Parameter pointA: First point in `n` dimensional space, where `n` is the collection count.
|
|
/// - Parameter pointB: Second point in `n` dimensional space, where `n` is the collection count.
|
|
/// - Returns: The distance squared between `pointA` and `pointB`.
|
|
@inlinable
|
|
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *)
|
|
public static func distanceSquared<U, V>(_ pointA: U,
|
|
_ pointB: V) -> Double
|
|
where
|
|
U: AccelerateBuffer,
|
|
V: AccelerateMutableBuffer,
|
|
U.Element == Double, V.Element == Double {
|
|
|
|
precondition(pointA.count == pointB.count)
|
|
|
|
let n = vDSP_Length(pointA.count)
|
|
var result = Double.nan
|
|
|
|
pointA.withUnsafeBufferPointer { a in
|
|
pointB.withUnsafeBufferPointer { b in
|
|
vDSP_distancesqD(a.baseAddress!, 1,
|
|
b.baseAddress!, 1,
|
|
&result,
|
|
n)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
}
|