@@ -77,8 +77,9 @@ if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 4.0, *) {
77
77
78
78
if #available( macOS 10 . 15 , iOS 13 . 0 , tvOS 13 . 0 , watchOS 6 . 0 , * ) {
79
79
80
+ let n = 1024
81
+
80
82
AccelerateTests . test ( " vDSP/DiscreteCosineTransform " ) {
81
- let n = 1024
82
83
83
84
let source = ( 0 ..< n) . map { i in
84
85
return sin ( Float ( i) * 0.05 ) + sin( Float ( i) * 0.025 )
@@ -110,18 +111,17 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
110
111
source,
111
112
& legacyDestination)
112
113
113
- expectTrue ( destination . elementsEqual ( legacyDestination) )
114
- expectTrue ( destination . elementsEqual ( returnedResult) )
114
+ expectTrue ( elementsAlmostEqual ( destination , legacyDestination) )
115
+ expectTrue ( elementsAlmostEqual ( destination , returnedResult) )
115
116
}
116
117
}
117
118
}
118
-
119
+
119
120
//===----------------------------------------------------------------------===//
120
121
//
121
122
// Sliding window summation
122
123
//
123
124
//===----------------------------------------------------------------------===//
124
-
125
125
if #available( macOS 10 . 15 , iOS 13 . 0 , tvOS 13 . 0 , watchOS 6 . 0 , * ) {
126
126
127
127
AccelerateTests . test ( " vDSP/SinglePrecisionSlidingWindowSum " ) {
@@ -135,7 +135,7 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
135
135
let returnedResult = vDSP. slidingWindowSum ( source,
136
136
usingWindowLength: 3 )
137
137
138
- expectTrue ( destination . elementsEqual ( returnedResult) )
138
+ expectTrue ( elementsAlmostEqual ( destination , returnedResult) )
139
139
expectTrue ( destination. map { Int ( $0) } . elementsEqual ( [ 23 , 31 , 24 , 19 , 12 , 15 ] ) )
140
140
}
141
141
@@ -150,8 +150,7 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
150
150
let returnedResult = vDSP. slidingWindowSum ( source,
151
151
usingWindowLength: 3 )
152
152
153
- expectTrue ( destination. elementsEqual ( returnedResult) )
154
-
153
+ expectTrue ( elementsAlmostEqual ( destination, returnedResult) )
155
154
expectTrue ( destination. map { Int ( $0) } . elementsEqual ( [ 23 , 31 , 24 , 19 , 12 , 15 ] ) )
156
155
}
157
156
@@ -194,8 +193,8 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
194
193
let returnedResult = vDSP. linearInterpolate ( a, b,
195
194
using: interpolationConstant)
196
195
197
- expectTrue ( result . elementsEqual ( legacyResult) )
198
- expectTrue ( result . elementsEqual ( returnedResult) )
196
+ expectTrue ( elementsAlmostEqual ( result , legacyResult) )
197
+ expectTrue ( elementsAlmostEqual ( result , returnedResult) )
199
198
}
200
199
201
200
AccelerateTests . test ( " vDSP/SinglePrecisionInterpolateBetweenNeighbours " ) {
@@ -230,8 +229,8 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
230
229
let returnedResult = vDSP. linearInterpolate ( elementsOf: shortSignal,
231
230
using: controlVector)
232
231
233
- expectTrue ( result . elementsEqual ( legacyResult) )
234
- expectTrue ( result . elementsEqual ( returnedResult) )
232
+ expectTrue ( elementsAlmostEqual ( result , legacyResult) )
233
+ expectTrue ( elementsAlmostEqual ( result , returnedResult) )
235
234
}
236
235
237
236
AccelerateTests . test ( " vDSP/DoublePrecisionInterpolateBetweenVectors " ) {
@@ -261,8 +260,8 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
261
260
let returnedResult = vDSP. linearInterpolate ( a, b,
262
261
using: interpolationConstant)
263
262
264
- expectTrue ( result . elementsEqual ( legacyResult) )
265
- expectTrue ( result . elementsEqual ( returnedResult) )
263
+ expectTrue ( elementsAlmostEqual ( result , legacyResult) )
264
+ expectTrue ( elementsAlmostEqual ( result , returnedResult) )
266
265
}
267
266
268
267
AccelerateTests . test ( " vDSP/DoublePrecisionInterpolateBetweenNeighbours " ) {
@@ -297,8 +296,8 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
297
296
let returnedResult = vDSP. linearInterpolate ( elementsOf: shortSignal,
298
297
using: controlVector)
299
298
300
- expectTrue ( result . elementsEqual ( legacyResult) )
301
- expectTrue ( result . elementsEqual ( returnedResult) )
299
+ expectTrue ( elementsAlmostEqual ( result , legacyResult) )
300
+ expectTrue ( elementsAlmostEqual ( result , returnedResult) )
302
301
}
303
302
}
304
303
@@ -344,8 +343,8 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
344
343
coefficients [ 3 ] ,
345
344
coefficients [ 4 ] ) )
346
345
347
- expectTrue ( result . elementsEqual ( legacyResult) )
348
- expectTrue ( result . elementsEqual ( returnedResult) )
346
+ expectTrue ( elementsAlmostEqual ( result , legacyResult) )
347
+ expectTrue ( elementsAlmostEqual ( result , returnedResult) )
349
348
}
350
349
351
350
AccelerateTests . test ( " vDSP/DifferenceEquationDoublePrecision " ) {
@@ -382,8 +381,8 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
382
381
coefficients [ 3 ] ,
383
382
coefficients [ 4 ] ) )
384
383
385
- expectTrue ( result . elementsEqual ( legacyResult) )
386
- expectTrue ( result . elementsEqual ( returnedResult) )
384
+ expectTrue ( elementsAlmostEqual ( result , legacyResult) )
385
+ expectTrue ( elementsAlmostEqual ( result , returnedResult) )
387
386
}
388
387
}
389
388
@@ -430,8 +429,8 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
430
429
decimationFactor: decimationFactor,
431
430
filter: filter)
432
431
433
- expectTrue ( result . elementsEqual ( legacyResult) )
434
- expectTrue ( result . elementsEqual ( returnedResult) )
432
+ expectTrue ( elementsAlmostEqual ( result , legacyResult) )
433
+ expectTrue ( elementsAlmostEqual ( result , returnedResult) )
435
434
}
436
435
437
436
AccelerateTests . test ( " vDSP/DownsampleDoublePrecision " ) {
@@ -470,8 +469,8 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
470
469
decimationFactor: decimationFactor,
471
470
filter: filter)
472
471
473
- expectTrue ( result . elementsEqual ( legacyResult) )
474
- expectTrue ( result . elementsEqual ( returnedResult) )
472
+ expectTrue ( elementsAlmostEqual ( result , legacyResult) )
473
+ expectTrue ( elementsAlmostEqual ( result , returnedResult) )
475
474
}
476
475
}
477
476
@@ -503,8 +502,8 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
503
502
let returnedResult = vDSP. evaluatePolynomial ( usingCoefficients: coefficients,
504
503
withVariables: variables)
505
504
506
- expectTrue ( result . elementsEqual ( legacyResult) )
507
- expectTrue ( result . elementsEqual ( returnedResult) )
505
+ expectTrue ( elementsAlmostEqual ( result , legacyResult) )
506
+ expectTrue ( elementsAlmostEqual ( result , returnedResult) )
508
507
}
509
508
510
509
AccelerateTests . test ( " vDSP/PolynomialEvaluationDoublePrecision " ) {
@@ -527,8 +526,53 @@ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) {
527
526
let returnedResult = vDSP. evaluatePolynomial ( usingCoefficients: coefficients,
528
527
withVariables: variables)
529
528
530
- expectTrue ( result. elementsEqual ( legacyResult) )
531
- expectTrue ( result. elementsEqual ( returnedResult) )
529
+ expectTrue ( elementsAlmostEqual ( result, legacyResult) )
530
+ expectTrue ( elementsAlmostEqual ( result, returnedResult) )
531
+ }
532
+
533
+ //===----------------------------------------------------------------------===//
534
+ //
535
+ // Array almost equal.
536
+ //
537
+ //===----------------------------------------------------------------------===//
538
+
539
+ func elementsAlmostEqual< T: FloatingPoint > ( _ lhs: [ T ] , _ rhs: [ T ] ) -> Bool {
540
+ var returnValue = true
541
+ zip ( lhs, rhs) . forEach {
542
+ if !isAlmostEqual( $0. 0 , $0. 1 ) {
543
+ returnValue = false
544
+ return
545
+ }
546
+ }
547
+ return returnValue
548
+ }
549
+
550
+ func isAlmostEqual< T: FloatingPoint > ( _ lhs: T ,
551
+ _ rhs: T ,
552
+ tolerance: T = T . ulpOfOne. squareRoot ( ) ) -> Bool {
553
+ assert ( tolerance >= . ulpOfOne && tolerance < 1 , " tolerance should be in [.ulpOfOne, 1). " )
554
+ guard lhs. isFinite && rhs. isFinite else {
555
+ return rescaledAlmostEqual ( lhs, rhs, tolerance: tolerance)
556
+ }
557
+ let scale = max ( abs ( lhs) , abs ( rhs) , . leastNormalMagnitude)
558
+ return abs ( lhs - rhs) < scale*tolerance
559
+ }
560
+
561
+ func rescaledAlmostEqual< T: FloatingPoint > ( _ lhs: T ,
562
+ _ rhs: T ,
563
+ tolerance: T ) -> Bool {
564
+ if lhs. isNaN || rhs. isNaN { return false }
565
+ if lhs. isInfinite {
566
+ if rhs. isInfinite { return lhs == rhs }
567
+ let scaledLhs = T ( sign: lhs. sign,
568
+ exponent: T . greatestFiniteMagnitude. exponent,
569
+ significand: 1 )
570
+ let scaledRhs = T ( sign: . plus,
571
+ exponent: - 1 ,
572
+ significand: rhs)
573
+ return isAlmostEqual ( scaledLhs, scaledRhs, tolerance: tolerance)
574
+ }
575
+ return rescaledAlmostEqual ( rhs, lhs, tolerance: tolerance)
532
576
}
533
577
}
534
578
0 commit comments