class Population
{
has @.population;
method BUILD() {
.population = <>;
}
method add($x) {
push(.population, $x);
}
}
####
use Population;
class DistributionPopulation is Population
{
method BUILD() {
}
method Expectance() {
my $e = 0.0;
for .population -> $p {
$e += $p;
}
return $e / .population.length;
}
method Variance () {
my $e = .Expectance();
my $var = 0.0;
for .population -> $p {
$var += ($p - $e) * ($p - $e);
}
return $var / (.population.length - 1);
}
}
####
class Covariance {
method Covariance($xpop,$ypop) {
my $ex = $xpop.Expectance();
my $ey = $ypop.Expectance();
my $cov = 0.0;
for $xpop.population, $ypop.population -> $p,$q {
$cov += ($p - $ex) * ($q - $ey);
}
return $cov / $xpop.population.length;
}
}
####
use Covariance;
role ThisCovariance { method cov($xpop,$ypop) {
return Covariance().Covariance($xpop,$ypop);
}
}
class Correlation does ThisCovariance {
method BUILD() {
}
method correlation($xpop,$ypop) { ### These are distribution args
my $varx = $xpop.Variance(), $vary = $ypop.Variance();
my $cov = .cov($xpop, $ypop);
return $cov / (sqrt($varx) * sqrt($vary));
}
}