Module: Enumerable
- Included in:
- FixedRange
- Defined in:
- lib/just_enumerable_stats.rb
Instance Attribute Summary collapse
-
#_jes_range_class_args ⇒ Object
readonly
The arguments needed to instantiate the custom-defined range class.
-
#_jes_range_hash ⇒ Object
readonly
The hash of lambdas that are used to categorize the enumerable.
Class Method Summary collapse
-
.safe_alias(sym1, sym2 = nil) ⇒ Object
Defines the new methods unobtrusively.
Instance Method Summary collapse
-
#_jes_add_category(hash, &block) ⇒ Object
Allows you to add one category at a time.
- #_jes_all_categories(value) ⇒ Object
-
#_jes_average(&block) ⇒ Object
The arithmetic mean, uses a block or default block.
-
#_jes_cartesian_product(other, &block) ⇒ Object
Finds the cartesian product, excluding duplicates items and self- referential pairs.
-
#_jes_categories ⇒ Object
Takes the range_class and returns its map.
- #_jes_category_map(reset = false) ⇒ Object
-
#_jes_category_values(reset = false) ⇒ Object
Returns a Hash or Dictionary (if available) for each category with a value as the set of matching values as an array.
-
#_jes_compliment(other) ⇒ Object
Everything on the left hand side except what’s shared on the right hand side.
-
#_jes_correlation(other) ⇒ Object
Finds the correlation between two enumerables.
-
#_jes_count_if(&block) ⇒ Object
Counts each element where the block evaluates to true Example: a = [1,2,3] a.count_if {|e| e % 2 == 0}.
-
#_jes_covariance(other) ⇒ Object
Returns the covariance of two lists.
-
#_jes_cum_max(&block) ⇒ Object
Example: [1,2,3,0,5].cum_max # => [1,2,3,3,5].
-
#_jes_cum_min(&block) ⇒ Object
Example: [1,2,3,0,5].cum_min # => [1,1,1,0,0].
-
#_jes_cum_prod(sorted = false, &block) ⇒ Object
The cummulative product.
-
#_jes_cum_sum(sorted = false, &block) ⇒ Object
The cummulative sum.
-
#_jes_default_block ⇒ Object
The block called to filter the values in the object.
-
#_jes_default_block=(block) ⇒ Object
Allows me to setup a block for a series of operations.
-
#_jes_dichotomize(split_value, first_label, second_label) ⇒ Object
Splits the values in two, <= the value and > the value.
-
#_jes_euclidian_distance(other) ⇒ Object
Returns the Euclidian distance between all points of a set of enumerables.
-
#_jes_exclusive_not(other) ⇒ Object
Everything but what’s shared.
-
#_jes_first_category(value) ⇒ Object
Returns the first category of a value.
-
#_jes_frequency ⇒ Object
Returns a hash or dictionary (if installed) of the frequency of each category.
- #_jes_frequency_for(key) ⇒ Object
-
#_jes_intersect(other) ⇒ Object
What’s shared on the left and right hand sides “The intersection of x and y”.
- #_jes_is_numeric? ⇒ Boolean
-
#_jes_max(&block) ⇒ Object
Returns the max, using an optional block.
-
#_jes_max_index(&block) ⇒ Object
Returns the first index of the max value.
-
#_jes_max_of_lists(*enums) ⇒ Object
Returns the max of two or more enumerables.
-
#_jes_median(ratio = 0.5, &block) ⇒ Object
The slow way is to iterate up to the middle point.
-
#_jes_min(&block) ⇒ Object
Min of any number of items.
-
#_jes_min_index(&block) ⇒ Object
Returns the first index of the min value.
-
#_jes_min_of_lists(*enums) ⇒ Object
Returns the min of two or more enumerables.
-
#_jes_new_sort(&block) ⇒ Object
I don’t pass the block to the sort, because a sort block needs to look something like: {|x,y| x <=> y}.
- #_jes_normalize ⇒ Object
- #_jes_normalize! ⇒ Object
-
#_jes_order(&block) ⇒ Object
Given values like [10,5,5,1] Rank should produce something like [4,2,2,1] And order should produce something like [4,2,3,1] The trick is that rank skips as many as were duplicated, so there could not be a 3 in the rank from the example above.
-
#_jes_pearson_correlation(other) ⇒ Object
The covariance / product of standard deviations en.wikipedia.org/wiki/Correlation.
-
#_jes_product ⇒ Object
Multiplies the values: >> product(1,2,3) => 6.0.
-
#_jes_quantile(&block) ⇒ Object
First quartile: nth_split_by_m(1, 4) Third quartile: nth_split_by_m(3, 4) Median: nth_split_by_m(1, 2) Doesn’t match R, and it’s silly to try to.
-
#_jes_rand_in_range(*args) ⇒ Object
Returns a random integer in the range for any number of lists.
-
#_jes_range(&block) ⇒ Object
Just an array of [min, max] to comply with R uses of the work.
-
#_jes_range_as_range(&block) ⇒ Object
Actually instantiates the range, instead of producing a min and max array.
-
#_jes_range_class ⇒ Object
When creating a range, what class will it be? Defaults to Range, but other classes are sometimes useful.
-
#_jes_rank(&block) ⇒ Object
Ranks the values.
-
#_jes_render_category(category) ⇒ Object
Returns a specific category’s values.
- #_jes_scale(val = nil, &block) ⇒ Object
- #_jes_scale!(val = nil, &block) ⇒ Object
- #_jes_scale_between(*values) ⇒ Object
- #_jes_scale_between!(*values) ⇒ Object
- #_jes_scale_to_sigmoid ⇒ Object
- #_jes_scale_to_sigmoid! ⇒ Object
-
#_jes_set_range(hash) ⇒ Object
Takes a hash of arrays for categories If Facets happens to be loaded on the computer, this keeps the order of the categories straight.
-
#_jes_set_range_class(klass, *args) ⇒ Object
Useful for setting a real range class (FixedRange).
-
#_jes_sigma_pairs(other, z = _jes_zero, &block) ⇒ Object
Sigma of pairs.
-
#_jes_standard_deviation(&block) ⇒ Object
The standard deviation.
-
#_jes_sum ⇒ Object
Adds up the list.
-
#_jes_tanimoto_pairs(other) ⇒ Object
Finds the tanimoto coefficient: the intersection set size / union set size.
-
#_jes_to_f! ⇒ Object
Some calculations have to have at least floating point numbers.
-
#_jes_to_pairs(other, &block) ⇒ Object
There are going to be a lot more of these kinds of things, so pay attention.
-
#_jes_union(other) ⇒ Object
All of the left and right hand sides, excluding duplicates.
-
#_jes_variance(&block) ⇒ Object
The variance, uses a block or default block.
-
#_jes_yield_transpose(*enums, &block) ⇒ Object
Transposes arrays of arrays and yields a block on the value.
- #method_missing(sym, *args, &block) ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args, &block) ⇒ Object
327 328 329 330 331 332 333 |
# File 'lib/just_enumerable_stats.rb', line 327 def method_missing(sym, *args, &block) if self.categories.include?(sym) self._jes_render_category(sym) else super end end |
Instance Attribute Details
#_jes_range_class_args ⇒ Object (readonly)
The arguments needed to instantiate the custom-defined range class.
356 357 358 |
# File 'lib/just_enumerable_stats.rb', line 356 def _jes_range_class_args @_jes_range_class_args end |
#_jes_range_hash ⇒ Object (readonly)
The hash of lambdas that are used to categorize the enumerable.
352 353 354 |
# File 'lib/just_enumerable_stats.rb', line 352 def _jes_range_hash @_jes_range_hash end |
Class Method Details
.safe_alias(sym1, sym2 = nil) ⇒ Object
Defines the new methods unobtrusively.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/just_enumerable_stats.rb', line 51 def self.safe_alias(sym1, sym2=nil) return false if not sym2 and not sym1.to_s.match(/^_jes_/) if sym2 old_meth = sym2 new_meth = sym1 else old_meth = sym1 new_meth = sym1.to_s.sub(/^_jes_/, '').to_sym return false if self.class.respond_to?(new_meth) end alias_method new_meth, old_meth end |
Instance Method Details
#_jes_add_category(hash, &block) ⇒ Object
Allows you to add one category at a time. You can actually add more than one category at a time, but it won’t disrupt any previously-set categories.
311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/just_enumerable_stats.rb', line 311 def _jes_add_category(hash, &block) _jes_init_range_hash if hash.is_a?(Hash) hash.each do |k, v| @_jes_range_hash[k] = v @_jes_categories << k end @_jes_category_values = nil hash # Allows the syntax a.add_category(:two_or_three) {|e| e == 2 or e == 3} elsif block _jes_add_category(hash => block) end end |
#_jes_all_categories(value) ⇒ Object
420 421 422 423 424 425 426 427 428 |
# File 'lib/just_enumerable_stats.rb', line 420 def _jes_all_categories(value) return [value] unless self.range_hash self._jes_range_hash.inject([]) do |list, e| cat = e.first block = e.last list << cat if block.call(value) list end end |
#_jes_average(&block) ⇒ Object
The arithmetic mean, uses a block or default block.
139 140 141 |
# File 'lib/just_enumerable_stats.rb', line 139 def _jes_average(&block) _jes_sum(&block)/size end |
#_jes_cartesian_product(other, &block) ⇒ Object
Finds the cartesian product, excluding duplicates items and self- referential pairs. Yields the block value if given.
668 669 670 671 672 673 674 675 |
# File 'lib/just_enumerable_stats.rb', line 668 def _jes_cartesian_product(other, &block) x,y = self.uniq.dup, other.uniq.dup pairs = x.inject([]) do |cp, i| cp | y.map{|b| i == b ? nil : [i,b]}.compact end return pairs unless block_given? pairs.map{|p| yield p.first, p.last} end |
#_jes_categories ⇒ Object
Takes the range_class and returns its map. Example: require ‘mathn’ a = [1,2,3] a range_class = FixedRange, a.min, a.max, 1/4 a.categories
> [1, 5/4, 3/2, 7/4, 2, 9/4, 5/2, 11/4, 3]
For non-numeric values, returns a unique set, ordered if possible.
254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/just_enumerable_stats.rb', line 254 def _jes_categories if @_jes_categories @_jes_categories elsif self.any? {|e| e.is_a?(Float)} val = self.map {|e| e} val.uniq.sort rescue val elsif self._jes_is_numeric? val = self._jes_range_instance.map {|e| e} val.uniq.sort rescue val else self.uniq.sort rescue self.uniq end end |
#_jes_category_map(reset = false) ⇒ Object
431 432 433 434 435 436 437 |
# File 'lib/just_enumerable_stats.rb', line 431 def _jes_category_map(reset=false) @_jes_category_map = nil if reset return @_jes_category_map if @_jes_category_map @_jes_category_map = self.inject([]) do |list, e| list << self._jes_first_category(e) end end |
#_jes_category_values(reset = false) ⇒ Object
Returns a Hash or Dictionary (if available) for each category with a value as the set of matching values as an array. Because this is supposed to be lean (just enumerables), but this is an expensive call, I’m going to cache it and offer a parameter to reset the cache. So, call category_values(true) if you need to reset the cache.
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/just_enumerable_stats.rb', line 386 def _jes_category_values(reset=false) @_jes_category_values = nil if reset return @_jes_category_values if @_jes_category_values container = defined?(Dictionary) ? Dictionary.new : Hash.new if self.range_hash @_jes_category_values = self._jes_categories.inject(container) do |cont, cat| cont[cat] = self.find_all &self._jes_range_hash[cat] cont end else @_jes_category_values = self._jes_categories.inject(container) do |cont, cat| cont[cat] = self.find_all {|e| e == cat} cont end end end |
#_jes_compliment(other) ⇒ Object
Everything on the left hand side except what’s shared on the right hand side. “The relative compliment of y in x”
655 656 657 |
# File 'lib/just_enumerable_stats.rb', line 655 def _jes_compliment(other) self - other end |
#_jes_correlation(other) ⇒ Object
Finds the correlation between two enumerables. Example: [1,2,3].cor [2,3,5] returns 0.981980506061966
717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
# File 'lib/just_enumerable_stats.rb', line 717 def _jes_correlation(other) n = [self.size, other.size]._jes_min sum_of_products_of_pairs = self._jes_sigma_pairs(other) {|a, b| a * b} self_sum = self._jes_sum other_sum = other._jes_sum sum_of_squared_self_scores = self._jes_sum { |e| e * e } sum_of_squared_other_scores = other._jes_sum { |e| e * e } numerator = (n * sum_of_products_of_pairs) - (self_sum * other_sum) self_denominator = ((n * sum_of_squared_self_scores) - (self_sum ** 2)) other_denominator = ((n * sum_of_squared_other_scores) - (other_sum ** 2)) denominator = Math.sqrt(self_denominator * other_denominator) return numerator / denominator end |
#_jes_count_if(&block) ⇒ Object
Counts each element where the block evaluates to true Example: a = [1,2,3] a.count_if {|e| e % 2 == 0}
372 373 374 375 376 377 |
# File 'lib/just_enumerable_stats.rb', line 372 def _jes_count_if(&block) self.inject(0) do |s, e| s += 1 if block.call(e) s end end |
#_jes_covariance(other) ⇒ Object
Returns the covariance of two lists.
761 762 763 764 765 766 767 768 769 |
# File 'lib/just_enumerable_stats.rb', line 761 def _jes_covariance(other) self._jes_to_f! other._jes_to_f! n = [self.size, other.size]._jes_min self_average = self._jes_average other_average = other._jes_average total_expected = self._jes_sigma_pairs(other) {|a, b| (a - self_average) * (b - other_average)} total_expected / n end |
#_jes_cum_max(&block) ⇒ Object
Example:
- 1,2,3,0,5].cum_max # => [1,2,3,3,5
586 587 588 589 590 591 |
# File 'lib/just_enumerable_stats.rb', line 586 def _jes_cum_max(&block) _jes_morph_list(&block).inject([]) do |list, e| found = (list | [e])._jes_max list << (found ? found : e) end end |
#_jes_cum_min(&block) ⇒ Object
Example:
- 1,2,3,0,5].cum_min # => [1,1,1,0,0
597 598 599 600 601 602 |
# File 'lib/just_enumerable_stats.rb', line 597 def _jes_cum_min(&block) _jes_morph_list(&block).inject([]) do |list, e| found = (list | [e]).min list << (found ? found : e) end end |
#_jes_cum_prod(sorted = false, &block) ⇒ Object
The cummulative product. Example:
- 1,2,3].cum_prod # => [1.0, 2.0, 6.0
558 559 560 561 562 563 564 565 566 567 568 |
# File 'lib/just_enumerable_stats.rb', line 558 def _jes_cum_prod(sorted=false, &block) prod = _jes_one obj = sorted ? self.sort : self if block_given? obj.map { |i| prod *= yield(i) } elsif _jes_default_block obj.map { |i| prod *= _jes_default_block[*i] } else obj.map { |i| prod *= i } end end |
#_jes_cum_sum(sorted = false, &block) ⇒ Object
The cummulative sum. Example:
- 1,2,3].cum_sum # => [1, 3, 6
542 543 544 545 546 547 548 549 550 551 552 |
# File 'lib/just_enumerable_stats.rb', line 542 def _jes_cum_sum(sorted=false, &block) sum = _jes_zero obj = sorted ? self.sort : self if block_given? obj.map { |i| sum += yield(i) } elsif _jes_default_block obj.map { |i| sum += _jes_default_block[*i] } else obj.map { |i| sum += i } end end |
#_jes_default_block ⇒ Object
The block called to filter the values in the object.
97 98 99 |
# File 'lib/just_enumerable_stats.rb', line 97 def _jes_default_block @_jes_default_stat_block end |
#_jes_default_block=(block) ⇒ Object
Allows me to setup a block for a series of operations. Example: a = [1,2,3] a.sum # => 6.0 a.default_block = lambda{|e| 1 / e} a.sum # => 1.0
107 108 109 |
# File 'lib/just_enumerable_stats.rb', line 107 def _jes_default_block=(block) @_jes_default_stat_block = block end |
#_jes_dichotomize(split_value, first_label, second_label) ⇒ Object
Splits the values in two, <= the value and > the value.
360 361 362 363 364 365 |
# File 'lib/just_enumerable_stats.rb', line 360 def _jes_dichotomize(split_value, first_label, second_label) container = defined?(Dictionary) ? Dictionary.new : Hash.new container[first_label] = lambda{|e| e <= split_value} container[second_label] = lambda{|e| e > split_value} _jes_set_range(container) end |
#_jes_euclidian_distance(other) ⇒ Object
Returns the Euclidian distance between all points of a set of enumerables
689 690 691 |
# File 'lib/just_enumerable_stats.rb', line 689 def _jes_euclidian_distance(other) Math.sqrt(self._jes_sigma_pairs(other) {|a, b| (a - b) ** 2}) end |
#_jes_exclusive_not(other) ⇒ Object
Everything but what’s shared
661 662 663 |
# File 'lib/just_enumerable_stats.rb', line 661 def _jes_exclusive_not(other) (self | other) - (self & other) end |
#_jes_first_category(value) ⇒ Object
Returns the first category of a value. Example: a = [1,2,3] a.first_category(2) # => 2 a.add_category(:small) {|e| e <= 1} a.add_category(:large) {|e| e > 1} a.first_category(2) # => :large
410 411 412 413 414 415 416 |
# File 'lib/just_enumerable_stats.rb', line 410 def _jes_first_category(value) return value unless self.range_hash self._jes_range_hash.each do |cat, block| return cat if block.call(value) end return nil end |
#_jes_frequency ⇒ Object
Returns a hash or dictionary (if installed) of the frequency of each category.
860 861 862 863 864 865 866 |
# File 'lib/just_enumerable_stats.rb', line 860 def _jes_frequency dict = defined?(Dictionary) ? Dictionary.new : Hash.new self._jes_category_values.each do |k, v| dict[k] = v.size / self.size end dict end |
#_jes_frequency_for(key) ⇒ Object
869 870 871 |
# File 'lib/just_enumerable_stats.rb', line 869 def _jes_frequency_for(key) self._jes_frequency[key] end |
#_jes_intersect(other) ⇒ Object
What’s shared on the left and right hand sides “The intersection of x and y”
647 648 649 |
# File 'lib/just_enumerable_stats.rb', line 647 def _jes_intersect(other) self & other end |
#_jes_is_numeric? ⇒ Boolean
269 270 271 |
# File 'lib/just_enumerable_stats.rb', line 269 def _jes_is_numeric? self.all? {|e| e.is_a?(Numeric)} end |
#_jes_max(&block) ⇒ Object
Returns the max, using an optional block.
67 68 69 70 71 72 |
# File 'lib/just_enumerable_stats.rb', line 67 def _jes_max(&block) self.inject do |best, e| val = _jes_block_sorter(best, e, &block) best = val > 0 ? best : e end end |
#_jes_max_index(&block) ⇒ Object
Returns the first index of the max value
76 77 78 |
# File 'lib/just_enumerable_stats.rb', line 76 def _jes_max_index(&block) self.index(_jes_max(&block)) end |
#_jes_max_of_lists(*enums) ⇒ Object
Returns the max of two or more enumerables. >> [1,2,3].max_of_lists(, [0,2,9])
> [1, 5, 9]
747 748 749 |
# File 'lib/just_enumerable_stats.rb', line 747 def _jes_max_of_lists(*enums) _jes_yield_transpose(*enums) {|e| e._jes_max} end |
#_jes_median(ratio = 0.5, &block) ⇒ Object
The slow way is to iterate up to the middle point. A faster way is to use the index, when available. If a block is supplied, always iterate to the middle point.
171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/just_enumerable_stats.rb', line 171 def _jes_median(ratio=0.5, &block) return _jes_iterate_midway(ratio, &block) if block_given? begin mid1, mid2 = _jes_middle_two sorted = sort med1, med2 = sorted[mid1], sorted[mid2] return med1 if med1 == med2 return med1 + ((med2 - med1) * ratio) rescue _jes_iterate_midway(ratio, &block) end end |
#_jes_min(&block) ⇒ Object
Min of any number of items
82 83 84 85 86 87 |
# File 'lib/just_enumerable_stats.rb', line 82 def _jes_min(&block) self.inject do |best, e| val = _jes_block_sorter(best, e, &block) best = val < 0 ? best : e end end |
#_jes_min_index(&block) ⇒ Object
Returns the first index of the min value
91 92 93 |
# File 'lib/just_enumerable_stats.rb', line 91 def _jes_min_index(&block) self.index(_jes_min(&block)) end |
#_jes_min_of_lists(*enums) ⇒ Object
Returns the min of two or more enumerables. >> [1,2,3].min_of_lists(, [0,2,9])
> [0, 2, 3]
755 756 757 |
# File 'lib/just_enumerable_stats.rb', line 755 def _jes_min_of_lists(*enums) _jes_yield_transpose(*enums) {|e| e.min} end |
#_jes_new_sort(&block) ⇒ Object
I don’t pass the block to the sort, because a sort block needs to look something like: {|x,y| x <=> y}. To get around this, set the default block on the object.
462 463 464 465 466 467 468 469 470 |
# File 'lib/just_enumerable_stats.rb', line 462 def _jes_new_sort(&block) if block_given? map { |i| yield(i) }.sort.dup elsif _jes_default_block map { |i| _jes_default_block[*i] }.sort.dup else sort().dup end end |
#_jes_normalize ⇒ Object
821 822 823 824 825 |
# File 'lib/just_enumerable_stats.rb', line 821 def _jes_normalize min = self._jes_min diff = self._jes_max - min self.map {|e| (e - min) / diff } end |
#_jes_normalize! ⇒ Object
828 829 830 831 832 |
# File 'lib/just_enumerable_stats.rb', line 828 def _jes_normalize! min = self._jes_min diff = self._jes_max - min self.map! {|e| (e - min) / diff } end |
#_jes_order(&block) ⇒ Object
Given values like [10,5,5,1] Rank should produce something like [4,2,2,1] And order should produce something like [4,2,3,1] The trick is that rank skips as many as were duplicated, so there could not be a 3 in the rank from the example above.
498 499 500 501 502 503 504 505 506 507 |
# File 'lib/just_enumerable_stats.rb', line 498 def _jes_order(&block) hold = [] _jes_rank(&block).each do |x| while hold.include?(x) do x += 1 end hold << x end hold end |
#_jes_pearson_correlation(other) ⇒ Object
The covariance / product of standard deviations en.wikipedia.org/wiki/Correlation
774 775 776 777 778 779 |
# File 'lib/just_enumerable_stats.rb', line 774 def _jes_pearson_correlation(other) self._jes_to_f! other._jes_to_f! denominator = self._jes_standard_deviation * other._jes_standard_deviation self._jes_covariance(other) / denominator end |
#_jes_product ⇒ Object
Multiplies the values: >> product(1,2,3)
> 6.0
609 610 611 |
# File 'lib/just_enumerable_stats.rb', line 609 def _jes_product self.inject(_jes_one) {|sum, a| sum *= a} end |
#_jes_quantile(&block) ⇒ Object
First quartile: nth_split_by_m(1, 4) Third quartile: nth_split_by_m(3, 4) Median: nth_split_by_m(1, 2) Doesn’t match R, and it’s silly to try to. def _jes_nth_split_by_m(n, m)
sorted = new_sort
dividers = m - 1
if size % m == dividers # Divides evenly
# Because we have a 0-based list, we get the floor
i = ((size / m.to_f) * n).floor
j = i
else
# This reflects R's approach, which I don't think I agree with.
i = (((size / m.to_f) * n) - 1)
i = i > (size / m.to_f) ? i.floor : i.ceil
j = i + 1
end
sorted[i] + ((n / m.to_f) * (sorted[j] - sorted[i]))
end
529 530 531 532 533 534 535 536 537 |
# File 'lib/just_enumerable_stats.rb', line 529 def _jes_quantile(&block) [ _jes_min(&block), _jes_first_half(&block)._jes_median(0.25, &block), _jes_median(&block), _jes_second_half(&block)._jes_median(0.75, &block), _jes_max(&block) ] end |
#_jes_rand_in_range(*args) ⇒ Object
Returns a random integer in the range for any number of lists. This is a way to get a random vector that is tenable based on the sample data. For example, given two sets of numbers:
a = [1,2,3]; b = [8,8,8]
rand_in_pair_range will return a value >= 1 and <= 8 in the first place, >= 2 and <= 8 in the second place, and >= 3 and <= 8 in the last place. Works for integers. Rethink this for floats. May consider setting up FixedRange for floats. O(n*5)
705 706 707 708 709 710 711 |
# File 'lib/just_enumerable_stats.rb', line 705 def _jes_rand_in_range(*args) min = self._jes_min_of_lists(*args) max = self._jes_max_of_lists(*args) (0...size).inject([]) do |ary, i| ary << rand_between(min[i], max[i]) end end |
#_jes_range(&block) ⇒ Object
Just an array of [min, max] to comply with R uses of the work. Use range_as_range if you want a real Range.
276 277 278 |
# File 'lib/just_enumerable_stats.rb', line 276 def _jes_range(&block) [_jes_min(&block), _jes_max(&block)] end |
#_jes_range_as_range(&block) ⇒ Object
Actually instantiates the range, instead of producing a min and max array.
448 449 450 451 452 453 454 |
# File 'lib/just_enumerable_stats.rb', line 448 def _jes_range_as_range(&block) if @_jes_range_class_args and not @_jes_range_class_args.empty? self._jes_range_class.new(*@_jes_range_class_args) else self._jes_range_class.new(_jes_min(&block), _jes_max(&block)) end end |
#_jes_range_class ⇒ Object
When creating a range, what class will it be? Defaults to Range, but other classes are sometimes useful.
442 443 444 |
# File 'lib/just_enumerable_stats.rb', line 442 def _jes_range_class @_jes_range_class ||= Range end |
#_jes_rank(&block) ⇒ Object
Ranks the values
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/just_enumerable_stats.rb', line 474 def _jes_rank(&block) sorted = _jes_new_sort(&block) # rank = map { |i| sorted.index(i) + 1 } if block_given? map { |i| sorted.index(yield(i)) + 1 } elsif _jes_default_block map { |i| sorted.index(_jes_default_block[*i]) + 1 } else map { |i| sorted.index(i) + 1 } end end |
#_jes_render_category(category) ⇒ Object
Returns a specific category’s values
336 337 338 |
# File 'lib/just_enumerable_stats.rb', line 336 def _jes_render_category(category) self.category_values[category] end |
#_jes_scale(val = nil, &block) ⇒ Object
793 794 795 796 797 798 799 |
# File 'lib/just_enumerable_stats.rb', line 793 def _jes_scale(val=nil, &block) if block self.map{|e| block.call(e)} else self.map{|e| e * val} end end |
#_jes_scale!(val = nil, &block) ⇒ Object
802 803 804 805 806 807 808 |
# File 'lib/just_enumerable_stats.rb', line 802 def _jes_scale!(val=nil, &block) if block self.map!{|e| block.call(e)} else self.map!{|e| e * val} end end |
#_jes_scale_between(*values) ⇒ Object
835 836 837 838 839 840 841 842 843 844 |
# File 'lib/just_enumerable_stats.rb', line 835 def _jes_scale_between(*values) raise ArgumentError, "Must provide two values" unless values.size == 2 values.sort! min = values[0] max = values[1] orig_min = self._jes_min scalar = (max - min) / (self._jes_max - orig_min).to_f shift = min - (orig_min * scalar) self._jes_scale{|e| (e * scalar) + shift} end |
#_jes_scale_between!(*values) ⇒ Object
847 848 849 850 851 852 853 854 855 856 |
# File 'lib/just_enumerable_stats.rb', line 847 def _jes_scale_between!(*values) raise ArgumentError, "Must provide two values" unless values.size == 2 values.sort! min = values[0] max = values[1] orig_min = self._jes_min scalar = (max - min) / (self._jes_max - orig_min).to_f shift = min - (orig_min * scalar) self._jes_scale!{|e| (e * scalar) + shift} end |
#_jes_scale_to_sigmoid ⇒ Object
811 812 813 |
# File 'lib/just_enumerable_stats.rb', line 811 def _jes_scale_to_sigmoid self._jes_scale { |e| 1 / (1 + Math.exp( -1 * (e))) } end |
#_jes_scale_to_sigmoid! ⇒ Object
816 817 818 |
# File 'lib/just_enumerable_stats.rb', line 816 def _jes_scale_to_sigmoid! self._jes_scale! { |e| 1 / (1 + Math.exp( -1 * (e))) } end |
#_jes_set_range(hash) ⇒ Object
Takes a hash of arrays for categories If Facets happens to be loaded on the computer, this keeps the order of the categories straight.
292 293 294 295 296 297 298 299 300 301 302 303 |
# File 'lib/just_enumerable_stats.rb', line 292 def _jes_set_range(hash) if defined?(Dictionary) @_jes_range_hash = Dictionary.new @_jes_range_hash.merge!(hash) @_jes_categories = @_jes_range_hash.keys.dup else @_jes_categories = hash.keys.dup @_jes_range_hash = hash end @_jes_category_values = nil @_jes_categories end |
#_jes_set_range_class(klass, *args) ⇒ Object
Useful for setting a real range class (FixedRange).
282 283 284 285 286 |
# File 'lib/just_enumerable_stats.rb', line 282 def _jes_set_range_class(klass, *args) @_jes_range_class = klass @_jes_range_class_args = args self._jes_range_class end |
#_jes_sigma_pairs(other, z = _jes_zero, &block) ⇒ Object
Sigma of pairs. Returns a single float, or whatever object is sent in. Example: [1,2,3].sigma_pairs(, 0) {|x, y| x + y} returns 21 instead of 21.0.
683 684 685 |
# File 'lib/just_enumerable_stats.rb', line 683 def _jes_sigma_pairs(other, z=_jes_zero, &block) self._jes_to_pairs(other,&block).inject(z) {|sum, i| sum += i} end |
#_jes_standard_deviation(&block) ⇒ Object
The standard deviation. Uses a block or default block.
162 163 164 |
# File 'lib/just_enumerable_stats.rb', line 162 def _jes_standard_deviation(&block) Math::sqrt(_jes_variance(&block)) end |
#_jes_sum ⇒ Object
Adds up the list. Uses a block or default block if present.
125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/just_enumerable_stats.rb', line 125 def _jes_sum sum = _jes_zero if block_given? each{|i| sum += yield(i)} elsif _jes_default_block each{|i| sum += _jes_default_block[*i]} else each{|i| sum += i} end sum end |
#_jes_tanimoto_pairs(other) ⇒ Object
Finds the tanimoto coefficient: the intersection set size / union set size. This is used to find the distance between two vectors. >> [1,2,3].cor()
> 0.981980506061966
> 0.5
628 629 630 |
# File 'lib/just_enumerable_stats.rb', line 628 def _jes_tanimoto_pairs(other) _jes_intersect(other).size / _jes_union(other).size.to_f end |
#_jes_to_f! ⇒ Object
Some calculations have to have at least floating point numbers. This generates a cached version of the operation–only runs once per object.
784 785 786 787 |
# File 'lib/just_enumerable_stats.rb', line 784 def _jes_to_f! return true if @_jes_to_f @_jes_to_f = self.map! {|e| e.to_f} end |
#_jes_to_pairs(other, &block) ⇒ Object
There are going to be a lot more of these kinds of things, so pay attention.
616 617 618 619 |
# File 'lib/just_enumerable_stats.rb', line 616 def _jes_to_pairs(other, &block) n = [self.size, other.size]._jes_min (0...n).map {|i| block.call(self[i], other[i]) } end |
#_jes_union(other) ⇒ Object
All of the left and right hand sides, excluding duplicates. “The union of x and y”
640 641 642 |
# File 'lib/just_enumerable_stats.rb', line 640 def _jes_union(other) self | other end |
#_jes_variance(&block) ⇒ Object
The variance, uses a block or default block.
147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/just_enumerable_stats.rb', line 147 def _jes_variance(&block) m = _jes_average(&block) sum_of_differences = if block_given? _jes_sum{ |i| j=yield(i); (m - j) ** 2 } elsif _jes_default_block _jes_sum{ |i| j=_jes_default_block[*i]; (m - j) ** 2 } else _jes_sum{ |i| (m - i) ** 2 } end sum_of_differences / (size - 1) end |
#_jes_yield_transpose(*enums, &block) ⇒ Object
Transposes arrays of arrays and yields a block on the value. The regular Array#transpose ignores blocks
736 737 738 739 740 741 |
# File 'lib/just_enumerable_stats.rb', line 736 def _jes_yield_transpose(*enums, &block) enums.unshift(self) n = enums.map{ |x| x.size}.min block ||= lambda{|e| e} (0...n).map { |i| block.call enums.map{ |x| x[i] } } end |