I have got one array with milions of floating points number (ordered) and then another one smaller and i need to match the numbers within a certain tolerance (there is no overlap between the values in the big array and the values in the small array) from the small array in the big array. okay so no big deal, this is the perl function for returning a not perfect match within the tolerance, it's inside a for loop there I am looping through the small array values.
sub bin_search{
my ($arr, $v, $t ) = @_;
my ($min, $max) = (0, @$arr-1);
while ($min <= $max) {
my $w = $v + $t;
my $k = $v - $t;
my $try = int( ( $min + $max ) / 2 );
$min = $try + 1, next if $arr -> [$try] < $k ;
$max = $try - 1, next if $arr -> [$try] > $w ;
return $arr -> [$try] ;
}
return 0;
}
but then after checkin my data it seems I have got some values discarded because it is returning just the first match. I tried grep but it is too slow.
my $min = $val - $t;
my $max = $val + $t;
my @arr2 = grep { ( $_ > $min ) && ($_ < $max ) }@big_arr1;
so I wanted to modify a bit the binary search for returning a range from $min to $max, because I thought once there is one match is either at $min or $max, so something like
sub bin_search{
my ($arr, $v, $t ) = @_;
my ($min, $max) = (0, @$arr-1);
my $w = $v + $t;
my $k = $v - $t;
while ($min <= $max) {
my $try = int( ( $min + $max ) / 2 );
$min = $try + 1, next if $arr -> [$try] < $k ;
$max = $try - 1, next if $arr -> [$try] > $w ;
last;
}
my @fin;
if ( ($arr -> [$try] < $w) && ($arr -> [$try] > $k) ) {
push @fin, $arr ->[$try]; $try++ }
return \@fin;
}
but I am missing some values, and I think that I am missing something, should I look just at one direction at the time? like left until we reach the lower limit then return to $try and do the same thing until higher limit?
push @finat most once.