Skip to content

Avoid inversion and save some space #4

@psmaragdis

Description

@psmaragdis

Hey Prem,
This snippet looks familiar! :)

You don't need to invert the DFT matrix to get the inverse transform. You can do this instead:

# Transform constants
sz,hp = 128,32
wn = hanning( sz+1)[:-1]**.5

# Make DFT matrix, split into real/imag, scale DC/Nyquist to make orthogonal
f  = fft( eye( sz)) / (.5*sqrt( sz) * sqrt( sz/hp))
f = vstack( (real( f[:sz//2+1,:]),imag(f[:sz//2+1,:])))

# This makes the DFT matrix work in both ways using convs
f[0,:] /= sqrt(2)
f[sz//2,:] /= sqrt(2)

# Make the transform kernel
DFT  = torch.FloatTensor( wn * f)[:,None,:]

# Input is bt x dim x time
x = torch.sin( 64 * torch.linspace( 0, 2*pi, 1024, dtype=torch.float32)).view( 1, 1, -1)

# Do DFT
f = F.conv1d( x, DFT, stride=hp, padding=sz)

# Get amplitude and phase
a = torch.sqrt(  f[:,:sz//2+1,:]**2 + f[:,sz//2+1:,:]**2)
p = torch.atan2( f[:,sz//2+1:,:], f[:,:sz//2+1,:])

# ... process ...

# Stack amplitudes and phase
f = torch.cat( [a*torch.cos( p), a*torch.sin( p)], dim=1)

# Inverse STFT using the same kernel
y = F.conv_transpose1d( f, DFT, stride=hp, padding=sz)

Paris

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions