class Dice_Stats::Internal_Utilities::Math_Utilities
This class simple contains some methods to aid the calculating of probability distributions
Public Class Methods
Cartesian_Product(arrays)
click to toggle source
Note that this method is not actually used. It was a proof of concept for templating a less “clever” way to do a Cartesian product of arbitrary objects in such a way that additional processing can be done on the elements.
# File lib/Internal_Utilities/Math_Utilities.rb, line 34 def self.Cartesian_Product(arrays) #arrays is an array of array to cartesian product # FROM https://gist.github.com/sepastian/6904643 # I found these examples later, after creating Option 3. # TODO: See if using these can be used to simplify the process. #Option 1 arrays[0].product(*arrays[1..-1]) #Option 2 arrays[1..-1].inject(arrays[0]) { |m,v| m.product(v).map(&:flatten) } #Option 3 # however, we need to actually perform additional logic on the specific combinations, # not just aggregate them into one giant array result = [] if (arrays.class != [].class) puts "Not an array" elsif (arrays.length == 1) arrays[0] elsif (arrays.length == 0) puts "No input." elsif (arrays[0].class != [].class) puts "Not an array of arrays" else counter = Arbitrary_base_counter.new([*0..arrays.length-1].map { |i| arrays[i].length }) while !counter.overflow do sub_result = [] (0..counter.length-1).each { |i| sub_result << arrays[i][counter[i]] } result << sub_result counter.increment end end result end
Cartesian_Product_For_Probabilities(hashes)
click to toggle source
This method combines an array of hashes (i.e. an array of probabilities) into an aggregate probability distribution
# File lib/Internal_Utilities/Math_Utilities.rb, line 75 def self.Cartesian_Product_For_Probabilities(hashes) #hashes is a hash of hashes to cartesian product result = {} if (hashes.class != Array) puts "Not an array" elsif (hashes.length == 1) puts "Returning first result" result = hashes.first elsif (hashes.length == 0) puts "Returning new hash" result = { 0 => 1 } elsif (hashes[0].class != Hash) puts "Not a Hash of Hashes" else counter = Arbitrary_base_counter.new([*0..hashes.length-1].map { |i| hashes[i].length }) hashes.map! { |h| h.to_a } while !counter.overflow do value = 0 probability = 1 sub_result = {} (0..counter.length-1).each { |i| value += hashes[i][counter[i]][0] probability *= hashes[i][counter[i]][1] } if (result.key?(value)) result[value] += probability else result[value] = probability end counter.increment end end result end
Choose(a, b)
click to toggle source
The “Choose” operator. Sometimes noted as “(5 3)” or “5 c 3”.
# File lib/Internal_Utilities/Math_Utilities.rb, line 15 def self.Choose(a, b) if (a < 0 || b < 0 || (a < b)) 1 elsif (a == b || b == 0) 1 else (a-b+1..a).inject(1, &:*) / (2..b).inject(1, &:*) end end
Factorial(a)
click to toggle source
The “Factorial” function
# File lib/Internal_Utilities/Math_Utilities.rb, line 27 def self.Factorial(a) (1..a).inject(:*) || 0 end