#!/usr/bin/perl -w

use Statistics::Table::F;

$projekty = [[18, 22, 17, 10, 34, 15, 12, 20, 21],
            [21, 34, 18, 18, 20, 22, 17, 19, 14, 10, 21],
            [21, 25, 28, 27, 30, 18, 26, 25, 25, 29],
            [25, 17, 19, 22, 18, 18, 22, 30]];

if (($F = anova($projekty)) >=
        F(@$projekty-1, liczba_elementow($projekty) - @$projekty, 0.05)) {
    print "F rowny $F; roznica miedzy rozkladami jest znaczaca.\n";
} else {
    print "F rowny $F; niewystarczajace dane, aby stwierdzic ich istotnosc.\n";
}

sub srednia {
    my ($element) = @_;
    my $wynik;
    foreach (@$element) { $wynik += $_ }
    return $wynik / @$element;
}

sub wariancja_szacowana {
    my ($element) = @_;
    my ($srednia) = srednia($element);
    my ($wynik);
    foreach (@$element) {
        $wynik += ($_ - $srednia) ** 2;
    }
    return $wynik / $#{$element};
}

sub suma_kwadratow {
    my ($element) = shift;
    my (@tablice) = @$element;
    my ($wynik, $element);
    foreach $element (@tablice) {
        foreach (@$element) { $wynik += $_ ** 2 }
    }
    return $wynik;
}

sub suma {
    my ($element) = shift;
    my (@tablice) = @$element;
    my ($wynik, $element);
    foreach $element (@tablice) {
        foreach (@$element) { $wynik += $_ }
    }
    return $wynik;
}

sub kwadrat_grup {
    my ($element) = shift;
    my (@tablice) = @$element;
    my ($wynik, $element);
    foreach $element (@tablice) {
        my $suma = 0;
        foreach (@$element) { $suma += $_ }
        $wynik += ($suma ** 2) / @$element;
    }
    return $wynik;

sub liczba_elementow {
    my ($element) = shift;
    my $wynik;
    foreach (@$element) { $wynik += @$_ }
    return $wynik;
}

# Procedura anova() wykonuje jednokierunkowa analize wariancji
# zwracajac wspolczynnik F.
sub anova {
    my ($wszystkie) = shift;
    my $liczba_elementow = liczba_elementow($wszystkie);
    my $kwadrat_elementow = suma_kwadratow($wszystkie);
    my $suma_elementow = suma($wszystkie);
    my $suma_grup = kwadrat_grup($wszystkie);
    my $wewnatrzgrupowy_poziom_swobody = $liczba_elementow - @$wszystkie;
    my $miedzygrupowy_poziom_swobody = @$wszystkie - 1;
    my $wewnatrzgrupowy_kwadrat_sum = $kwadrat_elementow - $suma_grup;
    my $wewnatrzgrupowa_srednia_kwadratow = $ wewnatrzgrupowy_kwadrat_sum /
        $wewnatrzgrupowy_poziom_swobody;
    my $miedzygrupowy_kwadrat_sum = $suma_grup -
        ($suma_elementow ** 2)/$liczba_elementow;
    my $miedzygrupowa_srednia_kwadratow = $miedzygrupowy_kwadrat_sum /
        $miedzygrupowy_poziom_swobody;
    return $miedzygrupowa_srednia_kwadratow / $wewnatrzgrupowa_srednia_kwadratow;
}

