# Path: maxdiv/eval.py
# def pointwiseLabelsToIntervals(labels):
#     """Converts an array of boolean labels for each point in a time series to a list of contiguous intervals."""
#     
#     regions = []
#     current_start = None
#     
#     for i, lbl in enumerate(labels):
#         # Begin of new interval
#         if (current_start is None) and lbl:
#             current_start = i
#         # End of current interval
#         elif (current_start is not None) and (not lbl):
#             regions.append((current_start, i))
#             current_start = None
#     
#     # Terminate trailing interval
#     if current_start is not None:
#         regions.append((current_start, len(labels)))
#     
#     return regions
# 
# Path: maxdiv/maxdiv_util.py
# def calc_gaussian_kernel(X, kernel_sigma_sq = 1.0, normalized=True):
#     """ Calculate a normalized Gaussian kernel using the columns of X """
#     # Let's first compute the kernel matrix from our squared Euclidean distances in $D$.
#     D = calc_distance_matrix(X)
#     # compute proper normalized Gaussian kernel values
#     K = np.exp(-D/(2.0*kernel_sigma_sq))
#     if normalized:
#         K = K / ((2*np.pi*kernel_sigma_sq) ** (X.shape[0] / 2))
#     return K
# 
# def IoU(start1, len1, start2, len2):
#     """ Computes the intersection over union of two intervals starting at start1 and start2 with lengths len1 and len2. """
#     intersection = max(0, min(start1 + len1, start2 + len2) - max(start1, start2))
#     return float(intersection) / (len1 + len2 - intersection)


import numpy as np
    from sklearn.mixture import GMM
    from sklearn.mixture import GaussianMixture
from .eval import pointwiseLabelsToIntervals
from .maxdiv_util import calc_gaussian_kernel, IoU
            out[i2] = a
            out[i3] = a * (c - x[i3])/(c - b)
            out[i4] = 0
            return out
    
    def parameter_select(K, type):
        n = K.shape[0]
        w = np.ones(n) / n
        tol = 1e-8
        norm2mu = np.dot(w.T, np.dot(K, w))
        normdiff = np.sqrt(K.diagonal()) + norm2mu - 2 * K.dot(w)
        J = normdiff.sum() / n
        while True:
            J_old = J
            w = 1.0 / normdiff
            w /= w.sum()
            norm2mu = np.dot(w.T, np.dot(K, w))
            normdiff = np.sqrt(K.diagonal()) + norm2mu - 2 * K.dot(w)
            J = normdiff.sum() / n
            if abs(J_old - J) < J_old * tol:
                break
        if type == 'huber':
            return (np.median(normdiff),)
        elif type == 'hampel':
            return (np.median(normdiff), np.percentile(normdiff, 95), np.max(normdiff))
    
    if type not in ('huber', 'hampel'):
        raise ValueError('Unknown loss function: {}'.format(type))
    
    d, n = X.shape

# Path: maxdiv/eval.py
# def pointwiseLabelsToIntervals(labels):
#     """Converts an array of boolean labels for each point in a time series to a list of contiguous intervals."""
#     
#     regions = []
#     current_start = None
#     
#     for i, lbl in enumerate(labels):
#         # Begin of new interval
#         if (current_start is None) and lbl:
#             current_start = i
#         # End of current interval
#         elif (current_start is not None) and (not lbl):
#             regions.append((current_start, i))
#             current_start = None
#     
#     # Terminate trailing interval
#     if current_start is not None:
#         regions.append((current_start, len(labels)))
#     
#     return regions
# 
# Path: maxdiv/maxdiv_util.py
# def calc_gaussian_kernel(X, kernel_sigma_sq = 1.0, normalized=True):
#     """ Calculate a normalized Gaussian kernel using the columns of X """
#     # Let's first compute the kernel matrix from our squared Euclidean distances in $D$.
#     D = calc_distance_matrix(X)
#     # compute proper normalized Gaussian kernel values
#     K = np.exp(-D/(2.0*kernel_sigma_sq))
#     if normalized:
#         K = K / ((2*np.pi*kernel_sigma_sq) ** (X.shape[0] / 2))
#     return K
# 
# def IoU(start1, len1, start2, len2):
#     """ Computes the intersection over union of two intervals starting at start1 and start2 with lengths len1 and len2. """
#     intersection = max(0, min(start1 + len1, start2 + len2) - max(start1, start2))
#     return float(intersection) / (len1 + len2 - intersection)


# Path: maxdiv/baselines_noninterval.py
import numpy as np
    from sklearn.mixture import GMM
    from sklearn.mixture import GaussianMixture
from .eval import pointwiseLabelsToIntervals
from .maxdiv_util import calc_gaussian_kernel, IoU

            out[i2] = a
            out[i3] = a * (c - x[i3])/(c - b)
            out[i4] = 0
            return out
    
    def parameter_select(K, type):
        n = K.shape[0]
        w = np.ones(n) / n
        tol = 1e-8
        norm2mu = np.dot(w.T, np.dot(K, w))
        normdiff = np.sqrt(K.diagonal()) + norm2mu - 2 * K.dot(w)
        J = normdiff.sum() / n
        while True:
            J_old = J
            w = 1.0 / normdiff
            w /= w.sum()
            norm2mu = np.dot(w.T, np.dot(K, w))
            normdiff = np.sqrt(K.diagonal()) + norm2mu - 2 * K.dot(w)
            J = normdiff.sum() / n
            if abs(J_old - J) < J_old * tol:
                break
        if type == 'huber':
            return (np.median(normdiff),)
        elif type == 'hampel':
            return (np.median(normdiff), np.percentile(normdiff, 95), np.max(normdiff))
    
    if type not in ('huber', 'hampel'):
        raise ValueError('Unknown loss function: {}'.format(type))
    
    d, n = X.shape

    K = calc_gaussian_kernel(X, kernel_sigma_sq)