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

Sign up to get free protection for your applications and to get access to all the features.
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
+