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,6 @@
1
+ dir, base = *File.split(__FILE__)
2
+ base = base.chomp('.rb')
3
+ Dir[File.join(dir, base, '*')].each do |lib|
4
+ require "facets/#{base}/#{File.basename(lib)}"
5
+ end
6
+
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Absolute value of +x+.
4
+ def self.abs(x)
5
+ x.abs
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Arcus cotangens of +x+
4
+ def self.acot(x)
5
+ (PI * 0.5) - atan(x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Area cotangens hyperbolicus of +x+
4
+ def self.acoth(x)
5
+ 0.5 * log((x + 1.0) / (x - 1.0))
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Arcus cosecans of +x+
4
+ def self.acsc(x)
5
+ asin(1.0 / x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Area cosecans hyperbolicus of +x+
4
+ def acsch(x)
5
+ ::Math.log(1.0 / x + Math.sqrt(1.0 + 1.0 / (x * x)))
6
+ end
7
+
8
+ end
@@ -0,0 +1,17 @@
1
+ require 'facets/math/rmd'
2
+ require 'facets/math/mean'
3
+
4
+ module Math
5
+
6
+ # The average absolute difference of two independent values drawn
7
+ # from the sample. Equal to the RMD * mean.
8
+ def self.amd(array)
9
+ rmd(array) * mean(array)
10
+ end
11
+
12
+ class << self
13
+ alias_method :absolute_mean_difference, :amd
14
+ #alias_method :md, :mean_difference
15
+ end
16
+
17
+ end
@@ -0,0 +1,15 @@
1
+ module Math
2
+
3
+ #
4
+ EPSILON = 0.000000001
5
+
6
+ # Approximately equal.
7
+ #
8
+ # TODO: Use core extension Numeric#approx? instead.
9
+ def self.approx_equal(a, b, epsilon=EPSILON)
10
+ c = a - b
11
+ c *= -1.0 if c < 0
12
+ c < epsilon
13
+ end
14
+
15
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Arcus secans of +x+
4
+ def self.asec(x)
5
+ acos(1.0 / x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Area secans hyperbolicus of +x+
4
+ def asech(x)
5
+ log((1.0 + sqrt(1.0 - x * x)) / x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,16 @@
1
+ require 'facets/math/theil_index'
2
+
3
+ module Math
4
+
5
+ # Closely related to the Theil index and easily expressible
6
+ # in terms of it.
7
+ #
8
+ # AI = 1-e^{theil_index}
9
+ #
10
+ # http://en.wikipedia.org/wiki/Atkinson_index
11
+ def self.atkinson_index(array)
12
+ t = theil_index(array)
13
+ (t < 0) ? -1 : 1-Math::E**(-t)
14
+ end
15
+
16
+ end
@@ -0,0 +1,9 @@
1
+ module Math
2
+
3
+ # Beta function of +x+ and +y+ - <code>beta(+x+, +y+) =
4
+ # tgamma(+x+) * tgamma(+y+) / tgamma(+x+ + +y+)</code>
5
+ def self.beta(x, y)
6
+ exp(lgamma(x) + lgamma(y) - lgamma(x+y))
7
+ end
8
+
9
+ end
@@ -0,0 +1,10 @@
1
+ module Math
2
+
3
+ # Returns the Cumulative Density Function of this
4
+ # sample (normalised to a fraction of 1.0).
5
+ def self.cdf(array, normalised=1.0)
6
+ s = sum(array).to_f
7
+ array.sort.inject([0.0]) { |c,d| c << c[-1] + normalised*d.to_f/s }
8
+ end
9
+
10
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Smallest integer not smaller than +x+.
4
+ def self.ceil(x)
5
+ x.ceil
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Cotangens of +x+
4
+ def self.cot(x)
5
+ tan((PI * 0.5) - x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Cotangens hyperbolicus of +x+
4
+ def self.coth(x)
5
+ 1.0 / tanh(x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Cosecans of +x+
4
+ def self.csc(x)
5
+ 1.0 / sin(x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Cosecans hyperbolicus of +x+
4
+ def self.csch(x)
5
+ 1.0 / sinh(x)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Kronecker symbol of +i+ and +j+ - 1 if +i+ and +j+ are equal, 0 otherwise.
4
+ def self.delta(i, j)
5
+ return Integer(i) == Integer(j) ? 1 : 0
6
+ end
7
+
8
+ end
@@ -0,0 +1,21 @@
1
+ module Math
2
+
3
+ # Levi-Civita symbol of +i+, +j+, and +k+ - 1 if (+i+, +j+, +k+)
4
+ # is (1, 2, 3), (2, 3, 1), or (3, 1, 2), -1 if it is (1, 3, 2),
5
+ # (2, 1, 3), or (3, 2, 1), 0 as long as +i+, +j+, and +k+ are
6
+ # all elements of {1, 2, 3}, otherwise returns <code>nil</code>.
7
+ def self.epsilon(i, j, k)
8
+ i = Integer(i)
9
+ return nil if i < 1 or i > 3
10
+ j = Integer(j)
11
+ return nil if j < 1 or j > 3
12
+ k = Integer(k)
13
+ return nil if k < 1 or k > 3
14
+ case i * 16 + j * 4 + k
15
+ when 27, 45, 54 then return 1
16
+ when 30, 39, 57 then return -1
17
+ end
18
+ 0
19
+ end
20
+
21
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # 10 to the power +x+
4
+ def self.exp10(x)
5
+ 10.0 ** x
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # 2 to the power +x+
4
+ def self.exp2(x)
5
+ 2.0 ** x
6
+ end
7
+
8
+ end
@@ -0,0 +1,37 @@
1
+ module Math
2
+
3
+ # First 16 factorials.
4
+ FACTORIALS = [
5
+ 1,
6
+ 1,
7
+ 2,
8
+ 6,
9
+ 24,
10
+ 120,
11
+ 720,
12
+ 5_040,
13
+ 40_320,
14
+ 362_880,
15
+ 3_628_800,
16
+ 39_916_800,
17
+ 479_001_600,
18
+ 6_227_020_800,
19
+ 87_178_291_200,
20
+ 1_307_674_368_000
21
+ ]
22
+
23
+ # 1 * 2 * ... * +n+, <code>nil</code> for negative numbers
24
+ def self.factorial(n)
25
+ n = Integer(n)
26
+ if n < 0
27
+ nil
28
+ elsif FACTORIALS.length > n
29
+ FACTORIALS[n]
30
+ else
31
+ h = FACTORIALS.last
32
+ (FACTORIALS.length .. n).each { |i| FACTORIALS.push h *= i }
33
+ h
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,8 @@
1
+ module Math
2
+
3
+ # Largest integer not larger than +x+.
4
+ def self.floor(x)
5
+ x.floor
6
+ end
7
+
8
+ end
@@ -0,0 +1,12 @@
1
+ require 'facets/math/lgamma'
2
+
3
+ module Math
4
+
5
+ unless defined?(gamma)
6
+ #
7
+ def self.gamma(x)
8
+ exp(lgamma(x))
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,23 @@
1
+ module Math
2
+
3
+ # Greatest common divisor of +m+ and +n+, +nil+ for non-positive
4
+ # numbers - gcd is computed by means of the Euclidian algorithm.
5
+ def self.gcd(m, n)
6
+ m = Integer(m)
7
+ n = Integer(n)
8
+ if m <= 0 || n <= 0
9
+ return nil
10
+ end
11
+ loop {
12
+ if m < n
13
+ m, n = n, m
14
+ end
15
+ if (l = m % n) == 0
16
+ break
17
+ end
18
+ m = l
19
+ }
20
+ n
21
+ end
22
+
23
+ end
@@ -0,0 +1,33 @@
1
+ require 'facets/math/approx_equal'
2
+
3
+ module Math
4
+
5
+ # Calculates the Gini Coefficient (a measure of inequality of a distribution
6
+ # based on the area between the Lorenz curve and the uniform curve).
7
+ #
8
+ # http://en.wikipedia.org/wiki/Gini_coefficient
9
+ #
10
+ # This is a slightly cleaner way of calculating the Gini Coefficient then
11
+ # the previous implementationj.
12
+ #
13
+ # GC = \frac{\sum_{i=1}^N (2i-N-1)x_i}{N^2-\bar{x}}
14
+ #
15
+ def self.gini_coefficient(array)
16
+ return -1 if size <= 0 or any? { |x| x < 0 }
17
+ return 0 if size < 2 or all? { |x| approx_equal(x,0) }
18
+ s = 0
19
+ sort.each_with_index { |li,i| s += (2*i+1-size)*li }
20
+ s.to_f/(size**2*mean).to_f
21
+ end
22
+
23
+ ## OLD WAY
24
+ ## GC = \frac{1}{N} \left ( N+1-2\frac{\sum_{i=1}^N (N+1-i)y_i}{\sum_{i=1}^N y_i} \right )
25
+ ## def self.gini_coefficient2(array)
26
+ ## return -1 if size <= 0 or any? { |x| x < 0 }
27
+ ## return 0 if size < 2 or all? { |x| Math::float_equal(x,0) }
28
+ ## s = 0
29
+ ## sort.each_with_index { |yi,i| s += (size - i)*yi }
30
+ ## (size+1-2*(s.to_f/sum.to_f)).to_f/size.to_f
31
+ ## end
32
+
33
+ end
@@ -0,0 +1,19 @@
1
+ module Math
2
+
3
+ # The Kullback-Leibler divergence from this array to that of +q+.
4
+ #
5
+ # NB: You will possibly want to sort both P and Q before calling this
6
+ # depending on what you're actually trying to measure.
7
+ #
8
+ # http://en.wikipedia.org/wiki/Kullback-Leibler_divergence
9
+ #
10
+ def self.kldivergence(array, q)
11
+ fail "Buggy."
12
+ fail "Cannot compare differently sized arrays." unless size = q.size
13
+ kld = 0
14
+ each_with_index { |pi,i| kld += pi*Math::log(pi.to_f/q[i].to_f) }
15
+ kld
16
+ end
17
+
18
+ end
19
+
@@ -0,0 +1,15 @@
1
+ module Math
2
+
3
+ # Least common multiple of +m+ and +n+, computed by multiplying
4
+ # +m+ and +n+ and dividing the product by the gcd of +m+ and +n+,
5
+ # +nil+ for non-positive numbers.
6
+ def self.lcm(m, n)
7
+ m = Integer(m)
8
+ n = Integer(n)
9
+ if m <= 0 || n <= 0
10
+ return nil
11
+ end
12
+ m / gcd(m, n) * n
13
+ end
14
+
15
+ end
@@ -0,0 +1,21 @@
1
+ module Math
2
+
3
+ unless defined?(lgamma)
4
+
5
+ # Logarithmus naturalis of gamma function of +x+
6
+ def self.lgamma(x)
7
+ h = x + 5.5
8
+ h -= (x + 0.5) * log(h)
9
+ sum = 1.000_000_000_190_015
10
+ sum += 76.180_091_729_471_46 / (x + 1.0)
11
+ sum -= 86.505_320_329_416_77 / (x + 2.0)
12
+ sum += 24.014_098_240_830_91 / (x + 3.0)
13
+ sum -= 1.231_739_572_450_155 / (x + 4.0)
14
+ sum += 0.120_865_097_386_617_9e-2 / (x + 5.0)
15
+ sum -= 0.539_523_938_495_3e-5 / (x + 6.0)
16
+ -h + log(2.506_628_274_631_000_5 * sum / x)
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,10 @@
1
+ module Math
2
+
3
+ # Returns real solution(s) of <code>+a+x + +b+ = +c+</code> or +nil+
4
+ # if no or an infinite number of solutions exist. If
5
+ # <code>c</code> is missing it is assumed to be 0.
6
+ def self.linsolve(a, b, c = 0.0)
7
+ a == 0 ? nil : (c - b) / a
8
+ end
9
+
10
+ end