elbow_helper.locator module

A from-scratch, NumPy-only implementation of the difference-curve knee locator.

This module implements the method credited in the project’s Acknowledgements section (README.md) so that elbow_helper depends on numpy only: no scipy at runtime.

Two scipy calls in a typical implementation are replaced here:

  • scipy.interpolate.interp1d(x, y)(x) evaluated at the same x is the identity, so with interp_method="interp1d" the fitted line is just y.

  • scipy.signal.argrelextrema(a, comparator, order, mode="clip") is a short NumPy helper (_argrelextrema()) that compares each sample against its clip-indexed neighbours, bit-for-bit equivalent for 1-D input.

The traversal logic in KneeLocator.find_knee(), the transform_y orientation table, the sensitivity threshold Tmx and the online-correction behaviour follow the reference implementation closely, so results match it for the supported inputs.

Author

Warith Harchaoui, <warith.harchaoui@deraison.ai>

class elbow_helper.locator.KneeLocator(x, y, S=1.0, curve='concave', direction='increasing', interp_method='interp1d', online=False, polynomial_degree=7)[source]

Bases: object

Locate the point of maximum curvature (knee/elbow) of a curve.

A NumPy-only implementation of the difference-curve locator, exposing the public surface used by this package: knee, norm_knee, all_knees, all_norm_knees, x_difference / y_difference and the extrema indices.

Parameters:
  • x (array-like) – Input coordinates, equal length. x must be strictly increasing.

  • y (array-like) – Input coordinates, equal length. x must be strictly increasing.

  • S (float, optional) – Sensitivity; larger values are more conservative. Default 1.0.

  • curve (str, optional) – "concave" to detect knees, "convex" to detect elbows.

  • direction (str, optional) – "increasing" or "decreasing".

  • interp_method (str, optional) – "interp1d" (identity fit) or "polynomial" (numpy.polyfit).

  • online (bool, optional) – If True, keep correcting the knee while traversing; if False, return the first knee found. Default False.

  • polynomial_degree (int, optional) – Degree used when interp_method="polynomial". Default 7.

property all_elbows

Alias for all_knees, for callers who think in “elbows”.

property all_norm_elbows

Alias for all_norm_knees, for callers who think in “elbows”.

property elbow

Alias for knee, for callers who think in “elbows”.

find_knee()[source]

Traverse the difference curve and return (knee, norm_knee).

Returns:

(knee, norm_knee) in data-space and normalized-space coordinates respectively, or (None, None) if no candidate clears its sensitivity threshold.

Return type:

tuple of (float or None), (float or None)

property norm_elbow

Alias for norm_knee, for callers who think in “elbows”.

static transform_y(y, direction, curve)[source]

Orient y to a concave, increasing frame (elbows become knees).

Parameters:
  • y (numpy.ndarray) – Normalized y values.

  • direction (str) – "increasing" or "decreasing".

  • curve (str) – "concave" or "convex".

Returns:

y, flipped and/or mirrored so the concave-increasing bump logic in find_knee() applies unchanged.

Return type:

numpy.ndarray