Fourier Analysis#
Warning
This is not meant to be a standalone notebook. This notebook is part of the process we have for adding entries to the NCL Index and is not meant to be used as tutorial or example code.
Functions covered#
NCL code#
; cfftf
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/cfftf.shtml
; (0) = real component
; (1) = imaginary component
; example 1: NCL example
example_data = (/ 1002, 1017, 1018, 1020, 1018, 1027, 1028, 1030, 1012, 1012, 982, 1012, 1001, 996, 995, 1011, 1027, 1025, 1030, 1016, 996, 1006, 1002, 982 /)
cf = cfftf(example_data, 0.0, 0)
print(cf)
;(0,0) 24265
;(0,1) 16.06125
;(0,2) -161.8083
;(0,3) 26
;(0,4) 39.5
;(0,5) -64.78089
;(0,6) 1
;(0,7) -32.69729
;(0,8) 32.5
;(0,9) 26
;(0,10) -4.191688
;(0,11) 35.41693
;(0,12) -43
;(0,13) 35.41693
;(0,14) -4.191688
;(0,15) 26
;(0,16) 32.5
;(0,17) -32.69729
;(0,18) 1
;(0,19) -64.78089
;(0,20) 39.5
;(0,21) 26
;(0,22) -161.8083
;(0,23) 16.06125
;(1,0) 0
;(1,1) -44.82336
;(1,2) -82.65768
;(1,3) -40.35534
;(1,4) -4.330127
;(1,5) -36.23454
;(1,6) -12
;(1,7) -49.3589
;(1,8) -18.18653
;(1,9) -30.35534
;(1,10) 31.65768
;(1,11) -33.69901
;(1,12) 0
;(1,13) 33.69901
;(1,14) -31.65768
;(1,15) 30.35534
;(1,16) 18.18653
;(1,17) 49.3589
;(1,18) 12
;(1,19) 36.23454
;(1,20) 4.330127
;(1,21) 40.35534
;(1,22) 82.65768
;(1,23) 44.82336
; example 2: positive
example_data = (/ 1, 3, 5, 10 /)
cf = cfftf(example_data, 0.0, 0)
print(cf)
;(0,0) 19
;(0,1) -4
;(0,2) -7
;(0,3) -4
;(1,0) 0
;(1,1) 7
;(1,2) 0
;(1,3) -7
; example 3: negative
example_data = (/ -1, -3, -5, -10 /)
cf = cfftf(example_data, 0.0, 0)
print(cf)
;(0,0) -19
;(0,1) 4
;(0,2) 7
;(0,3) 4
;(1,0) 0
;(1,1) -7
;(1,2) 0
;(1,3) 7
; example 4: input length is even number
example_data = (/ 1, 2, 3 /)
cf = cfftf(example_data, 0.0, 0)
print(cf)
;(0,0) 6
;(0,1) -1.5
;(0,2) -1.5
;(1,0) 0
;(1,1) 0.8660254
;(1,2) -0.8660254
; cfftb
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/cfftb.shtml
; (0) = real component
; (1) = imaginary component
; example 1: NCL example
example_data = (/ 1002, 1017, 1018, 1020, 1018, 1027, 1028, 1030, 1012, 1012, 982, 1012, 1001, 996, 995, 1011, 1027, 1025, 1030, 1016, 996, 1006, 1002, 982 /)
cft = cfftf(example_data, 0.0, 0)
cf = cfftb(cft, 0)
print(cf)
;(0,0) 1002
;(0,1) 1017
;(0,2) 1018
;(0,3) 1020
;(0,4) 1018
;(0,5) 1027
;(0,6) 1028
;(0,7) 1030
;(0,8) 1012
;(0,9) 1012
;(0,10) 982
;(0,11) 1012
;(0,12) 1001
;(0,13) 996
;(0,14) 995
;(0,15) 1011
;(0,16) 1027
;(0,17) 1025
;(0,18) 1030
;(0,19) 1016
;(0,20) 996
;(0,21) 1006
;(0,22) 1002
;(0,23) 982
;(1,0) 0
;(1,1) -5.255056e-15
;(1,2) -1.014004e-14
;(1,3) -1.564883e-14
;(1,4) -2.19084e-14
;(1,5) -5.488734e-14
;(1,6) 0
;(1,7) -2.716346e-14
;(1,8) -1.117624e-14
;(1,9) 2.706857e-15
;(1,10) 4.648134e-14
;(1,11) 2.252139e-15
;(1,12) 0
;(1,13) 2.553513e-14
;(1,14) 1.354472e-14
;(1,15) 4.483214e-15
;(1,16) -3.730349e-14
;(1,17) -4.541343e-14
;(1,18) 0
;(1,19) -4.662937e-15
;(1,20) 7.771561e-15
;(1,21) 1.218076e-14
;(1,22) 1.273056e-14
;(1,23) 1.05873e-13
; example 2: positive
example_data = (/ 1, 3, 5, 10 /)
cft = cfftf(example_data, 0.0, 0)
cf = cfftb(cft, 0)
print(cf)
;(0,0) 1
;(0,1) 3
;(0,2) 5
;(0,3) 10
;(1,0) 0
;(1,1) 0
;(1,2) 0
;(1,3) 0
; example 3: negative
example_data = (/ -1, -3, -5, -10 /)
cft = cfftf(example_data, 0.0, 0)
cf = cfftb(cft, 0)
print(cf)
;(0,0) -1
;(0,1) -3
;(0,2) -5
;(0,3) -10
;(1,0) 0
;(1,1) 0
;(1,2) 0
;(1,3) 0
; example 4: input length is even number
example_data = (/ 1, 2, 3 /)
cft = cfftf(example_data, 0.0, 0)
cf = cfftb(cft, 0)
print(cf)
;(0,0) 1
;(0,1) 2
;(0,2) 3
;(1,0) 0
;(1,1) 0
;(1,2) 0
ncl_results = {}
# cfftf
ncl_results["cfftf_1"] = [
24265,
16.06125,
-161.8083,
26,
39.5,
-64.78089,
1,
-32.69729,
32.5,
26,
-4.191688,
35.41693,
-43,
35.41693,
-4.191688,
26,
32.5,
-32.69729,
1,
-64.78089,
39.5,
26,
-161.8083,
16.06125,
0,
-44.82336,
-82.65768,
-40.35534,
-4.330127,
-36.23454,
-12,
-49.3589,
-18.18653,
-30.35534,
31.65768,
-33.69901,
0,
33.69901,
-31.65768,
30.35534,
18.18653,
49.3589,
12,
36.23454,
4.330127,
40.35534,
82.65768,
44.82336,
]
ncl_results["cfftf_2"] = [19, -4, -7, -4, 0, 7, 0, -7]
ncl_results["cfftf_3"] = [-19, 4, 7, 4, 0, -7, 0, 7]
ncl_results["cfftf_4"] = [6, -1.5, -1.5, 0, 0.8660254, -0.8660254]
# cfftb
ncl_results["cfftb_1"] = [
1002,
1017,
1018,
1020,
1018,
1027,
1028,
1030,
1012,
1012,
982,
1012,
1001,
996,
995,
1011,
1027,
1025,
1030,
1016,
996,
1006,
1002,
982,
0,
-5.255056e-15,
-1.014004e-14,
-1.564883e-14,
-2.19084e-14,
-5.488734e-14,
0,
-2.716346e-14,
-1.117624e-14,
2.706857e-15,
4.648134e-14,
2.252139e-15,
0,
2.553513e-14,
1.354472e-14,
4.483214e-15,
-3.730349e-14,
-4.541343e-14,
0,
-4.662937e-15,
7.771561e-15,
1.218076e-14,
1.273056e-14,
1.05873e-13,
]
ncl_results["cfftb_2"] = [1, 3, 5, 10, 0, 0, 0, 0]
ncl_results["cfftb_3"] = [-1, -3, -5, -10, 0, 0, 0, 0]
ncl_results["cfftb_4"] = [1, 2, 3, 0, 0, 0]
Python Functionality#
import numpy as np
python_results = {}
# cfftf
## cfftf example 1: NCL example
example_data = [
1002,
1017,
1018,
1020,
1018,
1027,
1028,
1030,
1012,
1012,
982,
1012,
1001,
996,
995,
1011,
1027,
1025,
1030,
1016,
996,
1006,
1002,
982,
]
cfftf = np.fft.fft(example_data)
python_results["cfftf_1"] = np.concatenate((cfftf.real, cfftf.imag))
## cfftf example 2: positive
example_data = [1, 3, 5, 10]
cfftf = np.fft.fft(example_data)
python_results["cfftf_2"] = np.concatenate((cfftf.real, cfftf.imag))
## cfftf example 3: negative
example_data = [-1, -3, -5, -10]
cfftf = np.fft.fft(example_data)
python_results["cfftf_3"] = np.concatenate((cfftf.real, cfftf.imag))
## cfftf example 4: input length is even number
example_data = [1, 2, 3]
cfftf = np.fft.fft(example_data)
python_results["cfftf_4"] = np.concatenate((cfftf.real, cfftf.imag))
# cfftb
## cfftb example 1: NCL example
example_data = [
1002,
1017,
1018,
1020,
1018,
1027,
1028,
1030,
1012,
1012,
982,
1012,
1001,
996,
995,
1011,
1027,
1025,
1030,
1016,
996,
1006,
1002,
982,
]
cfftf = np.fft.fft(example_data)
cfftb = np.fft.ifft(cfftf)
python_results["cfftb_1"] = np.concatenate((cfftb.real, cfftb.imag))
## cfftb example 2: positive
example_data = [1, 3, 5, 10]
cfftf = np.fft.fft(example_data)
cfftb = np.fft.ifft(cfftf)
python_results["cfftb_2"] = np.concatenate((cfftb.real, cfftb.imag))
## cfftb example 3: negative
example_data = [-1, -3, -5, -10]
cfftf = np.fft.fft(example_data)
cfftb = np.fft.ifft(cfftf)
python_results["cfftb_3"] = np.concatenate((cfftb.real, cfftb.imag))
## cfftb example 4: input length is even number
example_data = [1, 2, 3]
cfftf = np.fft.fft(example_data)
cfftb = np.fft.ifft(cfftf)
python_results["cfftb_4"] = np.concatenate((cfftb.real, cfftb.imag))
Comparison#
for key in ncl_results.keys():
if key in python_results.keys():
print(f"{key}:")
for i in range(len(ncl_results[key])):
try:
assert abs(ncl_results[key][i] - python_results[key][i]) <= 0.0001
print(
f"\tVALID:\n\t\tncl:\t\t{ncl_results[key][i]}\n\t\tpython:\t\t{python_results[key][i]}\n"
)
except Exception:
print(
f"\tINVALID:\n\t\tncl:\t\t{ncl_results[key][i]}\n\t\tpython:\t\t{python_results[key][i]}\n"
)
cfftf_1:
VALID:
ncl: 24265
python: 24265.0
VALID:
ncl: 16.06125
python: 16.061251728458643
VALID:
ncl: -161.8083
python: -161.8083117443839
VALID:
ncl: 26
python: 26.0
VALID:
ncl: 39.5
python: 39.5
VALID:
ncl: -64.78089
python: -64.78089402768201
VALID:
ncl: 1
python: 0.9999999999999929
VALID:
ncl: -32.69729
python: -32.69729069777971
VALID:
ncl: 32.5
python: 32.5
VALID:
ncl: 26
python: 25.999999999999993
VALID:
ncl: -4.191688
python: -4.191688255616084
VALID:
ncl: 35.41693
python: 35.41693299700307
VALID:
ncl: -43
python: -42.99999999999999
VALID:
ncl: 35.41693
python: 35.41693299700308
VALID:
ncl: -4.191688
python: -4.191688255616086
VALID:
ncl: 26
python: 25.999999999999993
VALID:
ncl: 32.5
python: 32.5
VALID:
ncl: -32.69729
python: -32.69729069777971
VALID:
ncl: 1
python: 0.9999999999999978
VALID:
ncl: -64.78089
python: -64.78089402768201
VALID:
ncl: 39.5
python: 39.49999999999999
VALID:
ncl: 26
python: 26.000000000000004
VALID:
ncl: -161.8083
python: -161.8083117443839
VALID:
ncl: 16.06125
python: 16.061251728458643
VALID:
ncl: 0
python: 0.0
VALID:
ncl: -44.82336
python: -44.823364065142925
VALID:
ncl: -82.65768
python: -82.65767664977295
VALID:
ncl: -40.35534
python: -40.35533905932737
VALID:
ncl: -4.330127
python: -4.330127018922191
VALID:
ncl: -36.23454
python: -36.23454231809353
VALID:
ncl: -12
python: -12.000000000000007
VALID:
ncl: -49.3589
python: -49.35889797107566
VALID:
ncl: -18.18653
python: -18.186533479473212
VALID:
ncl: -30.35534
python: -30.355339059327378
VALID:
ncl: 31.65768
python: 31.657676649772952
VALID:
ncl: -33.69901
python: -33.699008412160794
VALID:
ncl: 0
python: -8.881784197001252e-16
VALID:
ncl: 33.69901
python: 33.699008412160794
VALID:
ncl: -31.65768
python: -31.65767664977294
VALID:
ncl: 30.35534
python: 30.355339059327378
VALID:
ncl: 18.18653
python: 18.186533479473212
VALID:
ncl: 49.3589
python: 49.35889797107566
VALID:
ncl: 12
python: 11.999999999999998
VALID:
ncl: 36.23454
python: 36.23454231809353
VALID:
ncl: 4.330127
python: 4.330127018922192
VALID:
ncl: 40.35534
python: 40.35533905932738
VALID:
ncl: 82.65768
python: 82.65767664977295
VALID:
ncl: 44.82336
python: 44.823364065142925
cfftf_2:
VALID:
ncl: 19
python: 19.0
VALID:
ncl: -4
python: -4.0
VALID:
ncl: -7
python: -7.0
VALID:
ncl: -4
python: -4.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 7
python: 7.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: -7
python: -7.0
cfftf_3:
VALID:
ncl: -19
python: -19.0
VALID:
ncl: 4
python: 4.0
VALID:
ncl: 7
python: 7.0
VALID:
ncl: 4
python: 4.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: -7
python: -7.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 7
python: 7.0
cfftf_4:
VALID:
ncl: 6
python: 6.0
VALID:
ncl: -1.5
python: -1.5
VALID:
ncl: -1.5
python: -1.5
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 0.8660254
python: 0.8660254037844386
VALID:
ncl: -0.8660254
python: -0.8660254037844386
cfftb_1:
VALID:
ncl: 1002
python: 1002.0
VALID:
ncl: 1017
python: 1017.0
VALID:
ncl: 1018
python: 1018.0
VALID:
ncl: 1020
python: 1020.0
VALID:
ncl: 1018
python: 1018.0
VALID:
ncl: 1027
python: 1027.0
VALID:
ncl: 1028
python: 1028.0
VALID:
ncl: 1030
python: 1030.0
VALID:
ncl: 1012
python: 1012.0
VALID:
ncl: 1012
python: 1012.0
VALID:
ncl: 982
python: 982.0
VALID:
ncl: 1012
python: 1012.0
VALID:
ncl: 1001
python: 1001.0
VALID:
ncl: 996
python: 996.0
VALID:
ncl: 995
python: 995.0
VALID:
ncl: 1011
python: 1011.0
VALID:
ncl: 1027
python: 1027.0
VALID:
ncl: 1025
python: 1025.0
VALID:
ncl: 1030
python: 1030.0
VALID:
ncl: 1016
python: 1016.0
VALID:
ncl: 996
python: 996.0
VALID:
ncl: 1006
python: 1006.0
VALID:
ncl: 1002
python: 1002.0
VALID:
ncl: 982
python: 982.0
VALID:
ncl: 0
python: 1.0732155904709846e-15
VALID:
ncl: -5.255056e-15
python: -5.852247760094468e-16
VALID:
ncl: -1.014004e-14
python: 3.700743415417188e-17
VALID:
ncl: -1.564883e-14
python: 2.042303048936757e-15
VALID:
ncl: -2.19084e-14
python: -2.183438615096141e-15
VALID:
ncl: -5.488734e-14
python: 1.4363957615554e-15
VALID:
ncl: 0
python: 3.3306690738754696e-16
VALID:
ncl: -2.716346e-14
python: -5.249982486157097e-16
VALID:
ncl: -1.117624e-14
python: 3.2243885047530154e-16
VALID:
ncl: 2.706857e-15
python: -2.315891193754654e-15
VALID:
ncl: 4.648134e-14
python: 5.497974838564555e-16
VALID:
ncl: 2.252139e-15
python: -1.8011560746409963e-15
VALID:
ncl: 0
python: 1.0625875335587391e-15
VALID:
ncl: 2.553513e-14
python: -3.3996107784485026e-16
VALID:
ncl: 1.354472e-14
python: -1.2740040815715252e-15
VALID:
ncl: 4.483214e-15
python: 3.302518789593675e-15
VALID:
ncl: -3.730349e-14
python: -1.728721348333833e-15
VALID:
ncl: -4.541343e-14
python: 1.1454416417357605e-15
VALID:
ncl: 0
python: -4.757826155481117e-16
VALID:
ncl: -4.662937e-15
python: -7.755759752364289e-16
VALID:
ncl: 7.771561e-15
python: -9.885726652503954e-16
VALID:
ncl: 1.218076e-14
python: -3.3996107784485026e-16
VALID:
ncl: 1.273056e-14
python: 2.8283163160467443e-15
VALID:
ncl: 1.05873e-13
python: -7.99801608024594e-16
cfftb_2:
VALID:
ncl: 1
python: 1.0
VALID:
ncl: 3
python: 3.0
VALID:
ncl: 5
python: 5.0
VALID:
ncl: 10
python: 10.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 0
python: 0.0
cfftb_3:
VALID:
ncl: -1
python: -1.0
VALID:
ncl: -3
python: -3.0
VALID:
ncl: -5
python: -5.0
VALID:
ncl: -10
python: -10.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 0
python: 0.0
cfftb_4:
VALID:
ncl: 1
python: 1.0
VALID:
ncl: 2
python: 2.0
VALID:
ncl: 3
python: 3.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 0
python: 0.0
VALID:
ncl: 0
python: 0.0