SEMAFORInformatik / femagtools

Python API for FEMAG
BSD 2-Clause "Simplified" License
19 stars 13 forks source link

Datapreperation for numpy.fft.fft in is not good #85

Closed AreUsso closed 7 months ago

AreUsso commented 7 months ago

For the description of the problem I will focus on the following lines:

    if negative_periodic:
        bx = np.append(
            np.concatenate(
                [n*b[:-1]
                 for n in [m % 2 or -1
                           for m in range(1, ntiles+1)]]),
            b[0])
    else:
        bx = np.append(
            np.tile(b[:-1], ntiles),
            b[0])

    N = len(bx)
    # compute DFT from induction
    Y = np.fft.fft(bx)

This lines can be fond in airgap.py in older versions and utils.py (b->y) in the current version.

First remark: It is not correct to cut off the last element of the incoming array b For big numbers the impact is small for small numbers the impact on the results gets bigger.

Second remark: The method np.fft.fft() does not expect to get an array as an input where the last entry of the array of n periods is equal to the first entry in the array -> I want to say that the np.append methods should not be used at all

Testresults: To see what's going on you can mock the input signals like that:

pos = np.array([ 0. , 0.75, 1.5 , 2.25, 3. , 3.75, 4.5 , 5.25, 6. , 6.75, 7.5 , 8.25, 9. , 9.75, 10.5 , 11.25, 12. , 12.75, 13.5 , 14.25, 15. , 15.75, 16.5 , 17.25, 18. , 18.75, 19.5 , 20.25, 21. , 21.75, 22.5 , 23.25, 24. , 24.75, 25.5 , 26.25,

  1. , 27.75, 28.5 , 29.25, 30. , 30.75, 31.5 , 32.25, 33. , 33.75, 34.5 , 35.25, 36. , 36.75, 37.5 , 38.25, 39. , 39.75, 40.5 , 41.25, 42. , 42.75, 43.5 , 44.25, 45. , 45.75, 46.5 , 47.25, 48. , 48.75, 49.5 , 50.25, 51. , 51.75, 52.5 , 53.25,
  2. , 54.75, 55.5 , 56.25, 57. , 57.75, 58.5 , 59.25, 60. , 60.75, 61.5 , 62.25, 63. , 63.75, 64.5 , 65.25, 66. , 66.75, 67.5 , 68.25, 69. , 69.75, 70.5 , 71.25, 72. , 72.75, 73.5 , 74.25, 75. , 75.75, 76.5 , 77.25, 78. , 78.75, 79.5 , 80.25,
  3. , 81.75, 82.5 , 83.25, 84. , 84.75, 85.5 , 86.25, 87. , 87.75, 88.5 , 89.25, 90. ])

and put in an pure Sinus signal: generated through

    for k in range(len(b)):
        b[k] = 200 * np.sin(k*sw)

b = np.array([ 0. 10.04886364 20.07234297 30.04511782 39.9419961 49.73797743 59.40831632 68.92858463 78.27473337 87.42315333 96.35073482 105.03492599 113.45378983 121.58605954 129.41119231 136.90942119 144.06180498 150.85027615 157.25768643 163.26785014 168.8655851 174.03675093 178.76828483 183.04823452 186.86578849 190.21130326 193.07632777 195.45362471 197.33718884 198.7222621 199.60534569 199.98420884 199.85789453 199.22672183 198.09228514 196.45745015 194.32634658 191.7043578 188.59810718 185.01544137 180.96541049 176.45824529 171.50533124 166.11917984 160.31339697 154.10264856 147.50262347 140.52999396 133.20237349 125.53827226 117.55705046 109.27886935 100.72464033 91.91597212 82.8751162 73.62491054 64.18872196 54.5903871 44.85415219 35.0046118 25.06664671 15.06536111 5.02601909 -5.02601909 -15.06536111 -25.06664671 -35.0046118 -44.85415219 -54.5903871 -64.18872196 -73.62491054 -82.8751162 -91.91597212 -100.72464033 -109.27886935 -117.55705046 -125.53827226 -133.20237349 -140.52999396 -147.50262347 -154.10264856 -160.31339697 -166.11917984 -171.50533124 -176.45824529 -180.96541049 -185.01544137 -188.59810718 -191.7043578 -194.32634658 -196.45745015 -198.09228514 -199.22672183 -199.85789453 -199.98420884 -199.60534569 -198.7222621 -197.33718884 -195.45362471 -193.07632777 -190.21130326 -186.86578849 -183.04823452 -178.76828483 -174.03675093 -168.8655851 -163.26785014 -157.25768643 -150.85027615 -144.06180498 -136.90942119 -129.41119231 -121.58605954 -113.45378983 -105.03492599 -96.35073482 -87.42315333 -78.27473337 -68.92858463 -59.40831632 -49.73797743 -39.9419961 -30.04511782 -20.07234297 -10.04886364])

The clarified result spectrum is:

[ 0. 0. 0. 1.38225961 200.56521171 1.7969259 0. 0. 1.59163606 0.

        1. 0.
        1. 0.
        1. 0.
        1. 0.
  1. ]

which is wrong for a pure sinus signal.

Without the np.append methods and no cut off elements the clarified result spectrum is:

[ 0. 0. 0. 0. 200. 0. 0. 0. 0. 0. 0. 0. 0. 0.

                          1. 0.
    1. 0.]

which is totally expected for an pure sinus signal.

ronaldtanner commented 7 months ago

Thanks for your comment. I partially agree. The fft function in femagtools.util completes the array y to a full mechanical period by concatenation. The last element of y must be eliminated to create a correct curve because the first element is equal to the last. I am not able to reproduce your results as your arrays have incorrect dimensions: len(pos) = 121, len(b) = 125. However the numpy fft function should be called without the last element. I will correct this.