Others have noted that perl does not guarantee the order of hash elements. There is, though a simpler way to get what you want, without changing your data structures: use hash slices to extract the values from the hash, instead of using the
values function.
e.g:
my @keys = keys %{$database[0]}; #optionally use sort keys
my $pdl1 = pdl (@{$database[0]}{@keys});
my $n1 = norm $pdl1;
my ($pdl2, $n2, $dotproduct, $d, @angles);
for (0..$3database) {
$pdl2 = pdl ((@{$database[$_]}{@keys});
$n2 = norm $pdl2;
$dotproduct = inner ($n1, $n2);
$d = dotproduct->sclr();
$angles[$_] = (180/3.1415926)*acos($d);
}
A hash slice allows you to extract many elements of a hash at a time, returning an array, in the order of the array you passed in. By passing the same keys array to each hash, you guarantee they will come out in the same order. If you want to force the order, you can sort the
@keys array however you deem appropriate...
The syntax of hash slices is a little tricky, especially when dealing with references, but you can piece it apart, or what I did is "build it up" from first principles, starting from
@hash{@keys} and going from there to
@$hashref{@keys} to
@{$arrayofhashrefs[$arrayindex]}{@keys}.
Slices (of both hashes an arrays) can give incredible expressive power. They also are more efficient than looping yourself, since the looping is done in compiled C by the perl engine, rather than in interpreted code...
Hope this helps.
--JAS