matrix_gem 0.1.0
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.
- checksums.yaml +7 -0
- data/lib/matrix_gem/matrix_err.rb +33 -0
- data/lib/matrix_gem/properties_module.rb +47 -0
- data/lib/matrix_gem.rb +305 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dead9ede19c10d0e07aab6515af1c7b9beb37a03
|
4
|
+
data.tar.gz: 8982a7fb48c26c4ce88891d3c6308fd0d265b05a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2b5630df3882796c82788bdcb787938a6a121d2222ee81228deba8494bcda0267d380bc1aa662d31b5905a49d95147a975c5864107ed84767e075273e1b90d4a
|
7
|
+
data.tar.gz: f956702d425022d394d4597437bcf6ddc2f53e375261c4b3eb91415b6f0daf4f7ccfdace759660e24cabbe916b7d780c73704d2212d4baf58f63968e36f5eb89
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module MatrixErr
|
2
|
+
|
3
|
+
class Matrix_Error < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class MatrixArgumentError < Matrix_Error
|
7
|
+
end
|
8
|
+
|
9
|
+
class ErrOperationNotDefine < Matrix_Error
|
10
|
+
def message
|
11
|
+
"Operation is not define!"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ErrDimensionMismatch < Matrix_Error
|
16
|
+
def message
|
17
|
+
"Matrices dimensions mismatch!"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class NoSquareMatrix < Matrix_Error
|
22
|
+
def message
|
23
|
+
"Matrix should be squared!"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class ErrZeroDeterminant < Matrix_Error
|
28
|
+
def message
|
29
|
+
"Matrix determinant should be not equal to zero!"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Properties
|
2
|
+
# Returns an array of arrays that describe the rows of the matrix.
|
3
|
+
def to_a
|
4
|
+
self
|
5
|
+
end
|
6
|
+
|
7
|
+
# Returns the number of columns.
|
8
|
+
# Also aliased as n(), col_size(), column_count()
|
9
|
+
def col_length
|
10
|
+
self[0].length
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the number of rows.
|
14
|
+
# Also aliased as m(), row_size(), row_count()
|
15
|
+
def row_length
|
16
|
+
i = 0
|
17
|
+
self.each{ |row| i+=1 }
|
18
|
+
i/self[0].length
|
19
|
+
end
|
20
|
+
|
21
|
+
alias m row_length
|
22
|
+
alias row_size row_length
|
23
|
+
alias row_count m
|
24
|
+
|
25
|
+
|
26
|
+
alias n col_length
|
27
|
+
alias col_size col_length
|
28
|
+
alias column_count n
|
29
|
+
|
30
|
+
# Retun row on index.
|
31
|
+
def row(index)
|
32
|
+
self[index]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set value of matrix row.
|
36
|
+
def row_change(index, elements)
|
37
|
+
self[index] = elements
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return col on index
|
41
|
+
# Also aliased as column()
|
42
|
+
def col(index)
|
43
|
+
self.each { |a| p a[index] }
|
44
|
+
end
|
45
|
+
|
46
|
+
alias column col
|
47
|
+
end
|
data/lib/matrix_gem.rb
ADDED
@@ -0,0 +1,305 @@
|
|
1
|
+
require 'matrix_gem/matrix_err'
|
2
|
+
require 'matrix_gem/properties_module'
|
3
|
+
|
4
|
+
|
5
|
+
class Matrix
|
6
|
+
include MatrixErr
|
7
|
+
include Properties
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
#---------Initialize the matrix------
|
11
|
+
# 1. Matrix with values
|
12
|
+
# Matrix.new(rows, cols, numbers) // numbers = rows*cols
|
13
|
+
# 2. Matrix only with dimention(rows and cols) make Identity matrix
|
14
|
+
# Matrix.new(rows, cols)
|
15
|
+
def initialize(rows, cols, *nums)
|
16
|
+
if rows < 1 || cols < 1
|
17
|
+
raise MatrixArgumentError, "Rows and Columns should be positive numbers!"
|
18
|
+
elsif nums.length == 0
|
19
|
+
@matrix = identity cols
|
20
|
+
elsif rows * cols == nums.length
|
21
|
+
@matrix = matrix_with_values nums, cols
|
22
|
+
else
|
23
|
+
raise MatrixArgumentError,
|
24
|
+
"Wrong number of arguments (#{2 + nums.length} for #{2 + rows * cols})"
|
25
|
+
end
|
26
|
+
@matrix
|
27
|
+
end
|
28
|
+
|
29
|
+
#Return the sum of two matrices in new matrix
|
30
|
+
def +(matrix)
|
31
|
+
sum_validation(matrix, self)
|
32
|
+
values = self.zip(matrix).map{|i| i.inject(:+)}
|
33
|
+
|
34
|
+
Matrix.new self.m, self.n, *(values)
|
35
|
+
end
|
36
|
+
|
37
|
+
#Return the difference of two matrices in new matrix
|
38
|
+
def -(matrix)
|
39
|
+
sum_validation(matrix, self)
|
40
|
+
values = self.zip(matrix).map{|i| i.inject(:-)}
|
41
|
+
|
42
|
+
Matrix.new self.m, self.n, *(values)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns element (i,j) of the matrix. That is: row i, column j.
|
46
|
+
# If only i is given return row[i]. That is: row with index i.
|
47
|
+
def [](i, j = nil)
|
48
|
+
if j == nil
|
49
|
+
@matrix[i]
|
50
|
+
else
|
51
|
+
@matrix[i][j]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Set element (i,j) of the matrix. That is: row i, column j.
|
56
|
+
# Set row i of the matrix if j is not given. That is: column j.
|
57
|
+
# Also aliased as set_element
|
58
|
+
def []=(i, j = nil, val)
|
59
|
+
if j == nil
|
60
|
+
raise ErrDimensionMismatch if val.length != self.m
|
61
|
+
@matrix[i] = val
|
62
|
+
else
|
63
|
+
@matrix[i][j] = val
|
64
|
+
end
|
65
|
+
end
|
66
|
+
alias set_element []=
|
67
|
+
|
68
|
+
# Return a new matrix which is the transposition of the given one.
|
69
|
+
def transposed
|
70
|
+
elements = []
|
71
|
+
@matrix.to_a.transpose.map{ |x| x.map{ |y| elements << y } }
|
72
|
+
Matrix.new self.m, self.n, *(elements)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Transpose the matrix.
|
76
|
+
# Also aliased as t().
|
77
|
+
def transpose
|
78
|
+
elements = []
|
79
|
+
@matrix.to_a.transpose.map{ |x| x.map{ |y| elements << y } }
|
80
|
+
@matrix = elements.each_slice(@matrix[0].length).to_a
|
81
|
+
end
|
82
|
+
alias t transpose
|
83
|
+
|
84
|
+
#Each method.
|
85
|
+
def each
|
86
|
+
@matrix.each do |sub_arr|
|
87
|
+
sub_arr.each do |value|
|
88
|
+
yield value
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns true if and only if the two matrices contain equal elements.
|
94
|
+
def ==(matrix)
|
95
|
+
matrix.to_a == self.to_a
|
96
|
+
end
|
97
|
+
|
98
|
+
# Matrix multiplication.
|
99
|
+
def *(m)
|
100
|
+
case(m)
|
101
|
+
when Numeric
|
102
|
+
new_matrix_values = []
|
103
|
+
self.each { |x| new_matrix_values << x * m }
|
104
|
+
Matrix.new self.m, self.n, *(new_matrix_values)
|
105
|
+
when Matrix
|
106
|
+
multiply_validation self, m
|
107
|
+
rows = Array.new(self.m) { |i|
|
108
|
+
Array.new(m.n) { |j|
|
109
|
+
(0 ... m.n ).inject(0) do |vij, k|
|
110
|
+
vij + self[i, k] * m[k, j]
|
111
|
+
end
|
112
|
+
}
|
113
|
+
}
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns the determinant of the matrix.
|
118
|
+
# Also alised as determinant()
|
119
|
+
def det
|
120
|
+
is_square_validation self
|
121
|
+
|
122
|
+
_this = copy(self)
|
123
|
+
c = 1
|
124
|
+
new_matrix = nil
|
125
|
+
size = _this.n
|
126
|
+
|
127
|
+
(0..size - 2).each do |i|
|
128
|
+
(i + 1..size -1).each do |j|
|
129
|
+
if _this[i][i] == 0
|
130
|
+
(i+1..size-1).each do |k|
|
131
|
+
if _this[k,i] != 0
|
132
|
+
swap_rows(_this, k, i)
|
133
|
+
c *= -1
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
if _this[i,i] == 0
|
138
|
+
p _this
|
139
|
+
return 0
|
140
|
+
end
|
141
|
+
|
142
|
+
new_matrix = cauchy_method(_this, i, j, -_this[j,i]/_this[i,i].to_f)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
det = 1
|
147
|
+
|
148
|
+
(0..size-1).each do |i|
|
149
|
+
det *= new_matrix[i][i]
|
150
|
+
end
|
151
|
+
|
152
|
+
det *= c
|
153
|
+
det.round
|
154
|
+
end
|
155
|
+
alias determinant det
|
156
|
+
|
157
|
+
# Multiplication of matrix row with number.
|
158
|
+
def multiply_row(matrix, index, number)
|
159
|
+
matrix = matrix.row(index).map{ |n| n*number }
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns the inverse of the matrix.
|
163
|
+
def inverse
|
164
|
+
is_square_validation self
|
165
|
+
raise ErrZeroDeterminant if self.det == 0
|
166
|
+
|
167
|
+
_this = copy(self)
|
168
|
+
c = 1
|
169
|
+
e = Matrix.new _this.m, _this.n
|
170
|
+
size = _this.m
|
171
|
+
|
172
|
+
(0..size-2).each do |i|
|
173
|
+
(i+1..size-1).each do |j|
|
174
|
+
if _this[i, i] == 0
|
175
|
+
(i..size-2).each do |k|
|
176
|
+
if _this[k, i] != 0
|
177
|
+
swap_rows(_this, k, i)
|
178
|
+
swap_rows(e, k, i)
|
179
|
+
c *= -1
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
return 0 if _this[i, i] == 0
|
185
|
+
|
186
|
+
cauchy_method(e, i, j, -_this[j, i]/_this[i, i].to_f)
|
187
|
+
cauchy_method(_this, i, j, -_this[j, i]/_this[i, i].to_f)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
(0..size-2).each do |i|
|
192
|
+
(i+1..size-1).each do |j|
|
193
|
+
|
194
|
+
cauchy_method(e, size-i-1, size-j-1, -_this[size-j-1, size-i-1]/_this[size-i-1, size-i-1])
|
195
|
+
|
196
|
+
cauchy_method(_this, size-i-1, size-j-1, -_this[size-j-1, size-i-1]/_this[size-i-1, size-i-1])
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
(0..size-1).each do |i|
|
201
|
+
e.row_change i, multiply_row(e, i, 1/_this[i,i])
|
202
|
+
_this.row_change i, multiply_row(_this, i, 1/_this[i,i])
|
203
|
+
end
|
204
|
+
e
|
205
|
+
end
|
206
|
+
|
207
|
+
# Chanege matrix to its inversed.
|
208
|
+
def inversed
|
209
|
+
elements = []
|
210
|
+
self.inverse.each{ |x| elements << x}
|
211
|
+
@matrix = elements.each_slice(@matrix[0].length).to_a
|
212
|
+
end
|
213
|
+
|
214
|
+
# def to_s
|
215
|
+
# "Matrix[" + @matrix.map{|row|
|
216
|
+
# "[" + row.map{|e| e.to_s}.join("\t") + "]"
|
217
|
+
# }.join(", ") + "]"
|
218
|
+
# end
|
219
|
+
|
220
|
+
private
|
221
|
+
|
222
|
+
# Swap to matrix rows.
|
223
|
+
def swap_rows(_this, row1_index, row2_index)
|
224
|
+
_this[row1_index], _this[row2_index] = _this[row2_index], _this[row1_index]
|
225
|
+
end
|
226
|
+
|
227
|
+
# Return new instance of Matrix with same values.
|
228
|
+
def copy(_this)
|
229
|
+
values = []
|
230
|
+
_this.each{ |row| values << row }
|
231
|
+
copy = Matrix.new _this.m, _this.n, *(values)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Multiply the first row elements with multiplier and sum it with second row
|
235
|
+
# elements.
|
236
|
+
# Used to make matrix in triangular form.
|
237
|
+
def cauchy_method(_this, row1_index, row2_index, multiplier)
|
238
|
+
_this.row(row2_index).each_with_index do |row_element, i|
|
239
|
+
_this.row(row2_index)[i] += _this[row1_index][i] * multiplier
|
240
|
+
end
|
241
|
+
_this
|
242
|
+
end
|
243
|
+
|
244
|
+
# Check if caller matrix columns are equal to other matrix rows.
|
245
|
+
def multiply_validation(_this, matrix)
|
246
|
+
raise ErrDimensionMismatch if _this.n != matrix.m
|
247
|
+
end
|
248
|
+
|
249
|
+
# Check if matrix rows are equals to its columns.
|
250
|
+
def is_square_validation(_this)
|
251
|
+
raise NoSquareMatrix if _this.m != _this.n
|
252
|
+
end
|
253
|
+
|
254
|
+
# Check if matrices have same dimentions.
|
255
|
+
def sum_validation(_this, matrix)
|
256
|
+
raise ErrOperationNotDefine if matrix.is_a? Numeric
|
257
|
+
raise ErrDimensionMismatch if matrix.m != _this.m || matrix.n != _this.n
|
258
|
+
end
|
259
|
+
|
260
|
+
# Make Identity matrix.
|
261
|
+
def identity(dimension)
|
262
|
+
id_matrix = []
|
263
|
+
dimension.times do |x|
|
264
|
+
id_matrix[x] = []
|
265
|
+
dimension.times do |y|
|
266
|
+
if x == y
|
267
|
+
id_matrix[x][y] = 1
|
268
|
+
else
|
269
|
+
id_matrix[x][y] = 0
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
return id_matrix
|
274
|
+
end
|
275
|
+
|
276
|
+
# Format values.
|
277
|
+
def matrix_with_values(values, col_length)
|
278
|
+
matrixNums = values.each_slice(col_length).to_a
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
|
283
|
+
a = Matrix.new 3,3,1,2,57,1,3,43,5,6,70
|
284
|
+
# p a
|
285
|
+
c = Matrix.new 2,2,4,3,3,2
|
286
|
+
d = Matrix.new 3,3,2,3,1,1,2,1,3,5,3
|
287
|
+
# d = Matrix.new 2,2,0,1,3,0
|
288
|
+
# d = Matrix.new 2,2,0,9,5,2
|
289
|
+
|
290
|
+
|
291
|
+
d = Matrix.new 3,3
|
292
|
+
|
293
|
+
#
|
294
|
+
|
295
|
+
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
|
304
|
+
|
305
|
+
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: matrix_gem
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bozhidar Grigorov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-11 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Gem for work with matrices
|
14
|
+
email: bojko002@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/matrix_gem.rb
|
20
|
+
- lib/matrix_gem/matrix_err.rb
|
21
|
+
- lib/matrix_gem/properties_module.rb
|
22
|
+
homepage: http://rubygems.org/gems/matrix_gem
|
23
|
+
licenses:
|
24
|
+
- MIT
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 2.4.3
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Matrix gem
|
46
|
+
test_files: []
|