kxi 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kxi.rb +44 -39
- data/lib/kxi/application/config.rb +177 -177
- data/lib/kxi/application/config_reader.rb +16 -16
- data/lib/kxi/application/event.rb +35 -35
- data/lib/kxi/application/logger.rb +155 -155
- data/lib/kxi/application/version.rb +106 -74
- data/lib/kxi/application/version_expression.rb +94 -69
- data/lib/kxi/application/workspace.rb +105 -0
- data/lib/kxi/cli/anonymous_argument.rb +50 -50
- data/lib/kxi/cli/argument.rb +56 -56
- data/lib/kxi/cli/argument_values.rb +83 -83
- data/lib/kxi/cli/explicit_argument.rb +38 -38
- data/lib/kxi/cli/flag_argument.rb +15 -15
- data/lib/kxi/cli/named_argument.rb +59 -59
- data/lib/kxi/cli/property_list.rb +57 -48
- data/lib/kxi/cli/table.rb +82 -62
- data/lib/kxi/cli/verb.rb +282 -280
- data/lib/kxi/collections/array_collection.rb +106 -106
- data/lib/kxi/collections/enumerable.rb +527 -527
- data/lib/kxi/collections/enumerator.rb +31 -31
- data/lib/kxi/collections/hash_collection.rb +100 -100
- data/lib/kxi/collections/protected_collection.rb +20 -19
- data/lib/kxi/exceptions/abstract_exception.rb +34 -34
- data/lib/kxi/exceptions/argument_exception.rb +21 -21
- data/lib/kxi/exceptions/collection_exception.rb +13 -13
- data/lib/kxi/exceptions/configuration_exception.rb +36 -25
- data/lib/kxi/exceptions/dimension_mismatch_exception.rb +29 -0
- data/lib/kxi/exceptions/invalid_type_exception.rb +32 -32
- data/lib/kxi/exceptions/no_argument_exception.rb +20 -20
- data/lib/kxi/exceptions/not_implemented_exception.rb +12 -12
- data/lib/kxi/exceptions/out_of_range_exception.rb +43 -43
- data/lib/kxi/exceptions/parse_exception.rb +28 -20
- data/lib/kxi/exceptions/verb_expected_exception.rb +20 -20
- data/lib/kxi/exceptions/workspace_collision_exception.rb +21 -0
- data/lib/kxi/math/math.rb +45 -0
- data/lib/kxi/math/matrix.rb +303 -0
- data/lib/kxi/math/polynomial.rb +141 -101
- data/lib/kxi/math/vector.rb +181 -0
- data/lib/kxi/platform.rb +103 -57
- data/lib/kxi/reflection/stack_frame.rb +80 -80
- data/lib/kxi/version.rb +4 -4
- metadata +8 -3
- data/lib/kxi/exceptions/invalid_operation_exception.rb +0 -11
@@ -0,0 +1,303 @@
|
|
1
|
+
# Created by Matyáš Pokorný on 2018-04-12.
|
2
|
+
|
3
|
+
module KXI
|
4
|
+
module Math
|
5
|
+
# Represents a matrix
|
6
|
+
class Matrix
|
7
|
+
# Returns a square identity matrix
|
8
|
+
# @param [Integer] n Dimension of matrix
|
9
|
+
# @return [KXI::Math::Matrix] Square identity matrix of given dimension
|
10
|
+
def self.identity(n)
|
11
|
+
return KXI::Math::Matrix.new(n, n) { |c, r| c == r ? 1 : 0 }
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the number of rows
|
15
|
+
# @return [Integer] Number of rows
|
16
|
+
def rows
|
17
|
+
@rows
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the number of columns
|
21
|
+
# @return [Integer] Number of columns
|
22
|
+
def columns
|
23
|
+
@cols
|
24
|
+
end
|
25
|
+
|
26
|
+
# Instantiates the {KXI::Math::Matrix} class
|
27
|
+
# @overload initialize(cols)
|
28
|
+
# Creates a square matrix
|
29
|
+
# @param [Integer] cols Dimension of matrix
|
30
|
+
# @overload initialize(cols, rows)
|
31
|
+
# Creates a matrix
|
32
|
+
# @param [Integer] cols Number of columns in the matrix
|
33
|
+
# @param [Integer] rows Number of rows in the matrix
|
34
|
+
def initialize(cols, rows = nil)
|
35
|
+
rows = cols if rows == nil
|
36
|
+
@data = []
|
37
|
+
cols.times do |i|
|
38
|
+
if block_given?
|
39
|
+
@data[i] = []
|
40
|
+
rows.times do |j|
|
41
|
+
v = yield(i, j)
|
42
|
+
raise(KXI::Exceptions::InvalidTypeException.new(v.type, Numeric)) unless v.is_a?(Numeric)
|
43
|
+
@data[i].push(v)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
@data[i] = [0.0] * rows
|
47
|
+
end
|
48
|
+
end
|
49
|
+
@cols = cols
|
50
|
+
@rows = rows
|
51
|
+
end
|
52
|
+
|
53
|
+
# Swaps two rows of the matrix
|
54
|
+
# @param [Integer] a First row to swap
|
55
|
+
# @param [Integer] b Second row to swap with
|
56
|
+
# @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range
|
57
|
+
# @return [KXI::Math::Matrix] New matrix with swapped rows
|
58
|
+
def row_swap(a, b)
|
59
|
+
raise(KXI::Exceptions::OutOfRangeException.new(a, 0, @rows - 1)) if a < 0 or a >= @rows
|
60
|
+
raise(KXI::Exceptions::OutOfRangeException.new(b, 0, @rows - 1)) if b < 0 or b >= @rows
|
61
|
+
return KXI::Math::Matrix.new(@cols, @rows) do |c, r|
|
62
|
+
next get(c, b) if r == a
|
63
|
+
next get(c, a) if r == b
|
64
|
+
get(c, r)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Multiplies a row of matrix with specific coefficient
|
69
|
+
# @overload row_mult(src, cof)
|
70
|
+
# Multiplies a row by coefficient into that row
|
71
|
+
# @param [Integer] src Row to multiply
|
72
|
+
# @param [Numeric] cof Coefficient to multiply with
|
73
|
+
# @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range
|
74
|
+
# @return [Matrix] New matrix with multiplied row
|
75
|
+
# @overload row_mult(src, cof, dst)
|
76
|
+
# Multiplies a row by coefficient into other row
|
77
|
+
# @param [Integer] src Row to multiply
|
78
|
+
# @param [Numeric] cof Coefficient to multiply with
|
79
|
+
# @param [Numeric] dst Row to write the results of multiplication
|
80
|
+
# @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range
|
81
|
+
# @return [Matrix] New matrix with multiplied row
|
82
|
+
def row_mult!(src, cof, dst = nil)
|
83
|
+
dst = src if dst == nil
|
84
|
+
raise(KXI::Exceptions::OutOfRangeException.new(src, 0, @rows - 1)) if src < 0 or src >= @rows
|
85
|
+
raise(KXI::Exceptions::OutOfRangeException.new(dst, 0, @rows - 1)) if dst < 0 or dst >= @rows
|
86
|
+
return KXI::Math::Matrix.new(@cols, @rows) do |c, r|
|
87
|
+
next cof * get(c, src) if r == dst
|
88
|
+
get(c, r)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Multiplies a row of matrix with specific coefficient
|
93
|
+
# @overload row_mult(src, cof)
|
94
|
+
# Multiplies a row by coefficient and adds that to the row
|
95
|
+
# @param [Integer] src Row to multiply
|
96
|
+
# @param [Numeric] cof Coefficient to multiply with
|
97
|
+
# @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range
|
98
|
+
# @return [Matrix] New matrix with multiplied row
|
99
|
+
# @overload row_mult(src, cof, dst)
|
100
|
+
# Multiplies a row by coefficient and adds that to other row
|
101
|
+
# @param [Integer] src Row to multiply
|
102
|
+
# @param [Numeric] cof Coefficient to multiply with
|
103
|
+
# @param [Numeric] dst Row to write the results of multiplication
|
104
|
+
# @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range
|
105
|
+
# @return [Matrix] New matrix with multiplied row
|
106
|
+
def row_mult(src, cof, dst = nil)
|
107
|
+
dst = src if dst == nil
|
108
|
+
return KXI::Math::Matrix.new(@cols, @rows) do |c, r|
|
109
|
+
next get(c, r) + cof * get(c, src) if r == dst
|
110
|
+
get(c, r)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def sign(col, row)
|
115
|
+
return ((col % 2 == 0) == (row % 2 == 0)) ? 1 : -1
|
116
|
+
end
|
117
|
+
|
118
|
+
# Computes the determinant of matrix
|
119
|
+
# @return [Numeric] Determinant of matrix
|
120
|
+
def determinant
|
121
|
+
return get(0, 0) * get(1, 1) - get(1, 0) * get(0, 1) if @cols == 2
|
122
|
+
ci = 0
|
123
|
+
cz = 0
|
124
|
+
@cols.times do |col|
|
125
|
+
zeros = 0
|
126
|
+
@rows.times { |row| zeros += 1 if get(col, row) == 0 }
|
127
|
+
if zeros > cz
|
128
|
+
ci = col
|
129
|
+
cz = zeros
|
130
|
+
end
|
131
|
+
end
|
132
|
+
ret = 0
|
133
|
+
@rows.times do |row|
|
134
|
+
if get(ci, row) != 0
|
135
|
+
ret += sign(ci, row) * get(ci, row) * sub(ci, row).determinant
|
136
|
+
end
|
137
|
+
end
|
138
|
+
return ret
|
139
|
+
end
|
140
|
+
|
141
|
+
# Computes the inverse of matrix
|
142
|
+
# @return [KXI::Math::Matrix] Inverse matrix
|
143
|
+
def inverse
|
144
|
+
return (KXI::Math::Matrix.new(@cols, @rows) { |c, r| sign(c, r) * sub(c, r).determinant }).transpose * (1 / determinant)
|
145
|
+
end
|
146
|
+
|
147
|
+
def sub(col, row)
|
148
|
+
return KXI::Math::Matrix.new(@cols - 1, @rows - 1) do |c, r|
|
149
|
+
c = c + 1 if c >= col
|
150
|
+
r = r + 1 if r >= row
|
151
|
+
next get(c, r)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Gets the value of matrix at given column and row
|
156
|
+
# @param [Integer] col Column to get
|
157
|
+
# @param [Integer] row Row to get
|
158
|
+
# @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range
|
159
|
+
# @return [Numeric] Value of matrix at given column and row
|
160
|
+
def get(col, row)
|
161
|
+
raise(KXI::Exceptions::OutOfRangeException.new(col, 0, @cols - 1)) if col < 0 or col >= @cols
|
162
|
+
raise(KXI::Exceptions::OutOfRangeException.new(row, 0, @rows - 1)) if row < 0 or row >= @rows
|
163
|
+
return @data[col][row]
|
164
|
+
end
|
165
|
+
|
166
|
+
# Sets the value of vector at specific dimension
|
167
|
+
# @overload set(col, row, val)
|
168
|
+
# Sets the value of vector at specific dimension
|
169
|
+
# @param [Integer] col Column to set
|
170
|
+
# @param [Integer] row Row to set
|
171
|
+
# @param [Integer] val Value to set the matrix to
|
172
|
+
# @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range
|
173
|
+
# @raise [KXI::Exceptions::InvalidTypeException] When value has invalid type
|
174
|
+
# @return [Numeric] Value passed to function
|
175
|
+
# @overload set(col, row, val)
|
176
|
+
# Sets the values of vector to range of values starting from specific dimension
|
177
|
+
# @param [Integer] col Column to set
|
178
|
+
# @param [Integer] row Row to set
|
179
|
+
# @param [Array] val Values to set the matrix to
|
180
|
+
# @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range
|
181
|
+
# @raise [KXI::Exceptions::InvalidTypeException] When value has invalid type
|
182
|
+
# @return [Numeric] Value passed to function
|
183
|
+
def set(col, row, value)
|
184
|
+
raise(KXI::Exceptions::OutOfRangeException.new(col, 0, @cols - 1)) if col < 0 or col >= @cols
|
185
|
+
raise(KXI::Exceptions::OutOfRangeException.new(row, 0, @rows - 1)) if row < 0 or row >= @rows
|
186
|
+
if value.is_a?(Array)
|
187
|
+
i = 0
|
188
|
+
while i + col < @cols and i < value.length
|
189
|
+
j = 0
|
190
|
+
while j + row < @rows and j < value[i].length
|
191
|
+
@data[col + i][row + j] = value[i][j].to_f
|
192
|
+
j += 1
|
193
|
+
end
|
194
|
+
i += 1
|
195
|
+
end
|
196
|
+
elsif value.is_a?(Numeric)
|
197
|
+
@data[col][row] = value.to_f
|
198
|
+
else
|
199
|
+
raise(KXI::Exceptions::InvalidTypeException.new(value.type, Numeric, Array))
|
200
|
+
end
|
201
|
+
return value
|
202
|
+
end
|
203
|
+
|
204
|
+
# Iterates over each element of matrix
|
205
|
+
# @yield [col, row, val] Iterator function
|
206
|
+
# @yieldparam [Integer] col Column passed to iterator
|
207
|
+
# @yieldparam [Integer] row Row passed to iterator
|
208
|
+
# @yieldparam [Numeric] val Value of matrix at given column and row
|
209
|
+
def each
|
210
|
+
@cols.times do |col|
|
211
|
+
@rows.times do |row|
|
212
|
+
yield(col, row, @data[col][row])
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# Returns the transpose of matrix
|
218
|
+
# @return [KXI::Math::Matrix] Transposed matrix
|
219
|
+
def transpose
|
220
|
+
ret = KXI::Math::Matrix.new(@rows, @cols)
|
221
|
+
each do |col, row, value|
|
222
|
+
ret.set(row, col, value)
|
223
|
+
end
|
224
|
+
return ret
|
225
|
+
end
|
226
|
+
|
227
|
+
# Multiplies matrix
|
228
|
+
# @overload *(other)
|
229
|
+
# Scales matrix
|
230
|
+
# @param [Numeric] other Scalar to multiply with
|
231
|
+
# @raise [KXI::Exceptions::InvalidTypeException] When value is of invalid type
|
232
|
+
# @return [KXI::Math::Matrix] Scaled matrix
|
233
|
+
# @overload *(other)
|
234
|
+
# Multiplies matrix by another matrix
|
235
|
+
# @param [KXI::Math::Matrix] other Right-side matrix to multiply with
|
236
|
+
# @raise [KXI::Exceptions::InvalidTypeException] When value is of invalid type
|
237
|
+
# @return [KXI::Math::Matrix] Multiplied matrix
|
238
|
+
# @overload *(other)
|
239
|
+
# Multiplies matrix by vector
|
240
|
+
# @param [KXI::Math::Vector] other Vector to multiply with
|
241
|
+
# @raise [KXI::Exceptions::InvalidTypeException] When value is of invalid type
|
242
|
+
# @return [KXI::Math::Vector] Result of multiplication
|
243
|
+
def *(other)
|
244
|
+
if other.is_a?(Numeric)
|
245
|
+
return KXI::Math::Matrix.new(@cols, @rows) { |c, r| other * get(c, r) }
|
246
|
+
elsif other.is_a?(KXI::Math::Matrix)
|
247
|
+
return KXI::Math::Matrix.new(other.columns, @rows) do |c, r|
|
248
|
+
sum = 0
|
249
|
+
@cols.times { |i| sum += get(i, r) * other.get(c, i) }
|
250
|
+
next sum
|
251
|
+
end
|
252
|
+
elsif other.is_a?(KXI::Math::Vector)
|
253
|
+
return KXI::Math::Vector.new(@rows) do |d|
|
254
|
+
sum = 0
|
255
|
+
@cols.times { |c| sum += get(c, d) * other[c] }
|
256
|
+
next sum
|
257
|
+
end
|
258
|
+
else
|
259
|
+
raise(KXI::Exceptions::InvalidTypeException.new(other.class, Numeric, KXI::Math::Matrix, KXI::Math::Vector))
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# Compares matrix
|
264
|
+
# @param [void] other Value to compare to
|
265
|
+
# @return [Boolean] True if matrix is equivalent to given value; false otherwise
|
266
|
+
def ==(other)
|
267
|
+
return false unless other.is_a?(KXI::Math::Matrix)
|
268
|
+
return false if @cols != other.columns or @row != other.rows
|
269
|
+
@cols.times do |col|
|
270
|
+
@rows.times do |row|
|
271
|
+
return false if get(col, row) != other.get(col, row)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def str(num)
|
277
|
+
return (num == num.to_i ? num.to_i : num).to_s
|
278
|
+
end
|
279
|
+
|
280
|
+
# Converts matrix to string
|
281
|
+
# @param [Boolean] d Determines whether string should be decorated
|
282
|
+
# @return [String] String representation of matrix
|
283
|
+
def to_s(d = true)
|
284
|
+
ret = ''
|
285
|
+
just = [0] * @cols
|
286
|
+
each { |c, r, v| d = str(v).length; just[c] = d if d > just[c] }
|
287
|
+
@rows.times do |row|
|
288
|
+
ret += $/ unless row == 0
|
289
|
+
ret += '|' if d
|
290
|
+
@cols.times do |col|
|
291
|
+
ret += ' ' unless col == 0
|
292
|
+
ret += str(get(col, row)).rjust(just[col], ' ')
|
293
|
+
end
|
294
|
+
ret += '|' if d
|
295
|
+
end
|
296
|
+
|
297
|
+
return ret
|
298
|
+
end
|
299
|
+
|
300
|
+
private :sign, :sub, :str
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
data/lib/kxi/math/polynomial.rb
CHANGED
@@ -1,102 +1,142 @@
|
|
1
|
-
# Created by Matyáš Pokorný on 2018-01-26.
|
2
|
-
|
3
|
-
module KXI
|
4
|
-
module Math
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@cfs
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
1
|
+
# Created by Matyáš Pokorný on 2018-01-26.
|
2
|
+
|
3
|
+
module KXI
|
4
|
+
module Math
|
5
|
+
# Represents a polynomial
|
6
|
+
class Polynomial
|
7
|
+
# Returns the degree of polynomial
|
8
|
+
# @return [Integer] Degree of polynomial
|
9
|
+
def degree
|
10
|
+
@cfs.length - 1
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the coefficients of polynomial
|
14
|
+
# @return [Array<Numeric>] Coefficients of polynomial
|
15
|
+
def coefficients
|
16
|
+
@cfs
|
17
|
+
end
|
18
|
+
|
19
|
+
# Instantiates the {KXI::Math::Polynomial} class
|
20
|
+
# @param [Numeric] cfs Coefficients of polynomial
|
21
|
+
def initialize(*cfs)
|
22
|
+
cfs.shift while cfs.length > 1 and cfs[0] == 0
|
23
|
+
@cfs = cfs.collect do |i|
|
24
|
+
raise(KXI::Exceptions::InvalidTypeException.new(i.class, Numeric)) unless i.is_a?(Numeric)
|
25
|
+
i.to_f
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Converts polynomial to string
|
30
|
+
# @return [String] String equivalent to polynomial
|
31
|
+
def to_s
|
32
|
+
return (@cfs[0] == @cfs[0].to_i ? @cfs[0].to_i : @cfs[0]) if degree == 0
|
33
|
+
ret = nil
|
34
|
+
foreach do |k, d|
|
35
|
+
if k != 0
|
36
|
+
k = k.to_i if k.to_i == k
|
37
|
+
if d > 0
|
38
|
+
if ret == nil
|
39
|
+
ret = k >= 0 ? '' : '-'
|
40
|
+
else
|
41
|
+
ret += k >= 0 ? ' + ' : ' - '
|
42
|
+
end
|
43
|
+
ret += (k >= 0 ? k : -k).to_s if k != 1 and k != -1
|
44
|
+
ret += "x#{d > 1 ? "^#{d.to_s}" : ''}"
|
45
|
+
else
|
46
|
+
if ret == nil
|
47
|
+
ret = k >= 0 ? '' : '-'
|
48
|
+
else
|
49
|
+
ret += k >= 0 ? ' + ' : ' - '
|
50
|
+
end
|
51
|
+
ret += (k >= 0 ? k : -k).to_s
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
return ret
|
56
|
+
end
|
57
|
+
|
58
|
+
# Takes the derivative of polynomial
|
59
|
+
# @param [Integer] n Order of derivation
|
60
|
+
# @return [KXI::Math::Polynomial] Polynomial that represents the n-th derivative
|
61
|
+
def derivative(n = 1)
|
62
|
+
return Polynomial.new(0) if degree <= n
|
63
|
+
cfs = []
|
64
|
+
foreach do |k, d|
|
65
|
+
if d >= n
|
66
|
+
cfs.push(k * KXI::Math.pfact(d, d - n))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
return Polynomial.new(*cfs)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Takes the integral of polynomial
|
73
|
+
# @return [KXI::Math::Polynomial] Polynomial that represents the integral
|
74
|
+
def integral
|
75
|
+
cfs = []
|
76
|
+
foreach do |k, d|
|
77
|
+
cfs.push(k / (d + 1))
|
78
|
+
end
|
79
|
+
cfs.push(0)
|
80
|
+
return Polynomial.new(*cfs)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Integrates the polynomial
|
84
|
+
# @param [Numeric] x1 First bound of integration
|
85
|
+
# @param [Numeric] x2 Second bound of integration
|
86
|
+
# @return [Numeric] Result of integration
|
87
|
+
def integrate(x1, x2)
|
88
|
+
min = x1 > x2 ? x2 : x1
|
89
|
+
max = x1 > x2 ? x1 : x2
|
90
|
+
i = integral
|
91
|
+
return i.at(max) - i.at(min)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns the value of polynomial
|
95
|
+
# @param [Numeric] x Value of x
|
96
|
+
# @return [Numeric] Value of polynomial at x
|
97
|
+
def at(x)
|
98
|
+
sum = 0
|
99
|
+
foreach do |k, d|
|
100
|
+
sum += k * (x ** d)
|
101
|
+
end
|
102
|
+
return sum
|
103
|
+
end
|
104
|
+
|
105
|
+
# Iterates over every coefficient of polynomial (from higher powers to lower powers)
|
106
|
+
# @yield [k] Iterator
|
107
|
+
# @yieldparam [Numeric] k Coefficient of polynomial
|
108
|
+
def foreach
|
109
|
+
d = degree
|
110
|
+
@cfs.each do |k|
|
111
|
+
yield(k, d)
|
112
|
+
d -= 1
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Multiplies polynomial
|
117
|
+
# @overload *(other)
|
118
|
+
# Multiplies polynomial with coefficient
|
119
|
+
# @param [Numeric] other Coefficient to multiply with
|
120
|
+
# @return [KXI::Math::Polynomial] Result of multiplication
|
121
|
+
# @overload *(other)
|
122
|
+
# Multiplies polynomial with other polynomial
|
123
|
+
# @param [KXI::Math::Polynomial] other Polynomial to multiply with
|
124
|
+
# @return [KXI::Math::Polynomial] Result of multiplication
|
125
|
+
def *(other)
|
126
|
+
if other.is_a?(Polynomial)
|
127
|
+
cfs = [0] * (degree + other.degree + 1)
|
128
|
+
foreach do |k1, d1|
|
129
|
+
other.foreach do |k2, d2|
|
130
|
+
cfs[d1 + d2] += k1 * k2
|
131
|
+
end
|
132
|
+
end
|
133
|
+
return Polynomial.new(*cfs)
|
134
|
+
elsif other.is_a?(Numeric)
|
135
|
+
return @cfs.collect { |k| k * other }
|
136
|
+
else
|
137
|
+
raise(KXI::Exceptions::InvalidTypeException.new(other.class, Numeric, KXI::Math::Polynomial))
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
102
142
|
end
|