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,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