I have a Vector
struct that I use for linear algebra calculations where the generic values conform to the Real
type provided by the Numerics package. The example shown below is a simplified version of the struct. I can calculate the dot product of two vectors using the cblas_sdot()
and cblas_ddot()
functions from Accelerate which are only for Float
and Double
types respectively.
import Accelerate
import Numerics
struct Vector<T: Real> {
let size: Int
var values: [T]
init(_ values: [T]) {
self.size = values.count
self.values = values
}
}
func dotProduct(_ x: Vector<Float>, _ y: Vector<Float>) -> Float {
precondition(x.size == y.size, "Vectors must be same size")
var dot: Float = 0
x.values.withUnsafeBufferPointer { xPointer in
y.values.withUnsafeBufferPointer { yPointer in
dot = cblas_sdot(
Int32(x.size), .init(xPointer.baseAddress), 1, .init(yPointer.baseAddress), 1
)
}
}
return dot
}
I would like to have one generic dot product function instead of defining separate functions for Float
and Double
. I attempted this with the function shown below but I don't know how to convey the type information to the vector structs. I also can't pass a Real
value type to Accelerate so I have to switch on the type to use the appropriate function.
func dotProduct<T: Real>(_ x: Vector<T>, _ y: Vector<T>) -> T {
precondition(x.size == y.size, "Vectors must be same size")
switch T.self {
case is Float.Type:
var dot: Float = 0
x.values.withUnsafeBufferPointer { xPointer in
y.values.withUnsafeBufferPointer { yPointer in
dot = cblas_sdot(
Int32(x.size), .init(xPointer.baseAddress), 1, .init(yPointer.baseAddress), 1
)
}
}
return dot
case is Double.Type:
var dot: Double = 0
x.values.withUnsafeBufferPointer { xPointer in
y.values.withUnsafeBufferPointer { yPointer in
dot = cblas_ddot(
Int32(x.size), .init(xPointer.baseAddress), 1, .init(yPointer.baseAddress), 1
)
}
}
return dot
default:
fatalError("Only Float and Double are supported")
}
}
Does the Numerics package have any features that would help me write generic functions that use the Accelerate framework? I know I have asked similar questions in the forum on this topic but those questions didn't involve the use of the Numerics package.