2
package Statistics::Basic::Covariance;
11
'""' => sub { my $v = $_[0]->query; $Statistics::Basic::fmt->format_number("$v", $ENV{IPRES}) },
12
'0+' => sub { $_[0]->query },
13
( exists($ENV{TOLER}) ? ('==' => sub { abs($_[0]-$_[1])<=$ENV{TOLER} }) : () ),
14
'eq' => sub { "$_[0]" eq "$_[1]" },
15
fallback => 1; # tries to do what it would have done if this wasn't present.
22
my $v1 = eval { Statistics::Basic::Vector->new( $_[0] ) }; croak $@ if $@;
23
my $v2 = eval { Statistics::Basic::Vector->new( $_[1] ) }; croak $@ if $@;
25
if( my $c = $v1->get_linked_computer( covariance => $v2 ) ) {
26
warn "[linked covariance v1:$v1 v2:$v2]\n" if $ENV{DEBUG} >= 2;
30
my $this = bless {v1=>$v1, v2=>$v2}, $class;
31
warn "[new covariance v1:$this->{v1} v2:$this->{v2}]\n" if $ENV{DEBUG} >= 2;
33
$this->{m1} = eval { Statistics::Basic::Mean->new($v1) }; croak $@ if $@;
34
$this->{m2} = eval { Statistics::Basic::Mean->new($v2) }; croak $@ if $@;
36
$v1->set_linked_computer( covariance => $this, $v2 );
37
$v2->set_linked_computer( covariance => $this, $v1 );
46
my $c1 = $this->{v1}->size;
47
my $c2 = $this->{v2}->size;
49
warn "[recalc covariance] (\$c1, \$c2) = ($c1, $c2)\n" if $ENV{DEBUG};
51
confess "the two vectors in a Covariance object must be the same length ($c2!=$c1)" unless $c2 == $c1;
53
my $cardinality = $c1;
54
$cardinality -- if $ENV{UNBIAS};
56
delete $this->{recalc_necessary};
57
delete $this->{covariance};
58
return unless $cardinality > 0;
60
my $v1 = $this->{v1}->query;
61
my $v2 = $this->{v2}->query;
63
my $m1 = $this->{m1}->query;
64
my $m2 = $this->{m2}->query;
66
if( $ENV{DEBUG} >= 2 ) {
67
for my $i (0 .. $#$v1) {
68
warn "[recalc covariance] ( $v1->[$i] - $m1 ) * ( $v2->[$i] - $m2 )\n";
72
for my $i (0 .. $#$v1) {
73
$sum += ( $v1->[$i] - $m1 ) * ( $v2->[$i] - $m2 );
76
$this->{covariance} = ($sum / $cardinality);
78
warn "[recalc covariance] ($sum/$cardinality) = $this->{covariance}\n" if $ENV{DEBUG};
84
$this->{recalc_needed} = 1;
86
warn "[recalc_needed covariance]\n" if $ENV{DEBUG};
93
$this->recalc if $this->{recalc_needed};
95
warn "[query covariance $this->{covariance}]\n" if $ENV{DEBUG};
97
return $this->{covariance};
133
return ($this->{v2}->size, $this->{v1}->size); # only v1->size is returned in scalar context
141
eval { $this->{v1}->set_size( $size );
142
$this->{v2}->set_size( $size ); }; croak $@ if $@;
149
warn "[insert covariance]\n" if $ENV{DEBUG};
151
croak "this insert() takes precisely two arguments. They can be arrayrefs if you like." unless 2 == int @_;
153
$this->{v1}->insert( $_[0] );
154
$this->{v2}->insert( $_[1] );
161
warn "[ginsert covariance]\n" if $ENV{DEBUG};
163
croak "this ginsert() takes precisely two arguments. They can be arrayrefs if you like."
166
my ($v1, $v2) = (@$this{'v1', 'v2'});
168
$v1->ginsert( $_[0] );
169
$v2->ginsert( $_[1] );
175
croak "The two vectors in a Covariance object must be the same length ($c1!=$c2)."
184
warn "[set_vector covariance]\n" if $ENV{DEBUG};
186
croak "this set_vector() takes precisely two arguments. They can be arrayrefs if you like."
189
my ($v1, $v2) = (@$this{'v1', 'v2'});
191
$v1->set_vector( $_[0] );
192
$v2->set_vector( $_[1] );
197
confess "The two vectors in a Covariance object must be the same length ($c1!=$c2)."