Skip to content

Commit db46cc9

Browse files
committed
Add vDSP_vsortD
1 parent 3d8429d commit db46cc9

File tree

3 files changed

+82
-2
lines changed

3 files changed

+82
-2
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ The package is structured as follows:
6161
- [x] `vDSP_vsqD` - Square a vector
6262
- [x] `vDSP_dotprD` - Dot product of two vectors
6363
- [x] `vDSP_vlimD` - Limit a vector to a range
64-
- [c] `vDSP_vclipcD` - Clip a vector to a range
64+
- [x] `vDSP_vclipcD` - Clip a vector to a range
6565
- [x] `vDSP_vrsumD` - Recursive sum of a vector
66-
- [ ] `vDSP_vsortD` - Sort a vector
66+
- [x] `vDSP_vsortD` - Sort a vector
6767
- [ ] `vDSP_vrampD` - Ramp a vector
6868
- [ ] `vDSP.sum` - Sum of a vector
6969
- [ ] `vDSP.add` - Add two vectors

Sources/AccelerateLinux/VectorOps/VectorBasicOps.swift

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#if canImport(Accelerate)
22
@_exported import Accelerate
33
#else
4+
import CLAPACK
45

56
/// Calculates the double-precision maximum value of a vector.
67
/// - Parameters:
@@ -349,4 +350,70 @@ public func vDSP_vrsumD(
349350

350351
aux(__A, __IA, __S, __C, __IC, __N)
351352
}
353+
354+
/// Performs an in-place sort of a double-precision vector.
355+
/// - Parameters:
356+
/// - __C: The vector that the function sorts in-place.
357+
/// - __N: The number of elements in the vector.
358+
/// - __Order: A value that specifies the sort order. Pass 1 to specify ascending order, or -1 for descending order.
359+
#warning("If the array is bigger than Int.max, vDSP_vsortD will do nothing. Find a solution")
360+
public func vDSP_vsortD(
361+
_ __C: UnsafeMutablePointer<Double>,
362+
_ __N: vDSP_Length,
363+
_ __Order: Int32
364+
) {
365+
// If dealing with 32 bit use LAPACK
366+
#warning("Update this when we switch to 64 bit compat")
367+
if __N <= vDSP_Length(Int32.max) {
368+
var n = Int32(__N)
369+
var info = Int32(0)
370+
371+
return dlasrt_(
372+
(__Order == 1) ? "I" : "D",
373+
&n,
374+
__C,
375+
&info,
376+
0
377+
)
378+
}
379+
380+
let length = Int(__N - 1)
381+
guard length > 0 else { return }
382+
quicksort(__C, __N, __Order, p: 0, r: Int(__N - 1))
383+
}
384+
385+
private func quicksort(
386+
_ vec: UnsafeMutablePointer<Double>,
387+
_ len: vDSP_Length,
388+
_ ord: Int32,
389+
p: Int,
390+
r: Int
391+
) {
392+
func partition(
393+
_ vec: UnsafeMutablePointer<Double>,
394+
p: Int,
395+
r: Int,
396+
ord: Int32
397+
) -> Int {
398+
let x = vec[r]
399+
var i = p - 1
400+
var j = p
401+
while j < r {
402+
if (ord == 1 && vec[j] < x) || (ord == -1 && vec[j] > x) {
403+
i += 1
404+
swap(&vec[Int(j)], &vec[Int(i)])
405+
}
406+
j += 1
407+
}
408+
i += 1
409+
swap(&vec[Int(i)], &vec[Int(r)])
410+
return i
411+
}
412+
413+
if p < r {
414+
let q = partition(vec, p: p, r: r, ord: ord)
415+
quicksort(vec, len, ord, p: p, r: q - 1)
416+
quicksort(vec, len, ord, p: q + 1, r: r)
417+
}
418+
}
352419
#endif

Tests/AccelerateLinuxTests/VectorTests/VectorBasicOpsTests.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,17 @@ struct VectorBasicOpsTests {
285285

286286
#expect(c == [0.0, 20.0, 50.0, 90.0])
287287
}
288+
289+
@Test("vDSP_vsortD")
290+
func vDSP_vsortDTest() {
291+
var a: [Double] = [15.0, 3.0, 9.0, -23.0]
292+
293+
vDSP_vsortD(
294+
&a,
295+
4,
296+
1
297+
)
298+
299+
#expect(a == [-23.0, 3.0, 9.0, 15.0])
300+
}
288301
}

0 commit comments

Comments
 (0)