diff --git a/stdlib/public/Differentiation/FloatingPointDifferentiation.swift.gyb b/stdlib/public/Differentiation/FloatingPointDifferentiation.swift.gyb index f2ff2fcbff530..8d784c1ae1274 100644 --- a/stdlib/public/Differentiation/FloatingPointDifferentiation.swift.gyb +++ b/stdlib/public/Differentiation/FloatingPointDifferentiation.swift.gyb @@ -282,4 +282,22 @@ where let y = squareRoot() return (y, { v in v / (2 * y) }) } + + @inlinable + @derivative(of: minimum) + static func _vjpMinimum(_ x: Self, _ y: Self) -> ( + value: Self, pullback: (TangentVector) -> (TangentVector, TangentVector) + ) { + if x <= y || y.isNaN { return (x, { v in (v, .zero) }) } + return (y, { v in (.zero, v) }) + } + + @inlinable + @derivative(of: maximum) + static func _vjpMaximum(_ x: Self, _ y: Self) -> ( + value: Self, pullback: (TangentVector) -> (TangentVector, TangentVector) + ) { + if x > y || y.isNaN { return (x, { v in (v, .zero) }) } + return (y, { v in (.zero, v) }) + } } diff --git a/test/AutoDiff/stdlib/floating_point.swift.gyb b/test/AutoDiff/stdlib/floating_point.swift.gyb index c1eef2f03a8b5..512070963df7a 100644 --- a/test/AutoDiff/stdlib/floating_point.swift.gyb +++ b/test/AutoDiff/stdlib/floating_point.swift.gyb @@ -83,6 +83,22 @@ FloatingPointDerivativeTests.test("${Self}.addingProduct") { expectEqual((1, 2, 3), gradient(at: ${Self}(10), 3, 2, in: { $0.addingProduct($1, $2) })) } +FloatingPointDerivativeTests.test("${Self}.minimum") { + expectEqual((1.0, 0.0), gradient(at: ${Self}(1), ${Self}(2), in : { ${Self}.minimum($0, $1) })) + expectEqual((1.0, 0.0), gradient(at: ${Self}(1), ${Self}(1), in : { ${Self}.minimum($0, $1) })) + expectEqual((0.0, 1.0), gradient(at: ${Self}(2), ${Self}(1), in : { ${Self}.minimum($0, $1) })) + expectEqual((1.0, 0.0), gradient(at: ${Self}(1), .nan, in : { ${Self}.minimum($0, $1) })) + expectEqual((0.0, 1.0), gradient(at: .nan, ${Self}(1), in : { ${Self}.minimum($0, $1) })) +} + +FloatingPointDerivativeTests.test("${Self}.maximum") { + expectEqual((0.0, 1.0), gradient(at: ${Self}(1), ${Self}(2), in : { ${Self}.maximum($0, $1) })) + expectEqual((0.0, 1.0), gradient(at: ${Self}(1), ${Self}(1), in : { ${Self}.maximum($0, $1) })) + expectEqual((1.0, 0.0), gradient(at: ${Self}(2), ${Self}(1), in : { ${Self}.maximum($0, $1) })) + expectEqual((1.0, 0.0), gradient(at: ${Self}(1), .nan, in : { ${Self}.maximum($0, $1) })) + expectEqual((0.0, 1.0), gradient(at: .nan, ${Self}(1), in : { ${Self}.maximum($0, $1) })) +} + %if Self == 'Float80': #endif %end