def _clip(X, lower, upper):
    """Clip an array.

    Parameters
    ----------
    X : array, shape = (n_samples, n_timestamps)
        Array to clip.

    lower : array
        Minimum values in the clipped array. It must be
        two- or three-dimensional.

    upper : array
        Maximum values in the clipped array. It must be
        two- or three-dimensional, and have the same shape
        as ``lower``.

    Returns
    -------
    X_clipped : array
        Clipped array.

    """
    X = check_array(X)
    lower = check_array(lower, ensure_2d=False, allow_nd=True)
    upper = check_array(upper, ensure_2d=False, allow_nd=True)
    n_dims = lower.ndim
    if n_dims not in (2, 3):
        raise ValueError("'lower' must be two- or three-dimensional.")
    if not lower.shape == upper.shape:
        raise ValueError(
            "'lower' and 'upper' must have the same shape "
            "({0} != {1})".format(lower.shape, upper.shape)
        )
    if n_dims == 2:
        n_samples_X, n_timestamps = X.shape
        n_samples_clip, _ = lower.shape
        X_clipped = _clip_2d(
            X, lower, upper, n_samples_X, n_samples_clip, n_timestamps
        )
    else:
        n_samples_X, n_samples_Y, n_timestamps = lower.shape
        X_clipped = _clip_3d(
            X, lower, upper, n_samples_Y, n_samples_X, n_timestamps
        )
    return X_clipped
Clip an array.

    Parameters
    ----------
    X : array, shape = (n_samples, n_timestamps)
        Array to clip.

    lower : array
        Minimum values in the clipped array. It must be
        two- or three-dimensional.

    upper : array
        Maximum values in the clipped array. It must be
        two- or three-dimensional, and have the same shape
        as ``lower``.

    Returns
    -------
    X_clipped : array
        Clipped array.

    
pyts/metrics/lower_bounds.py