| 1 | #!/usr/local/bin/webwork-perl |
1 | #!/usr/local/bin/webwork-perl |
| 2 | |
2 | |
| 3 | sub _PGstatisticsmacros_init { |
3 | sub _PGstatisticsmacros_init { |
| 4 | foreach my $t (@Distributions::EXPORT_OK) { |
4 | foreach my $t (@Distributions::EXPORT_OK) { |
| 5 | *{$t} = *{"Distributions::$t"} |
5 | *{$t} = *{"Distributions::$t"} |
| 6 | } |
6 | } |
| 7 | foreach my $t (@Regression::EXPORT_OK) { |
7 | foreach my $t (@Regression::EXPORT_OK) { |
| 8 | *{$t} = *{"Regression::$t"} |
8 | *{$t} = *{"Regression::$t"} |
| … | |
… | |
| 11 | |
11 | |
| 12 | =head1 Statistics Macros |
12 | =head1 Statistics Macros |
| 13 | |
13 | |
| 14 | =head3 Normal distribution |
14 | =head3 Normal distribution |
| 15 | |
15 | |
| 16 | =pod |
16 | =pod |
| 17 | |
17 | |
| 18 | Usage: normal_prob(a, b, mean=>0, deviation=>1); |
18 | Usage: normal_prob(a, b, mean=>0, deviation=>1); |
| 19 | |
19 | |
| 20 | Computes the probability of x being in the interval (a,b) for normal distribution. |
20 | Computes the probability of x being in the interval (a,b) for normal distribution. |
| 21 | The first two arguments are required. Use '-infty' for negative infinity, and 'infty' or '+infty' for positive infinity. |
21 | The first two arguments are required. Use '-infty' for negative infinity, and 'infty' or '+infty' for positive infinity. |
| 22 | The mean and deviation are optional, and are 0 and 1 respectively by default. |
22 | The mean and deviation are optional, and are 0 and 1 respectively by default. |
| 23 | Load PGnumericalmacros.pl in your problem if you use this method. |
23 | Load PGnumericalmacros.pl in your problem if you use this method. |
| 24 | |
24 | |
| 25 | =cut |
25 | =cut |
| 26 | |
26 | |
| 27 | sub normal_prob { |
27 | sub normal_prob { |
| 28 | warn 'You must also load PGnumericalmacros to use PGstatisticsmacros' unless defined(&_PGnumericalmacros_init); |
28 | warn 'You must also load PGnumericalmacros to use PGstatisticsmacros' unless defined(&_PGnumericalmacros_init); |
| 29 | |
29 | |
| 30 | my $a = shift; |
30 | my $a = shift; |
| 31 | my $b = shift; |
31 | my $b = shift; |
| 32 | my %options=@_; |
32 | my %options=@_; |
| 33 | |
33 | |
| 34 | my $mean = $options{'mean'} if defined ($options{'mean'}); |
34 | my $mean = $options{'mean'} if defined ($options{'mean'}); |
| 35 | $mean = 0 unless defined $mean; |
35 | $mean = 0 unless defined $mean; |
| 36 | |
36 | |
| 37 | my $deviation = $options{'deviation'} if defined ($options{'deviation'}); |
37 | my $deviation = $options{'deviation'} if defined ($options{'deviation'}); |
| 38 | $deviation = 1 unless defined $deviation; |
38 | $deviation = 1 unless defined $deviation; |
| 39 | |
39 | |
| 40 | if ($deviation <= 0) { |
40 | if ($deviation <= 0) { |
| 41 | warn 'Deviation must be a positive number.'; |
41 | warn 'Deviation must be a positive number.'; |
| 42 | return; |
42 | return; |
| 43 | } |
43 | } |
| 44 | |
44 | |
| 45 | my $z_score_of_a; |
45 | my $z_score_of_a; |
| 46 | my $z_score_of_b; |
46 | my $z_score_of_b; |
| 47 | |
47 | |
| 48 | if ( $a eq '-infty' ) { |
48 | if ( $a eq '-infty' ) { |
| 49 | $z_score_of_a = -6; |
49 | $z_score_of_a = -6; |
| 50 | } else { |
50 | } else { |
| 51 | $z_score_of_a = ($a - $mean)/$deviation; |
51 | $z_score_of_a = ($a - $mean)/$deviation; |
| 52 | } |
52 | } |
| 53 | |
53 | |
| 54 | if (($b eq 'infty') or ($b eq '+infty')) { |
54 | if (($b eq 'infty') or ($b eq '+infty')) { |
| 55 | $z_score_of_b = 6; |
55 | $z_score_of_b = 6; |
| 56 | } else { |
56 | } else { |
| 57 | $z_score_of_b = ($b - $mean)/$deviation; |
57 | $z_score_of_b = ($b - $mean)/$deviation; |
| 58 | } |
58 | } |
| 59 | |
59 | |
| 60 | my $function = sub { my $x=shift; |
60 | my $function = sub { my $x=shift; |
| 61 | $E**(-$x**2/2)/sqrt(2*$PI); |
61 | $E**(-$x**2/2)/sqrt(2*$PI); |
| 62 | }; |
62 | }; |
| 63 | |
63 | |
| 64 | my $prob = romberg($function, $z_score_of_a, $z_score_of_b, 8); |
64 | my $prob = romberg($function, $z_score_of_a, $z_score_of_b, level => 8); |
| 65 | $prob; |
65 | $prob; |
| 66 | } |
66 | } |
| 67 | |
67 | |
| 68 | =head3 "Inverse" of normal distribution |
68 | =head3 "Inverse" of normal distribution |
| 69 | |
69 | |
| 70 | =pod |
70 | =pod |
| 71 | |
71 | |
| 72 | Usage: normal_distr(prob, mean=>0, deviation=>1); |
72 | Usage: normal_distr(prob, mean=>0, deviation=>1); |
| 73 | |
73 | |
| 74 | Computes the positive number b such that the probability of x being in the interval (0,b) |
74 | Computes the positive number b such that the probability of x being in the interval (0,b) |
| 75 | is equal to the given probability (first argument). The mean and deviation are |
75 | is equal to the given probability (first argument). The mean and deviation are |
| 76 | optional, and are 0 and 1 respectively by default. |
76 | optional, and are 0 and 1 respectively by default. |
| 77 | Caution: since students may use tables, they may only be able to provide the answer correct to 2 or 3 |
77 | Caution: since students may use tables, they may only be able to provide the answer correct to 2 or 3 |
| 78 | decimal places. Use tolerance when evaluating answers. |
78 | decimal places. Use tolerance when evaluating answers. |
| 79 | Load PGnumericalmacros.pl if you use this method. |
79 | Load PGnumericalmacros.pl if you use this method. |
| 80 | |
80 | |
| 81 | =cut |
81 | =cut |
| 82 | |
82 | |
| 83 | sub normal_distr { |
83 | sub normal_distr { |
| 84 | warn 'You must also load PGnumericalmacros to use PGstatisticsmacros' unless defined(&_PGnumericalmacros_init); |
84 | warn 'You must also load PGnumericalmacros to use PGstatisticsmacros' unless defined(&_PGnumericalmacros_init); |
| 85 | |
85 | |
| 86 | my $prob = shift; |
86 | my $prob = shift; |
| 87 | my %options=@_; |
87 | my %options=@_; |
| 88 | |
88 | |
| 89 | my $mean = $options{'mean'} if defined ($options{'mean'}); |
89 | my $mean = $options{'mean'} if defined ($options{'mean'}); |
| 90 | $mean = 0 unless defined $mean; |
90 | $mean = 0 unless defined $mean; |
| 91 | |
91 | |
| 92 | my $deviation = $options{'deviation'} if defined ($options{'deviation'}); |
92 | my $deviation = $options{'deviation'} if defined ($options{'deviation'}); |
| 93 | $deviation = 1 unless defined $deviation; |
93 | $deviation = 1 unless defined $deviation; |
| 94 | |
94 | |
| 95 | if ($deviation <= 0) { |
95 | if ($deviation <= 0) { |
| 96 | warn 'Deviation must be a positive number.'; |
96 | warn 'Deviation must be a positive number.'; |
| … | |
… | |
| 103 | |
103 | |
| 104 | my $z_score_of_b = inv_romberg($function, 0, $prob); |
104 | my $z_score_of_b = inv_romberg($function, 0, $prob); |
| 105 | |
105 | |
| 106 | my $b = $z_score_of_b * $deviation + $mean; |
106 | my $b = $z_score_of_b * $deviation + $mean; |
| 107 | $b; |
107 | $b; |
| 108 | } |
108 | } |
| 109 | |
109 | |
| 110 | ########################################## |
110 | ########################################## |
| 111 | |
111 | |
| 112 | 1; |
112 | 1; |
| 113 | |
113 | |