Skip to content

Commit c2a9b43

Browse files
committed
add OTFFT notebook
1 parent 3e16ce8 commit c2a9b43

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

docs/OTFFT.ipynb

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "5b88fa48",
6+
"metadata": {},
7+
"source": [
8+
"This notebook implements the 6-step / 8-step FFT (fft) algorithm as provided in [OTFFT](http://wwwa.pikara.ne.jp/okojisan/otfft-en/stockham2.html). Accordingly, the inverse FFT (ifft) algorithm will be implemented as well. When the input of FFT, `T` with length `n`, consists of real-valued elements only, we can take advantage of real FFT (rfft) as explained in [2.6.2](https://www.researchgate.net/profile/Christos-Bechlioulis/publication/341270520_FFT_algorithms_are_not_mine_However_I_am_going_to_convince_you_soon_regarding_the_visit_of_RMS_to_our_university_Believe_it_or_not_this_is_me_This_is_us_Univeristy_of_Patras_you_have_chosen_a_quite_wr/links/5fa53ce7299bf10f7328c33b/FFT-algorithms-are-not-mine-However-I-am-going-to-convince-you-soon-regarding-the-visit-of-RMS-to-our-university-Believe-it-or-not-this-is-me-This-is-us-Univeristy-of-Patras-you-have-chosen-a-quite.pdf). "
9+
]
10+
},
11+
{
12+
"cell_type": "code",
13+
"execution_count": 15,
14+
"id": "c9a886c2",
15+
"metadata": {},
16+
"outputs": [],
17+
"source": [
18+
"import math\n",
19+
"import time\n",
20+
"\n",
21+
"import numba\n",
22+
"import numpy as np\n",
23+
"import matplotlib.pyplot as plt\n",
24+
"import scipy\n",
25+
"\n",
26+
"from numba import njit, prange\n",
27+
"import numpy.testing as npt\n",
28+
"\n",
29+
"from stumpy import core"
30+
]
31+
},
32+
{
33+
"cell_type": "markdown",
34+
"id": "80765bca",
35+
"metadata": {},
36+
"source": [
37+
"Let's start with `rfft`. First, we write the test!"
38+
]
39+
},
40+
{
41+
"cell_type": "code",
42+
"execution_count": 16,
43+
"id": "7bb4242c",
44+
"metadata": {},
45+
"outputs": [],
46+
"source": [
47+
"def test_rfft(n_powers_list):\n",
48+
" seed = 0\n",
49+
" np.random.seed(seed)\n",
50+
" for p in n_powers_list:\n",
51+
" n = 2 ** p\n",
52+
" T = np.random.rand(n)\n",
53+
" \n",
54+
" ref = scipy.fft.rfft(T)\n",
55+
" comp = rfft(T)\n",
56+
" \n",
57+
" npt.assert_almost_equal(ref, comp)"
58+
]
59+
},
60+
{
61+
"cell_type": "markdown",
62+
"id": "5a1c553e",
63+
"metadata": {},
64+
"source": [
65+
"We now implement `rfft` function according to the steps provided in [2.6.2](https://www.researchgate.net/profile/Christos-Bechlioulis/publication/341270520_FFT_algorithms_are_not_mine_However_I_am_going_to_convince_you_soon_regarding_the_visit_of_RMS_to_our_university_Believe_it_or_not_this_is_me_This_is_us_Univeristy_of_Patras_you_have_chosen_a_quite_wr/links/5fa53ce7299bf10f7328c33b/FFT-algorithms-are-not-mine-However-I-am-going-to-convince-you-soon-regarding-the-visit-of-RMS-to-our-university-Believe-it-or-not-this-is-me-This-is-us-Univeristy-of-Patras-you-have-chosen-a-quite.pdf)."
66+
]
67+
},
68+
{
69+
"cell_type": "code",
70+
"execution_count": 17,
71+
"id": "d0033890",
72+
"metadata": {},
73+
"outputs": [],
74+
"source": [
75+
"def _rfft(T):\n",
76+
" n = len(T)\n",
77+
" half_n = int(n // 2)\n",
78+
" \n",
79+
" x = T[::2] + 1j * T[1::2]\n",
80+
" x[:] = scipy.fft.fft(x) # we will implement our fft shortly!\n",
81+
" \n",
82+
" out = np.empty(half_n + 1, dtype=np.complex_)\n",
83+
" out[0] = x[0].real + x[0].imag\n",
84+
" out[half_n] = x[0].real - x[0].imag\n",
85+
" out[n // 4] = x[n // 4].conjugate()\n",
86+
" \n",
87+
" theta0 = 2 * math.pi / n\n",
88+
" for k in range(1, n // 4):\n",
89+
" theta = theta0 * k\n",
90+
" a = x[half_n - k].conjugate()\n",
91+
" b = 0.5 * (x[k] - a) * (1.0 + complex(math.sin(theta), math.cos(theta)))\n",
92+
" out[k] = x[k] - b\n",
93+
" out[half_n - k] = (a + b).conjugate()\n",
94+
" \n",
95+
" return out\n",
96+
" \n",
97+
"\n",
98+
"def rfft(T):\n",
99+
" \"\"\"\n",
100+
" For the input `T` with length `n=len(T)`, this function returns its\n",
101+
" real fast fourier transform (rfft) with length of `(n // 2) + 1`.\n",
102+
" \n",
103+
" Parameters\n",
104+
" ----------\n",
105+
" T : numpy.ndarray\n",
106+
" A time series of interest, with real-valued numbers\n",
107+
" \n",
108+
" Returns\n",
109+
" -------\n",
110+
" out : numpy.ndarray\n",
111+
" the real fast fourier transform (rfft) of input `T`\n",
112+
" \"\"\"\n",
113+
" return _rfft(T)"
114+
]
115+
},
116+
{
117+
"cell_type": "code",
118+
"execution_count": 18,
119+
"id": "ded21f89",
120+
"metadata": {},
121+
"outputs": [],
122+
"source": [
123+
"n_powers_list = np.arange(2, 11)\n",
124+
"test_rfft(n_powers_list)"
125+
]
126+
},
127+
{
128+
"cell_type": "code",
129+
"execution_count": null,
130+
"id": "335ddf79",
131+
"metadata": {},
132+
"outputs": [],
133+
"source": []
134+
}
135+
],
136+
"metadata": {
137+
"kernelspec": {
138+
"display_name": "Python 3 (ipykernel)",
139+
"language": "python",
140+
"name": "python3"
141+
},
142+
"language_info": {
143+
"codemirror_mode": {
144+
"name": "ipython",
145+
"version": 3
146+
},
147+
"file_extension": ".py",
148+
"mimetype": "text/x-python",
149+
"name": "python",
150+
"nbconvert_exporter": "python",
151+
"pygments_lexer": "ipython3",
152+
"version": "3.10.12"
153+
}
154+
},
155+
"nbformat": 4,
156+
"nbformat_minor": 5
157+
}

0 commit comments

Comments
 (0)