class OPRCalc::ScoreSet
Attributes
Public Class Methods
# File lib/opr-calc/score_set.rb, line 43 def initialize(ared, ablue, scorered, scoreblue) raise TypeError, 'ared must be a Matrix' unless ared.is_a? Matrix raise TypeError, 'ablue must be a Matrix' unless ablue.is_a? Matrix raise TypeError, 'scorered must be a Matrix' unless scorered.is_a? Matrix raise TypeError, 'scoreblue must be a Matrix' unless scoreblue.is_a? Matrix @ared = ared @ablue = ablue @scorered = scorered @scoreblue = scoreblue end
Public Instance Methods
# File lib/opr-calc/score_set.rb, line 28 def ablue=(value) @ablue = value @opr_recalc = @dpr_recalc = @ccwm_recalc = true end
# File lib/opr-calc/score_set.rb, line 23 def ared=(value) @ared = value @opr_recalc = @dpr_recalc = @ccwm_recalc = true end
Calculated contribution to winning margin: the average amount of points that a team contributes to their alliance’s winning margin.
This value is high for a good team.
# File lib/opr-calc/score_set.rb, line 191 def ccwm(recalc = false) if !@ccwm || recalc || @ccwm_recalc a = alliance_smooshey @ared, @ablue red_wm = Matrix.build(@scorered.row_size, @scorered.column_size) do |row, column| @scorered[row, column] - @scoreblue[row, column] end blue_wm = Matrix.build(@scoreblue.row_size, @scoreblue.column_size) do |row, column| @scoreblue[row, column] - @scorered[row, column] end score = alliance_smooshey red_wm, blue_wm @ccwm = opr_calculate a, score @ccwm_recalc = false end @ccwm end
Defensive power rating: the average amount of points that a team lets the other alliance score.
This is low for a good team.
# File lib/opr-calc/score_set.rb, line 172 def dpr(recalc = false) if !@dpr || recalc || @dpr_recalc a = alliance_smooshey @ared, @ablue # scoreblue and scorered are intentionally # swapped; that's how dpr works. score = alliance_smooshey @scoreblue, @scorered @dpr = opr_calculate a, score @dpr_recalc = false end @dpr end
Offensive power rating: the average amount of points that a team contributes to their alliance’s score.
This is high for a good team.
# File lib/opr-calc/score_set.rb, line 156 def opr(recalc = false) if !@opr || recalc || @opr_recalc a = alliance_smooshey @ared, @ablue score = alliance_smooshey @scorered, @scoreblue @opr = opr_calculate a, score @opr_recalc = false end @opr end
# File lib/opr-calc/score_set.rb, line 139 def opr_calculate(a, score) p = a.t * a s = a.t * score l = p.cholesky_factor # l.output # l.t.output y = forward_substitute l, s back_substitute l.t, y end
# File lib/opr-calc/score_set.rb, line 38 def scoreblue=(value) @scoreblue = value @opr_recalc = @dpr_recalc = @ccwm_recalc = true end
# File lib/opr-calc/score_set.rb, line 33 def scorered=(value) @scorered = value @opr_recalc = @dpr_recalc = @ccwm_recalc = true end
Private Instance Methods
A generic function for smooshing two matrices (one red, one blue). Each should have the same dimensions.
# File lib/opr-calc/score_set.rb, line 57 def alliance_smooshey(redmatrix, bluematrix) throw ArgumentError 'Matrices must have same dimensions' unless (redmatrix.row_size == bluematrix.row_size) && (redmatrix.column_size == bluematrix.column_size) # Then we just pull the column and row size # from the red matrix because we can. column_count = redmatrix.column_size row_count = redmatrix.row_size # Use a block function to generate the new matrix. matrix = Matrix.build(row_count * 2, column_count) do |row, column| # note: no need to alternate, instead put all red, then all blue. if row < row_count # first half = red redmatrix[row, column] else # second half = blue bluematrix[row - row_count, column] end end # This will end up looking like as follows: # [[red[0]], # [red[1]], # [red[2]], # ... # [red[n]], # [blue[0]], # [blue[1]], # [blue[2]], # ... # [blue[n]]] return matrix end
Solve equation of form [u] = [s] for [x] u must be a upper triangular matrix.
# File lib/opr-calc/score_set.rb, line 119 def back_substitute(u, s) raise 'u must be an upper triangular matrix' unless u.upper_triangular? x = Array.new s.row_size (x.size - 1).downto 0 do |i| x[i] = s[i, 0] (i + 1).upto(x.size - 1) do |j| x[i] -= u[i, j] * x[j] end x[i] /= u[i, i] end Matrix.column_vector x end
Solve equation of form [l] = [s] for [x] l must be a lower triangular matrix. Based off of algorithm given at ‘en.wikipedia.org/wiki/Triangular_matrix#Forward_and_back_substitution`.
# File lib/opr-calc/score_set.rb, line 99 def forward_substitute(l, s) raise 'l must be a lower triangular matrix' unless l.lower_triangular? x = Array.new s.row_size x.size.times do |i| x[i] = s[i, 0] i.times do |j| x[i] -= l[i, j] * x[j] end x[i] /= l[i, i] end Matrix.column_vector x end