|
| 1 | +using LinearAlgebra |
| 2 | +import DifferentiationInterface |
| 3 | +using DifferentiationInterface: AutoZygote, AutoEnzyme |
| 4 | +import Zygote, Enzyme |
| 5 | +using FiniteDiff: finite_difference_derivative |
| 6 | + |
| 7 | +DI = DifferentiationInterface |
| 8 | +backend = AutoZygote() |
| 9 | +# backend = AutoEnzyme(; mode = Enzyme.Reverse, function_annotation = Enzyme.Const) |
| 10 | + |
| 11 | +@testset "Zygote-over-TaylorDiff on same variable" begin |
| 12 | + # Scalar functions |
| 13 | + some_number = 0.7 |
| 14 | + some_numbers = [0.3, 0.4, 0.1] |
| 15 | + for f in (exp, log, sqrt, sin, asin, sinh, asinh, x -> x^3) |
| 16 | + @test DI.derivative(x -> derivative(f, x, 2), backend, some_number) ≈ |
| 17 | + derivative(f, some_number, 3) |
| 18 | + @test DI.jacobian(x -> derivative.(f, x, 2), backend, some_numbers) ≈ |
| 19 | + diagm(derivative.(f, some_numbers, 3)) |
| 20 | + end |
| 21 | + |
| 22 | + # Vector functions |
| 23 | + g(x) = x[1] * x[1] + x[2] * x[2] |
| 24 | + @test DI.gradient(x -> derivative(g, x, [1.0, 0.0], 1), backend, [1.0, 2.0]) ≈ |
| 25 | + [2.0, 0.0] |
| 26 | + |
| 27 | + # Matrix functions |
| 28 | + some_matrix = [0.7 0.1; 0.4 0.2] |
| 29 | + f(x) = sum(exp.(x), dims = 1) |
| 30 | + dfdx1(x) = derivative(f, x, [1.0, 0.0], 1) |
| 31 | + dfdx2(x) = derivative(f, x, [0.0, 1.0], 1) |
| 32 | + res(x) = sum(dfdx1(x) .+ 2 * dfdx2(x)) |
| 33 | + grad = DI.gradient(res, backend, some_matrix) |
| 34 | + @test grad ≈ [1 0; 0 2] * exp.(some_matrix) |
| 35 | +end |
| 36 | + |
| 37 | +@testset "Zygote-over-TaylorDiff on different variable" begin |
| 38 | + linear_model(x, p, b) = exp.(b + p * x + b)[1] |
| 39 | + loss_taylor(x, p, b, v) = derivative(x -> linear_model(x, p, b), x, v, 1) |
| 40 | + ε = cbrt(eps(Float64)) |
| 41 | + loss_finite(x, p, b, v) = (linear_model(x + ε * v, p, b) - |
| 42 | + linear_model(x - ε * v, p, b)) / (2 * ε) |
| 43 | + let some_x = [0.58, 0.36], some_v = [0.23, 0.11], some_p = [0.49 0.96], some_b = [0.88] |
| 44 | + @test DI.gradient( |
| 45 | + p -> loss_taylor(some_x, p, some_b, some_v), backend, some_p) ≈ |
| 46 | + DI.gradient( |
| 47 | + p -> loss_finite(some_x, p, some_b, some_v), backend, some_p) |
| 48 | + end |
| 49 | +end |
0 commit comments