1# encoding: utf-8
2######################################################################
3# This file is imported from the minitest project.
4# DO NOT make modifications in this repo. They _will_ be reverted!
5# File a patch instead and assign it to Ryan Davis.
6######################################################################
7
8require 'minitest/autorun'
9require 'minitest/benchmark'
10
11##
12# Used to verify data:
13# http://www.wolframalpha.com/examples/RegressionAnalysis.html
14
15class TestMiniTestBenchmark < MiniTest::Unit::TestCase
16  def test_cls_bench_exp
17    assert_equal [2, 4, 8, 16, 32], self.class.bench_exp(2, 32, 2)
18  end
19
20  def test_cls_bench_linear
21    assert_equal [2, 4, 6, 8, 10], self.class.bench_linear(2, 10, 2)
22  end
23
24  def test_cls_benchmark_methods
25    assert_equal [], self.class.benchmark_methods
26
27    c = Class.new(MiniTest::Unit::TestCase) do
28      def bench_blah
29      end
30    end
31
32    assert_equal ["bench_blah"], c.benchmark_methods
33  end
34
35  def test_cls_bench_range
36    assert_equal [1, 10, 100, 1_000, 10_000], self.class.bench_range
37  end
38
39  def test_fit_exponential_clean
40    x = [1.0, 2.0, 3.0, 4.0, 5.0]
41    y = x.map { |n| 1.1 * Math.exp(2.1 * n) }
42
43    assert_fit :exponential, x, y, 1.0, 1.1, 2.1
44  end
45
46  def test_fit_exponential_noisy
47    x = [1.0, 1.9, 2.6, 3.4, 5.0]
48    y = [12, 10, 8.2, 6.9, 5.9]
49
50    # verified with Numbers and R
51    assert_fit :exponential, x, y, 0.95, 13.81148, -0.1820
52  end
53
54  def test_fit_constant_clean
55    x = (1..5).to_a
56    y = [5.0, 5.0, 5.0, 5.0, 5.0]
57
58    assert_fit :linear, x, y, nil, 5.0, 0
59  end
60
61  def test_fit_constant_noisy
62    x = (1..5).to_a
63    y = [1.0, 1.2, 1.0, 0.8, 1.0]
64
65    # verified in numbers and R
66    assert_fit :linear, x, y, nil, 1.12, -0.04
67  end
68
69  def test_fit_linear_clean
70    # y = m * x + b where m = 2.2, b = 3.1
71    x = (1..5).to_a
72    y = x.map { |n| 2.2 * n + 3.1 }
73
74    assert_fit :linear, x, y, 1.0, 3.1, 2.2
75  end
76
77  def test_fit_linear_noisy
78    x = [ 60,  61,  62,  63,  65]
79    y = [3.1, 3.6, 3.8, 4.0, 4.1]
80
81    # verified in numbers and R
82    assert_fit :linear, x, y, 0.8315, -7.9635, 0.1878
83  end
84
85  def test_fit_power_clean
86    # y = A x ** B, where B = b and A = e ** a
87    # if, A = 1, B = 2, then
88
89    x = [1.0, 2.0, 3.0, 4.0, 5.0]
90    y = [1.0, 4.0, 9.0, 16.0, 25.0]
91
92    assert_fit :power, x, y, 1.0, 1.0, 2.0
93  end
94
95  def test_fit_power_noisy
96    # from www.engr.uidaho.edu/thompson/courses/ME330/lecture/least_squares.html
97    x = [10, 12, 15, 17, 20, 22, 25, 27, 30, 32, 35]
98    y = [95, 105, 125, 141, 173, 200, 253, 298, 385, 459, 602]
99
100    # verified in numbers
101    assert_fit :power, x, y, 0.90, 2.6217, 1.4556
102
103    # income to % of households below income amount
104    # http://library.wolfram.com/infocenter/Conferences/6461/PowerLaws.nb
105    x = [15000, 25000, 35000, 50000, 75000, 100000]
106    y = [0.154, 0.283, 0.402, 0.55, 0.733, 0.843]
107
108    # verified in numbers
109    assert_fit :power, x, y, 0.96, 3.119e-5, 0.8959
110  end
111
112  def assert_fit msg, x, y, fit, exp_a, exp_b
113    a, b, rr = send "fit_#{msg}", x, y
114
115    assert_operator rr, :>=, fit if fit
116    assert_in_delta exp_a, a
117    assert_in_delta exp_b, b
118  end
119end
120