<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def interpolate_intervals(intervals, labels, time_points, fill_value=None):
 """Assign labels to a set of points in time given a set of intervals. Time points that do not lie within an interval are mapped to `fill_value`. Parameters intervals : np.ndarray, shape=(n, 2) An array of time intervals, as returned by :func:`mir_eval.io.load_intervals()`. The ``i`` th interval spans time ``intervals[i, 0]`` to ``intervals[i, 1]``. Intervals are assumed to be disjoint. labels : list, shape=(n,) The annotation for each interval time_points : array_like, shape=(m,) Points in time to assign labels. These must be in non-decreasing order. fill_value : type(labels[0]) Object to use for the label with out-of-range time points. (Default value = None) Returns ------- aligned_labels : list Labels corresponding to the given time points. Raises ------ ValueError If `time_points` is not in non-decreasing order. """


    # Verify that time_points is sorted
    time_points = np.asarray(time_points)

    if np.any(time_points[1:] < time_points[:-1]):
        raise ValueError('time_points must be in non-decreasing order')

    aligned_labels = [fill_value] * len(time_points)

    starts = np.searchsorted(time_points, intervals[:, 0], side='left')
    ends = np.searchsorted(time_points, intervals[:, 1], side='right')

    for (start, end, lab) in zip(starts, ends, labels):
        aligned_labels[start:end] = [lab] * (end - start)

    return aligned_labels