Class: Matrix

Inherits:
Object
  • Object
show all
Includes:
Enumerable, MatrixErr, Properties
Defined in:
lib/matrix_gem/matrix.rb

Direct Known Subclasses

Diagonal_Matrix, Orthogonal_Matrix

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Properties

#col, #col_length, #diagonal_values, #is_diagonal, #is_square, #orthogonal?, #row, #row_length, #set_col, #set_diagonal, #set_row, #to_a, #to_f, #zero?

Constructor Details

#initialize(rows, cols, *nums) ⇒ Matrix

———Initialize the matrix——–

1. Matrix with values
   Matrix.new(rows, cols, numbers) // numbers = rows*cols
2. Matrix only with dimension(rows and cols) make Identity matrix with dimension
   equal to rows
   Matrix.new(rows, cols)


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/matrix_gem/matrix.rb', line 12

def initialize(rows, cols, *nums)
  if rows < 1 || cols < 1
    raise MatrixArgumentError, "Rows and Columns should be positive numbers!"
  elsif ((cols.is_a? Float) || (rows.is_a? Float))
    raise MatrixArgumentError, "Dimension of matrix can't be floating point number"
  elsif nums.length == 0
    @matrix = identity rows
  elsif rows * cols == nums.length
    @matrix = matrix_with_values nums, cols
  else
    raise MatrixArgumentError,
    "Wrong number of arguments (#{2 + nums.length} for #{2 + rows * cols})"
  end
  @matrix
end

Class Method Details

.diagonal(*nums) ⇒ Object

Creates a matrix where the diagonal elements are composed of values.

Raises:

  • (ArgumentError)


37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/matrix_gem/matrix.rb', line 37

def diagonal(*nums)
  raise ArgumentError, "Matrix values can't be nil" if nums.include? nil
  size = nums.length
  matrix_values = []
  Array.new(size) { |i| Array.new(size) do |j|
    if i == j
      matrix_values << nums[i]
    else
      matrix_values << 0
    end
 end
    }
  Matrix.new(size, size, *(matrix_values))
end

.identity(n) ⇒ Object

Creates an n by n identity matrix.



53
54
55
# File 'lib/matrix_gem/matrix.rb', line 53

def identity(n)
  Matrix.new n, n
end

.zero(n) ⇒ Object

Creates an n by n zero matrix.



31
32
33
34
# File 'lib/matrix_gem/matrix.rb', line 31

def zero(n)
  values = Array.new(n*n, 0)
  Matrix.new n, n, *(values)
end

Instance Method Details

#*(matrix) ⇒ Object

Matrix multiplication.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/matrix_gem/matrix.rb', line 77

def *(matrix)
  case(matrix)
  when Numeric
    new_matrix_values = []
    self.each { |x| new_matrix_values << x * matrix }
    Matrix.new self.m, self.n, *(new_matrix_values)
  when Matrix
    multiply_validation self, matrix
    rows = Array.new(self.m) { |i|
      Array.new(matrix.n) { |j|
        (0 ... self.n).inject(0) do |vij, k|
          vij + self[i, k] * matrix[k, j]
        end
      }
    }
    values = []
    rows.each{ |x| x.each { |y| values << y} }
    Matrix.new self.m, matrix.n, *(values)
  end
end

#**(n) ⇒ Object

Matrix exponentiation. Equivalent to multiplying the matrix by itself N times.



272
273
274
275
276
277
# File 'lib/matrix_gem/matrix.rb', line 272

def **(n)
  raise MatrixArgumentError if !(n.is_a? Integer)
  matrix = Matrix.identity(self.m)
  n.times { |_| matrix *= self } if self.square?
  matrix
end

#+(matrix) ⇒ Object

Return the sum of two matrices in new matrix Raises an error if matrices dimension mismatch.



60
61
62
63
64
65
# File 'lib/matrix_gem/matrix.rb', line 60

def +(matrix)
  sum_validation(self, matrix)
  values = self.zip(matrix).map{ |i| i.inject(:+) }

  Matrix.new self.m, self.n, *(values)
end

#-(matrix) ⇒ Object

Return the difference of two matrices in new matrix. Raises an error if matrices dimension mismatch.



69
70
71
72
73
74
# File 'lib/matrix_gem/matrix.rb', line 69

def -(matrix)
  sum_validation(self, matrix)
  values = self.zip(matrix).map{|i| i.inject(:-)}

  Matrix.new self.m, self.n, *(values)
end

#/(matrix) ⇒ Object

Matrix division (multiplication by the inverse).



99
100
101
102
103
104
105
106
107
108
# File 'lib/matrix_gem/matrix.rb', line 99

def /(matrix)
  case matrix
  when Numeric
    new_matrix_values = []
    self.each { |x| new_matrix_values << x / matrix.to_f }
    Matrix.new self.m, self.n, *(new_matrix_values)
  when Matrix
    self * matrix.inversed
  end
end

#==(matrix) ⇒ Object

Returns true if and only if the two matrices contain equal elements.



160
161
162
163
164
165
166
167
# File 'lib/matrix_gem/matrix.rb', line 160

def ==(matrix)
  (0..self.m-1).each do |i|
    (0..self.n-1).each do |j|
      return false if self[i][j] != matrix[i][j]
    end
  end
  true
end

#[](i, j = nil) ⇒ Object

Returns element (i,j) of the matrix. That is: row i, column j. If only i is given return row. That is: row with index i.



112
113
114
115
116
117
118
# File 'lib/matrix_gem/matrix.rb', line 112

def [](i, j = nil)
  if j == nil
    @matrix[i]
  else
    @matrix[i][j]
  end
end

#[]=(i, j = nil, val) ⇒ Object Also known as: set_element

Set element (i,j) of the matrix. That is: row i, column j. Set row i of the matrix if j is not given. That is: column j. Also aliased as set_element



123
124
125
126
127
128
129
130
# File 'lib/matrix_gem/matrix.rb', line 123

def []=(i, j = nil, val)
  if j == nil
    raise ErrDimensionMismatch if val.length != self.m
    @matrix[i] = val
  elsif (i < self.m && j < self.n)
    @matrix[i][j] = val
  end
end

#detObject Also known as: determinant

Returns the determinant of the matrix. Also alised as determinant()



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/matrix_gem/matrix.rb', line 171

def det
  is_square_validation self

  _this = copy(self)
  c = 1
  new_matrix = nil
  size = _this.n

  (0..size - 2).each do |i|
    (i + 1..size -1).each do |j|
      if _this[i][i] == 0
        (i+1..size-1).each do |k|
          if _this[k,i] != 0
            swap_rows(_this, k, i)
            c *= -1
          end
        end
      end
      if _this[i,i] == 0
        return 0
      end

      new_matrix = cauchy_method(_this, i, j, -_this[j,i]/_this[i,i].to_f)
    end
  end

  det = 1

  (0..size-1).each do |i|
    det *= new_matrix[i][i]
  end

  det *= c
  det.round
end

#eachObject

Each method.



151
152
153
154
155
156
157
# File 'lib/matrix_gem/matrix.rb', line 151

def each
  @matrix.each do |sub_arr|
    sub_arr.each do |value|
      yield value
    end
  end
end

#inverseObject

Chanege matrix to its inversed.



254
255
256
257
258
259
# File 'lib/matrix_gem/matrix.rb', line 254

def inverse
  elements = []
  self.inversed.each{ |x| elements << x}
  @matrix = elements.each_slice(@matrix[0].length).to_a
  self
end

#inversedObject

Returns new matrix witch is the inverse of the matrix.

Raises:



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/matrix_gem/matrix.rb', line 209

def inversed
is_square_validation self
raise ErrZeroDeterminant if self.det == 0

_this = copy(self)
c = 1
e = Matrix.new _this.m, _this.n
size = _this.m

(0..size-2).each do |i|
  (i+1..size-1).each do |j|
    if _this[i, i] == 0
      (i..size-2).each do |k|
        if _this[k, i] != 0
          swap_rows(_this, k, i)
          swap_rows(e, k, i)
          c *= -1
        end
      end
    end

    return 0 if _this[i, i] == 0

    cauchy_method(e, i, j, -_this[j, i]/_this[i, i].to_f)
    cauchy_method(_this, i, j, -_this[j, i]/_this[i, i].to_f)
  end
end

(0..size-2).each do |i|
  (i+1..size-1).each do |j|

    cauchy_method(e, size-i-1, size-j-1, -_this[size-j-1, size-i-1]/_this[size-i-1, size-i-1])

    cauchy_method(_this, size-i-1, size-j-1, -_this[size-j-1, size-i-1]/_this[size-i-1, size-i-1])
  end
end

(0..size-1).each do |i|
  e.set_row i, multiply_row(e, i, 1/_this[i,i])
  _this.set_row i, multiply_row(_this, i, 1/_this[i,i])
end
  Matrix.new self.m, self.m, *(e)
end

#minor(*param) ⇒ Object

Returns a section of the matrix. The parameters are: row_range, col_range



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/matrix_gem/matrix.rb', line 281

def minor(*param)
  row_range, col_range = param

  from_row = row_range.first
  form_row += self.m if from_row < 0
  to_row = row_range.end
  to_row += self.m if to_row < 0
  to_row += 1 unless row_range.exclude_end?
  size_row = to_row - from_row

  from_col = col_range.first
  from_col += self.n if from_col < 0
  to_col = col_range.end
  to_col += self.n if from_col < 0
  to_col += 1 unless col_range.exclude_end?
  size_col = to_col - from_col
  return nil if from_row > row_count || from_col > column_count ||
    from_row < 0 || from_col < 0
    rows = @matrix[from_row, size_row].collect{ |row| row[from_col, size_col] }
    values = []
    rows.each{ |row| row.each {|val| values << val } }
    Matrix.new [self.m - from_row, size_row].min, [self.n - from_col, size_col].min, *(values)
end

#to_strObject

To stirng method.



262
263
264
265
266
267
268
269
# File 'lib/matrix_gem/matrix.rb', line 262

def to_str
  a = "Matrix\n" + @matrix.map do |row|
    "[" + row.map do |e|
       e.to_s
    end.join(" ") + "]"
  end.join(",\n")
  puts a
end

#transposeObject Also known as: t

Transpose the matrix. Also aliased as t().



142
143
144
145
146
147
# File 'lib/matrix_gem/matrix.rb', line 142

def transpose
  elements = []
  @matrix.to_a.transpose.map{ |x| x.map{ |y| elements << y } }
  @matrix = elements.each_slice(@matrix[0].length).to_a
  self
end

#transposedObject

Return a new matrix which is the transposition of the given one.



134
135
136
137
138
# File 'lib/matrix_gem/matrix.rb', line 134

def transposed
  elements = []
  @matrix.to_a.transpose.map{ |x| x.map{ |y| elements << y } }
  Matrix.new self.m, self.n, *(elements)
end