Make rank distribution using both ppf and brute force.

    Setting crit = 1 is equivalent to just using the ppf

    Parameters
    ----------
    {0}

def _make_rank(dist_obj, n, mu, sigma, crit=0.5, upper=10000, xtol=1):
    """
    Make rank distribution using both ppf and brute force.

    Setting crit = 1 is equivalent to just using the ppf

    Parameters
    ----------
    {0}

    """
    qs = (np.arange(1, n + 1) - 0.5) / n
    rank = np.empty(len(qs))

    brute_ppf = lambda val, prob: prob - dist_obj.cdf(val, mu, sigma)

    qs_less = qs <= crit
    ind = np.sum(qs_less)

    # Use ppf if qs are below crit
    rank[qs_less] = dist_obj.ppf(qs[qs_less], mu, sigma)

    # Use brute force if they are above
    for i, tq in enumerate(qs[~qs_less]):

        j = ind + i
        try:
            # TODO: Use an adaptable lower bound to increase speed
            rank[j] = np.abs(np.ceil(optim.brentq(brute_ppf, -1, upper,
                                        args=(tq,), xtol=xtol)))

        except ValueError:

            # If it is above the upper bound set all remaining values
            # to the previous value
            rank[j:] = np.repeat(rank[j - 1], len(rank[j:]))
            break

    return rank