facets 2.9.0.pre.1 → 2.9.0.pre.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. data/AUTHORS +1 -0
  2. data/COPYING +1 -2
  3. data/HISTORY.rdoc +16 -8
  4. data/lib/core/facets/hash/subset.rb +24 -0
  5. data/lib/core/facets/hash/zip.rb +18 -0
  6. data/lib/core/facets/kernel/try.rb +3 -3
  7. data/lib/core/facets/module/home.rb +90 -0
  8. data/lib/core/facets/module/homename.rb +1 -0
  9. data/lib/core/facets/module/housing.rb +1 -0
  10. data/lib/core/facets/module/modname.rb +1 -22
  11. data/lib/core/facets/na.rb +11 -5
  12. data/lib/core/facets/object/clone.rb +1 -0
  13. data/lib/core/facets/{kernel/try_dup.rb → object/dup.rb} +41 -35
  14. data/lib/core/facets/{kernel → object}/object_state.rb +15 -18
  15. data/lib/core/facets/object/replace.rb +43 -0
  16. data/lib/core/facets/object/try_dup.rb +1 -0
  17. data/lib/core/facets/string/cleanlines.rb +2 -0
  18. data/lib/core/facets/time/ago.rb +1 -1
  19. data/lib/core/facets/time/in.rb +1 -93
  20. data/lib/core/facets/time/less.rb +1 -0
  21. data/lib/core/facets/time/shift.rb +95 -0
  22. data/lib/more/facets/interval.rb +284 -0
  23. data/lib/more/facets/math.rb +6 -0
  24. data/lib/more/facets/math/abs.rb +8 -0
  25. data/lib/more/facets/math/acot.rb +8 -0
  26. data/lib/more/facets/math/acoth.rb +8 -0
  27. data/lib/more/facets/math/acsc.rb +8 -0
  28. data/lib/more/facets/math/acsch.rb +8 -0
  29. data/lib/more/facets/math/amd.rb +17 -0
  30. data/lib/more/facets/math/approx_equal.rb +15 -0
  31. data/lib/more/facets/math/asec.rb +8 -0
  32. data/lib/more/facets/math/asech.rb +8 -0
  33. data/lib/more/facets/math/atkinson_index.rb +16 -0
  34. data/lib/more/facets/math/beta.rb +9 -0
  35. data/lib/more/facets/math/cdf.rb +10 -0
  36. data/lib/more/facets/math/ceil.rb +8 -0
  37. data/lib/more/facets/math/cot.rb +8 -0
  38. data/lib/more/facets/math/coth.rb +8 -0
  39. data/lib/more/facets/math/csc.rb +8 -0
  40. data/lib/more/facets/math/csch.rb +8 -0
  41. data/lib/more/facets/math/delta.rb +8 -0
  42. data/lib/more/facets/math/epsilon.rb +21 -0
  43. data/lib/more/facets/math/exp10.rb +8 -0
  44. data/lib/more/facets/math/exp2.rb +8 -0
  45. data/lib/more/facets/math/factorial.rb +37 -0
  46. data/lib/more/facets/math/floor.rb +8 -0
  47. data/lib/more/facets/math/gamma.rb +12 -0
  48. data/lib/more/facets/math/gcd.rb +23 -0
  49. data/lib/more/facets/math/gini_coefficient.rb +33 -0
  50. data/lib/more/facets/math/kldivergence.rb +19 -0
  51. data/lib/more/facets/math/lcm.rb +15 -0
  52. data/lib/more/facets/math/lgamma.rb +21 -0
  53. data/lib/more/facets/math/linsolve.rb +10 -0
  54. data/lib/more/facets/math/log2.rb +14 -0
  55. data/lib/more/facets/math/max.rb +1 -0
  56. data/lib/more/facets/math/mean.rb +16 -0
  57. data/lib/more/facets/math/median.rb +15 -0
  58. data/lib/more/facets/math/min.rb +35 -0
  59. data/lib/more/facets/math/pow.rb +8 -0
  60. data/lib/more/facets/math/pstd.rb +1 -0
  61. data/lib/more/facets/math/pvariance.rb +1 -0
  62. data/lib/more/facets/math/rmd.rb +16 -0
  63. data/lib/more/facets/math/root.rb +8 -0
  64. data/lib/more/facets/math/sec.rb +8 -0
  65. data/lib/more/facets/math/sech.rb +8 -0
  66. data/lib/more/facets/math/sign.rb +9 -0
  67. data/lib/more/facets/math/sinc.rb +8 -0
  68. data/lib/more/facets/math/sqr.rb +8 -0
  69. data/lib/more/facets/math/sqsolve.rb +53 -0
  70. data/lib/more/facets/math/std.rb +27 -0
  71. data/lib/more/facets/math/stderr.rb +1 -0
  72. data/lib/more/facets/math/sum.rb +16 -0
  73. data/lib/more/facets/math/summed_sqdevs.rb +14 -0
  74. data/lib/more/facets/math/theil_index.rb +24 -0
  75. data/lib/more/facets/math/variance.rb +31 -0
  76. data/lib/more/facets/thread.rb +24 -0
  77. data/lib/tour/facets/array/op_pow.rb +5 -0
  78. data/lib/tour/facets/module/enclosure.rb +15 -1
  79. data/lib/tour/facets/module/preextend.rb +26 -0
  80. data/lib/tour/facets/module/prepend.rb +39 -13
  81. data/meta/gemfile +1 -1
  82. data/qed/core/binding/caller.rdoc +1 -3
  83. data/test/core/array/test_after.rb +1 -1
  84. data/test/core/array/test_before.rb +1 -1
  85. data/test/core/array/test_conjoin.rb +1 -1
  86. data/test/core/array/test_store.rb +1 -1
  87. data/test/core/hash/test_argumentize.rb +1 -1
  88. data/test/core/hash/test_join.rb +1 -1
  89. data/test/core/kernel/test_dup.rb +1 -1
  90. data/test/core/kernel/test_get.rb +1 -1
  91. data/test/core/kernel/test_qua_class.rb +1 -1
  92. data/test/core/time/test_ago.rb +5 -117
  93. data/test/core/time/test_hence.rb +2 -2
  94. data/test/core/time/test_in.rb +4 -115
  95. data/test/core/time/test_less.rb +137 -0
  96. data/test/core/time/test_set.rb +1 -1
  97. data/test/core/time/test_shift.rb +126 -0
  98. data/test/more/test_date.rb +1 -1
  99. data/test/tour/module/test_cattr.rb +1 -1
  100. data/test/tour/module/test_class_extend.rb +1 -1
  101. data/test/tour/module/test_instance_function.rb +1 -1
  102. data/test/tour/module/test_method_space.rb +1 -1
  103. metadata +76 -10
  104. data/lib/core/facets/hash/zipnew.rb +0 -18
  105. data/lib/core/facets/kernel/clone.rb +0 -1
  106. data/lib/core/facets/kernel/dup.rb +0 -34
  107. data/lib/core/facets/kernel/replace.rb +0 -1
@@ -0,0 +1,14 @@
1
+ module Math
2
+
3
+ INVERSE_LN_2 = 1.0 / ::Math.log(2.0)
4
+
5
+ unless defined?(log2)
6
+
7
+ # Logarithmus dualis of +x+.
8
+ def self.log2(x)
9
+ Math.log(x) * INVERSE_LN_2
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1 @@
1
+ require 'facets/math/min'
@@ -0,0 +1,16 @@
1
+ require 'facets/math/sum'
2
+
3
+ module Math
4
+
5
+ # Mean average.
6
+ def self.mean(array, &blk)
7
+ s = array.size
8
+ return 0.0 if s == 0
9
+ sum(array, &blk) / s
10
+ end
11
+
12
+ class << self
13
+ alias_method :mean_average, :mean
14
+ end
15
+
16
+ end
@@ -0,0 +1,15 @@
1
+ module Math
2
+
3
+ #
4
+ def self.median(array)
5
+ return 0 if array.size == 0
6
+ tmp = array.sort
7
+ mid = tmp.size / 2
8
+ if (tmp.size % 2) == 0
9
+ (tmp[mid-1] + tmp[mid]).to_f / 2
10
+ else
11
+ tmp[mid]
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,35 @@
1
+ module Math
2
+
3
+ #
4
+ def self.min(array, &block)
5
+ if block_given?
6
+ if min = array.find{ |i| i }
7
+ min = yield(min)
8
+ array.each do |i|
9
+ j = yield(i)
10
+ min = j if min > j
11
+ end
12
+ min
13
+ end
14
+ else
15
+ array.min
16
+ end
17
+ end
18
+
19
+ #
20
+ def self.max(array, block)
21
+ if block_given?
22
+ if max = find{|i| i}
23
+ max = yield(max)
24
+ each{|i|
25
+ j = yield(i)
26
+ max = j if max < j
27
+ }
28
+ max
29
+ end
30
+ else
31
+ array.max
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # +x+ to the power +y+
4
+ def self.pow(x, y)
5
+ x ** y
6
+ end
7
+
8
+ end
@@ -0,0 +1 @@
1
+ require 'facets/math/std'
@@ -0,0 +1 @@
1
+ require 'facets/math/variance'
@@ -0,0 +1,16 @@
1
+ require 'facets/math/approx_equal'
2
+
3
+ module Math
4
+
5
+ # Calculates the relative mean difference of this sample.
6
+ # Makes use of the fact that the Gini Coefficient is half the RMD.
7
+ def self.rmd(array)
8
+ return 0.0 if approx_equal(mean(array), 0.0)
9
+ gini_coefficient(array) * 2
10
+ end
11
+
12
+ class << self
13
+ alias_method :relative_mean_difference, :rmd
14
+ end
15
+
16
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # The +y+ root of +x+.
4
+ def self.root(x, y)
5
+ x ** (1.0 / y)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Secans of +x+.
4
+ def self.sec(x)
5
+ 1.0 / cos(x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Secans hyperbolicus of +x+
4
+ def self.sech(x)
5
+ 1.0 / cosh(x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,9 @@
1
+ module Math
2
+
3
+ # Sign of +x+.
4
+ # Returns -1 for negative x, +1 for positive x and zero for x = 0
5
+ def self.sign(x)
6
+ (x > 0.0) ? 1.0 : ((x < 0.0) ? -1.0 : 0.0)
7
+ end
8
+
9
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Sinc function of +x+.
4
+ def self.sinc(x)
5
+ (x == 0.0) ? 1.0 : sin(x) / x
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Square of number.
4
+ def self.sqr(x)
5
+ x * x
6
+ end
7
+
8
+ end
@@ -0,0 +1,53 @@
1
+ module Math
2
+
3
+ # Returns array of real solution of <code>ax**2 + bx + c = d</code>
4
+ # or <code>nil</code> if no or an infinite number of solutions exist.
5
+ # If +d+ is missing it is assumed to be 0.
6
+ #
7
+ # == Solving second order equations
8
+ # In order to solve <code>ax**2 + bx + c = d</code> +Extmath.sqsolve+ identifies several cases:
9
+ # * <code>a == 0:</code>
10
+ # The equation to be solved is the linear equation <code>bx + c = d</code>. #sqsolve> delegates the computation to
11
+ # #linsolve>. If it results in +nil+, +nil+ is returned (not <code>[nil]</code>!). Otherwise a one-element array
12
+ # containing result of #linsolve is returned.
13
+ # * <code>a != 0:</code>
14
+ # The equation to be solved actually is a second order one.
15
+ # * <code>c == d</code>
16
+ # The equation to be solved is <code>ax**2 + bx = 0</code>. One solution of this equation obviously is
17
+ # <code>x = 0</code>, the second one solves <code>ax + b = 0</code>. The solution of the latter is
18
+ # delegated to +Extmath.linsolve+. An array containing both results in ascending order is returned.
19
+ # * <code>c != d</code>
20
+ # The equation cannot be separated into <code>x</code> times some factor.
21
+ # * <code>b == 0</code>
22
+ # The equation to be solved is <code>ax**2 + c = d</code>. This can be written as the linear equation
23
+ # <code>ay + c = d</code> with <code>y = x ** 2</code>. The solution of the linear equation is delegated
24
+ # to +Extmath.linsolve+. If the returned value for +y+ is +nil+, that becomes the overall return value.
25
+ # Otherwise an array containing the negative and positive squareroot of +y+ is returned
26
+ # * <code>b != 0 </code>
27
+ # The equation cannot be reduced to simpler cases. We now first have to compute what is called the
28
+ # discriminant <code>x = b**2 + 4a(d - c)</code> (that's what we need to compute the square root of).
29
+ # If the descriminant is negative no real solution exists and <code>nil</code> is returned. The ternary
30
+ # operator checking whether <code>b</code> is negative does ensure better numerical stability --only one
31
+ # of the two solutions is computed using the widely know formula for solving second order equations.
32
+ # The second one is computed from the fact that the product of both solutions is <code>(c - d) / a</code>.
33
+ # Take a look at a book on numerical mathematics if you don't understand why this should be done.
34
+ #
35
+ def self.sqsolve(a, b, c, d = 0.0)
36
+ if a == 0.0
37
+ x = linsolve(b, c, d)
38
+ return x.nil? ? nil: [ linsolve(b, c, d) ]
39
+ else
40
+ return [0.0, linsolve(a, b)].sort if c == d
41
+ if b == 0.0
42
+ x = Extmath.linsolve(a, c, d)
43
+ x < 0.0 ? nil : [-Math.sqrt(x), Math.sqrt(x)]
44
+ else
45
+ x = b * b + 4.0 * a * (d - c)
46
+ return nil if x < 0.0
47
+ x = b < 0 ? b - Math.sqrt(x) : b + Math.sqrt(x)
48
+ [-0.5 * x / a, 2.0 * (d - c) / x].sort
49
+ end
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,27 @@
1
+ require 'facets/math/variance'
2
+
3
+ module Math
4
+
5
+ # Standard deviation of a sample.
6
+ #
7
+ def self.std(array, &block)
8
+ sqrt(variance(array, &block))
9
+ end
10
+
11
+ class << self
12
+ alias_method :standard_deviation, :std
13
+ end
14
+
15
+ # Standard deviation of a population.
16
+ #
17
+ def self.pstd(array, &block)
18
+ Math::sqrt(pvariance(array, &block))
19
+ end
20
+
21
+ # Calculates the standard error of a sample.
22
+ def self.stderr(array)
23
+ return 0.0 if array.size < 2
24
+ std(array) / sqrt(array.size)
25
+ end
26
+
27
+ end
@@ -0,0 +1 @@
1
+ require 'facets/math/std'
@@ -0,0 +1,16 @@
1
+ module Math
2
+
3
+ # Returns sum. When a block is given, summation is taken over the
4
+ # each result of block evaluation.
5
+ #
6
+ def self.sum(array) #:yield:
7
+ sum = 0.0
8
+ if block_given?
9
+ array.each{|i| sum += yield(i)}
10
+ else
11
+ array.each{|i| sum += i}
12
+ end
13
+ sum
14
+ end
15
+
16
+ end
@@ -0,0 +1,14 @@
1
+ require 'facets/math/sum'
2
+ require 'facets/math/mean'
3
+
4
+ module Math
5
+
6
+ # The sum of the squared deviations from the mean.
7
+ #
8
+ def self.summed_sqdevs(array)
9
+ return 0 if array.size < 2
10
+ m = mean(array)
11
+ sum(array.map{ |x| (x - m) ** 2 })
12
+ end
13
+
14
+ end
@@ -0,0 +1,24 @@
1
+ require 'facets/math/sum'
2
+ require 'facets/math/mean'
3
+ require 'facets/math/approx_equal'
4
+
5
+ module Math
6
+
7
+ # Calculates the Theil index (a statistic used to measure
8
+ # economic inequality).
9
+ #
10
+ # TI = \sum_{i=1}^N \frac{x_i}{\sum_{j=1}^N x_j} ln \frac{x_i}{\bar{x}}
11
+ #
12
+ # http://en.wikipedia.org/wiki/Theil_index
13
+ #
14
+ def self.theil_index(array)
15
+ return -1 if array.size <= 0 or any? { |x| x < 0 }
16
+ return 0 if array.size < 2 or all? { |x| approx_equal(x, 0) }
17
+ m = mean(array)
18
+ s = sum(array).to_f
19
+ inject(0) do |theil, xi|
20
+ theil + ((xi > 0) ? (log(xi.to_f/m) * xi.to_f/s) : 0.0)
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,31 @@
1
+ require 'facets/math/summed_sqdevs'
2
+
3
+ module Math
4
+
5
+ #
6
+ def self.variance(array, &block)
7
+ sum2 = if block_given?
8
+ sum(array){ |i| j = block[i]; j*j }
9
+ else
10
+ sum(array){ |i| i**2 }
11
+ end
12
+ sum2/array.size - mean(array, &block)**2
13
+ end
14
+
15
+ # Variance of the sample.
16
+ # Variance of 0 or 1 elements is 0.0.
17
+ #
18
+ # TODO: Same as #variance? Then choose one.
19
+ def self.variance2(array)
20
+ return 0.0 if array.size < 2
21
+ summed_sqdevs(array) / (array.size - 1)
22
+ end
23
+
24
+ # Variance of a population.
25
+ # Variance of 0 or 1 elements is 0.0.
26
+ def self.pvariance(array)
27
+ return 0.0 if array.size < 2
28
+ summed_sqdevs(array) / array.size
29
+ end
30
+
31
+ end
@@ -71,4 +71,28 @@ module Enumerable
71
71
 
72
72
  end
73
73
 
74
+
75
+ module Kernel
76
+ private
77
+
78
+ # CREDIT: Zucker
79
+ def sandbox(rescueblock_or_default=nil) #:yield:
80
+ Thread.start do
81
+ $SAFE = 4
82
+ yield
83
+ end.value
84
+ rescue SecurityError => e
85
+ if !rescueblock_or_default.nil?
86
+ if rescueblock_or_default.is_a? Proc
87
+ rescueblock_or_default.call e
88
+ else
89
+ rescueblock_or_default
90
+ end
91
+ else
92
+ raise e
93
+ end
94
+ end
95
+
96
+ end
97
+
74
98
  # Copyright (c) 2006 Sean O'Halpin, Thomas Sawyer
@@ -0,0 +1,5 @@
1
+ require 'facets/array/product'
2
+
3
+ class Array
4
+ alias_method :**, :product
5
+ end
@@ -58,5 +58,19 @@ class Module
58
58
  n
59
59
  end
60
60
 
61
- end
61
+ # Eclosure name.
62
+ #
63
+ # module ::EncExample
64
+ # module M
65
+ # module N
66
+ # end
67
+ # end
68
+ # end
69
+ #
70
+ # EncExample::M::N.encname #=> "EncExample::M"
71
+ #
72
+ def encname
73
+ /::[^:]+\Z/ =~ self.name ? $` : nil
74
+ end
62
75
 
76
+ end
@@ -0,0 +1,26 @@
1
+ class Module
2
+
3
+ # Prepend an +aspect+ module to a module.
4
+ # This only works at the module level.
5
+ #
6
+ # module ::PreX
7
+ # def x; "x"; end
8
+ # end
9
+ #
10
+ # module ::PreU
11
+ # def x; '{' + super + '}'; end
12
+ # end
13
+ #
14
+ # PreX.preextend(PreU)
15
+ #
16
+ # PreX.x # => "{x}"
17
+ #
18
+ # CREDIT Trans
19
+
20
+ def preextend(aspect)
21
+ aspect.__send__(:include, self)
22
+ extend aspect
23
+ end
24
+
25
+ end
26
+