xmd79

Normalized, Variety, Fast Fourier Transform Explorer [Loxx]

Dec 10th, 2022
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.73 KB | None | 0 0
  1. // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
  2. // © loxx
  3.  
  4. //@version=5
  5. indicator("Normalized, Variety, Fast Fourier Transform Explorer [Loxx]",
  6. shorttitle = "NVFFTE [Loxx]",
  7. overlay = false,
  8. max_lines_count = 500,
  9. precision = 8)
  10.  
  11. greencolor = #2DD204
  12. redcolor = #D2042D
  13.  
  14. _fastsinetransform(float[] a, int tnn, bool inversefst)=>
  15. int j = 0
  16. int tm = 0
  17. int n2 = 0
  18. float sum = 0.
  19. float y1 = 0.
  20. float y2 = 0.
  21. float theta = 0.
  22. float wi = 0.
  23. float wr = 0.
  24. float wpi = 0.
  25. float wpr = 0.
  26. float wtemp = 0.
  27. float twr = 0.
  28. float twi = 0.
  29. float twpr = 0.
  30. float twpi = 0.
  31. float twtemp = 0.
  32. float ttheta = 0.
  33. int i = 0
  34. int i1 = 0
  35. int i2 = 0
  36. int i3 = 0
  37. int i4 = 0
  38. float c1 = 0.
  39. float c2 = 0.
  40. float h1r = 0.
  41. float h1i = 0.
  42. float h2r = 0.
  43. float h2i = 0.
  44. float wrs = 0.
  45. float wis = 0.
  46. int nn = 0
  47. int n = 0
  48. int mmax = 0
  49. int m = 0
  50. int istep = 0
  51. int isign = 0
  52. float tempr = 0.
  53. float tempi = 0.
  54.  
  55. theta := math.pi/tnn
  56. wr := 1.0
  57. wi := 0.0
  58. wpr := - 2.0 * math.pow(math.sin(0.5 * theta),2)
  59. wpi := math.sin(theta)
  60. array.set(a, 0, 0.)
  61. tm := tnn / 2
  62. n2 := tnn + 2
  63. for jx = 2 to tm + 1
  64. wtemp := wr
  65. wr := wr * wpr - wi * wpi + wr
  66. wi := wi * wpr + wtemp * wpi + wi
  67. y1 := wi * (array.get(a, jx - 1) + array.get(a, n2 - jx - 1))
  68. y2 := 0.5 * (array.get(a, jx - 1) - array.get(a, n2 - jx - 1))
  69. array.set(a, jx - 1, y1 + y2)
  70. array.set(a, n2 - jx - 1, y1 - y2)
  71. ttheta := 2.0 * math.pi/tnn
  72. c1 := 0.5
  73. c2 := - 0.5
  74. isign := 1
  75. n := tnn
  76. nn := tnn / 2
  77. j := 1
  78. for ii = 1 to nn
  79. i := 2 * ii - 1
  80. if j > i
  81. tempr := array.get(a, j - 1)
  82. tempi := array.get(a, j)
  83. array.set(a, j - 1, array.get(a, i - 1))
  84. array.set(a, j, array.get(a, i))
  85. array.set(a, i - 1, tempr)
  86. array.set(a, i, tempi)
  87. m := n/2
  88. while(m >= 2 and j > m)
  89. j := j - m
  90. m := m/2
  91. j := j + m
  92.  
  93. mmax := 2
  94. while(n > mmax)
  95. istep := 2 * mmax
  96. theta := 2.0 * math.pi / (isign * mmax)
  97. wpr := - 2.0 * math.pow(math.sin(0.5 * theta), 2)
  98. wpi := math.sin(theta)
  99. wr := 1.0
  100. wi := 0.0
  101. for ii = 1 to mmax/2
  102. m := 2 * ii - 1
  103. for jj = 0 to (n - m) / istep
  104. i := m + jj * istep
  105. j := i + mmax
  106. tempr := wr * array.get(a, j - 1) - wi * array.get(a, j)
  107. tempi := wr * array.get(a, j) + wi * array.get(a, j - 1)
  108. array.set(a, j - 1, array.get(a, i - 1) - tempr)
  109. array.set(a, j, array.get(a, i) - tempi)
  110. array.set(a, i - 1, array.get(a, i - 1) + tempr)
  111. array.set(a, i, array.get(a, i) + tempi)
  112. wtemp := wr
  113. wr := wr * wpr - wi * wpi + wr
  114. wi := wi * wpr + wtemp * wpi + wi
  115. mmax := istep
  116.  
  117. twpr := - 2.0 * math.pow(math.sin(0.5 * ttheta),2)
  118. twpi := math.sin(ttheta)
  119. twr := 1.0 + twpr
  120. twi := twpi
  121. for ix = 2 to tnn/4 + 1
  122. i1 := ix + ix - 2
  123. i2 := i1 + 1
  124. i3 := tnn + 1 - i2
  125. i4 := i3 + 1
  126. wrs := twr
  127. wis := twi
  128. h1r := c1 * (array.get(a, i1) + array.get(a, i3))
  129. h1i := c1 * (array.get(a, i2) - array.get(a, i4))
  130. h2r := - c2 * (array.get(a, i2) + array.get(a, i4))
  131. h2i := c2 * (array.get(a, i1) - array.get(a, i3))
  132. array.set(a, i1, h1r + wrs * h2r - wis * h2i)
  133. array.set(a, i2, h1i + wrs * h2i + wis * h2r)
  134. array.set(a, i3, h1r - wrs * h2r + wis * h2i)
  135. array.set(a, i4, - h1i + wrs * h2i + wis * h2r)
  136. twtemp := twr
  137. twr := twr * twpr - twi * twpi + twr
  138. twi := twi * twpr + twtemp * twpi + twi
  139.  
  140. h1r := array.get(a, 0)
  141. array.set(a, 0, h1r + array.get(a, 1))
  142. array.set(a, 1, h1r - array.get(a, 1))
  143. sum := 0.0
  144. array.set(a, 0, 0.5 * array.get(a, 0))
  145. array.set(a, 1, 0.)
  146. for jj = 0 to tm - 1
  147. j := 2 * jj + 1
  148. sum := sum + array.get(a, j - 1)
  149. array.set(a, j - 1, array.get(a, j))
  150. array.set(a, j, sum)
  151. if inversefst
  152. for jx = 1 to tnn
  153. array.set(a, jx - 1, array.get(a, jx - 1) * 2 / tnn)
  154. a
  155.  
  156. _fastcosinetransform(float[] a, int tnn, bool inversefct)=>
  157. int j = 0
  158. int n2 = 0
  159. float sum = 0.
  160. float y1 = 0.
  161. float y2 = 0.
  162. float theta = 0.
  163. float wi = 0.
  164. float wpi = 0.
  165. float wr = 0.
  166. float wpr = 0.
  167. float wtemp = 0.
  168. float twr = 0.
  169. float twi = 0.
  170. float twpr = 0.
  171. float twpi = 0.
  172. float twtemp = 0.
  173. float ttheta = 0.
  174. int i = 0
  175. int i1 = 0
  176. int i2 = 0
  177. int i3 = 0
  178. int i4 = 0
  179. float c1 = 0.
  180. float c2 = 0.
  181. float h1r = 0.
  182. float h1i = 0.
  183. float h2r = 0.
  184. float h2i = 0.
  185. float wrs = 0.
  186. float wis = 0.
  187. int nn = 0
  188. int n = 0
  189. int mmax = 0
  190. int m = 0
  191. int istep = 0
  192. int isign = 0
  193. float tempr = 0.
  194. float tempi = 0.
  195.  
  196. while true
  197. if (tnn == 1)
  198. y1 := array.get(a, 0)
  199. y2 := array.get(a, 1)
  200. array.set(a, 0, 0.5 * (y1 + y2))
  201. array.set(a, 1, 0.5 * (y1 - y2))
  202. if inversefct
  203. array.set(a, 0, array.get(a, 0) * 2)
  204. array.set(a, 1, array.get(a, 1) * 2)
  205. break
  206. wi := 0
  207. wr := 1
  208. theta := math.pi / tnn
  209. wtemp := math.sin(theta * 0.5)
  210. wpr := -2.0 * wtemp * wtemp
  211. wpi := math.sin(theta)
  212. sum := 0.5 * (array.get(a, 0) - array.get(a, tnn))
  213. array.set(a, 0, 0.5 * (array.get(a, 0) + array.get(a, tnn)))
  214. n2 := tnn + 2
  215. for jx = 2 to tnn / 2
  216. wtemp := wr
  217. wr := wtemp * wpr - wi * wpi + wtemp
  218. wi := wi * wpr + wtemp * wpi + wi
  219. y1 := 0.5 * (array.get(a, jx - 1) + array.get(a, n2 - jx - 1))
  220. y2 := array.get(a, jx - 1) - array.get(a, n2 - jx - 1)
  221. array.set(a, jx - 1, y1 - wi * y2)
  222. array.set(a, n2 - jx - 1, y1 + wi * y2)
  223. sum := sum + wr * y2
  224.  
  225. ttheta := 2.0 * math.pi / tnn
  226. c1 := 0.5
  227. c2 := -0.5
  228. isign := 1
  229. n := tnn
  230. nn := tnn / 2
  231. j := 1
  232. for ii = 1 to nn
  233. i := 2 * ii - 1
  234. if (j > i)
  235. tempr := array.get(a, j - 1)
  236. tempi := array.get(a, j)
  237. array.set(a, j - 1, array.get(a, i - 1))
  238. array.set(a, j, array.get(a, i))
  239. array.set(a, i - 1, tempr)
  240. array.set(a, i, tempi)
  241. m := n / 2
  242. while (m >= 2 and j > m)
  243. j := j - m
  244. m := m / 2
  245. j := j + m
  246. mmax := 2
  247. while (n > mmax)
  248. istep := 2 * mmax
  249. theta := 2.0 * math.pi / (isign * mmax)
  250. wpr := -2.0 * math.pow(math.sin(0.5 * theta), 2)
  251. wpi := math.sin(theta)
  252. wr := 1.0
  253. wi := 0.0
  254. for ii = 1 to mmax / 2
  255. m := 2 * ii - 1
  256. for jj = 0 to (n - m) / istep
  257. i := m + jj * istep
  258. j := i + mmax
  259. tempr := wr * array.get(a, j - 1) - wi * array.get(a, j)
  260. tempi := wr * array.get(a, j) + wi * array.get(a, j - 1)
  261. array.set(a, j - 1, array.get(a, i - 1) - tempr)
  262. array.set(a, j, array.get(a, i) - tempi)
  263. array.set(a, i - 1, array.get(a, i - 1) + tempr)
  264. array.set(a, i, array.get(a, i) + tempi)
  265.  
  266. wtemp := wr
  267. wr := wr * wpr - wi * wpi + wr
  268. wi := wi * wpr + wtemp * wpi + wi
  269.  
  270. mmax := istep
  271. twpr := -2.0 * math.pow(math.sin(0.5 * ttheta), 2)
  272. twpi := math.sin(ttheta)
  273. twr := 1.0 + twpr
  274. twi := twpi
  275. for ix = 2 to tnn / 4 + 1
  276. i1 := ix + ix - 2
  277. i2 := i1 + 1
  278. i3 := tnn + 1 - i2
  279. i4 := i3 + 1
  280. wrs := twr
  281. wis := twi
  282. h1r := c1 * (array.get(a, i1) + array.get(a, i3))
  283. h1i := c1 * (array.get(a, i2) - array.get(a, i4))
  284. h2r := -c2 * (array.get(a, i2) + array.get(a, i4))
  285. h2i := c2 * (array.get(a, i1) - array.get(a, i3))
  286. array.set(a, i1, h1r + wrs * h2r - wis * h2i)
  287. array.set(a, i2, h1i + wrs * h2i + wis * h2r)
  288. array.set(a, i3, h1r - wrs * h2r + wis * h2i)
  289. array.set(a, i4, -h1i + wrs * h2i + wis * h2r)
  290. twtemp := twr
  291. twr := twr * twpr - twi * twpi + twr
  292. twi := twi * twpr + twtemp * twpi + twi
  293.  
  294. h1r := array.get(a, 0)
  295. array.set(a, 0, h1r + array.get(a, 1))
  296. array.set(a, 1, h1r - array.get(a, 1))
  297. array.set(a, tnn, array.get(a, 1))
  298. array.set(a, 1, sum)
  299. j := 4
  300. while (j <= tnn)
  301. sum := sum + array.get(a, j - 1)
  302. array.set(a, j - 1, sum)
  303. j := j + 2
  304. if (inversefct)
  305. for jx = 0 to tnn
  306. array.set(a, jx, array.get(a, jx) * 2 / tnn)
  307. break
  308. a
  309.  
  310. _realFastFourierTransform(float[] a, int tnn, bool inversefft)=>
  311. float twr = 0.
  312. float twi = 0.
  313. float twpr = 0.
  314. float twpi = 0.
  315. float twtemp = 0.
  316. float ttheta = 0.
  317. int i = 0
  318. int i1 = 0
  319. int i2 = 0
  320. int i3 = 0
  321. int i4 = 0
  322. float c1 = 0.
  323. float c2 = 0.
  324. float h1r = 0.
  325. float h1i = 0.
  326. float h2r = 0.
  327. float h2i = 0.
  328. float wrs = 0.
  329. float wis = 0.
  330. int nn = 0
  331. int n = 0
  332. int mmax = 0
  333. int m = 0
  334. int j = 0
  335. int istep = 0
  336. int isign = 0
  337. float wtemp = 0.
  338. float wr = 0.
  339. float wpr = 0.
  340. float wpi = 0.
  341. float wi = 0.
  342. float theta = 0.
  343. float tempr = 0.
  344. float tempi = 0.
  345.  
  346. if (tnn != 1)
  347. if (not inversefft)
  348. ttheta := 2.0 * math.pi / tnn
  349. c1 := 0.5
  350. c2 := -0.5
  351. else
  352. ttheta := 2.0 * math.pi / tnn
  353. c1 := 0.5
  354. c2 := 0.5
  355. ttheta := -ttheta
  356. twpr := -2.0 * math.pow(math.sin(0.5 * ttheta), 2)
  357. twpi := math.sin(ttheta)
  358. twr := 1.0 + twpr
  359. twi := twpi
  360.  
  361. for ix = 2 to tnn / 4 + 1
  362. i1 := ix + ix - 2
  363. i2 := i1 + 1
  364. i3 := tnn + 1 - i2
  365. i4 := i3 + 1
  366. wrs := twr
  367. wis := twi
  368. h1r := c1 * (array.get(a, i1) + array.get(a, i3))
  369. h1i := c1 * (array.get(a, i2) - array.get(a, i4))
  370. h2r := -c2 * (array.get(a, i2) + array.get(a, i4))
  371. h2i := c2 * (array.get(a, i1) - array.get(a, i3))
  372. array.set(a, i1, h1r + wrs * h2r - wis * h2i)
  373. array.set(a, i2, h1i + wrs * h2i + wis * h2r)
  374. array.set(a, i3, h1r - wrs * h2r + wis * h2i)
  375. array.set(a, i4, -h1i + wrs * h2i + wis * h2r)
  376. twtemp := twr
  377. twr := twr * twpr - twi * twpi + twr
  378. twi := twi * twpr + twtemp * twpi + twi
  379.  
  380.  
  381. h1r := array.get(a, 0)
  382. array.set(a, 0, c1 * (h1r + array.get(a, 1)))
  383. array.set(a, 1, c1 * (h1r - array.get(a, 1)))
  384.  
  385. if (inversefft)
  386. isign := -1
  387. else
  388. isign := 1
  389.  
  390. n := tnn
  391. nn := tnn / 2
  392. j := 1
  393. for ii = 1 to nn
  394. i := 2 * ii - 1
  395. if (j > i)
  396. tempr := array.get(a, j - 1)
  397. tempi := array.get(a, j)
  398. array.set(a, j - 1, array.get(a, i - 1))
  399. array.set(a, j, array.get(a, i))
  400. array.set(a, i - 1, tempr)
  401. array.set(a, i, tempi)
  402.  
  403. m := n / 2
  404. while (m >= 2 and j > m)
  405. j := j - m
  406. m := m / 2
  407.  
  408. j := j + m
  409.  
  410. mmax := 2
  411. while (n > mmax)
  412. istep := 2 * mmax
  413. theta := 2.0 * math.pi / (isign * mmax)
  414. wpr := -2.0 * math.pow(math.sin(0.5 * theta), 2)
  415. wpi := math.sin(theta)
  416. wr := 1.0
  417. wi := 0.0
  418. for ii = 1 to mmax / 2
  419. m := 2 * ii - 1
  420. for jj = 0 to (n - m) / istep
  421. i := m + jj * istep
  422. j := i + mmax
  423. tempr := wr * array.get(a, j - 1) - wi * array.get(a, j)
  424. tempi := wr * array.get(a, j) + wi * array.get(a, j - 1)
  425. array.set(a, j - 1, array.get(a, i - 1) - tempr)
  426. array.set(a, j, array.get(a, i) - tempi)
  427. array.set(a, i - 1, array.get(a, i - 1) + tempr)
  428. array.set(a, i, array.get(a, i) + tempi)
  429.  
  430. wtemp := wr
  431. wr := wr * wpr - wi * wpi + wr
  432. wi := wi * wpr + wtemp * wpi + wi
  433.  
  434. mmax := istep
  435.  
  436. if (inversefft)
  437. for ix = 1 to 2 * nn
  438. array.set(a, ix - 1, array.get(a, ix - 1) / nn)
  439.  
  440. if (not inversefft)
  441. twpr := -2.0 * math.pow(math.sin(0.5 * ttheta), 2)
  442. twpi := math.sin(ttheta)
  443. twr := 1.0 + twpr
  444. twi := twpi
  445.  
  446. for ix = 2 to tnn / 4 + 1
  447. i1 := ix + ix - 2
  448. i2 := i1 + 1
  449. i3 := tnn + 1 - i2
  450. i4 := i3 + 1
  451. wrs := twr
  452. wis := twi
  453. h1r := c1 * (array.get(a, i1) + array.get(a, i3))
  454. h1i := c1 * (array.get(a, i2) - array.get(a, i4))
  455. h2r := -c2 * (array.get(a, i2) + array.get(a, i4))
  456. h2i := c2 * (array.get(a, i1) - array.get(a, i3))
  457. array.set(a, i1, h1r + wrs * h2r - wis * h2i)
  458. array.set(a, i2, h1i + wrs * h2i + wis * h2r)
  459. array.set(a, i3, h1r - wrs * h2r + wis * h2i)
  460. array.set(a, i4, -h1i + wrs * h2i + wis * h2r)
  461. twtemp := twr
  462. twr := twr * twpr - twi * twpi + twr
  463. twi := twi * twpr + twtemp * twpi + twi
  464.  
  465.  
  466. h1r := array.get(a, 0)
  467. array.set(a, 0, h1r + array.get(a, 1))
  468. array.set(a, 1, h1r - array.get(a, 1))
  469.  
  470. a
  471.  
  472. //Normalize data
  473. _InSigNormalize(float[] aa)=>
  474. float sum_sqrt = 0.
  475. int element_count = array.size(aa)
  476. for i = 0 to element_count - 1
  477. sum_sqrt += math.pow(array.get(aa, i), 2)
  478.  
  479. sum_sqrt := math.sqrt(sum_sqrt)
  480. if (sum_sqrt != 0)
  481. for i = 0 to element_count - 1
  482. array.set(aa, i, array.get(aa, i) / sum_sqrt)
  483. aa
  484.  
  485. src = input.source(open, "Source")
  486. windowper = input.string("1024", "Window Period", options = ["16", "32", "64", "128", "256", "512", "1024", "2048"])
  487. SS = input.int(20, "Smoothing Period")
  488.  
  489. type = input.string("Fast Sine", "Fast Fourier Transform Type", options =["Fast Cosine", "Fast Sine", "Real Fast"])
  490.  
  491. Fmin1 = input.int(3, "Minimum Frequency Filter")
  492. Fmax1 = input.int(21, "Maximum Frequency Filter")
  493. barsback = input.int(0, "Last Bar", minval = 0)
  494. Inverse = input.bool(true, "Add inverse step?")
  495.  
  496. Window = str.tonumber(windowper)
  497.  
  498. n = int(math.log(Window) / math.log(2))
  499. N = int(math.max(math.pow(2, n), 16))
  500.  
  501. var aa = array.new<float>(N + (type == "Fast Cosine" ? 1 : 0), 0.)
  502.  
  503. var pvlines = array.new_line(0)
  504. countout = N >= 256 ? 250 : N
  505.  
  506. if barstate.isfirst
  507. for i = 0 to countout - 1
  508. array.push(pvlines, line.new(na, na, na, na))
  509.  
  510. if barstate.islast
  511. for i = 0 to N - 1
  512. array.set(aa, i, nz(src[i + barsback]))
  513.  
  514. M = array.size(aa)
  515. end = M - 1
  516. ss = int(math.min(SS, M))
  517.  
  518. _InSigNormalize(aa)
  519.  
  520. if type == "Fast Cosine"
  521. _fastcosinetransform(aa, N, false)
  522. else if type == "Fast Sine"
  523. _fastsinetransform(aa, N, false)
  524. else
  525. _realFastFourierTransform(aa, N, false)
  526.  
  527. for k = 0 to end
  528. if k >= ss
  529. array.set(aa, k, 0.)
  530.  
  531. Fmax1 := math.min(Fmax1, array.size(aa) - 1)
  532.  
  533. for i = 0 to array.size(aa) - 1
  534. if i < Fmin1 or i > Fmax1
  535. array.set(aa, i, 0.)
  536.  
  537. if (Inverse)
  538. if type == "Fast Cosine"
  539. _fastcosinetransform(aa, N, true)
  540. else if type == "Fast Sine"
  541. _fastsinetransform(aa, N, true)
  542. else
  543. _realFastFourierTransform(aa, N, true)
  544.  
  545. xm = array.copy(aa)
  546.  
  547. skipper = N >= 2048 ? 8 : N >= 1024 ? 4 : N == 512 ? 2 : 1
  548. int i = 0
  549. int j = 0
  550.  
  551. while i < N and i < array.size(xm) - 2
  552.  
  553. if j > array.size(pvlines) - 1
  554. break
  555. pvline = array.get(pvlines, j)
  556. colorout = i < array.size(xm) - 2 ? array.get(xm, i) > array.get(xm, i + skipper) ? greencolor : redcolor : na
  557. line.set_xy1(pvline, bar_index - i - skipper - barsback, array.get(xm, i + skipper))
  558. line.set_xy2(pvline, bar_index - i - barsback, array.get(xm, i))
  559. line.set_color(pvline, colorout)
  560. line.set_style(pvline, line.style_solid)
  561. line.set_width(pvline, 2)
  562.  
  563. i += skipper
  564. j += 1
  565.  
  566. plot(0, color = bar_index % 2 ? color.gray : na)
Advertisement
Add Comment
Please, Sign In to add comment