Class: SPCore::FFT
- Inherits:
-
Object
- Object
- SPCore::FFT
- Defined in:
- lib/spcore/transforms/fft.rb
Overview
Class Method Summary collapse
-
.forward(input, force_radix_2_size = true) ⇒ Object
Forward Radix-2 FFT transform using decimation-in-time.
-
.inverse(input) ⇒ Object
Inverse Radix-2 FFT transform.
- .power_of_two?(size) ⇒ Boolean
Class Method Details
.forward(input, force_radix_2_size = true) ⇒ Object
Forward Radix-2 FFT transform using decimation-in-time. Operates on an array of real values, representing a time domain signal. Ported from unlicensed MATLAB code which was posted to the MathWorks file exchange by Dinesh Dileep Gaurav. See www.mathworks.com/matlabcentral/fileexchange/17778.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/spcore/transforms/fft.rb', line 24 def self.forward input, force_radix_2_size = true size = input.size power_of_two = Math::log2(size) if power_of_two.floor != power_of_two # input size is not an even power of two if force_radix_2_size new_size = 2**(power_of_two.to_i() + 1) input += Array.new(new_size - size, 0.0) size = input.size power_of_two = Math::log2(size) else raise ArgumentError, "input.size #{size} is not a radix-2 number" end end power_of_two = power_of_two.to_i x = bit_reverse_order input, power_of_two phase = Array.new(size/2){|n| Complex(Math::cos(TWO_PI*n/size), -Math::sin(TWO_PI*n/size)) } for a in 1..power_of_two l = 2**a phase_level = [] 0.step(size/2, size/l) do |i| phase_level << phase[i] end ks = [] 0.step(size-l, l) do |k| ks << k end ks.each do |k| for n in 0...l/2 idx1 = n+k idx2 = n+k + (l/2) first = x[idx1] second = x[idx2] * phase_level[n] x[idx1] = first + second x[idx2] = first - second end end end return x end |
.inverse(input) ⇒ Object
Inverse Radix-2 FFT transform. Operates on an array of complex values, as one would obtain from the forward FFT transform. Ported from unlicensed MATLAB code which was posted to the MathWorks file exchange by Dinesh Dileep Gaurav. See www.mathworks.com/matlabcentral/fileexchange/17778.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/spcore/transforms/fft.rb', line 80 def self.inverse input size = input.size power_of_two = Math::log2(size) raise ArgumentError, "input.size #{size} is not power of 2" if power_of_two.floor != power_of_two power_of_two = power_of_two.to_i x = bit_reverse_order input, power_of_two phase = Array.new(size/2){|n| Complex(Math::cos(TWO_PI*n/size), -Math::sin(TWO_PI*n/size)) } for a in 1..power_of_two l = 2**a phase_level = [] 0.step(size/2, size/l) do |i| phase_level << phase[i] end ks = [] 0.step(size-l, l) do |k| ks << k end ks.each do |k| for n in 0...l/2 idx1 = n+k idx2 = n+k + (l/2) first = x[idx1] second = x[idx2] * phase_level[n] x[idx1] = (first + second) x[idx2] = (first - second) end end end return x.map {|val| val / size } end |
.power_of_two?(size) ⇒ Boolean
6 7 8 9 |
# File 'lib/spcore/transforms/fft.rb', line 6 def self.power_of_two? size log2size = Math::log2(size) return log2size.floor == log2size end |