# Slicing for Zygote

**URL:** <https://discourse.julialang.org/t/slicing-for-zygote/52042>\
**Category:** New to Julia\
**Tags:** question, zygote\
**Created:** [December 18, 2020, 11:35am UTC](https://discourse.julialang.org/t/slicing-for-zygote/52042 "2020-12-18T11:35:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![kadir-gunel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kadir-gunel/32/35790_2.png) [@kadir-gunel](https://discourse.julialang.org/u/kadir-gunel)\
**Post date:** [December 18, 2020, 11:35am UTC](https://discourse.julialang.org/t/slicing-for-zygote/52042/1 "2020-12-18T11:35:51Z")

</div>

Hello,

Do you remember this issue [Understanding Flux and Zygote …](https://discourse.julialang.org/t/understanding-flux-and-zygote-mutating-errors-not-supported-and-a-new-error/51860/4) I got stuck with slicing again. And since I do not know how to use Zygote properly I couldn’t make progress.

The original function `istft` . And my objective is to convert this function to handle 3d-arrays. To do so first I wanted to see how the first `for` loop can be converted; since it has mutation and slicing.

```julia
using PencilFFTs
using AbstractFFTs: rfft, irfft

function hanning(n::Integer)
    [0.5*(1-cos(2*pi*k/(n-1))) for k=0:n-1]
end

function istft(spectrogram::Matrix{T},
                           framelen::Int=1024,
                           hopsize::Int=div(framelen,2),
                           window=hanning(framelen)) where T <: Complex

    numframes = size(spectrogram, 2)

    expectedlen = framelen + (numframes-1)*hopsize
    reconstructed = zeros(expectedlen)
    windowsum = zeros(expectedlen)
    windowsquare = window .* window

    # Overlapping addition
    for i=1:numframes
        s, e = (i-1)*hopsize+1, (i-1)*hopsize+framelen
        r = irfft(spectrogram[:,i], framelen)
        reconstructed[s:e] += r .* window # how can it be converted w/o slicing? 
        windowsum[s:e] += windowsquare # how can it be converted w/o slicing? 
    end

    # Normalized by window
    for i=1:reconstructed[end]
        # avoid zero division
        if windowsum[i] > 1.0e-7
            reconstructed[i] /= windowsum[i]
        end
    end

    return reconstructed
end

```

The good part is that I can convert most part of the code with directly vector operations. But I could not handle the slicing part where it overlaps and sums.

```julia

function my_istft(spectrogram::Matrix{T},
                            framelen::Int=1024,
                            hopsize::Int=div(framelen, 2),
                            window=hanning(framelen)) where T <: Complex

    numframes = size(spectrogram, 2);
    

    expectedlen = framelen + (numframes-1)*hopsize
    reconstructed = zeros(expectedlen)
    windowsum = zeros(expectedlen)

    se = [(i-1)*hopsize+1:(i-1)*hopsize+framelen for i in 1:numframes]; # starting and ending points of overlaps

    # overlapping
    reconst = vec(irfft(spectrogram, framelen, 1) .* window)
    winsum = vec(ones(framelen, numframes) .* (window .^2))
    idx = winsum .> 1.0e-7 

    reconstructed[s:e] # how can I convert this ? 

    reconst[idx] = reconst[idx] ./ winsum[idx]
    return reconstructed

end

```

My overall objective is to convert this method for n-dimensional arrays. But since the 2-d arrays are more simple . I chose to translate first with this.

Could you help me to convert the function ?

B.R.

p.s. The first `istft` is not mine I cloned it from another repo and did some minor changes for Julia 1.5 support.

---

<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:** [December 18, 2020, 3:39pm UTC](https://discourse.julialang.org/t/slicing-for-zygote/52042/2 "2020-12-18T15:39:36Z")

</div>

Without checking anything too carefully, can you do something like this?

```julia
# test data:
spectrogram = rand(ComplexF32, 5,16)
framelen = 8
hopsize = 4
window=hanning(framelen) # real 8-vec
numframes = size(spectrogram, 2) # 16
expectedlen = framelen + (numframes-1)*hopsize # 68

# even/odd & combine:
wr_odd = window .* irfft(spectrogram[:,1:2:end], framelen, 1)
wr_even = window .* irfft(spectrogram[:,2:2:end], framelen, 1)
recon5 = vcat(vec(wr_odd), zeros(hopsize)) .+ vcat(zeros(hopsize), vec(wr_even))

reconstructed ≈ recon5 # after stage "Overlapping addition"

```

---

<div class="post-metadata">

**Author:** ![kadir-gunel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kadir-gunel/32/35790_2.png) [@kadir-gunel](https://discourse.julialang.org/u/kadir-gunel)\
**Post date:** [December 22, 2020, 7:03am UTC](https://discourse.julialang.org/t/slicing-for-zygote/52042/3 "2020-12-22T07:03:18Z")

</div>

@mcabbott thank you. Now, it works on 4 dimensional arrays. In addition, the original function is now faster 🙂
