# Forwarddiff through setindex

**URL:** https://discourse.julialang.org/t/forwarddiff-through-setindex/67422
**Category:** General Usage
**Tags:** type, forwarddiff, autodiff
**Created:** [August 31, 2021, 12:27pm UTC](https://discourse.julialang.org/t/forwarddiff-through-setindex/67422 "2021-08-31T12:27:33Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)
#### Post date: [August 31, 2021, 12:27pm UTC](https://discourse.julialang.org/t/forwarddiff-through-setindex/67422/1 "2021-08-31T12:27:34Z")

</div>

I’m having trouble differentiating through the `setindex!()` of a custom type.

Here’s a minimum example using the [`ArrayAndChar` type from the Julia docs](https://docs.julialang.org/en/v1/manual/interfaces/) to replicate the issue.

```julia
using ForwardDiff

struct ArrayAndChar{T,N} <: AbstractArray{T,N}
    data::Array{T,N}
    char::Char
end
Base.size(A::ArrayAndChar) = size(A.data)
Base.getindex(A::ArrayAndChar{T,N}, inds::Vararg{Int,N}) where {T,N} = A.data[inds...]
Base.setindex!(A::ArrayAndChar{T,N}, val, inds::Vararg{Int,N}) where {T,N} = A.data[inds...] = val
Base.showarg(io::IO, A::ArrayAndChar, toplevel) = print(io, typeof(A), " with char '", A.char, "'")

function f(x) 
    a = ArrayAndChar(ones(5),'a')
    b = ArrayAndChar(zeros(5),'b')
    for i in eachindex(a,b)
        j = oneunit(i)
        b[i] = x*a[max(j,i-j)]
    end
    b
end
f(2)

```

> 5-element ArrayAndChar{Float64, 1} with char ‘b’:  
> 2.0  
> 2.0  
> 4.0  
> 6.0  
> 8.0

```julia
g(x) = ForwardDiff.derivative(f,x)
g(2)

```

> ERROR: LoadError: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Int64}, Float64, 1})  
> Closest candidates are:  
> (::Type{T})(::Real, ::RoundingMode) where T\<:AbstractFloat at rounding.jl:200  
> (::Type{T})(::T) where T\<:Number at boot.jl:760  
> (::Type{T})(::AbstractChar) where T\<:Union{AbstractChar, Number} at char.jl:50  
> …

> **Stacktrace**
>
> > [1] convert(#unused#::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Int64}, Float64, 1})  
> > @ Base ./number.jl:7  
> > [2] setindex!(A::Vector{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Int64}, Float64, 1}, i1::Int64)  
> > @ Base ./array.jl:839  
> > [3] setindex!(A::ArrayAndChar{Float64, 1}, val::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Int64}, Float64, 1}, inds::Int64)  
> > @ Main ~/Workspace/GeometricMultigrid.jl/MWE.jl:9  
> > [4] \_setindex!  
> > @ ./abstractarray.jl:1297 [inlined]  
> > [5] setindex!  
> > @ ./abstractarray.jl:1267 [inlined]  
> > [6] f(x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Int64}, Int64, 1})  
> > @ Main ~/Workspace/GeometricMultigrid.jl/MWE.jl:16  
> > [7] derivative  
> > @ ~/.julia/packages/ForwardDiff/5gUap/src/derivative.jl:14 [inlined]  
> > [8] g(x::Int64)  
> > @ Main ~/Workspace/GeometricMultigrid.jl/MWE.jl:21  
> > [9] top-level scope

This example works if I replace the loop with something simple like `b=x*a`, but this loop with an index shift is more like what I need.

How can I change `setindex!()` to allow ForwardDiff to change the type to a `Dual` in this example?

---

<div class="post-metadata">

### Author: ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)
#### Post date: [August 31, 2021, 12:38pm UTC](https://discourse.julialang.org/t/forwarddiff-through-setindex/67422/2 "2021-08-31T12:38:07Z")

</div>

Oh, this works!

```julia
function f(x::T) where T
    a = ArrayAndChar([1.,2.,3.,4.,5.],'a')
    b = ArrayAndChar(zeros(T,5),'b')
    for i in eachindex(a,b)
        j = oneunit(i)
        b[i] = x*a[max(j,i-j)]
    end
    b
end

```

So I just needed to initialize the `struct` properly.
