-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Description
Firstly, thanks the developers for the great package !
I tried to use the package with Zygote.jl
(for automatic differentiation) but sadly this failed due to the usage of =.
in the definition of pfaffian(A)
.
The usual fix for this is to define the backwards derivative manually, in this case I got :
using Zygote
using ChainRulesCore
using ChainRules
function ChainRules.rrule(::typeof(pfaffian), x::Union{Number, AbstractMatrix})
Ω = pfaffian(x)
function det_pullback(ΔΩ)
∂x = x isa Number ? zero(ΔΩ) : #=0.5 *=# inv(x)' * dot(Ω, ΔΩ) #we removed the 0.5 because changing element ij immediatelyu changes element ji.
return (NoTangent(), ∂x)
end
return Ω, det_pullback
end
which works well from the test :
for _ in 1:100
n = rand(1:10)
A = rand(2*n,2*n)
A = A - transpose(A)
A = SkewHermitian(A)
epsi = 1e-6
function make_zero_but_ij(i,j)
out = zero(A)
if i != j
out[i,j] = 1. #note, the one half here is because the pfaffian is antisymmetric in the rows and columns.
end
return out
end
numerical = gradient(x->pfaffian(x), A)[1]
analytical = [(pfaffian(A + epsi*make_zero_but_ij(i,j) )-pfaffian(A))/epsi for i ∈ 1:2*n, j ∈ 1:2*n]
@show analytical ≈ numerical
end
would it be desirable if I made a pull request with this code ?
All the best,
Gertian
Metadata
Metadata
Assignees
Labels
No labels