# Buggy code
def _filter(X, filtered_homology_dimensions, cutoff):
    n = len(X)
    homology_dimensions = sorted(list(set(X[0, :, 2])))
    unfiltered_homology_dimensions = [
        dim for dim in homology_dimensions if dim not in filtered_homology_dimensions
    ]

    if len(unfiltered_homology_dimensions) == 0:
        Xuf = np.empty((n, 0, 3), dtype=X.dtype)
    else:
        Xuf = _subdiagrams(X, unfiltered_homology_dimensions)

    # Compute a global 2D cutoff mask once
    cutoff_mask = X[:, :, 1] - X[:, :, 0] > cutoff
    Xf = []
    for dim in filtered_homology_dimensions:
        # Compute a 2D mask for persistence pairs in dimension dim
        dim_mask = X[:, :, 2] == dim
        # Need the indices relative to X of persistence triples in dimension
        # dim surviving the cutoff
        indices = np.nonzero(np.logical_and(dim_mask, cutoff_mask))
        if not indices[0].size:
            Xdim = np.tile([0.0, 0.0, dim], (n, 1, 1))
        else:
            # A unique element k is repeated N times *consecutively* in
            # indices[0] iff there are exactly N valid persistence triples
            # in the k-th diagram
            unique, counts = np.unique(indices[0], return_counts=True)
            max_n_points = np.max(counts)
            # Make a global 2D array of all valid triples
            X_indices = X[indices]
            min_value = np.min(X_indices[:, 0])  # For padding
            # Initialise the array of filtered subdiagrams in dimension m
            Xdim = np.tile([min_value, min_value, dim], (n, max_n_points, 1))
            # Since repeated indices in indices[0] are consecutive and we know
            # the counts per unique index, we can fill the top portion of
            # each 2D array entry of Xdim with the filtered triples from the
            # corresponding entry of X
            Xdim[indices[0], _multirange(counts)] = X_indices
        Xf.append(Xdim)

    Xf.append(Xuf)
    Xf = np.concatenate(Xf, axis=1)
    return Xf


# Traceback (TypeError)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-5e233492b878> in <module>
----> 1 Amplitude(metric="persistence_image").fit_transform(Xd)

~\Workspace\giotto-tda_ulupo\gtda\utils\_docs.py in fit_transform_wrapper(*args, **kwargs)
104         @wraps(original_fit_transform)
105         def fit_transform_wrapper(*args, **kwargs):
--> 106             return original_fit_transform(*args, **kwargs)
107         fit_transform_wrapper.__doc__ = \
108             make_fit_transform_docs(fit_docs, transform_docs)

~\Anaconda3\envs\gtda-ulupo-py38\lib\site-packages\sklearn\base.py in fit_transform(self, X, y, **fit_params)
688         if y is None:
689             # fit method of arity 1 (unsupervised transformation)
--> 690             return self.fit(X, **fit_params).transform(X)
691         else:
692             # fit method of arity 2 (supervised transformation)

~\Workspace\giotto-tda_ulupo\gtda\diagrams\features.py in fit(self, X, y)
273         if self.metric == 'persistence_image':
274             self.effective_metric_params_['weights'] = \
--> 275                 _calculate_weights(X, **self.effective_metric_params_)
276
277         return self

TypeError: _calculate_weights() missing 1 required positional argument: 'weight_function'

# Fixed code
def _filter(X, filtered_homology_dimensions, cutoff):
    n = len(X)
    homology_dimensions = sorted(np.unique(X[0, :, 2]))
    unfiltered_homology_dimensions = [
        dim for dim in homology_dimensions if dim not in filtered_homology_dimensions
    ]

    if len(unfiltered_homology_dimensions) == 0:
        Xuf = np.empty((n, 0, 3), dtype=X.dtype)
    else:
        Xuf = _subdiagrams(X, unfiltered_homology_dimensions)

    # Compute a global 2D cutoff mask once
    cutoff_mask = X[:, :, 1] - X[:, :, 0] > cutoff
    Xf = []
    for dim in filtered_homology_dimensions:
        # Compute a 2D mask for persistence pairs in dimension dim
        dim_mask = X[:, :, 2] == dim
        # Need the indices relative to X of persistence triples in dimension
        # dim surviving the cutoff
        indices = np.nonzero(np.logical_and(dim_mask, cutoff_mask))
        if not indices[0].size:
            Xdim = np.tile([0.0, 0.0, dim], (n, 1, 1))
        else:
            # A unique element k is repeated N times *consecutively* in
            # indices[0] iff there are exactly N valid persistence triples
            # in the k-th diagram
            unique, counts = np.unique(indices[0], return_counts=True)
            max_n_points = np.max(counts)
            # Make a global 2D array of all valid triples
            X_indices = X[indices]
            min_value = np.min(X_indices[:, 0])  # For padding
            # Initialise the array of filtered subdiagrams in dimension m
            Xdim = np.tile([min_value, min_value, dim], (n, max_n_points, 1))
            # Since repeated indices in indices[0] are consecutive and we know
            # the counts per unique index, we can fill the top portion of
            # each 2D array entry of Xdim with the filtered triples from the
            # corresponding entry of X
            Xdim[indices[0], _multirange(counts)] = X_indices
        Xf.append(Xdim)

    Xf.append(Xuf)
    Xf = np.concatenate(Xf, axis=1)
    return Xf