title: How to get the right results for Cumulative Match Characteristic (CMC) curve
body: <p>I am using this to base my equation on but it does not seem to work well</p>
  
  <p><a href="https://blog.rankone.io/2018/11/01/face-recognition-dictionary/#cmc" rel="nofollow noreferrer">https://blog.rankone.io/2018/11/01/face-recognition-dictionary/#cmc</a></p>
  
  <p>I have two arrays a query and gallery array with the shape like this</p>
  
  <pre><code>query_array = [filename, feature] 
  gallery_array = [filename, feature]
  </code></pre>
  
  <p>the filename is the image file and the feature is extracted features using resnet50. </p>
  
  <p>The results are like this which does not look right to me.</p>
  
  <pre><code>[0.8, 0.2, 0.2, 0.4, 0.2, 0.2, 0.4, 0.4, 0.0, 0.6, 0.2, 0.0, 0.4, 0.4, 0.0, 0.4, 0.0, 0.0, 0.0, 0.6, 0.0, 0.0, 0.0, 0.2, 0.0, 0.0, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.2, 0.0, 0.2, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
  </code></pre>
  
  <p>I would think that it would get closer to 100% as the rank increased. 1->10 but it does not. </p>
  
  <p>Here is my code for this </p>
  
  <pre><code># Gallery is a array[image, feature]
  # query is a array[image, feature]
  def find_cmc(query, gallery):
      print("Calculating CMC")
       # Create rank array to see where a person is positivly id
  
      correct = np.zeros(len(gallery))
      total_at_i = np.zeros(len(gallery))
      total_compared = 0
  
      for query_id, query_feature in query:
          # total number of images in the gallery
          dist = []
          # Cacluate the distance between query and each image in the gallery
          for gallery_img, gallery_feature in gallery:
              # Use eucludean distance
              d = np.linalg.norm(query_feature - gallery_feature)
              # Add to the dist array
              dist.append([gallery_img, d])
  
          # Sort the array by smallest to larget distance [1] index
          dist.sort(key=custom_sort)
  
          # Now check to see where the positive images are found
          for i in range(0,len(dist)):
              total_compared +=1
              total_at_i[i] += 1
              name,_,_ = get_info(dist[i][0])
              if name == query_id:
                  # Increase rank by 1 as there is a match
                  correct[i] +=1
      # Get the percentage for each rank@i
      ret_cmc = []
      for i in range(0,len(correct)):
          percent = correct[i]/total_at_i[i]
          ret_cmc.append(percent)
  
      return ret_cmc
  </code></pre>
  
  <h2>Edit</h2>
  
  <p>I have been playing around with the summation and I still can get it right as I would think it should be</p>
  
  <pre><code># Get the percentage for each rank@i
  ret_cmc = []
  correct_sum = 0
  for i in range(0,len(correct)):
      correct_sum += correct[i]
      #percent = correct_sum/total_compared
      percent = correct_sum/total_at_i[i]
      #percent = correct[i]/total_at_i[i]
      ret_cmc.append(percent)
  
  return ret_cmc
  </code></pre>
  
  <h2>Edit</h2>
  
  <p>I think I figured this out; would someone give me their opinion on this, as it seems to be working just fine.</p>
  
  <p>Newest code for this</p>
  
  <pre><code>def cmc(querys, gallery, topk):
      ret = np.zeros(topk)
      valid_queries = 0
      all_rank = []
      sum_rank = np.zeros(topk)
      for query in querys:
          q_id = query[0]
          q_feature = query[1]
          # Calculate the distances for each query
          distmat = []
          for img, feature in gallery:
              # Get the label from the image
              name,_,_ = get_info(img)
              dist = np.linalg.norm(q_feature - feature)
              distmat.append([name, dist, img])
  
          # Sort the results for each query
          distmat.sort(key=custom_sort)
          # Find matches
          matches = np.zeros(len(distmat))
          # Zero if no match 1 if match
          for i in range(0, len(distmat)):
              if distmat[i][0] == q_id:
                  # Match found
                  matches[i] = 1
          rank = np.zeros(topk)
          for i in range(0, topk):
              if matches[i] == 1:
                  rank[i] = 1
                  # If 1 is found then break as you dont need to look further path k
                  break
          all_rank.append(rank)
          valid_queries +=1
      #print(all_rank)
      sum_all_ranks = np.zeros(len(all_rank[0]))
      for i in range(0,len(all_rank)):
          my_array = all_rank[i]
          for g in range(0, len(my_array)):
              sum_all_ranks[g] = sum_all_ranks[g] + my_array[g]
      sum_all_ranks = np.array(sum_all_ranks)
      print("NPSAR", sum_all_ranks)
      cmc_restuls = np.cumsum(sum_all_ranks) / valid_queries
      print(cmc_restuls)
      return cmc_restuls
  </code></pre>