I’d like to be able to create this tensor without using Numpy, but I can’t find the PyTorch equivalent to Numpy’s fft.fftfreq
:
import numpy as np
def get_fft_scale(h, w, decay_power=.75):
d=.5**.5 # set center frequency scale to 1
fy = np.fft.fftfreq(h,d=d)[:,None]
if w % 2 == 1:
fx = np.fft.fftfreq(w,d=d)[: w // 2 + 2]
else:
fx = np.fft.fftfreq(w,d=d)[: w // 2 + 1]
freqs = (fx*fx + fy*fy) ** decay_power
scale = 1.0 / np.maximum(freqs, 1.0 / (max(w, h)*d))
scale = torch.Tensor(scale).float()[None,None,...,None]
return scale
albanD
(Alban D)
May 12, 2020, 5:11pm
2
Hi,
What is the difference between this and a histogram functions?
So, I guess the question is how to generate the initial tensors then?
>>> import numpy as np
>>> h = 8
>>> d = .5**.5
>>> fy = np.fft.fftfreq(h,d=d)
>>> fy
array([ 0. , 0.1767767 , 0.35355339, 0.53033009, -0.70710678,
-0.53033009, -0.35355339, -0.1767767 ])
I’m not quite sure. I’m using this tensor for spatial decorrelation of a tensor.
albanD
(Alban D)
May 12, 2020, 6:57pm
5
Given this and the definition in their doc, it feels like you can implement it with a simple arange function no?
It looks like I can recreate it with the following function, using torch.arange
twice:
def create_freq_tensor(size, cf=.5**.5):
step=(cf/(size/2))
end = (step * size)/2
return torch.cat([torch.arange(0,end=end,step=step), torch.arange(-cf, end=0, step=step)])
1 Like
And then I guess this is the full function:
def create_freq_tensor(size, cf=.5**.5, device='cpu'):
step=(cf/(size/2))
end = (step * size)/2
return torch.cat([torch.arange(0, end=end, step=step, device=device), torch.arange(-cf, end=0, step=step, device=device)])
def get_fft_scale(h, w, decay_power=.75, device='cpu'):
d=.5**.5
fy = create_freq_tensor(h, device=device)[:,None]
if w % 2 == 1:
wadd = 2
else:
wadd = 1
fx = create_freq_tensor(w, device=device)[: w // 2 + wadd]
freqs = (fx*fx + fy*fy) ** decay_power
scale = 1 / torch.max(freqs, torch.full_like(freqs, 1.0 / (max(w, h)*d)))
return scale[None,None,...,None]
Is there a way I could do it better?
albanD
(Alban D)
May 12, 2020, 7:48pm
9
Given that you take only the first half of the output of create_freq_tensor
, you might just want a single arange call. and you can remove the cat as well no?
Yes, I can just remove the cat as well and instead do this (based on the NumPy code ):
# NumPy fft.fftfreq in PyTorch
def pytorch_fftfreq(n, d=1.0, device='cpu'):
results = torch.empty(n, device=device)
s = (n-1) // 2 + 1
results[:s] = torch.arange(0, s, device=device)
results[s:] = torch.arange(-(n//2), 0, device=device)
return results * (1.0 / (n * d))
1 Like