class_docstr: Abstract class for scoring layer.
docstr: Computes the ranks of triples against their corruptions.
  
  Ranks are computed by corrupting triple subject and/or object with the embeddings in ent_matrix.
  
  Parameters
  -----------
  triples: array-like, shape (n, k)
      Batch of input embeddings.
  ent_matrix: array-like, shape (m, k)
      Slice of embedding matrix (corruptions).
  start_ent_id: int
      Original id of the first row of embedding matrix (used during partitioned approach).
  end_ent_id: int
      Original id of the last row of embedding matrix (used during partitioned approach).
  filters: list of lists
      Size of list is either 1 or 2 depending on ``corrupt_side``.
      Size of the internal list is equal to the size of the input triples.
      Each list contains an array of filters (True Positives) related to the specified side of triples to corrupt.
  corrupt_side: str
      Which side to corrupt during evaluation.
  comparison_type: str
      Indicates how to break ties (default: `worst`, i.e., assigns the worst rank to the test triple).
      One of the three types can be passed: `"best"`, `"middle"`, `"worst"`.
  
  Returns
  --------
  ranks: tf.Tensor, shape (n,2)
      Ranks of triple against subject and object corruptions (corruptions defined by `ent_embs` matrix).
code: def get_ranks(
      self,
      triples,
      ent_matrix,
      start_ent_id,
      end_ent_id,
      filters,
      mapping_dict,
      corrupt_side="s,o",
      comparison_type="worst",
  ):
      """Computes the ranks of triples against their corruptions.
  
      Ranks are computed by corrupting triple subject and/or object with the embeddings in ent_matrix.
  
      Parameters
      -----------
      triples: array-like, shape (n, k)
          Batch of input embeddings.
      ent_matrix: array-like, shape (m, k)
          Slice of embedding matrix (corruptions).
      start_ent_id: int
          Original id of the first row of embedding matrix (used during partitioned approach).
      end_ent_id: int
          Original id of the last row of embedding matrix (used during partitioned approach).
      filters: list of lists
          Size of list is either 1 or 2 depending on ``corrupt_side``.
          Size of the internal list is equal to the size of the input triples.
          Each list contains an array of filters (True Positives) related to the specified side of triples to corrupt.
      corrupt_side: str
          Which side to corrupt during evaluation.
      comparison_type: str
          Indicates how to break ties (default: `worst`, i.e., assigns the worst rank to the test triple).
          One of the three types can be passed: `"best"`, `"middle"`, `"worst"`.
  
      Returns
      --------
      ranks: tf.Tensor, shape (n,2)
          Ranks of triple against subject and object corruptions (corruptions defined by `ent_embs` matrix).
      """
      # compute the score of true positives
      triple_score = self._compute_scores(triples)
  
      # Handle the floating point comparison by multiplying by reqd precision and casting to int
      # before comparing
      triple_score = tf.cast(
          triple_score * COMPARISION_PRECISION, tf.int32
      )
  
      out_ranks = tf.TensorArray(tf.int32, size=0, dynamic_size=True)
      filter_index = 0
      if tf.strings.regex_full_match(corrupt_side, ".*s.*"):
          # compute the score by corrupting the subject side of triples by
          # ent_matrix
          sub_corr_score = self._get_subject_corruption_scores(
              triples, ent_matrix
          )
          # Handle the floating point comparison by multiplying by reqd precision and casting to int
          # before comparing
          sub_corr_score = tf.cast(
              sub_corr_score * COMPARISION_PRECISION, tf.int32
          )
  
          # if pos score: 0.5, corr_score: 0.5, 0.5, 0.3, 0.6, 0.5, 0.5
          if comparison_type == "best":
              # returns: 1 i.e. only. 1 corruption is having score greater
              # than positive (optimistic)
              sub_rank = tf.reduce_sum(
                  tf.cast(
                      tf.expand_dims(triple_score, 1) < sub_corr_score,
                      tf.int32,
                  ),
                  1,
              )
          elif comparison_type == "middle":
              # returns: 3 i.e. 1 + (4/2) i.e. only 1  corruption is having score greater than positive
              # and 4 corruptions are having same (middle rank is 4/2 = 1),
              # so 1+2=3
              sub_rank = tf.reduce_sum(
                  tf.cast(
                      tf.expand_dims(triple_score, 1) < sub_corr_score,
                      tf.int32,
                  ),
                  1,
              )
              part = tf.cast(
                  tf.expand_dims(triple_score, 1) == sub_corr_score,
                  tf.int32,
              )
              sub_rank += tf.cast(
                  tf.math.ceil(tf.reduce_sum(part, 1) / 2), tf.int32
              )
          else:
              # returns: 5 i.e. 5 corruptions are having score >= positive
              # as you can see this strategy returns the worst rank
              # (pessimistic)
  
              # compare True positive score against their respective
              # corruptions and get rank.
              sub_rank = tf.reduce_sum(
                  tf.cast(
                      tf.expand_dims(triple_score, 1) <= sub_corr_score,
                      tf.int32,
                  ),
                  1,
              )
  
          if filters.shape[0] > 0:
              # tf.print(tf.shape(triple_score)[0])
              for i in tf.range(tf.shape(triple_score)[0]):
                  # get the ids of True positives that needs to be filtered
                  filter_ids = filters[filter_index][i]
  
                  if mapping_dict.size() > 0:
                      filter_ids = mapping_dict.lookup(filter_ids)
                      filter_ids = tf.reshape(filter_ids, (-1,))
  
                      filter_ids_selector = tf.math.greater_equal(
                          filter_ids, 0
                      )
                      filter_ids = tf.boolean_mask(
                          filter_ids, filter_ids_selector, axis=0
                      )
  
                  # This is done for partitioning (where the full emb matrix is not used)
                  # this gets only the filter ids of the current partition
                  # being used for generating corruption
                  filter_ids_selector = tf.logical_and(
                      filter_ids >= start_ent_id,
                      filter_ids <= end_ent_id,
                  )
  
                  filter_ids = tf.boolean_mask(
                      filter_ids, filter_ids_selector
                  )
                  # from entity id convert to index in the current partition
                  filter_ids = filter_ids - start_ent_id
  
                  # get the score of the corruptions which are actually True
                  # positives
                  score_filter = tf.gather(
                      tf.squeeze(tf.gather_nd(sub_corr_score, [[i]])),
                      filter_ids,
                  )
                  # check how many of those were ranked higher than the test
                  # triple
                  num_filters_ranked_higher = tf.reduce_sum(
                      tf.cast(
                          tf.gather(triple_score, [i]) <= score_filter,
                          tf.int32,
                      )
                  )
                  # adjust the rank of the test triple accordingly
                  sub_rank = tf.tensor_scatter_nd_sub(
                      sub_rank, [[i]], [num_filters_ranked_higher]
                  )
  
          out_ranks = out_ranks.write(out_ranks.size(), sub_rank)
  
      if tf.strings.regex_full_match(corrupt_side, ".*o.*"):
          # compute the score by corrupting the object side of triples by
          # ent_matrix
          obj_corr_score = self._get_object_corruption_scores(
              triples, ent_matrix
          )
  
          # Handle the floating point comparison by multiplying by reqd precision and casting to int
          # before comparing
          obj_corr_score = tf.cast(
              obj_corr_score * COMPARISION_PRECISION, tf.int32
          )
  
          # if pos score: 0.5, corr_score: 0.5, 0.5, 0.3, 0.6, 0.5, 0.5
          if comparison_type == "best":
              # returns: 1 i.e. only. 1 corruption is having score greater
              # than positive (optimistic)
              obj_rank = tf.reduce_sum(
                  tf.cast(
                      tf.expand_dims(triple_score, 1) < obj_corr_score,
                      tf.int32,
                  ),
                  1,
              )
          elif comparison_type == "middle":
              print("middle")
              # returns: 3 i.e. 1 + (4/2) i.e. only 1  corruption is having score greater than positive
              # and 4 corruptions are having same (middle rank is 4/2 = 1),
              # so 1+2=3
              obj_rank = tf.reduce_sum(
                  tf.cast(
                      tf.expand_dims(triple_score, 1) < obj_corr_score,
                      tf.int32,
                  ),
                  1,
              )
              part = tf.cast(
                  tf.expand_dims(triple_score, 1) == obj_corr_score,
                  tf.int32,
              )
              obj_rank += tf.cast(
                  tf.math.ceil(tf.reduce_sum(part, 1) / 2), tf.int32
              )
          else:
              # returns: 5 i.e. 5 corruptions are having score >= positive
              # as you can see this strategy returns the worst rank
              # (pessimistic)
  
              # compare True positive score against their respective
              # corruptions and get rank.
              obj_rank = tf.reduce_sum(
                  tf.cast(
                      tf.expand_dims(triple_score, 1) <= obj_corr_score,
                      tf.int32,
                  ),
                  1,
              )
  
          if filters.shape[0] > 0:
              for i in tf.range(tf.shape(triple_score)[0]):
                  if (
                      corrupt_side in ["s", "o"]
                      and filters.shape[0] == 1
                  ):
                      filter_index = 0
                  else:
                      filter_index = 1
                  # get the ids of True positives that needs to be filtered
                  filter_ids = filters[filter_index][i]
  
                  if mapping_dict.size() > 0:
                      filter_ids = mapping_dict.lookup(filter_ids)
                      filter_ids = tf.reshape(filter_ids, (-1,))
  
                      filter_ids_selector = tf.math.greater_equal(
                          filter_ids, 0
                      )
                      filter_ids = tf.boolean_mask(
                          filter_ids, filter_ids_selector, axis=0
                      )
  
                  # This is done for patritioning (where the full emb matrix is not used)
                  # this gets only the filter ids of the current partition
                  # being used for generating corruption
                  filter_ids_selector = tf.logical_and(
                      filter_ids >= start_ent_id,
                      filter_ids <= end_ent_id,
                  )
                  filter_ids = tf.boolean_mask(
                      filter_ids, filter_ids_selector
                  )
                  # from entity id convert to index in the current partition
                  filter_ids = filter_ids - start_ent_id
  
                  # get the score of the corruptions which are actually True
                  # positives
                  score_filter = tf.gather(
                      tf.squeeze(tf.gather_nd(obj_corr_score, [[i]])),
                      filter_ids,
                  )
                  # check how many of those were ranked higher than the test
                  # triple
                  num_filters_ranked_higher = tf.reduce_sum(
                      tf.cast(
                          tf.gather(triple_score, [i]) <= score_filter,
                          tf.int32,
                      )
                  )
                  # adjust the rank of the test triple accordingly
                  obj_rank = tf.tensor_scatter_nd_sub(
                      obj_rank, [[i]], [num_filters_ranked_higher]
                  )
  
          out_ranks = out_ranks.write(out_ranks.size(), obj_rank)
  
      out_ranks = out_ranks.stack()
      return out_ranks
  
file_path: AmpliGraph/ampligraph/latent_features/layers/scoring/AbstractScoringLayer.py
imports: import tensorflow
label_desc: Use image node_id 7 for calling the AbstractScoringLayer obj's underlying member method code with example usage: obj.get_ranks(triples, ent_matrix, start_ent_id, end_ent_id, filters, mapping_dict, corrupt_side, comparison_type) and returns: out_ranks