def METHOD_NAME(signal, change="meanvar", penalty=None):
    """PELT algorithm to find change points in a signal.
    Adapted from: https://github.com/ruipgil/changepy https://github.com/deepcharles/ruptures
    https://github.com/STOR-i/Changepoints.jl https://github.com/rkillick/changepoint/
    """
    # Initialize
    length = len(signal)
    if penalty is None:
        penalty = np.log(length)  # pylint: disable=E1111
    if change.lower() == "var":
        cost = _signal_changepoints_cost_var(signal)
    elif change.lower() == "mean":
        cost = _signal_changepoints_cost_mean(signal)
    else:
        cost = _signal_changepoints_cost_meanvar(signal)
    # Run algorithm
    F = np.zeros(length + 1)
    R = np.array([0], dtype=int)
    candidates = np.zeros(length + 1, dtype=int)
    F[0] = -penalty  # pylint: disable=E1130
    for tstar in range(2, length + 1):
        cpt_cands = R
        seg_costs = np.array([cost(cpt_cands[i], tstar) for i in range(len(cpt_cands))])
        F_cost = F[cpt_cands] + seg_costs
        F[tstar] = np.nanmin(F_cost) + penalty
        tau = np.nanargmin(F_cost)
        candidates[tstar] = cpt_cands[tau]
        ineq_prune = [val < F[tstar] for val in F_cost]
        R = [cpt_cands[j] for j, val in enumerate(ineq_prune) if val]
        R.append(tstar - 1)
        R = np.array(R, dtype=int)
    changepoints = np.sort(np.unique(candidates[candidates]))
    changepoints = changepoints[changepoints > 0]
    return changepoints