jakevdp / nfft

Lightweight non-uniform Fast Fourier Transform in Python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Locations of datapoints

KehanLong opened this issue · comments

I am currently playing with the nfft packages in 1D to help me better understand the implementation. However, when I tried some examples below, I got very confusing results. Could you help me with it?

Also, I am confused about how to set the locations of the datapoints, I believe that the locations x should be in the range of [-0.5,0.5), but in my example and other examples in other issues, the locations seem to be not in the range. Could anyone also help me with it?

Screenshot from 2020-01-07 16-06-01
Screenshot from 2020-01-07 16-06-16

See https://github.com/jakevdp/nfft#basic-usage for information on basic usage. The example there is quite similar to what you are trying to do.

Also see #14 for an example of reconstructing a signal.

Hi Jake,

Thanks for your quick reply and help!

The #14 example works in my case, but if I change the input signal into my exam_input and change the time input into my x, the result seems to be wrong (in my original post). I just change the inputs and keep the reconstruction parts the same as in #14.

Also, in #14, the time input t is not in the range of [-0.5,0.5). But in your basic usage, the evaluation points are forced to be in the range of [-0.5,0.5). Could you tell me if there is a function to convert the time input into the range of [-0.5,0.5), or the tine/spatial locations can be some arbitrary numbers?

The package automatically normalizes the domain to lie between -0.5 and 0.5. Look at the source to see the utilities that do this.

I don't know how you computed your f_reconstructed, because x and f_hat have different lengths which leads to an error.

Also, please in the future paste actual code into the issue rather than a screenshot – it makes it much easier to answer your question.

Thanks very much! That helps a lot.

I am currently comparing your methods with the methods in pynfft packages with input data from #14 . By reading your codes and explanations in #14 , I am still not sure why you set N = 100000 in #14 to make the reconstruction work. If N equals the length of the input data (64), the reconstruction does not work well, and the reconstruction results are same in nfft and pynfft.

I just wonder, could you explain a little more about why we choose N = 100000? And, is there a way to reconstruct the signal correctly if we set N = 64 (the number of Fourier coefficients), cause I believe we cannot set N in the pynfft packages.

Followings are the codes and results:

r = np.array([119.75024144, 119.77177673, 119.79671626, 119.81566188,
       119.81291201, 119.71610143, 119.24156708, 117.66932347,
       114.22145178, 109.27266933, 104.57675147, 101.63381325,
       100.42623807, 100.09436745, 100.02798438, 100.02696846,
       100.05422613, 100.12216521, 100.27569606, 100.60962812,
       101.32023289, 102.71102637, 105.01826819, 108.17052642,
       111.67848758, 114.78442424, 116.95337537, 118.19437002,
       118.84307457, 119.19571404, 119.40326818, 119.53101551,
      119.61170874, 119.66610072, 119.68315253, 119.53757829,
       118.83748609, 116.90425868, 113.32095843, 108.72465638,
       104.58292906, 101.93316248, 100.68856962, 100.22523098,
       100.08558767, 100.07194691, 100.11193397, 100.19142891,
       100.33208922, 100.5849306 , 101.04224415, 101.87565882,
       103.33985519, 105.63631456, 108.64972952, 111.86837667,
       114.67115037, 116.69548163, 117.96207449, 118.69589499,
       119.11781077, 119.36770681, 119.51566311, 119.59301667])

z = np.array ([-422.05230434, -408.98182253, -395.78387843, -382.43143962,
       -368.92341485, -355.26851343, -341.47780372, -327.56493425,
       -313.54536462, -299.43740189, -285.26768576, -271.07676026,
      -256.92098157, -242.86416227, -228.95449427, -215.207069  ,
       -201.61590575, -188.17719265, -174.89201262, -161.75452196,
       -148.74812279, -135.85126854, -123.04093538, -110.29151714,
       -97.57502515,  -84.86119278,  -72.1145478 ,  -59.2947726 ,
        -46.36450604,  -33.29821629,  -20.08471733,   -6.72030326,
          6.80047849,   20.48309726,   34.32320864,   48.30267819,
         62.393214  ,   76.56022602,   90.76260159,  104.94787451,
        119.04731699,  132.98616969,  146.71491239,  160.23436159,
       173.58582543,  186.81849059,  199.96724955,  213.05229133,
       226.08870416,  239.09310452,  252.08377421,  265.0769367 ,
        278.08234368,  291.10215472,  304.13509998,  317.18351924,
        330.25976991,  343.38777732,  356.59626164,  369.90725571,
        383.33109354,  396.87227086,  410.5309987 ,  424.28994387])


def shifted(x):
    """Shift x values to the range [-0.5, 0.5)"""
    return -0.5 + (x + 0.5) % 1


#experiment with nfft package
N = 100000
length = r.shape[0]
r_hat = nfft.nfft_adjoint(z, r, 64)

r_reconstructed = nfft.nfft(z, r_hat)

plt.plot(z, r, '.', color='blue')
plt.plot(z, r_reconstructed, '-', color='red')

#experiment with pynfft package


plan = NFFT([length],length)

plan.x = shifted(z)

plan.precompute()
plan.f = r
f_hat = plan.adjoint()

plan.f_hat = f_hat
f_reconstructed  = plan.trafo() 

print(LA.norm(r_reconstructed-f_reconstructed,2))

Screenshot from 2020-01-09 11-37-12

See the explanation in #14 (comment)

Thank you!

Does that mean we cannot reasonably reconstruct those signals with the band-limited frequency representation?

Therefore, to make the reconstruction results reasonable, maybe I have to find a way to set the a wider frequency grid in pynfft as well.

That's correct: in general it is not possible to perfectly represent N unequally-spaced data points with an N-term Fourier series.