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 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: []