I have two sorted arrays of float numbers (usually 800-1500 elements), size of the two arrays can be different by +-20-30 %. I am looking for a fast method which pick a correspondent pair of all elements of the smaller array from the elements of the biggest array on the basis of minimal difference.
Currently I am using this
def get_pairs(ary1,ary2)
if ary1.size<ary2.size then
smaller=ary1;bigger=ary2
else
smaller=ary2;bigger=ary1;
end
p=Array.new(smaller.size)
smaller.each_with_index do |z,i|
pair=bigger.min_by{|elem| (elem-z).abs}
p[i]=[z, pair]
end
return p
end
This is the key element of my program, it is called very often and unfortunately it is too slow for me.
The problem with using min_by
is that you have to iterate over every single element of bigger
for each element of smaller
. Try breaking early once you've found the pair with lowest difference.
def get_pairs(a, b)
smaller, bigger = [a, b].map(&:sort).sort_by(&:length)
smaller.map do |x|
lowest_diff = nil
lowest_element = nil
bigger.each_with_index do |y, i|
diff = (x - y).abs
if lowest_diff.nil? || diff < lowest_diff
lowest_diff = diff
lowest_element = y
elsif diff > lowest_diff || y == bigger.last
break [x, lowest_element]
end
end
end
end