# ForwardDiff.jl with Symbolics.jl

**URL:** https://discourse.julialang.org/t/forwarddiff-jl-with-symbolics-jl/98706
**Category:** General Usage
**Tags:** question, forwarddiff, symbolics
**Created:** [May 11, 2023, 11:18pm UTC](https://discourse.julialang.org/t/forwarddiff-jl-with-symbolics-jl/98706 "2023-05-11T23:18:49Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![dchang10](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dchang10/32/44162_2.png) [@dchang10](https://discourse.julialang.org/u/dchang10)
#### Post date: [May 11, 2023, 11:18pm UTC](https://discourse.julialang.org/t/forwarddiff-jl-with-symbolics-jl/98706/1 "2023-05-11T23:18:49Z")

</div>

I’m trying to do mixed symbolic and numeric derivatives. I want to define a type that holds a function that I will use to differentiate on in the future, this function may be ill-defined, so I would like to be able to operate on symbols.

In this MWE, I define an example type that stores the function. `ForwardDiff` works fine with the symbolic arguments as long as the function definition is exact.

```julia
using Symbolics, ForwardDiff

struct ExampleType
    func
end

function foo(obj, args)
    tempfunc(θ) = obj.func(θ...)
    return ForwardDiff.gradient(tempfunc, args)
end

myobj1 = ExampleType(+)
@variables r, θ
foo(myobj1, [r,θ]) # This works

```

The problem appears if I define a function that returns some sort of symbol.

```julia
function ω(r, θ)
    @variables ω(..)
    return ω(r,θ)
end
myobj2 = ExampleType(ω)
foo(myobj2, [r,θ]) # This does not work        

```

I get the following error message when I attempt to do this.

```julia
ERROR: DimensionMismatch: gradient(f, x) expects that f(x) is a real number. Perhaps you meant jacobian(f, x)?

```

I’ve tried defining a custom diff\_rule with no luck.

```julia
ForwardDiff.DiffRules.@define_diffrule Main.ω(r, θ) = :(Differential($r)(ω($r,$θ))), :(Differential($θ)(ω($r,$θ)))
f

```

Is there someway to define custom derivatives on these. sort of objects?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [May 11, 2023, 11:43pm UTC](https://discourse.julialang.org/t/forwarddiff-jl-with-symbolics-jl/98706/2 "2023-05-11T23:43:13Z")

</div>

What about manually defining the dual numbers?

---

<div class="post-metadata">

### Author: ![dchang10](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dchang10/32/44162_2.png) [@dchang10](https://discourse.julialang.org/u/dchang10)
#### Post date: [July 26, 2023, 4:36pm UTC](https://discourse.julialang.org/t/forwarddiff-jl-with-symbolics-jl/98706/3 "2023-07-26T16:36:08Z")

</div>

I bumped into you at juliacon and decided to try resurrecting this question. Do you mean defining a custom dual number, and overloading gradient’s behaviour on that dual number?

One thing that I tried that did work was overloading the function to act appropriately on each argument signature. Something like this worked:

```julia
function ω(r, θ)
    @variables ω(..)
    return ω(r,θ)
end
function ω(r::ForwardDiff.Dual{T}, θ) where T
    @variables ω(..)
    return ForwardDiff.Dual{T}(ω(r.value,θ), Differential(r.value)(ω(r.value,θ))*r.partials)
end
function ω(r, θ::ForwardDiff.Dual{T}) where T
    @variables ω(..)
    return Dual{T}(ω(r,θ.value), Differential(θ.value)(ω(r,θ.value))*θ.partials)
end
function ω(r::ForwardDiff.Dual{T}, θ::ForwardDiff.Dual{T}) where T
    @variables ω(..)
    return ForwardDiff.Dual{T}(ω(r.value,θ.value), Differential(r.value)(ω(r.value,θ.value))*r.partials+Differential(θ.value)(ω(r.value,θ.value))*θ.partials)
end
myobj2 = ExampleType(ω)
foo(myobj2, [r,θ]) # This worked

```

This solution seems to require a lot of boiler plate code though.

It also has the added issue that it doesn’t work past taking the first derivative. I seem to need to define dynamic dispatch on argument signatures associated with higher order derivatives.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [July 28, 2023, 2:43pm UTC](https://discourse.julialang.org/t/forwarddiff-jl-with-symbolics-jl/98706/4 "2023-07-28T14:43:28Z")

</div>

No overloads or new types. Just define a dual number with Num values in the primal and dual parts and then stick it into the function and interpret the output. Find me at the hackathon if you need help.
