# Zygote mutating arrays is not supported

**URL:** <https://discourse.julialang.org/t/zygote-mutating-arrays-is-not-supported/47467>\
**Category:** New to Julia\
**Created:** [September 29, 2020, 6:40am UTC](https://discourse.julialang.org/t/zygote-mutating-arrays-is-not-supported/47467 "2020-09-29T06:40:44Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rezabayani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rezabayani/32/25954_2.png) [@rezabayani](https://discourse.julialang.org/u/rezabayani)\
**Post date:** [September 29, 2020, 6:40am UTC](https://discourse.julialang.org/t/zygote-mutating-arrays-is-not-supported/47467/1 "2020-09-29T06:40:44Z")

</div>

I have a problem with differentiation in Zygote. Let me start with an example of what I need to achieve:  
If we have a vector like a = [0,2,4,1], and b = 2, I would like to create a vector which is a binary, with ones as the first 2 (=b) lowest elements of a and the rest be zeros. i.e. my desired output is c = [1,0,0,1] in this case. To this end, I figured that a permutation matrix is needed so that p\*a = sort(a), and here is my problem:  
minimal example:

# first thing I came up with

```julia-auto
function create_prem(a)
    a_sort = sortperm(a)
    a_perm = zeros(4, 4)
    for i in 1:4
        a_perm[i:i,:] = vcat(zeros(a_sort[i]-1, 1),1,zeros(4-a_sort[i], 1))'
    end
    return a_perm
end

function my(a,b)
    p = create_prem(a)
    return sum(a[1:b])
end
a = [0,2,4,1]
gradient(x -> my(x, 2), a) # Error > Mutating arrays is not supported
# this error points to the line in "for" loop. I could circumvent this issue with Buffer()

function create_prem_buffer(a)
    a_sort = sortperm(a)
    buf_perm = Buffer(zeros(4, 4))
    for i in 1:n_ev
        buf_perm[i:i,:] = vcat(zeros(a_sort[i]-1, 1),1,zeros(U, 4-a_sort[i], 1))'
    end
    return copy(buf_perm)
end

function my_buffer(a,b)
    p = create_prem_buffer(a)
    return sum(a[1:b])
end

gradient(x -> my_buffer(x, 2), a) # Error > Mutating arrays is not supported
# this message points to the line "sortperm(a)" and I have no idea how to deal with it.

```

I really appreciate your help in advance.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [September 29, 2020, 9:13am UTC](https://discourse.julialang.org/t/zygote-mutating-arrays-is-not-supported/47467/2 "2020-09-29T09:13:03Z")

</div>

Here’s one way:

```julia
julia> function keepn(a::AbstractVector, b::Int)
         which = sortperm_b(a, b)
         [i in which ? a[i] : zero(eltype(a)) for i in axes(a,1)]
       end;

julia> sortperm_b(a, b::Int) = sortperm(a)[1:b];

julia> Zygote.@nograd sortperm_b

julia> a = [0,2,4,1];

julia> gradient(a -> sum(keepn(a,2)), a)
([1, 0, 0, 1],)

```

I think Zygote ought to have `@nograd sortperm` globally, as that can’t have a sensible gradient, in which case there would be no need to pull this out into its own function like I did.

---

<div class="post-metadata">

**Author:** ![rezabayani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rezabayani/32/25954_2.png) [@rezabayani](https://discourse.julialang.org/u/rezabayani)\
**Post date:** [September 29, 2020, 8:31pm UTC](https://discourse.julialang.org/t/zygote-mutating-arrays-is-not-supported/47467/3 "2020-09-29T20:31:37Z")

</div>

Thanks a lot. This seems to be working.
