1# -*- perl -*-
2
3# Test that multiplying the weights by a constant does not change results
4
5use strict;
6
7use Test::More tests => 25;
8
9my $epsilon = 1.0e-10;
10my (@x, @y, @weights);
11my $n = 100;
12for (my $i = 0; $i < $n; ++$i) {
13    $x[$i] = $i + 1;
14    $y[$i] = $i ** 0.75;
15    if ($i % 3 == 0) {
16        $weights[$i] = $i;
17    } elsif ($i % 2 == 0) {
18        $weights[$i] = 50;
19    } else {
20        $weights[$i] = $n + 1 - $i;
21    }
22}
23
24eval {
25    use Statistics::LineFit;
26    my $lineFit = Statistics::LineFit->new();
27
28# Test absolute value of results
29    is($lineFit->setData(\@x, \@y, \@weights), 1,
30        'setData1(\@x, \@y, \@weights)');
31    my $rSquared1 = $lineFit->rSquared();
32    cmp_ok(abs($rSquared1 - 0.991788159320494), "<", $epsilon, 'rSquared1()');
33    my $durbinWatson1 = $lineFit->durbinWatson();
34    cmp_ok(abs($durbinWatson1 - 0.0192675216315352), "<", $epsilon,
35        'durbinWatson1()');
36    my @tStatistics1 = $lineFit->tStatistics();
37    cmp_ok(abs($tStatistics1[0] - 18.7895097501605), "<", $epsilon,
38        'tStatistics1[0]');
39    cmp_ok(abs($tStatistics1[1] - 108.793322452779), "<", $epsilon,
40        'tStatistics1[0]');
41    my @varianceOfEstimates1 = $lineFit->varianceOfEstimates();
42    cmp_ok(abs($varianceOfEstimates1[0] - 0.000758134044735196), "<", $epsilon,
43        'varianceOfEstimates1[0]');
44    cmp_ok(abs($varianceOfEstimates1[1] - 1.78672521866159e-07), "<", $epsilon,
45        'varianceOfEstimates1[0]');
46    my $meanSqError1 = $lineFit->meanSqError();
47    cmp_ok(abs($meanSqError1 - 0.603149693112746), "<", $epsilon,
48        'meanSqError1()');
49    my $sigma1 = $lineFit->sigma();
50    cmp_ok(abs($sigma1 - 0.784511867675187), "<", $epsilon, 'sigma1()');
51    my @coefficients1 = $lineFit->coefficients();
52    cmp_ok(abs($coefficients1[0] - 2.9923929074799), "<", $epsilon,
53        'coefficients1[0]');
54    cmp_ok(abs($coefficients1[1] - 0.295653654441678), "<", $epsilon,
55        'coefficients1[1]');
56    my $sumSqErrors1 = 0;
57    my @residuals = $lineFit->residuals();
58    for (my $i = 0; $i < @residuals; ++$i) {
59        $sumSqErrors1 += $residuals[$i] ** 2 * $weights[$i];
60    }
61    cmp_ok(abs($sumSqErrors1 - $lineFit->sumSqErrors()), "<", $epsilon,
62        'sumSqErrors1()');
63
64# Rescale weights and verify the results are the same
65    for (my $i = 0; $i < $n; ++$i) { $weights[$i] *= 1000 }
66    is($lineFit->setData(\@x, \@y, \@weights), 1,
67        'setData2(\@x, \@y, \@weights)');
68    cmp_ok(abs($lineFit->rSquared() - $rSquared1), "<", $epsilon, 'rSquared()');
69    cmp_ok(abs($lineFit->durbinWatson() - $durbinWatson1), "<", $epsilon,
70        'durbinWatson2()');
71    my @tStatistics2 = $lineFit->tStatistics();
72    cmp_ok(abs($tStatistics2[0] - $tStatistics1[0]), "<", $epsilon,
73        'tStatistics2[0]');
74    cmp_ok(abs($tStatistics1[1] - 108.793322452779), "<", $epsilon,
75        'tStatistics2[0]');
76    my @varianceOfEstimates2 = $lineFit->varianceOfEstimates();
77    cmp_ok(abs($varianceOfEstimates2[0] - $varianceOfEstimates1[0]), "<",
78        $epsilon, 'varianceOfEstimates2[0]');
79    cmp_ok(abs($varianceOfEstimates1[1] - 1.78672521866159e-07), "<", $epsilon,
80        'varianceOfEstimates2[0]');
81    cmp_ok(abs($lineFit->meanSqError() - $meanSqError1), "<", $epsilon,
82        'meanSqError2()');
83    cmp_ok(abs($lineFit->sigma() - $sigma1), "<", $epsilon, 'sigma2()');
84    my @coefficients2 = $lineFit->coefficients();
85    cmp_ok(abs($coefficients2[0] - $coefficients1[0]), "<", $epsilon,
86        'coefficients2[0]');
87    cmp_ok(abs($coefficients2[1] - $coefficients1[1]), "<", $epsilon,
88        'coefficients2[1]');
89    my $sumSqErrors2 = 0;
90    @residuals = $lineFit->residuals();
91    for (my $i = 0; $i < @residuals; ++$i) {
92        $sumSqErrors2 += $residuals[$i] ** 2 * $weights[$i];
93    }
94    cmp_ok(abs($sumSqErrors2 - $sumSqErrors1), "<", $epsilon, 'sumSqErrors2()');
95};
96is($@, '', 'eval error trap');
97