diff --git a/Package.swift b/Package.swift index 109d7878..3a66975b 100644 --- a/Package.swift +++ b/Package.swift @@ -20,11 +20,14 @@ let package = Package( targets: ["Algorithms"]), ], dependencies: [ + .package(url: "https://github.com/apple/swift-numerics", from: "0.0.1"), ], targets: [ .target( name: "Algorithms", - dependencies: []), + dependencies: [ + .product(name: "RealModule", package: "swift-numerics"), + ]), .testTarget( name: "SwiftAlgorithmsTests", dependencies: ["Algorithms"]), diff --git a/Sources/Algorithms/RandomSample.swift b/Sources/Algorithms/RandomSample.swift index c8ffd4d8..f358abe7 100644 --- a/Sources/Algorithms/RandomSample.swift +++ b/Sources/Algorithms/RandomSample.swift @@ -9,17 +9,9 @@ // //===----------------------------------------------------------------------===// -// For log(_:) and exp(_:) -#if canImport(Glibc) +// For log(_:) and root(_:_:) @_implementationOnly -import Glibc -#elseif canImport(ucrt) -@_implementationOnly -import ucrt -#elseif canImport(Darwin) -@_implementationOnly -import Darwin -#endif +import RealModule //===----------------------------------------------------------------------===// // randomStableSample(count:) @@ -90,15 +82,15 @@ extension Collection { // https://dl.acm.org/doi/pdf/10.1145/198429.198435 fileprivate func nextW( - k: Double, using rng: inout G + k: Int, using rng: inout G ) -> Double { - exp(log(Double.random(in: 0..<1, using: &rng)) / k) + Double.root(.random(in: 0..<1, using: &rng), k) } fileprivate func nextOffset( w: Double, using rng: inout G ) -> Int { - Int(log(Double.random(in: 0..<1, using: &rng)) / log(1 - w)) + Int(Double.log(.random(in: 0..<1, using: &rng)) / .log(1 - w)) } extension Collection { @@ -129,11 +121,10 @@ extension Collection { result.append(self[i]) formIndex(after: &i) } - - let dk = Double(k) + while i < endIndex { // Calculate the next value of w. - w *= nextW(k: dk, using: &rng) + w *= nextW(k: k, using: &rng) // Find index of the next element to swap into the reservoir. let offset = nextOffset(w: w, using: &rng) @@ -198,10 +189,9 @@ extension Sequence { result.append(el) } - let dk = Double(k) while true { // Calculate the next value of w. - w *= nextW(k: dk, using: &rng) + w *= nextW(k: k, using: &rng) // Find the offset of the next element to swap into the reservoir. var offset = nextOffset(w: w, using: &rng) + 1