num_seq 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.
- data/lib/num_seq.rb +220 -0
- data/lib/num_seq/array.rb +5 -0
- data/lib/num_seq/internal_ops/common.rb +32 -0
- data/lib/num_seq/internal_ops/conv.rb +0 -0
- data/lib/num_seq/internal_ops/div.rb +14 -0
- data/lib/num_seq/internal_ops/exp.rb +14 -0
- data/lib/num_seq/internal_ops/interpolation.rb +35 -0
- data/lib/num_seq/internal_ops/math.rb +0 -0
- data/lib/num_seq/internal_ops/mod.rb +14 -0
- data/lib/num_seq/internal_ops/mul.rb +14 -0
- data/lib/num_seq/internal_ops/sub.rb +15 -0
- data/lib/num_seq/internal_ops/sum.rb +14 -0
- data/lib/num_seq/ops.rb +39 -0
- metadata +58 -0
data/lib/num_seq.rb
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
class NumSeq
|
2
|
+
include Enumerable
|
3
|
+
def self.from_array(array, index_origin = 0)
|
4
|
+
len = array.length
|
5
|
+
seq = Sequence.new(len, index_origin) do |n, i|
|
6
|
+
array[i]
|
7
|
+
end
|
8
|
+
return seq
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
class SequenceArray < Array
|
13
|
+
def initialize(n, offset)
|
14
|
+
@offset = offset
|
15
|
+
super(n)
|
16
|
+
end
|
17
|
+
|
18
|
+
def offset=(new_offset)
|
19
|
+
raise "Wrong point reached" if new_offset >= @offset
|
20
|
+
(@offset-new_offset).times { self.unshift nil }
|
21
|
+
@offset = new_offset
|
22
|
+
end
|
23
|
+
|
24
|
+
def [](n)
|
25
|
+
super(n - @offset)
|
26
|
+
end
|
27
|
+
|
28
|
+
def []=(n,value)
|
29
|
+
super(n - @offset, value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(len, start_at = 0)
|
34
|
+
if len < 0 then
|
35
|
+
raise ArgumentError,
|
36
|
+
"Length of a num_seq must be positive"
|
37
|
+
end
|
38
|
+
|
39
|
+
@@strict = false
|
40
|
+
@undef_value = nil
|
41
|
+
|
42
|
+
if 0 == len then
|
43
|
+
@undef_inf = @undef_sup = start_at
|
44
|
+
else
|
45
|
+
@undef_inf = start_at - 1
|
46
|
+
@undef_sup = start_at + len
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
@elems = SequenceArray.new(len, @undef_inf + 1)
|
51
|
+
|
52
|
+
if block_given? then
|
53
|
+
((@undef_inf+1)...@undef_sup).each_with_index do |n,i|
|
54
|
+
@elems[n] = yield(n,i)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
attr_accessor :undef_value
|
60
|
+
|
61
|
+
def self.behave_strict?
|
62
|
+
return @@strict
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.strict_behavior
|
66
|
+
@@strict = true
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.rough_behavior
|
70
|
+
@@strict = false
|
71
|
+
end
|
72
|
+
|
73
|
+
def seq_defined_at?(n)
|
74
|
+
return n > @undef_inf && n < @undef_sup
|
75
|
+
end
|
76
|
+
private :seq_defined_at?
|
77
|
+
|
78
|
+
def [](n)
|
79
|
+
return @undef_value unless seq_defined_at? n
|
80
|
+
return @elems[n]
|
81
|
+
end
|
82
|
+
|
83
|
+
def []=(n, value)
|
84
|
+
if self.class.behave_strict? and not seq_defined_at?(n) then
|
85
|
+
raise IndexError,
|
86
|
+
%Q%Attempt to assign at index #{n} % +
|
87
|
+
%q%where the num_seq is not defined%
|
88
|
+
end
|
89
|
+
return @elems[n] = value if seq_defined_at? n
|
90
|
+
if n <= @undef_inf then
|
91
|
+
@undef_inf = n - 1
|
92
|
+
@elems.offset = n
|
93
|
+
@elems[n] = value
|
94
|
+
elsif n >= @undef_sup then
|
95
|
+
@undef_sup = n + 1
|
96
|
+
@elems[n] = value
|
97
|
+
else
|
98
|
+
raise "Impossible point reached"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
def range
|
104
|
+
return (@undef_inf+1..@undef_sup-1)
|
105
|
+
end
|
106
|
+
|
107
|
+
def length
|
108
|
+
return @undef_sup - @undef_inf - 1
|
109
|
+
end
|
110
|
+
alias :size :length
|
111
|
+
|
112
|
+
def min_index
|
113
|
+
return @undef_inf + 1
|
114
|
+
end
|
115
|
+
alias :n_min :min_index
|
116
|
+
|
117
|
+
def max_index
|
118
|
+
return @undef_sup - 1
|
119
|
+
end
|
120
|
+
alias :n_max :max_index
|
121
|
+
|
122
|
+
def first
|
123
|
+
return self[n_min]
|
124
|
+
end
|
125
|
+
|
126
|
+
def last
|
127
|
+
return self[n_max]
|
128
|
+
end
|
129
|
+
|
130
|
+
# y[n] = x[n-k]
|
131
|
+
def shift(k)
|
132
|
+
if k < 0 then
|
133
|
+
# left shift
|
134
|
+
_lshift(-k)
|
135
|
+
elsif k > 0 then
|
136
|
+
# right shift
|
137
|
+
_rshift(k)
|
138
|
+
else
|
139
|
+
# return copy -> CHANGE!!
|
140
|
+
return nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def rshift(k)
|
145
|
+
if k < 0 then
|
146
|
+
raise ArgumentError, "Argument should be non-negative"
|
147
|
+
end
|
148
|
+
return _rshift(k)
|
149
|
+
end
|
150
|
+
|
151
|
+
def lshift(k)
|
152
|
+
if k < 0 then
|
153
|
+
raise ArgumentError, "Argument should be non-negative"
|
154
|
+
end
|
155
|
+
return _lshift(k)
|
156
|
+
end
|
157
|
+
|
158
|
+
def _rshift(k)
|
159
|
+
start_at = self.n_min
|
160
|
+
length = self.length
|
161
|
+
seq = Sequence.new(length, start_at + k) do |n|
|
162
|
+
self[n-k]
|
163
|
+
end
|
164
|
+
return seq
|
165
|
+
end
|
166
|
+
private :_rshift
|
167
|
+
|
168
|
+
def _lshift(k)
|
169
|
+
start_at = self.n_min
|
170
|
+
length = self.length
|
171
|
+
seq = Sequence.new(length, start_at - k) do |n|
|
172
|
+
self[n+k]
|
173
|
+
end
|
174
|
+
return seq
|
175
|
+
end
|
176
|
+
private :_lshift
|
177
|
+
|
178
|
+
# x[Mn]
|
179
|
+
def compress(m)
|
180
|
+
end
|
181
|
+
|
182
|
+
# x[n/L]
|
183
|
+
def expand(l)
|
184
|
+
end
|
185
|
+
|
186
|
+
def to_s
|
187
|
+
index = self.n_min
|
188
|
+
@elems.each do |e|
|
189
|
+
puts "#{index} #{e}"
|
190
|
+
index += 1
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
require 'num_seq/common'
|
196
|
+
require 'num_seq/enumerable'
|
197
|
+
require 'num_seq/array'
|
198
|
+
require 'num_seq/ops'
|
199
|
+
require 'num_seq/internal_ops/common'
|
200
|
+
require 'num_seq/internal_ops/sum'
|
201
|
+
require 'num_seq/internal_ops/sub'
|
202
|
+
require 'num_seq/internal_ops/conv'
|
203
|
+
require 'num_seq/internal_ops/mul'
|
204
|
+
require 'num_seq/internal_ops/div'
|
205
|
+
require 'num_seq/internal_ops/exp'
|
206
|
+
require 'num_seq/internal_ops/mod'
|
207
|
+
require 'num_seq/internal_ops/math'
|
208
|
+
require 'num_seq/internal_ops/interpolation'
|
209
|
+
require 'num_seq/external_ops/common'
|
210
|
+
require 'num_seq/external_ops/sum'
|
211
|
+
require 'num_seq/external_ops/sub'
|
212
|
+
require 'num_seq/external_ops/mul'
|
213
|
+
require 'num_seq/external_ops/div'
|
214
|
+
require 'num_seq/external_ops/mod'
|
215
|
+
require 'num_seq/external_ops/exp'
|
216
|
+
require 'num_seq/external_ops/energetic'
|
217
|
+
require 'num_seq/external_ops/stats'
|
218
|
+
|
219
|
+
|
220
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class NumSeq
|
2
|
+
def self.minimal_index(seq_a, seq_b)
|
3
|
+
if seq_a.min_index < seq_b.min_index then
|
4
|
+
seq_a.min_index
|
5
|
+
else
|
6
|
+
seq_b.min_index
|
7
|
+
end
|
8
|
+
end
|
9
|
+
private_class_method :minimal_index
|
10
|
+
|
11
|
+
def self.maximal_index(seq_a, seq_b)
|
12
|
+
if seq_a.max_index > seq_b.max_index then
|
13
|
+
seq_a.max_index
|
14
|
+
else
|
15
|
+
seq_b.max_index
|
16
|
+
end
|
17
|
+
end
|
18
|
+
private_class_method :maximal_index
|
19
|
+
|
20
|
+
def self.operate(elem_a, elem_b, op)
|
21
|
+
if nil != elem_a and nil != elem_b then
|
22
|
+
elem_a.send(op, elem_b)
|
23
|
+
elsif nil != elem_a then
|
24
|
+
elem_a
|
25
|
+
elsif nil != elem_b then
|
26
|
+
elem_b
|
27
|
+
else
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
private_class_method :operate
|
32
|
+
end
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class NumSeq
|
2
|
+
def idiv(seq)
|
3
|
+
n_min = self.class.send(:minimal_index, self, seq)
|
4
|
+
n_max = self.class.send(:maximal_index, self, seq)
|
5
|
+
|
6
|
+
len = n_max - n_min + 1
|
7
|
+
|
8
|
+
res = self.class.new(len, n_min) do |n|
|
9
|
+
self.class.send(:operate, self[n], seq[n], :/)
|
10
|
+
end
|
11
|
+
return res
|
12
|
+
end
|
13
|
+
private :idiv
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class NumSeq
|
2
|
+
def iexp(seq)
|
3
|
+
n_min = self.class.send(:minimal_index, self, seq)
|
4
|
+
n_max = self.class.send(:maximal_index, self, seq)
|
5
|
+
|
6
|
+
len = n_max - n_min + 1
|
7
|
+
|
8
|
+
res = self.class.new(len, n_min) do |n|
|
9
|
+
self.class.send(:operate, self[n], seq[n], :**)
|
10
|
+
end
|
11
|
+
return res
|
12
|
+
end
|
13
|
+
private :iexp
|
14
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class NumSeq
|
2
|
+
def interpolate
|
3
|
+
if block_given? then
|
4
|
+
n_inf = n_sup = self.n_min
|
5
|
+
while true
|
6
|
+
# find the next defined element
|
7
|
+
n = n_sup + 1
|
8
|
+
n_inf = n_sup
|
9
|
+
while n <= self.n_max
|
10
|
+
begin
|
11
|
+
next if nil == self[n]
|
12
|
+
n_sup = n
|
13
|
+
break
|
14
|
+
ensure
|
15
|
+
n += 1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
(n_inf..n_sup).each do |m|
|
19
|
+
self[m] = yield(n_inf,n_sup, m)
|
20
|
+
end
|
21
|
+
break if self.n_max == n_sup
|
22
|
+
end
|
23
|
+
else
|
24
|
+
# perform linear interpolation by default
|
25
|
+
self.interpolate do |n0,n1,k;m|
|
26
|
+
m = (self[n1] - self[n0])
|
27
|
+
# to avoid integer divisions
|
28
|
+
m *= 1.0 if m.is_a? Numeric
|
29
|
+
m /= n1 - n0
|
30
|
+
next (self[n0] + m * (k - n0))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return self
|
34
|
+
end
|
35
|
+
end
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class NumSeq
|
2
|
+
def imod(seq)
|
3
|
+
n_min = self.class.send(:minimal_index, self, seq)
|
4
|
+
n_max = self.class.send(:maximal_index, self, seq)
|
5
|
+
|
6
|
+
len = n_max - n_min + 1
|
7
|
+
|
8
|
+
res = self.class.new(len, n_min) do |n|
|
9
|
+
self.class.send(:operate, self[n], seq[n], :%)
|
10
|
+
end
|
11
|
+
return res
|
12
|
+
end
|
13
|
+
private :imod
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class NumSeq
|
2
|
+
def imul(seq)
|
3
|
+
n_min = self.class.send(:minimal_index, self, seq)
|
4
|
+
n_max = self.class.send(:maximal_index, self, seq)
|
5
|
+
|
6
|
+
len = n_max - n_min + 1
|
7
|
+
|
8
|
+
res = self.class.new(len, n_min) do |n|
|
9
|
+
self.class.send(:operate, self[n], seq[n], :*)
|
10
|
+
end
|
11
|
+
return res
|
12
|
+
end
|
13
|
+
private :imul
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class NumSeq
|
2
|
+
def isub(seq)
|
3
|
+
n_min = self.class.send(:minimal_index, self, seq)
|
4
|
+
n_max = self.class.send(:maximal_index, self, seq)
|
5
|
+
|
6
|
+
len = n_max - n_min + 1
|
7
|
+
|
8
|
+
res = self.class.new(len, n_min) do |n|
|
9
|
+
self.class.send(:operate, self[n], seq[n], :-)
|
10
|
+
end
|
11
|
+
return res
|
12
|
+
end
|
13
|
+
private :isub
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class NumSeq
|
2
|
+
def isum(seq)
|
3
|
+
n_min = self.class.send(:minimal_index, self, seq)
|
4
|
+
n_max = self.class.send(:maximal_index, self, seq)
|
5
|
+
|
6
|
+
len = n_max - n_min + 1
|
7
|
+
|
8
|
+
res = self.class.new(len, n_min) do |n|
|
9
|
+
self.class.send(:operate, self[n], seq[n], :+)
|
10
|
+
end
|
11
|
+
return res
|
12
|
+
end
|
13
|
+
private :isum
|
14
|
+
end
|
data/lib/num_seq/ops.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
class NumSeq
|
2
|
+
def +(arg)
|
3
|
+
use_proper_operator(arg, :isum, :xsum)
|
4
|
+
end
|
5
|
+
|
6
|
+
def -(arg)
|
7
|
+
use_proper_operator(arg, :isub, :xsub)
|
8
|
+
end
|
9
|
+
|
10
|
+
def *(arg)
|
11
|
+
use_proper_operator(arg, :imul, :xmul)
|
12
|
+
end
|
13
|
+
|
14
|
+
def /(arg)
|
15
|
+
use_proper_operator(arg, :idiv, :xdiv)
|
16
|
+
end
|
17
|
+
|
18
|
+
def %(arg)
|
19
|
+
use_proper_operator(arg, :imod, :xmod)
|
20
|
+
end
|
21
|
+
|
22
|
+
def **(arg)
|
23
|
+
use_proper_operator(arg, :iexp, :xexp)
|
24
|
+
end
|
25
|
+
|
26
|
+
def use_proper_operator(arg, internal_operator, external_operator)
|
27
|
+
if arg.is_a? Numeric then
|
28
|
+
return self.send(external_operator, arg)
|
29
|
+
elsif arg.is_a? NumSeq then
|
30
|
+
return self.send(internal_operator, arg)
|
31
|
+
else
|
32
|
+
raise(ArgumentError, "Attempt to operate an object " +
|
33
|
+
"of the '#{self.class}' class with an object " +
|
34
|
+
"of the '#{arg.class}' class using the " +
|
35
|
+
"'#{caller[0][/`.*'/][1..-2]}' operator")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
private :use_proper_operator
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: num_seq
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jorge F.M. Rinaldi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-30 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: For representing Numerical Sequences, especially Discret-Time signals
|
15
|
+
email: jorge.madronal.rinaldi@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/num_seq.rb
|
21
|
+
- lib/num_seq/array.rb
|
22
|
+
- lib/num_seq/ops.rb
|
23
|
+
- lib/num_seq/internal_ops/common.rb
|
24
|
+
- lib/num_seq/internal_ops/sum.rb
|
25
|
+
- lib/num_seq/internal_ops/sub.rb
|
26
|
+
- lib/num_seq/internal_ops/conv.rb
|
27
|
+
- lib/num_seq/internal_ops/mul.rb
|
28
|
+
- lib/num_seq/internal_ops/div.rb
|
29
|
+
- lib/num_seq/internal_ops/mod.rb
|
30
|
+
- lib/num_seq/internal_ops/exp.rb
|
31
|
+
- lib/num_seq/internal_ops/math.rb
|
32
|
+
- lib/num_seq/internal_ops/interpolation.rb
|
33
|
+
homepage: http://mrinaldi.net
|
34
|
+
licenses:
|
35
|
+
- GPLv3
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.8.24
|
55
|
+
signing_key:
|
56
|
+
specification_version: 3
|
57
|
+
summary: Numerical Sequences in Ruby
|
58
|
+
test_files: []
|