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;