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)); } }