So, part (all?) of the problem here is that you have an off-by-one error in your array traversal: @weights in scalar context will give you the number of elements in the array, not the last index. Thus you are always falling off the end of your weights array. Change to:
for ( 0..$#weights ) { # ...
You've said that the two arrays have the same number of elements. If they are all defined, always, then you have solved the problem.
If any of them might be undefined (ie. the array is sparse) then you have a different issue, which you probably want to solve the way you supressed the warning above. (or with $weights[$_] ||= 0)