# TODO increase speed with vectors, matrices? class Array # Sum the size of single arrays in an array of arrays # @param [Array] Array of arrays # @return [Integer] Sum of size of array elements def sum_size self.inject(0) { |s,a| if a.respond_to?('size') s+=a.size else internal_server_error "No size available: #{a.inspect}" end } end # Check if the array has just one unique value. # @param [Array] Array to test. # @return [TrueClass,FalseClass] def zero_variance? return self.uniq.size == 1 end # Get the median of an array # @return [Numeric] def median sorted = self.sort len = sorted.length (sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0 end # Get the mean of an array # @return [Numeric] def mean self.compact.inject{ |sum, el| sum + el }.to_f / self.compact.size end # Get the variance of an array # @return [Numeric] def sample_variance m = self.mean sum = self.compact.inject(0){|accum, i| accum +(i-m)**2 } sum/(self.compact.length - 1).to_f end # Get the standard deviation of an array # @return [Numeric] def standard_deviation Math.sqrt(self.sample_variance) end # Calculate dot product # @param [Array] # @return [Numeric] def dot_product(a) products = self.zip(a).map{|a, b| a * b} products.inject(0) {|s,p| s + p} end # Calculate magnitude # @return [Numeric] def magnitude squares = self.map{|x| x ** 2} Math.sqrt(squares.inject(0) {|s, c| s + c}) end # Convert array values for R # @return [Array] def for_R if self.first.is_a?(String) #"\"#{self.collect{|v| v.sub('[','').sub(']','')}.join(" ")}\"" # quote and remove square brackets "NA" else self.median end end def remove indices out = self indices.sort.reverse_each do |i| out.delete_at i end out end # Correlation coefficient # @param [Array] # @return [Numeric] def r(y) raise "Argument is not a Array class!" unless y.class == Array raise "Self array is nil!" if self.size == 0 raise "Argument array size is invalid!" unless self.size == y.size mean_x = self.inject(0) { |s, a| s += a } / self.size.to_f mean_y = y.inject(0) { |s, a| s += a } / y.size.to_f cov = self.zip(y).inject(0) { |s, a| s += (a[0] - mean_x) * (a[1] - mean_y) } var_x = self.inject(0) { |s, a| s += (a - mean_x) ** 2 } var_y = y.inject(0) { |s, a| s += (a - mean_y) ** 2 } r = cov / Math.sqrt(var_x) r /= Math.sqrt(var_y) end end