my general idea is to
- Fourier transform some data
- Select out a few modes which meet certain criteria, by putting all other modes to zero
- Do an inverse Fourier transformation
The physics scenario could be to select only the modes with some given wave number.
Here is my implementation. I'm using a two-dimensional example but ultimately my data is 3D.
(* generate data *)
n = 16;
l = RandomReal[{-1, 1}, {n, n}];
(* define the wave vectors *)
kx = {Range[0, n/2 - 1], Range[-n/2, -1]} // Flatten // N;
kvec = Outer[List, kx, kx];
(* compute the norm of each wave vector *)
knorm = Map[Round@*Norm, kvec, {2}];
(* let's say we want to filter out the wave number = 3 modes *)
p = 3;
(* find out where the modes are *)
pos = Position[knorm, p];
(* using the factor g to make all other modes 0 *)
g = ConstantArray[0, {n, n}] // ReplacePart[#, pos -> 1] &;
Re@InverseFourier[g*Fourier[l]]
Altogether I can write some function like
Clear[fourierFilter]
fourierFilter[l_, p_] := Module[{n, kx, knorm, pos, g},
n = Dimensions[l][[1]];
kx = {Range[0, n/2 - 1], Range[-n/2, -1]} // Flatten // N;
knorm = Map[Round@*Norm, Outer[List, kx, kx], {2}];
pos = Position[knorm, p];
g = ConstantArray[0, {n, n}] // ReplacePart[#, pos -> 1] &;
Re@InverseFourier[g*Fourier[l]]
]
Is there a better way to implement the idea, either in terms of time or memory efficiency? I know Fourier
can take a second argument which specifies which mode I want, but I'm not sure if there is a straightforward way to inverse transform with these selected modes. I tried to do that by hand but it turns out to be slower than the implementation above.