Predict the rank of selected interactions. Computes recommendation
        rankings across all items for every user in interactions and calculates
        the rank of all non-zero entries in the recommendation ranking, with 0
        meaning the top of the list (most recommended) and n_items - 1 being
        the end of the list (least recommended).

        Performs best when only a handful of interactions need to be evaluated
        per user. If you need to compute predictions for many items for every
        user, use the predict method instead.

        For details on how to use feature matrices, see the documentation
        on the :class:`lightfm.LightFM` class.

        Arguments
        ---------

        test_interactions: np.float32 csr_matrix of shape [n_users, n_items]
             Non-zero entries denote the user-item pairs
             whose rank will be computed.
        train_interactions: np.float32 csr_matrix of shape [n_users, n_items], optional
             Non-zero entries denote the user-item pairs which will be excluded
             from rank computation. Use to exclude training set interactions
             from being scored and ranked for evaluation.
        user_features: np.float32 csr_matrix of shape [n_users, n_user_features], optional
             Each row contains that user's weights over features.
        item_features: np.float32 csr_matrix of shape [n_items, n_item_features], optional
             Each row contains that item's weights over features.
        num_threads: int, optional
             Number of parallel computation threads to use.
             Should not be higher than the number of physical cores.
        check_intersections: bool, optional, True by default,
            Only relevant when train_interactions are supplied.
            A flag that signals whether the test and train matrices should be checked
            for intersections to prevent optimistic ranks / wrong evaluation / bad data split.

        Returns
        -------

        np.float32 csr_matrix of shape [n_users, n_items]
            the [i, j]-th entry of the matrix will contain the rank of the j-th
            item in the sorted recommendations list for the i-th user.
            The degree of sparsity of this matrix will be equal to that of the
            input interactions matrix.

def predict_rank(
        self,
        test_interactions,
        train_interactions=None,
        item_features=None,
        user_features=None,
        num_threads=1,
        check_intersections=True,
    ):
        """
        Predict the rank of selected interactions. Computes recommendation
        rankings across all items for every user in interactions and calculates
        the rank of all non-zero entries in the recommendation ranking, with 0
        meaning the top of the list (most recommended) and n_items - 1 being
        the end of the list (least recommended).

        Performs best when only a handful of interactions need to be evaluated
        per user. If you need to compute predictions for many items for every
        user, use the predict method instead.

        For details on how to use feature matrices, see the documentation
        on the :class:`lightfm.LightFM` class.

        Arguments
        ---------

        test_interactions: np.float32 csr_matrix of shape [n_users, n_items]
             Non-zero entries denote the user-item pairs
             whose rank will be computed.
        train_interactions: np.float32 csr_matrix of shape [n_users, n_items], optional
             Non-zero entries denote the user-item pairs which will be excluded
             from rank computation. Use to exclude training set interactions
             from being scored and ranked for evaluation.
        user_features: np.float32 csr_matrix of shape [n_users, n_user_features], optional
             Each row contains that user's weights over features.
        item_features: np.float32 csr_matrix of shape [n_items, n_item_features], optional
             Each row contains that item's weights over features.
        num_threads: int, optional
             Number of parallel computation threads to use.
             Should not be higher than the number of physical cores.
        check_intersections: bool, optional, True by default,
            Only relevant when train_interactions are supplied.
            A flag that signals whether the test and train matrices should be checked
            for intersections to prevent optimistic ranks / wrong evaluation / bad data split.

        Returns
        -------

        np.float32 csr_matrix of shape [n_users, n_items]
            the [i, j]-th entry of the matrix will contain the rank of the j-th
            item in the sorted recommendations list for the i-th user.
            The degree of sparsity of this matrix will be equal to that of the
            input interactions matrix.
        """

        self._check_initialized()

        if num_threads < 1:
            raise ValueError("Number of threads must be 1 or larger.")

        if check_intersections:
            self._check_test_train_intersections(test_interactions, train_interactions)

        n_users, n_items = test_interactions.shape

        (user_features, item_features) = self._construct_feature_matrices(
            n_users, n_items, user_features, item_features
        )

        if not item_features.shape[1] == self.item_embeddings.shape[0]:
            raise ValueError("Incorrect number of features in item_features")

        if not user_features.shape[1] == self.user_embeddings.shape[0]:
            raise ValueError("Incorrect number of features in user_features")

        test_interactions = test_interactions.tocsr()
        test_interactions = self._to_cython_dtype(test_interactions)

        if train_interactions is None:
            train_interactions = sp.csr_matrix((n_users, n_items), dtype=CYTHON_DTYPE)
        else:
            train_interactions = train_interactions.tocsr()
            train_interactions = self._to_cython_dtype(train_interactions)

        ranks = sp.csr_matrix(
            (
                np.zeros_like(test_interactions.data),
                test_interactions.indices,
                test_interactions.indptr,
            ),
            shape=test_interactions.shape,
        )

        lightfm_data = self._get_lightfm_data()

        predict_ranks(
            CSRMatrix(item_features),
            CSRMatrix(user_features),
            CSRMatrix(test_interactions),
            CSRMatrix(train_interactions),
            ranks.data,
            lightfm_data,
            num_threads,
        )

        return ranks