Changed `distSq…` of ’Arithmetic.swift’ to be implemented in terms of `sum`, `sq` & `sub` with minimal temporary array allocations

This commit is contained in:
Vincent Esche 2019-09-24 16:27:14 +02:00
parent 1a198b0396
commit b590bc8ee6
2 changed files with 12 additions and 14 deletions

View File

@ -852,20 +852,14 @@ public func dist<L: UnsafeMemoryAccessible, R: UnsafeMemoryAccessible>(_ lhs: L,
public func distSq<L: UnsafeMemoryAccessible, R: UnsafeMemoryAccessible>(_ lhs: L, _ rhs: R) -> Float where L.Element == Float, R.Element == Float {
precondition(lhs.count == rhs.count, "Vectors must have equal count")
let sub = lhs .- rhs
var squared = [Float](repeating: 0.0, count: numericCast(lhs.count))
squared.withUnsafeMutableBufferPointer { bufferPointer in
vDSP_vsq(sub, 1, bufferPointer.baseAddress!, 1, numericCast(lhs.count))
}
return sum(squared)
var partialDistancesSquared = lhs .- rhs
sqInPlace(&partialDistancesSquared)
return sum(partialDistancesSquared)
}
public func distSq<L: UnsafeMemoryAccessible, R: UnsafeMemoryAccessible>(_ lhs: L, _ rhs: R) -> Double where L.Element == Double, R.Element == Double {
precondition(lhs.count == rhs.count, "Vectors must have equal count")
let sub = lhs .- rhs
var squared = [Double](repeating: 0.0, count: numericCast(lhs.count))
squared.withUnsafeMutableBufferPointer { bufferPointer in
vDSP_vsqD(sub, 1, bufferPointer.baseAddress!, 1, numericCast(lhs.count))
}
return sum(squared)
var partialDistancesSquared = lhs .- rhs
sqInPlace(&partialDistancesSquared)
return sum(partialDistancesSquared)
}

View File

@ -710,7 +710,9 @@ class ArithmeticTests: XCTestCase {
actual = distSq(lhs, rhs)
}
let expected: Scalar = Swift.zip(lhs, rhs).map({ $0 - $1 }).map({ $0 * $0 }).reduce(0.0, +)
let partialDistances: [Scalar] = Swift.zip(lhs, rhs).map { $0 - $1 }
let partialDistancesSquared: [Scalar] = partialDistances.map { $0 * $0 }
let expected: Scalar = partialDistancesSquared.reduce(0.0, +)
XCTAssertEqual(actual, expected, accuracy: 1e-6)
}
@ -726,7 +728,9 @@ class ArithmeticTests: XCTestCase {
actual = distSq(lhs, rhs)
}
let expected: Scalar = Swift.zip(lhs, rhs).map({ $0 - $1 }).map({ $0 * $0 }).reduce(0.0, +)
let partialDistances: [Scalar] = Swift.zip(lhs, rhs).map { $0 - $1 }
let partialDistancesSquared: [Scalar] = partialDistances.map { $0 * $0 }
let expected: Scalar = partialDistancesSquared.reduce(0.0, +)
XCTAssertEqual(actual, expected, accuracy: 1e-6)
}