#!/usr/bin/perl

use 5.038;

# sample data of two series of wages to detect differences which could qualify as discriminant

# Wilcoxon signed rank method

my $n = 60;
my (@aa, @bb);
for my $i (0..$n-1){
    $aa[$i] = 100*rand();
    $bb[$i] = 100*rand() - (rand()-0.5) *20;
}

# step 1. Calculate the differences
my @d;
$d[$_] = $aa[$_]-$bb[$_] for (0..$n-1);

# step 2. Rank the absolute values of the differences (|Di|) from smallest to largest, assigning an integer rank value (Ri) to each difference
 
my @sd = sort { abs($a) <=> abs($b) } @d;
my %h;
my $c = 0;
for my $i (@sd){            # @sd preserves the sign
    $c++;
    $h{$i}=$c;
}
    
# step 3. Calculate the sum of the ranks for the positive differences (T+) and the negative differences (T-) separately
my ( $sumpos, $sumneg ) = (0,0); 
for my $i (@sd){
    if ($i > 0){
	$sumpos += $h{$i};
    }elsif ($i < 0){
	$sumneg += $h{$i};
    }			
}

# step 4. Use the smaller of T+ and T- as your Wilcoxon signed-rank statistic (W)
my $W = ($sumpos < $sumneg) ? $sumpos : $sumneg;

# step 5. Compare the calculated W with the critical value from the Wilcoxon signed-rank test table, based on your chosen significance level (α) and sample size
say "W=$W\n";
say "Search the critical value for W in the Wilconson signed rank table.";
say "For n=$n and alpha= 0.01, 0.05 or 0.10. If W is higher, the ";
say "hypothesis of significant differences happen.\n";

 for my $alpha (0.10, 0.05, 0.01){
     print "alpha = $alpha\t\t";
     my $cv = int((($n * ($n + 1)) / 2) * (1 - $alpha / 2));
     print "$cv\n";
 }

say "\nAlternatively, search z/2 in a normal table, where z is = ";
my $z = ($W-($n*($n+1)/4)) / sqrt($n*($n+1)*(2*$n+1)/24);
say "z=$z // Remember to use a two tail normal table.";

exit 2;


__END__
  
Es un test no paramétrico. Hay otros test que sí lo so y puede
  ofrecer resultados mejores potencialmente.
  
