Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
- // © RicardoSantos
- //@version=5
- //@description Method for Complex Discrete Fourier Transform (DFT).
- library(title='MathSpecialFunctionsDiscreteFourierTransform')
- import RicardoSantos/MathComplexCore/1 as complex
- import RicardoSantos/MathComplexOperator/1 as complex_op
- import RicardoSantos/MathComplexArray/1 as complex_array
- // @function Complex Discrete Fourier Transform (DFT).
- // @param inputs float array, pseudo complex array of paired values [(a0+b0i), ...].
- // @param inverse bool, invert the transformation.
- // @returns float array, pseudo complex array of paired values [(a0+b0i), ...].
- export dft (float[] _inputs, bool _inverse) => //{
- int _size = int(math.floor(array.size(id=_inputs) / 2))
- float _pi = 3.14159265359
- float _pi2 = _inverse ? 2.0 * _pi : -2.0 * _pi
- float _invs = 1.0 / _size
- //| @return:
- //| _output: Complex array
- float[] _output = complex_array.new(_size, complex.new(0.0, 0.0))
- for _y = 0 to _size - 1 by 1
- for _x = 0 to _size - 1 by 1
- _a = _pi2 * _y * _x * _invs
- _ca = math.cos(_a)
- _sa = -math.sin(_a)
- float[] _complex_input = complex_array.get(_inputs, _x)
- float[] _complex_output = complex_array.get(_output, _y)
- float _input_real = complex.get_real(_complex_input)
- float _input_imaginary = complex.get_imaginary(_complex_input)
- float _output_real = complex.get_real(_complex_output)
- float _output_imaginary = complex.get_imaginary(_complex_output)
- float _add_real = _output_real + _input_real * _ca - _input_imaginary * _sa
- float _add_imaginary = _output_imaginary + _input_real * _sa + _input_imaginary * _ca
- complex_array.set(_output, _y, complex.new(_add_real, _add_imaginary))
- if not _inverse
- float[] _mult = complex_op.multiply(complex_array.get(_output, _y), complex.new(_invs, _invs))
- complex_array.set(_output, _y, _mult)
- _output
- //{ usage:
- var float[] inputs = complex_array.new(8, complex.new(0.0, 0.0))
- if barstate.islast
- for _i = 0 to 8 by 1
- complex_array.set(inputs, _i, complex.new(close[_i], _i))
- // plot(series=f_Sre(0), color=acol, linewidth=aline, style=plot.style_histogram, transp=20, histbase=0, offset=-0, show_last=1)
- // plot(series=f_Sim(0), color=bcol, linewidth=bline, style=plot.style_histogram, transp=20, histbase=0, offset=-0, show_last=1)
- float[] S = dft(inputs, false)
- float[] A = dft(S, true)
- var table T = table.new(position.bottom_right, 3, 9, border_width=1)
- table.cell(T, 0, 0, 'Original', text_color=color.silver, text_size=size.small, bgcolor=color.gray)
- table.cell(T, 1, 0, 'DFT', text_color=color.silver, text_size=size.small, bgcolor=color.gray)
- table.cell(T, 2, 0, 'Inverse', text_color=color.silver, text_size=size.small, bgcolor=color.gray)
- if barstate.islast
- for _l = 0 to math.floor(array.size(inputs) / 2) - 1 by 1
- table.cell(T, 0, _l+1, str.tostring(complex_array.get(inputs, _l)), text_size=size.small, bgcolor=color.silver)
- table.cell(T, 1, _l+1, str.tostring(complex_array.get(S, _l)), text_size=size.small, bgcolor=color.silver)
- table.cell(T, 2, _l+1, str.tostring(complex_array.get(A, _l)), text_size=size.small, bgcolor=color.silver)
- // interface to validate if there is values:
- f_Sre(_i) => array.size(S) > 0 ? complex.get_real(complex_array.get(S, _i)) : na
- f_Sim(_i) => array.size(S) > 0 ? complex.get_imaginary(complex_array.get(S, _i)) : na
- color acol = input(#0000ff50)
- color bcol = input(#8080a050)
- int aline = 8
- int bline = 3
- plot(series=f_Sre(1), color=acol, linewidth=aline, style=plot.style_histogram, histbase=0, offset=-1, show_last=1)
- plot(series=f_Sim(1), color=bcol, linewidth=bline, style=plot.style_histogram, histbase=0, offset=-1, show_last=1)
- plot(series=f_Sre(2), color=acol, linewidth=aline, style=plot.style_histogram, histbase=0, offset=-2, show_last=1)
- plot(series=f_Sim(2), color=bcol, linewidth=bline, style=plot.style_histogram, histbase=0, offset=-2, show_last=1)
- plot(series=f_Sre(3), color=acol, linewidth=aline, style=plot.style_histogram, histbase=0, offset=-3, show_last=1)
- plot(series=f_Sim(3), color=bcol, linewidth=bline, style=plot.style_histogram, histbase=0, offset=-3, show_last=1)
- plot(series=f_Sre(4), color=acol, linewidth=aline, style=plot.style_histogram, histbase=0, offset=-4, show_last=1)
- plot(series=f_Sim(4), color=bcol, linewidth=bline, style=plot.style_histogram, histbase=0, offset=-4, show_last=1)
- plot(series=f_Sre(5), color=acol, linewidth=aline, style=plot.style_histogram, histbase=0, offset=-5, show_last=1)
- plot(series=f_Sim(5), color=bcol, linewidth=bline, style=plot.style_histogram, histbase=0, offset=-5, show_last=1)
- plot(series=f_Sre(6), color=acol, linewidth=aline, style=plot.style_histogram, histbase=0, offset=-6, show_last=1)
- plot(series=f_Sim(6), color=bcol, linewidth=bline, style=plot.style_histogram, histbase=0, offset=-6, show_last=1)
- plot(series=f_Sre(7), color=acol, linewidth=aline, style=plot.style_histogram, histbase=0, offset=-7, show_last=1)
- plot(series=f_Sim(7), color=bcol, linewidth=bline, style=plot.style_histogram, histbase=0, offset=-7, show_last=1)
- plot(series=f_Sre(8), color=acol, linewidth=aline, style=plot.style_histogram, histbase=0, offset=-8, show_last=1)
- plot(series=f_Sim(8), color=bcol, linewidth=bline, style=plot.style_histogram, histbase=0, offset=-8, show_last=1)
- //{ remarks:
- // https://en.wikipedia.org/wiki/Discrete_Fourier_transform
- // https://www.tradingview.com/script/XXBfMnVE-Function-Discrete-Fourier-Transform/
- // https://www.gaussianwaves.com/2015/11/interpreting-fft-results-complex-dft-frequency-bins-and-fftshift/
- //}}}
Advertisement
Add Comment
Please, Sign In to add comment