def _compare_features_with_threshold(vec: Dict, features: np.ndarray,
                                     cat_features: np.ndarray) -> np.ndarray:
    """
    Compare each feature with each corresponding threshold
    Args:
        vec: vectorized information dict in a tree, with reference
             to response vec of function _vectorize_tree
        features: continuous features, shape (N, fea_num),
                  N is number of data, fea_num is the number
                  of continuous features
        cat_features: categorical features, shape (N, cat_fea_num),
                      N is number of data, cat_feat_num is the number
                      of categorical features

    Returns:
        d: Comparison of features and thresholds, True to the
           right, False to the left, np.bool, shape: (N, node_num),
           N is the number of data, node_num is the node num
           in a tree.
    """
    N = features.shape[0]
    node_num = vec['feature_id'].size

    is_cont = vec['feature_id'] < features.shape[1]
    cont_fid = np.where(is_cont, vec['feature_id'], 0)
    row = np.arange(N).repeat(node_num).reshape(N, node_num)
    cont_X = features[row, cont_fid]

    is_nan = np.isnan(cont_X)
    threshold = np.tile(vec['threshold'], (N, 1))
    less = cont_X < threshold
    d = ~np.where(is_nan, vec['default_left'], less)

    if is_cont.sum() < is_cont.size:
        is_cat = ~is_cont
        cat_fid = np.where(is_cat, vec['feature_id'] - features.shape[1], 0)
        cat_X = cat_features[row, cat_fid]

        tmp = [~np.in1d(cat_X[:, i], cat_threshold).reshape(-1, 1)
                for i, cat_threshold in enumerate(vec['cat_threshold'])]
        cat_in = np.concatenate(tmp, axis=1)

        d = np.where(is_cont, d, cat_in)

    return d

    Compare each feature with each corresponding threshold
    Args:
        vec: vectorized information dict in a tree, with reference
             to response vec of function _vectorize_tree
        features: continuous features, shape (N, fea_num),
                  N is number of data, fea_num is the number
                  of continuous features
        cat_features: categorical features, shape (N, cat_fea_num),
                      N is number of data, cat_feat_num is the number
                      of categorical features

    Returns:
        d: Comparison of features and thresholds, True to the
           right, False to the left, np.bool, shape: (N, node_num),
           N is the number of data, node_num is the node num
           in a tree.
    
fedlearner/model/tree/tree.py