static int _EstimateParameters(int k, double expected_recall, NeighborhoodHash I, int[] Q, HashSet<int>[] res_array)
{
var recall = 0.0;
var recall_sq = 0.0;
for (int i = 0; i < Q.Length; ++i) {
var res = res_array [i];
double matches = 0;
var approx_res = I.SearchKNN (I.DB [Q[i]], k);
foreach (var p in approx_res) {
if (res.Contains (p.ObjID)) {
++matches;
}
}
// we remove one, the first item is always found
if (i % 10 == 0) {
Console.WriteLine ("estimation step, query matches: {0}", matches);
}
var current_recall = (matches - 1) / (k - 1);
recall += current_recall;
recall_sq += current_recall * current_recall;
}
recall /= Q.Length;
recall_sq /= Q.Length;
var recall_stddev = Math.Sqrt (recall_sq - recall * recall);
Console.WriteLine ("=== expected recall mean: {0}, recall stddev: {1}",
recall, recall_stddev);
if (recall == 0) {
throw new ArgumentException ("A recall zero will produce an infinite number of instances, " +
"please check the basic setup in order to create a valid index");
}
// recall *= (1.0 - recall_stddev);
// Console.WriteLine ("=== CORRECTED recall: {0}", recall);
var num_instances = 1 + (int)(Math.Log (1.0 - expected_recall) / Math.Log(1.0 - recall));
Console.WriteLine ("=== # instances {0}", num_instances);
return num_instances;
}