v1 * w1 + v2 * w2 + v3 * w3 + ... + vn * wn
####
V * W
--------- = cos ( theta )
|V| * |W|
or
VV = V / |V|; WW = W / |W|
VV * WW VV * WW
----------- = ------- = cos( theta )
|VV| * |WW| 1 * 1
##
##
$v = [ 1, 4, 7, 10, 13, 16, 19, 22 ];
$w = [ 1, 2, 4, 8, 16 ];
sub dot_prod {
# report error unless args exist and are references to arrays
return unless ( (2 = @_ ) &&
(ref $_[0] eq "ARRAY") &&
(ref $_[1] eq "ARRAY") );
# if either array is empty, the dot product is zero.
return 0 unless ( @{$_[0]} && @{$_[1]} );
my @v = @{$_[0]};
my @w = @{$_[1]};
my $result = 0;
my ( $v, $w ) = ( shift @v, shift @w );
do {
if ( $v == $w ) {
$v = shift @v;
$w = shift @w;
$result++;
} elsif ( $v > $w ) {
$w = shift @w;
} elsif ( $v < $w ) {
$v = shift @v;
}
} while ( @v && @w );
return $result;
}
sub norm {
return 0 unless ( @_ && ( ref $_[0] eq "ARRAY ) )
return sqrt( @{$_[0]} );
}
my $dot_product = dot_prod( $v, $w ) or die( "dot_prod error" );;
my $denom = (norm( $v ) * norm( $w );
my $cos_theta = $denom ? $dot_product / $denom : 0;