# Taking Complex Autodiff Seriously in ChainRules

**URL:** <https://discourse.julialang.org/t/taking-complex-autodiff-seriously-in-chainrules/39317>\
**Category:** Specific Domains\
**Tags:** numerics, chainrulescore, complex-numbers\
**Created:** [May 12, 2020, 1:52am UTC](https://discourse.julialang.org/t/taking-complex-autodiff-seriously-in-chainrules/39317 "2020-05-12T01:52:35Z")\
**Posts on this page:** 1\
**Showing post:** 62

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [June 27, 2020, 9:22pm UTC](https://discourse.julialang.org/t/taking-complex-autodiff-seriously-in-chainrules/39317/62 "2020-06-27T21:22:54Z")

</div>

Okay, so after some very productive and stimulating conversation, this recent push has resulting in [ChainRulesCore.jl/pull/167](https://github.com/JuliaDiff/ChainRulesCore.jl/pull/167) (thanks @ettersi!) and [ChainRules.jl/pull/196](https://github.com/JuliaDiff/ChainRules.jl/pull/196) which I must say feels like we’ve come up with a really great set of shared definitions and conventions.

The result of @ettersi’s now merged PR can be viewed in all of it’s LaTeX glory here:  
[https://www.juliadiff.org/ChainRulesCore.jl/dev/complex.html](https://www.juliadiff.org/ChainRulesCore.jl/dev/complex.html)

Perhaps next up, we can lift some ideas from here: [Complex Differentiation · Zygote](https://fluxml.ai/Zygote.jl/dev/complex/) such as the example showing how to get the Wirtinger derivatives, \partial \over \partial z and \partial \over \partial \bar{z} from the Jacobian, i.e.

```julia
using ChainRules
function wirtinger_rrule(f, z)
    _, pullback = rrule(f, z)
    du, dv = pullback(1)[2], pullback(im)[2]
    (du' + im*dv')/2, (du + im*dv)/2
end

wirtinger_rrule(abs2, 1 + im)

#+RESULTS:
: (1.0 - 1.0im, 1.0 + 1.0im)

```

```julia
function wirtinger_frule(f, z)
    du_dx, dv_dx = reim(frule((Zero(), 1),f,z)[2])
    du_dy, dv_dy = reim(frule((Zero(),im),f,z)[2])

    (du_dx + dv_dy + im*(-du_dy + dv_dx))/2, (du_dx - dv_dy + im*(du_dy + dv_dx))/2
end

wirtinger_frule(sin, 1 + im)

#+RESULTS:
: (0.8337300251311491 - 0.9888977057628651im, 0.0 + 0.0im)

```

---

_[View the full topic](https://discourse.julialang.org/t/taking-complex-autodiff-seriously-in-chainrules/39317)._
