roctave 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []