Class: Matrix

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/TrueSkill/Mathematics/matrix.rb

Instance Method Summary collapse

Constructor Details

#initialize(src = nil, width = nil, height = nil, options = {}) ⇒ Matrix

Returns a new instance of Matrix.



6
7
8
9
10
11
12
13
14
15
16
17
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
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 6

def initialize(src=nil,width=nil,height=nil,options={})
  if options.include? :func
    f,src=options[:func],{}
    @size=[width,height]
    if width.nil?
      @size[0]=Proc.new do |w|
        @size[0]=w
      end
    end
    if height.nil?
      @size[1]=Proc.new do |h|
        @size[1]=h
      end
    end
    arr=Array(f.call(@size[0],@size[1]))
    #pp arr
    arr.each do|v,val|
      src[[v[0],v[1]]]=val
    end
    width=@size[0]
    height=@size[1]
  end
  if src.is_a? Array
    unique_col_sizes=Set.new(src.map { |x| x.length })
    if not unique_col_sizes.length==1
      raise "Must be a rectangular range of numbers"
    end
    num=true
    src.flatten.each { |x| if not x.is_a? Numeric then num=false end }
    if num==false
      raise "Must be a rectangular range of numbers"
    end 
    two_dimensional_array=src
  elsif src.is_a? Hash
    if width.nil? or height.nil?
      w,h=0,0
      src.each_key do |x|
        r=x[0]
        c=x[1]
        if width.nil?
          w=[w,r+1].max
        end
        if height.nil?
          h=[h,c+1].max
        end
      end
      if width.nil?
        width=w
      end
      if height.nil?
        height=h
      end
    end
    two_dimensional_array=[]
    (0...height).each do |r|
      row=[]
      (0...width).each do |c|
        if src.include? [r,c]
          val=src[[r,c]]
        else
          val=0
        end
        row << val 
      end
      two_dimensional_array << row
    end
  end
  @base=two_dimensional_array  
end

Instance Method Details

#*(other) ⇒ Object



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
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 214

def *(other)
  if other.is_a? Matrix
    w,h=other.width,height
    #pp w
    #pp h
    #pp other.width
    #pp other.height
    if not width== other.height
      raise "Must be same size"
    end
    src={}
    (0...h).each do |r|
      (0...w).each do |c|
        lst=[]
        #pp r
        #pp c
        
        (0...width).each { |x|  lst << (self[r,x] * other[x,c])}
        src[[r,c]]=lst.inject(:+)
      end
    end
    return Matrix.new(src,w,h)
  else
    w,h=width,height
    src={}
    (0...h).each do |r|
      (0...w).each do |c|
        src[[r,c]]=other*self[r,c]
      end
    end
    return Matrix.new(src,w,h)
  end
end

#+(other) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 200

def +(other)
  w,h=width,height
  if not (w== other.width and h==other.height)
    raise "Must be same size"
  end 
  src={}
  (0...h).each do |r|
    (0...w).each do |c|
      src[[r,c]]=self[r,c]+other[r,c]
    end
  end
  return Matrix.new(src,w,h)
end

#[](r, c) ⇒ Object



86
87
88
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 86

def [](r,c)
  return @base[r][c]
end

#[]=(r, c, val) ⇒ Object



89
90
91
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 89

def []=(r,c,val)
  @base[r][c]=val
end

#adjucateObject



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 164

def adjucate
  w,h=width,height
  if h==2
    a,b=self[0,0],self[0,1]
    c,d=self[1,0],self[1,1]
    return Matrix.new([[d,-b],[-c,a]])
  else
    src={}
    (0...height).each do |r|
      (0...width).each do |c|
        v=0
        if (r+c) % 2==1
          v=-1
        else
          v=1
        end
        src[[r,c]]=self.minor(r,c).determinant*v
      end
    end
    return Matrix.new(src,w,h)
  end
end

#cloneObject



247
248
249
250
251
252
253
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 247

def clone
  rows=[]
  @base.each do |x|
    rows << x.clone
  end
  Matrix.new(rows)
end

#coerce(other) ⇒ Object



196
197
198
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 196

def coerce(other)
  return self, other
end

#determinantObject



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 130

def determinant
  w,h=width,height
  if not w==h
    raise "Must be a square matrix"
  end
  tmp,rv=self.clone,1
  (w-1).downto(1) do |c|
    p=[]
    (0..c).each {|r| p << [tmp[r,c].abs,r]}
    pivot,r=p.max
    pivot=tmp[r,c]
    if pivot.nil?
      return 0
    end

    val=tmp.row(r)
    tmp.setrow(r,tmp.row(c))
    
    tmp.setrow(c,val)
    if not r==c
      rv=-rv
    end
    rv*=pivot
    fact=-1.0/pivot
    (0...c).each do |r|
      f=fact*tmp[r,c]
      (0...c).each do |x|
        tmp[r,x]+=f*tmp[c,x]
      end
    end
  end
  return rv*tmp[0,0]
end

#each(&block) ⇒ Object



83
84
85
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 83

def each(&block)
  return
end

#heightObject



80
81
82
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 80

def height
  return @base.length
end

#inverseObject



187
188
189
190
191
192
193
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 187

def inverse
  if width==1 and height==1
    return Matrix.new([[1.0/self[0,0]]])
  else
    return (1.0/self.determinant())*self.adjucate()
  end
end

#minor(row_n, col_n) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 103

def minor(row_n,col_n)
  w,h=width,height
  if row_n < 0  or row_n >= w or col_n < 0 or col_n >= h
    raise 'invalid row or column number'
  end 
  two_dimensional_array=[]
  (0...h).each do |r|
    if r==row_n
      next
    end
    row=[]
    (0...w).each do |c|
      if c==col_n
        next
      end
      row << @base[r][c]
    end
    two_dimensional_array << row
  end
  return Matrix.new(two_dimensional_array)
end

#row(r) ⇒ Object



124
125
126
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 124

def row(r)
  @base[r]
end

#setrow(r, val) ⇒ Object



127
128
129
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 127

def setrow(r,val)
  @base[r]=val
end

#transposeObject



93
94
95
96
97
98
99
100
101
102
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 93

def transpose
  w,h=width,height
  src={}
  (0...w).each do |c|
    (0...h).each do |r|
      src[[c,r]]=@base[r][c]
    end
  end
  return Matrix.new(src,h,w)
end

#widthObject



76
77
78
# File 'lib/TrueSkill/Mathematics/matrix.rb', line 76

def width
  return @base[0].length
end