def partition(curve, ratio=0.3):
    """Return a list of indices that partition the curve into segments.

    Take the local minima in order, greatest values first.
    If the minimum has a value that is more than 'ratio' percent of the value
    of one of the local maxima on either side, then discard that local
    minimum and the smaller of the two adjacent local maxima.

    Remaining minima with values no more than 'ratio' percent of both
    adjacent maxima are partition points.

    Assumes that curve[0] and curve[-1] are known to be local minima.
    """
    last_maximum = None
    last_minimum = None
    minima = []
    for i, v in enumerate(curve):
        if not i or i == len(curve) - 1:
            continue
        if v >= curve[i - 1] and v > curve[i + 1]:
            if last_maximum:
                index, value = last_minimum
                minima.append([index, value, last_maximum, v])
            last_maximum = v
        elif v < curve[i - 1] and v <= curve[i + 1]:
            last_minimum = i, v
    minima.sort(key=lambda x: x[1])
    points = []
    for i, (index, value, left_max, right_max) in enumerate(minima):
        if value > ratio * left_max or value > ratio * right_max:
            min_diff = None
            min_n = None
            for n in range(i + 1, len(minima)):
                n_index = minima[n][0]
                diff = abs(n_index - index)
                if not min_diff or diff < min_diff:
                    min_diff = diff
                    min_n = n
            if min_n:
                if minima[min_n][0] < index:
                    minima[min_n][3] = right_max
                else:
                    minima[min_n][2] = left_max
            continue
        points.append(index)
    points.sort()
    if len(points):
        ret = [(0, points[0])]
    else:
        ret = [(0, len(curve) - 1)]
    for n in range(len(points)):
        if n == len(points) - 1:
            next_point = len(curve) - 1
        else:
            next_point = points[n + 1]
        ret.append((points[n], next_point))
    return ret
