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
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]

Python Functionality#

python_results = {}

# cfftf
import numpy as np

## 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))

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