From 67da3c23594a0bfb4268892b9e190c026ff2b1e1 Mon Sep 17 00:00:00 2001 From: Mingchung Xia <mingchung.xia@gmail.com> Date: Sat, 16 Mar 2024 16:59:52 -0400 Subject: [PATCH] Added basic linux support for similarity metrics --- .../HNSW/CartesianDistanceMetric.swift | 19 ++++++++++++++++++ .../HNSW/CosineSimilarityMetric.swift | 20 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/Sources/SwiftNLP/1. Data Collection/HNSW/CartesianDistanceMetric.swift b/Sources/SwiftNLP/1. Data Collection/HNSW/CartesianDistanceMetric.swift index 3b2b7dc6..70678a58 100644 --- a/Sources/SwiftNLP/1. Data Collection/HNSW/CartesianDistanceMetric.swift +++ b/Sources/SwiftNLP/1. Data Collection/HNSW/CartesianDistanceMetric.swift @@ -26,6 +26,10 @@ import Foundation import SimilarityMetric + +#if canImport(Surge) && canImport(Accelerate) && os(macOS) + +import Accelerate import Surge public struct CartesianDistanceMetric<Vector: Collection & Codable>: SimilarityMetric where Vector.Element: BinaryFloatingPoint { @@ -33,3 +37,18 @@ public struct CartesianDistanceMetric<Vector: Collection & Codable>: SimilarityM return Vector.Element(Surge.distSq(someItem as! [Double], otherItem as! [Double])) } } + +#else + +// This may be less efficient on Linux + +public struct CartesianDistanceMetric<Vector: Collection & Codable>: SimilarityMetric where Vector.Element: BinaryFloatingPoint { + public func similarity(between someItem: Vector, _ otherItem: Vector) -> Vector.Element { + return someItem.enumerated().reduce(0) { result, item in + let diff = item.element - otherItem[item.offset] + return result + diff * diff + } + } +} + +#endif diff --git a/Sources/SwiftNLP/1. Data Collection/HNSW/CosineSimilarityMetric.swift b/Sources/SwiftNLP/1. Data Collection/HNSW/CosineSimilarityMetric.swift index 54d10b68..66b2f389 100644 --- a/Sources/SwiftNLP/1. Data Collection/HNSW/CosineSimilarityMetric.swift +++ b/Sources/SwiftNLP/1. Data Collection/HNSW/CosineSimilarityMetric.swift @@ -5,6 +5,8 @@ // Created by Mingchung Xia on 2024-03-14. // +#if canImport(Surge) && canImport(Accelerate) && os(macOS) + import Foundation import Accelerate import SimilarityMetric @@ -33,3 +35,21 @@ public struct CosineSimilarityMetric<Vector: Collection & Codable>: SimilarityMe return Vector.Element(cosineSimilarity) } } + +#else + +// This may be less efficient on Linux + +public struct CosineSimilarityMetric<Vector: Collection & Codable>: SimilarityMetric where Vector.Element: BinaryFloatingPoint { + public func similarity(between someItem: Vector, _ otherItem: Vector) -> Vector.Element { + let dotProduct = zip(someItem, otherItem).reduce(0) { $0 + $1.0 * $1.1 } + let magnitudeSomeItem = sqrt(someItem.reduce(0) { $0 + $1 * $1 }) + let magnitudeOtherItem = sqrt(otherItem.reduce(0) { $0 + $1 * $1 }) + + let cosineSimilarity = dotProduct / (magnitudeSomeItem * magnitudeOtherItem) + + return cosineSimilarity + } +} + +#endif -- GitLab