code: def range_PR(lims_ref, Iref, lims_new, Inew, mode="overall"):
      """compute the precision and recall of range search results. The
      function does not take the distances into account."""
  
      def ref_result_for(i):
          return Iref[lims_ref[i] : lims_ref[i + 1]]
  
      def new_result_for(i):
          return Inew[lims_new[i] : lims_new[i + 1]]
  
      nq = lims_ref.size - 1
      assert lims_new.size - 1 == nq
  
      ninter = np.zeros(nq, dtype="int64")
  
      def compute_PR_for(q):
          # ground truth results for this query
          gt_ids = ref_result_for(q)
  
          # results for this query
          new_ids = new_result_for(q)
  
          # there are no set functions in numpy so let's do this
          inter = np.intersect1d(gt_ids, new_ids)
  
          ninter[q] = len(inter)
  
      # run in a thread pool, which helps in spite of the GIL
      pool = ThreadPool(20)
      pool.map(compute_PR_for, range(nq))
  
      return counts_to_PR(
          lims_ref[1:] - lims_ref[:-1],
          lims_new[1:] - lims_new[:-1],
          ninter,
          mode=mode,
      )
  
imports: import numpy
  import unittest
  import time
  import faiss
  from multiprocessing.pool import ThreadPool
label_desc: Use image node_id 3 for calling a global function with example usage: range_PR(lims_ref, Iref, lims_new, Inew, mode) and returns: counts_to_PR, Iref, Inew