Chi-squared distribution
# 20221101 Raku programming solution
use Graphics::PLplot;
sub Γ(\z) { # https://rosettacode.org/wiki/Gamma_function#Raku
constant g = 9;
z < .5 ?? π/ sin(π * z) / Γ(1 - z)
!! sqrt(2*π) * (z + g - 1/2)**(z - 1/2) * exp(-(z + g - 1/2)) *
[+] < 1.000000000000000174663 5716.400188274341379136
-14815.30426768413909044 14291.49277657478554025
-6348.160217641458813289 1301.608286058321874105
-108.1767053514369634679 2.605696505611755827729
-0.7423452510201416151527e-2 0.5384136432509564062961e-7
-0.4023533141268236372067e-8 > Z* 1, |map 1/(z + *), 0..*
}
sub χ2(\x,\k) {x>0 && k>0 ?? (x**(k/2 - 1)*exp(-x/2)/(2**(k/2)*Γ(k / 2))) !! 0}
sub Γ_cdf(\k,\x) { x**k * exp(-x) * sum( ^101 .map: { x** $_ / Γ(k+$_+1) } ) }
sub cdf_χ2(\x,\k) { (x <= 0 or k <= 0) ?? 0.0 !! Γ_cdf(k / 2, x / 2) }
say ' 𝒙 χ² ', [~] (1..5)».&{ "𝒌 = $_" ~ ' ' x 13 };
say '-' x my \width = 93;
for 0..10 -> \x {
say x.fmt('%2d'), [~] (1…5)».&{χ2(x, $_).fmt: " %-.{((width-2) div 5)-4}f"}
}
say "\nχ² 𝒙 cdf for χ² P value (df=3)\n", '-' x 36;
for 2 «**« ^6 -> \p {
my $cdf = cdf_χ2(p, 3).fmt: '%-.10f';
say p.fmt('%2d'), " $cdf ", (1-$cdf).fmt: '%-.10f'
}
my \airport = [ <77 23>, <88 12>, <79 21>, <81 19> ];
my \expected = [ <81.25 18.75> xx 4 ];
my \dtotal = ( (airport »-« expected)»² »/» expected )».List.flat.sum;
say "\nFor the airport data, diff total is ",dtotal,", χ² is ", χ2(dtotal, 3), ", p value ", cdf_χ2(dtotal, 3);
given Graphics::PLplot.new( device => 'png', file-name => 'output.png' ) {
.begin;
.pen-width: 3 ;
.environment: x-range => [-1.0, 10.0], y-range => [-0.1, 0.5], just => 0 ;
.label: x-axis => '', y-axis => '', title => 'Chi-squared distribution' ;
for 0..3 -> \𝒌 {
.color-index0: 1+2*𝒌;
.line: (0, .1 … 10).map: -> \𝒙 { ( 𝒙, χ2( 𝒙, 𝒌 ) )».Num };
.text-viewport: side=>'t', disp=>-𝒌-2, pos=>.5, just=>.5, text=>'k = '~𝒌
} # plplot.sourceforge.net/docbook-manual/plplot-html-5.15.0/plmtex.html
.end
}Output:
Last updated
Was this helpful?