roctave 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +33 -0
  4. data/ext/roctave/cu8_file_reader.c +331 -0
  5. data/ext/roctave/cu8_file_reader.h +30 -0
  6. data/ext/roctave/extconf.rb +6 -0
  7. data/ext/roctave/fir_filter.c +795 -0
  8. data/ext/roctave/fir_filter.h +29 -0
  9. data/ext/roctave/freq_shifter.c +410 -0
  10. data/ext/roctave/freq_shifter.h +29 -0
  11. data/ext/roctave/iir_filter.c +462 -0
  12. data/ext/roctave/iir_filter.h +29 -0
  13. data/ext/roctave/roctave.c +38 -0
  14. data/ext/roctave/roctave.h +27 -0
  15. data/lib/roctave.rb +168 -0
  16. data/lib/roctave/bilinear.rb +92 -0
  17. data/lib/roctave/butter.rb +87 -0
  18. data/lib/roctave/cheby.rb +180 -0
  19. data/lib/roctave/cu8_file_reader.rb +45 -0
  20. data/lib/roctave/dft.rb +280 -0
  21. data/lib/roctave/filter.rb +64 -0
  22. data/lib/roctave/finite_difference_coefficients.rb +73 -0
  23. data/lib/roctave/fir.rb +121 -0
  24. data/lib/roctave/fir1.rb +134 -0
  25. data/lib/roctave/fir2.rb +246 -0
  26. data/lib/roctave/fir_design.rb +311 -0
  27. data/lib/roctave/firls.rb +380 -0
  28. data/lib/roctave/firpm.rb +499 -0
  29. data/lib/roctave/freq_shifter.rb +47 -0
  30. data/lib/roctave/freqz.rb +233 -0
  31. data/lib/roctave/iir.rb +80 -0
  32. data/lib/roctave/interp1.rb +78 -0
  33. data/lib/roctave/plot.rb +748 -0
  34. data/lib/roctave/poly.rb +46 -0
  35. data/lib/roctave/roots.rb +73 -0
  36. data/lib/roctave/sftrans.rb +157 -0
  37. data/lib/roctave/version.rb +3 -0
  38. data/lib/roctave/window.rb +116 -0
  39. data/roctave.gemspec +79 -0
  40. data/samples/butter.rb +12 -0
  41. data/samples/cheby.rb +28 -0
  42. data/samples/dft.rb +18 -0
  43. data/samples/differentiator.rb +48 -0
  44. data/samples/differentiator_frequency_scaling.rb +52 -0
  45. data/samples/fft.rb +40 -0
  46. data/samples/finite_difference_coefficient.rb +53 -0
  47. data/samples/fir1.rb +13 -0
  48. data/samples/fir2.rb +14 -0
  49. data/samples/fir2_windows.rb +29 -0
  50. data/samples/fir2bank.rb +30 -0
  51. data/samples/fir_low_pass.rb +44 -0
  52. data/samples/firls.rb +77 -0
  53. data/samples/firpm.rb +78 -0
  54. data/samples/hilbert_transformer.rb +20 -0
  55. data/samples/hilbert_transformer_frequency_scaling.rb +47 -0
  56. data/samples/plot.rb +45 -0
  57. data/samples/stem.rb +8 -0
  58. data/samples/type1.rb +25 -0
  59. data/samples/type3.rb +24 -0
  60. data/samples/windows.rb +25 -0
  61. metadata +123 -0
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/roctave.rb'
4
+
5
+ ## Low pass type I
6
+ n = 60
7
+ f = [(0 .. 0.2), (0.25 .. 0.5), (0.55 .. 1)]
8
+ a = [0, 1, 0]
9
+ b = Roctave.firpm(n, f, a, :even_symmetry, 16)
10
+ exit
11
+
12
+ # ## Low pass type I
13
+ # n = 32
14
+ # f = [(0 .. 0.45), (0.55 .. 0.7), (0.75 .. 1)]
15
+ # a = [1, 0, 0.5]
16
+ # w = [1, 1, 20]
17
+ # b = Roctave.firpm(n, f, a, w, :even_symmetry)
18
+
19
+ # ## Low pass type II
20
+ # n = 11
21
+ # f = [(0 .. 0.3), (0.7 .. 1)]
22
+ # a = [1, 0]
23
+ # w = [2, 1]
24
+ # b = Roctave.firls(n, f, a, w, :even_symmetry)
25
+
26
+ # ## Differentiator type III
27
+ # n = 10
28
+ # f = [0.05, 0.75]
29
+ # a = [f]
30
+ # w = [Roctave.linspace(f.first, f.last, 16).collect{|v| 1/v}]
31
+ # b = Roctave.firls(n, f, a, w, 16, :odd_symmetry)
32
+
33
+ # ## Hilbert transformer type IV
34
+ # n = 11
35
+ # f = [1.0/8, 7.0/8]
36
+ # a = [1]
37
+ # w = [1]
38
+ # b = Roctave.firls(n, f, a, w, :odd_symmetry)
39
+
40
+
41
+
42
+ r = Roctave.dft(b, 2048)
43
+ h = r[0..1024].abs
44
+ p = r[0..1024].arg
45
+ p = Roctave.unwrap(p)
46
+ w = Roctave.linspace(0, 1, 1025)
47
+
48
+ # if (n & 1) == 0 then
49
+ # Roctave.stem((-n/2..n/2).to_a, b, :filled, grid: true)
50
+ # else
51
+ # Roctave.stem((n+1).times.collect{|i| i - (n+1)/2.0 + 0.5}, b, :filled, grid: true)
52
+ # end
53
+ # Roctave.plot(w, p, grid: true, title: 'Phase')
54
+ # Roctave.plot(w, h.collect{|v| 10*Math.log10(v)}, xlabel: 'Normalized frequency', ylabel: 'Magnitude response (dB)', grid: true, title: 'Magnitude')
55
+ Roctave.plot([0, 0.3], [1, 1], '-b', [0.7, 1], [0, 0], '-b', w, h, 'r', title: 'Magnitude response', xlim: (0 .. 1), grid: true)
56
+
57
+
58
+
59
+
60
+
61
+ exit
62
+ n = 4
63
+ f = [(0 .. 0.4), (0.6 .. 1)]
64
+ a = [1, 0]
65
+ b = Roctave.firls(n, f, a, 1)
66
+ exit
67
+
68
+ n = 32
69
+ grid = 8
70
+ f = [[0.2, 0.3], [0.4, 0.6], [0.7, 0.8]]
71
+ a = [
72
+ 0.5,
73
+ Roctave.linspace(0, Math::PI, 64).collect{|t| 1 - Math.sin(t)},
74
+ (0.5 .. 0)
75
+ ]
76
+
77
+ b = Roctave.firls(n, f, a, grid)
78
+
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/roctave.rb'
4
+
5
+ # H(e^(jw)) = -j when 0 <= w < pi, j when -pi <= w < 0
6
+ # h(n) = 0 when n == 0, else (1 - (-1)^n) / (pi.n)
7
+
8
+ n = 64
9
+
10
+ b = Roctave.fir_hilbert(n, window: :nuttall)
11
+
12
+ Roctave.stem((-n/2..n/2).to_a, b, :filled, grid: true, title: "FIR type III order #{n}")
13
+
14
+ r = Roctave.dft(b, 2048)
15
+ r = Roctave.fftshift(r)
16
+ h = r.abs
17
+ p = r.arg
18
+ w = Roctave.linspace(-1, 1, 2048)
19
+ Roctave.plot([-1, 1], [1, 1], '--;Ideal;', w, h, ";FIR type III order #{n};", grid: true, title: 'Magnitude')
20
+ Roctave.plot(w, p, grid: true, title: 'Phase')
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/roctave.rb'
4
+
5
+
6
+
7
+ n = 33
8
+ f = [0, 1]
9
+ m = [Complex(0, -1), Complex(0, -1)]
10
+
11
+ b = Roctave.fir2(n, f, m, :odd_symetry, window: :blackman)
12
+
13
+ Roctave.stem(b, :filled, grid: true)
14
+
15
+ r = Roctave.dft(b, 2048)
16
+ r = Roctave.fftshift(r)
17
+ h = r.abs
18
+ p = r.arg
19
+ w = Roctave.linspace(-1, 1, 2048)
20
+ Roctave.plot([-1, 1], [1, 1], '--;Ideal;', w, h, ';Actual;', grid: true, title: 'Magnitude')
21
+ Roctave.plot(w, p, grid: true, title: 'Phase')
22
+
23
+ =begin
24
+ n = [2, order.to_i].max
25
+ n += n & 1
26
+ grid = 1024
27
+ mgridl = Roctave.linspace(0, Math::PI, grid + 1).collect{|i| Complex(0.0, i)}
28
+ mgridr = mgridl[1...-1].reverse.conj
29
+ mgrid = mgridl + mgridr
30
+ b = Roctave.idft(mgrid)
31
+ mid = (n+1) / 2.0
32
+ b = (b[-(mid.floor) .. -1] + b[0 ... mid.ceil]).collect{|e| e.real}
33
+ window = Roctave.blackman(n+1)
34
+ b = b.collect.with_index{|e, i| e*window[i]}
35
+
36
+ indexes = (-n/2..n/2).to_a
37
+ Roctave.stem(indexes, b, :filled, grid: true, title: "FIR type III order #{n}")
38
+
39
+ r = Roctave.dft(b, 2048)
40
+ h = r[0...1024].abs
41
+ p = r[0...1024].arg
42
+ w = Roctave.linspace(0, 1, 1024)
43
+ Roctave.plot([0, Math::PI], '--;Ideal;', w, h, ";FIR type III order #{n};", grid: true, title: 'Magnitude')
44
+ Roctave.plot(w, p, grid: true, title: 'Phase')
45
+ =end
46
+
47
+
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/roctave.rb'
4
+
5
+ # t = Roctave.linspace(0, 1)
6
+ # s1 = t.collect{|e| Math.sin(2*Math::PI*2*e + 0*Math::PI/2)}
7
+ # s2 = t.collect{|e| Math.sin(2*Math::PI*2*e + 1*Math::PI/2)}
8
+ # s3 = t.collect{|e| Math.sin(2*Math::PI*2*e + 2*Math::PI/2)}
9
+ # s4 = t.collect{|e| Math.sin(2*Math::PI*2*e + 3*Math::PI/2)}
10
+ # Roctave.plot(t, s1, '-+;{/Symbol f} = 0;', t, s2, '--o;{/Symbol f} = {/Symbol p} / 2;', t, s3, ':*;{/Symbol f} = 2 {/Symbol p} / 2;', t, s4, '-..;{/Symbol f} = 3 {/Symbol p} / 2;', grid: true, title: 'y = sin(x + {/Symbol f})', xlabel: 'Time t^2 h^{titi} t_2 t_{titi} Z@^{en haut}_{en bas} escape\\\_underscore', ylabel: 'Amplitude', terminal: 'pngcairo transparent truecolor rounded enhanced font "Sans,10" size 1280,720', output: 'titi.png')
11
+ # #Roctave.plot(t, s1, '+-;{/Symbol f} = 0;', t, s2, '--o;{/Symbol f} = {/Symbol p} / 2;', t, s3, ':*;{/Symbol f} = 2 {/Symbol p} / 2;', t, s4, '-..;{/Symbol f} = 3 {/Symbol p} / 2;', grid: true, title: 'y = sin(x + {/Symbol f})', xlabel: 'Time t^2 h^{titi} t_2 t_{titi} Z@^{en haut}_{en bas} escape\\\_underscore', ylabel: 'Amplitude', terminal: "wxt enhanced persist font \"Times New Roman,13\" size 1280,720")
12
+ # Roctave.plot(t, s1, '+-;{/Symbol f} = 0;', t, s2, '--o;{/Symbol f} = {/Symbol p} / 2;', t, s3, ':*;{/Symbol f} = 2 {/Symbol p} / 2;', t, s4, '-..;{/Symbol f} = 3 {/Symbol p} / 2;', grid: true, title: 'y = sin(x + {/Symbol f})', xlabel: 'Time t^2 h^{titi} t_2 t_{titi} Z@^{en haut}_{en bas} escape\\\_underscore', ylabel: 'Amplitude', terminal: "wxt enhanced persist font \"Sans,13\" size 1280,720")
13
+ # Roctave.plot(
14
+ # t, s1,
15
+ # :color,
16
+ # 'orange',
17
+ # :dashtype,
18
+ # '-_',
19
+ # :pointtype,
20
+ # :square,
21
+ # :empty,
22
+ # :pointsize,
23
+ # 2,
24
+ # :linewidth,
25
+ # 2,
26
+ # grid: true, title: 'y = sin(x + {/Symbol f})', xlabel: 'Time t^2 h^{titi} t_2 t_{titi} Z@^{en haut}_{en bas} escape\\\_underscore', ylabel: 'Amplitude', terminal: "wxt enhanced persist size 1280,720"
27
+ # )
28
+
29
+ t = Roctave.linspace(0, 1, 1000)
30
+ s1 = t.collect{|e| Math.sin(2*Math::PI*2*e + 0*Math::PI/2)}
31
+ s2 = t.collect{|e| Math.sin(2*Math::PI*2*e + 1*Math::PI/2)}
32
+ s3 = t.collect{|e| Math.sin(2*Math::PI*2*e + 2*Math::PI/2)}
33
+ s4 = t.collect{|e| Math.sin(2*Math::PI*2*e + 3*Math::PI/2)}
34
+ Roctave.plot(
35
+ t, s1, ';{/Symbol f} = 0;',
36
+ t, s2, ';{/Symbol f} = {/Symbol p} / 2;',
37
+ t, s3, ';{/Symbol f} = 2 {/Symbol p} / 2;',
38
+ t, s4, ';{/Symbol f} = 3 {/Symbol p} / 2;',
39
+ grid: true,
40
+ title: 'y = sin(x + {/Symbol f})',
41
+ xlabel: 'Time t^2 h^{titi} t_2 t_{titi} Z@^{en haut}_{en bas} escape\\\_underscore',
42
+ ylabel: 'Amplitude',
43
+ terminal: "wxt enhanced persist size 854,480"
44
+ )
45
+
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/roctave.rb'
4
+
5
+ t = Roctave.linspace(0, 2*Math::PI, 50)
6
+ y = t.collect{|x| Math.exp(0.3*x) * Math.sin(3*x)}
7
+ Roctave.stem(t, y, :legend, 'Coucou', t, y.reverse, ';plop;', :filled, grid: true)
8
+
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/roctave.rb'
4
+
5
+ n = 32
6
+ fc = 0.5
7
+
8
+ b1 = Roctave.fir_low_pass(n, fc)
9
+ ns = (-n/2..n/2).to_a
10
+ Roctave.stem(ns, b1, :filled, grid: true)
11
+
12
+ h1 = Roctave.dft(b1, 2048).abs[0...1024]
13
+ w = Roctave.linspace(0.0, 1.0, 1024)
14
+
15
+ bb = b1[n/2+1..-1]
16
+ h2 = (0...1024).collect do |i|
17
+ acc = 0.0
18
+ bb.each.with_index do |e, j|
19
+ acc += e*Math.cos((i*Math::PI/1024)*(j+1))
20
+ end
21
+ b1[n/2] + 2.0*acc
22
+ end
23
+
24
+ Roctave.plot(w, h1, ';real;', w, h2, ';test;', grid: true, ylim: [0, 1.4])
25
+
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/roctave.rb'
4
+
5
+ n = 32
6
+
7
+ b1 = Roctave.fir_differentiator(n, window: :blackman)
8
+ ns = (-n/2..n/2).to_a
9
+ Roctave.stem(ns, b1, :filled, grid: true)
10
+
11
+ h1 = Roctave.dft(b1, 2048).abs[0...1024]
12
+ w = Roctave.linspace(0.0, 1.0, 1024)
13
+
14
+ bb = b1[n/2+1..-1]
15
+ h2 = (0...1024).collect do |i|
16
+ acc = 0.0
17
+ bb.each.with_index do |e, j|
18
+ acc += -e*Math.sin((i*Math::PI/1024)*(j+1))
19
+ end
20
+ b1[n/2] + 2.0*acc
21
+ end
22
+
23
+ Roctave.plot(w, h1, ';real;', w, h2, ';test;', grid: true)
24
+
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/roctave.rb'
4
+ require 'gnuplot'
5
+
6
+ Gnuplot.open do |gp|
7
+ Gnuplot::Plot.new(gp) do |plot|
8
+ plot.terminal 'wxt'
9
+ plot.title "Roctave::Window"
10
+ plot.yrange "[0:1.1]"
11
+ plot.grid
12
+
13
+ n = 100
14
+ x = (0...n).to_a
15
+
16
+ [:hann, :hamming, :blackman, :nuttall, :blackman_nuttall, :blackman_harris, :gaussian].each do |name|
17
+ y = Roctave::Window.send(name, n)
18
+ plot.data << Gnuplot::DataSet.new([x, y]) { |ds|
19
+ ds.with = "lines"
20
+ ds.title = name.to_s.split('_').collect{|s| s.capitalize}.join(' ')
21
+ }
22
+ end
23
+ end
24
+ end
25
+
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roctave
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Théotime Bollengier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-01-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gnuplot
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.6'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.6.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.6'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.6.2
33
+ description: Roctave is an attempt to provide some Matlab / Gnu Octave functions in
34
+ a Ruby gem to generate and analyze digital filters.
35
+ email: theotime.bollengier@gmail.com
36
+ executables: []
37
+ extensions:
38
+ - ext/roctave/extconf.rb
39
+ extra_rdoc_files: []
40
+ files:
41
+ - LICENSE
42
+ - README.md
43
+ - ext/roctave/cu8_file_reader.c
44
+ - ext/roctave/cu8_file_reader.h
45
+ - ext/roctave/extconf.rb
46
+ - ext/roctave/fir_filter.c
47
+ - ext/roctave/fir_filter.h
48
+ - ext/roctave/freq_shifter.c
49
+ - ext/roctave/freq_shifter.h
50
+ - ext/roctave/iir_filter.c
51
+ - ext/roctave/iir_filter.h
52
+ - ext/roctave/roctave.c
53
+ - ext/roctave/roctave.h
54
+ - lib/roctave.rb
55
+ - lib/roctave/bilinear.rb
56
+ - lib/roctave/butter.rb
57
+ - lib/roctave/cheby.rb
58
+ - lib/roctave/cu8_file_reader.rb
59
+ - lib/roctave/dft.rb
60
+ - lib/roctave/filter.rb
61
+ - lib/roctave/finite_difference_coefficients.rb
62
+ - lib/roctave/fir.rb
63
+ - lib/roctave/fir1.rb
64
+ - lib/roctave/fir2.rb
65
+ - lib/roctave/fir_design.rb
66
+ - lib/roctave/firls.rb
67
+ - lib/roctave/firpm.rb
68
+ - lib/roctave/freq_shifter.rb
69
+ - lib/roctave/freqz.rb
70
+ - lib/roctave/iir.rb
71
+ - lib/roctave/interp1.rb
72
+ - lib/roctave/plot.rb
73
+ - lib/roctave/poly.rb
74
+ - lib/roctave/roots.rb
75
+ - lib/roctave/sftrans.rb
76
+ - lib/roctave/version.rb
77
+ - lib/roctave/window.rb
78
+ - roctave.gemspec
79
+ - samples/butter.rb
80
+ - samples/cheby.rb
81
+ - samples/dft.rb
82
+ - samples/differentiator.rb
83
+ - samples/differentiator_frequency_scaling.rb
84
+ - samples/fft.rb
85
+ - samples/finite_difference_coefficient.rb
86
+ - samples/fir1.rb
87
+ - samples/fir2.rb
88
+ - samples/fir2_windows.rb
89
+ - samples/fir2bank.rb
90
+ - samples/fir_low_pass.rb
91
+ - samples/firls.rb
92
+ - samples/firpm.rb
93
+ - samples/hilbert_transformer.rb
94
+ - samples/hilbert_transformer_frequency_scaling.rb
95
+ - samples/plot.rb
96
+ - samples/stem.rb
97
+ - samples/type1.rb
98
+ - samples/type3.rb
99
+ - samples/windows.rb
100
+ homepage: https://gitlab.com/theotime_bollengier/roctave
101
+ licenses:
102
+ - GPL-3.0+
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubygems_version: 3.0.6
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Some Matlab / Gnu Octave functions implemented in Ruby.
123
+ test_files: []