File: floating_point.swift.gyb

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (126 lines) | stat: -rw-r--r-- 5,003 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// RUN: %target-run-simple-swiftgyb(-Xfrontend -enable-experimental-forward-mode-differentiation)
// REQUIRES: executable_test

#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
  typealias TestLiteralType = Float80
#else
  typealias TestLiteralType = Double
#endif

import _Differentiation
import StdlibUnittest

var FloatingPointDerivativeTests = TestSuite("FloatingPointDerivatives")

func expectEqualWithTolerance<T>(_ expected: TestLiteralType, _ actual: T,
                                 ulps allowed: T = 3,
                                 file: String = #file, line: UInt = #line
) where T: BinaryFloatingPoint {
  if actual == T(expected) || actual.isNaN && expected.isNaN {
    return
  }
  //  Compute error in ulp, compare to tolerance.
  let absoluteError = T(abs(TestLiteralType(actual) - expected))
  let ulpError = absoluteError / T(expected).ulp
  expectTrue(ulpError <= allowed,
             "\(actual) != \(expected) as \(T.self)" +
             "\n  \(ulpError)-ulp error exceeds \(allowed)-ulp tolerance.",
             file: file, line: line)
}

%for Self in ['Float', 'Double', 'Float80']:

%if Self == 'Float80':
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
%end

%for Other in ['Float', 'Double', 'Float80']:
%if Other == 'Float80':
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
%end

FloatingPointDerivativeTests.test("${Self}.init(_:${Other})") {
  expectEqual(1, gradient(at: ${Other}(4), of: ${Self}.init(_:)))
  expectEqual(10, pullback(at: ${Other}(4), of: ${Self}.init(_:))(${Self}(10)))

  expectEqual(1, derivative(at: ${Other}(4), of: ${Self}.init(_:)))
  expectEqual(10, differential(at: ${Other}(4), of: ${Self}.init(_:))(${Other}(10)))
}

%if Other == 'Float80':
#endif
%end
%end # for Other in ['Float', 'Double', 'Float80']:

FloatingPointDerivativeTests.test("${Self}.+") {
  expectEqual((1, 1), gradient(at: ${Self}(4), ${Self}(5), of: +))
  expectEqual((10, 10), pullback(at: ${Self}(4), ${Self}(5), of: +)(${Self}(10)))

  expectEqual(2, derivative(at: ${Self}(4), ${Self}(5), of: +))
  expectEqual(20, differential(at: ${Self}(4), ${Self}(5), of: +)(${Self}(10), ${Self}(10)))
}

FloatingPointDerivativeTests.test("${Self}.-") {
  expectEqual((1, -1), gradient(at: ${Self}(4), ${Self}(5), of: -))
  expectEqual((10, -10), pullback(at: ${Self}(4), ${Self}(5), of: -)(${Self}(10)))

  expectEqual(0, derivative(at: ${Self}(4), ${Self}(5), of: -))
  expectEqual(-5, differential(at: ${Self}(4), ${Self}(5), of: -)(${Self}(5), ${Self}(10)))
}

FloatingPointDerivativeTests.test("${Self}.*") {
  expectEqual((5, 4), gradient(at: ${Self}(4), ${Self}(5), of: *))
  expectEqual((50, 40), pullback(at: ${Self}(4), ${Self}(5), of: *)(${Self}(10)))

  expectEqual(9, derivative(at: ${Self}(4), ${Self}(5), of: *))
  expectEqual(90, differential(at: ${Self}(4), ${Self}(5), of: *)(${Self}(10), ${Self}(10)))
}

FloatingPointDerivativeTests.test("${Self}./") {
  do {
    let (dx, dy) = gradient(at: ${Self}(4), ${Self}(5), of: /)
    expectEqual(0.2, dx)
    expectEqual(-0.16, dy)
  }
  do {
    let (dx, dy) = pullback(at: ${Self}(4), ${Self}(5), of: /)(${Self}(10))
    expectEqual(2, dx)
    expectEqualWithTolerance(-1.6, dy)
  }

  expectEqualWithTolerance(0.04, derivative(at: ${Self}(4), ${Self}(5), of: /))
  expectEqual(90, differential(at: ${Self}(4), ${Self}(5), of: *)(${Self}(10), ${Self}(10)))
}

FloatingPointDerivativeTests.test("${Self}.squareRoot") {
  expectEqual(0.5, gradient(at: 1, of: { $0.squareRoot() }))
  expectEqual(0.25, gradient(at: 4, of: { $0.squareRoot() }))
}

FloatingPointDerivativeTests.test("${Self}.addingProduct") {
  expectEqual((1, 2, 3), gradient(at: ${Self}(10), 3, 2, of: { $0.addingProduct($1, $2) }))
  expectEqual((2, 4, 6), pullback(at: ${Self}(10), 3, 2, of: { $0.addingProduct($1, $2) })(2))
}

FloatingPointDerivativeTests.test("${Self}.minimum") {
  expectEqual((1.0, 0.0), gradient(at: ${Self}(1), ${Self}(2), of: { ${Self}.minimum($0, $1) }))
  expectEqual((1.0, 0.0), gradient(at: ${Self}(1), ${Self}(1), of: { ${Self}.minimum($0, $1) }))
  expectEqual((0.0, 1.0), gradient(at: ${Self}(2), ${Self}(1), of: { ${Self}.minimum($0, $1) }))
  expectEqual((1.0, 0.0), gradient(at: ${Self}(1), .nan, of: { ${Self}.minimum($0, $1) }))
  expectEqual((0.0, 1.0), gradient(at: .nan, ${Self}(1), of: { ${Self}.minimum($0, $1) }))
}

FloatingPointDerivativeTests.test("${Self}.maximum") {
  expectEqual((0.0, 1.0), gradient(at: ${Self}(1), ${Self}(2), of: { ${Self}.maximum($0, $1) }))
  expectEqual((0.0, 1.0), gradient(at: ${Self}(1), ${Self}(1), of: { ${Self}.maximum($0, $1) }))
  expectEqual((1.0, 0.0), gradient(at: ${Self}(2), ${Self}(1), of: { ${Self}.maximum($0, $1) }))
  expectEqual((1.0, 0.0), gradient(at: ${Self}(1), .nan, of: { ${Self}.maximum($0, $1) }))
  expectEqual((0.0, 1.0), gradient(at: .nan, ${Self}(1), of: { ${Self}.maximum($0, $1) }))
}

%if Self == 'Float80':
#endif
%end
%end # for Self in ['Float', 'Double', 'Float80']:

runAllTests()