EllipticFourierAnalysis#

class ktch.harmonic.EllipticFourierAnalysis(n_harmonics: int = 20, n_dim: int = 2, norm: bool = True, return_orientation_scale: bool = False, n_jobs: int | None = None, verbose: int = 0, norm_method: str = 'area')[source]#

Elliptic Fourier Analysis (EFA)

Parameters:
n_harmonics: int, default=20

Number of harmonics

n_dim: int, default=2

Dimension of the coordinate space. Must be 2 (for planar curves) or 3 (for space curves).

normbool, default=True

Normalize the elliptic Fourier coefficients by the major axis of the 1st ellipse.

return_orientation_scalebool, default=False

Return orientation and scale of the outline (requires norm=True).

  • 2D: Appends [psi, scale] to the end of the coefficient vector.

  • 3D: Appends [alpha, beta, gamma, phi, scale] to the end.

n_jobs: int, default=None

The number of jobs to run in parallel. None means 1 unless in a joblib.parallel_backend context. -1 means using all processors.

verbose: int, default=0

The verbosity level.

norm_methodstr, default=”area”

Normalization method for 3D EFA coefficients when norm=True. Only affects n_dim=3.

  • "area": Scale by sqrt(pi * a1 * b1) where a1 and b1 are the semi-major and semi-minor axis lengths of the 1st harmonic ellipse (Godefroy et al. 2012).

  • "semi_major_axis": Scale by the semi-major axis length a1 of the 1st harmonic ellipse, consistent with the 2D normalization convention (Kuhl & Giardina 1982).

Notes

EFA is widely applied for outline shape analysis in two-dimensional space [Kuhl_Giardina_1982].

\[\begin{split}\begin{align} x(l) &= \frac{a_0}{2} + \sum_{i=1}^{n} \left[ a_i \cos\left(\frac{2\pi i t}{T}\right) + b_i \sin\left(\frac{2\pi i t}{T}\right) \right]\\ y(l) &= \frac{c_0}{2} + \sum_{i=1}^{n} \left[ c_i \cos\left(\frac{2\pi i t}{T}\right) + d_i \sin\left(\frac{2\pi i t}{T}\right) \right]\\ \end{align}\end{split}\]

EFA is also applied for a closed curve in the three-dimensional space (e.g., [Lestrel_1997], [Lestrel_et_al_1997], and [Godefroy_et_al_2012]).

For 3D data (n_dim=3), normalization (norm=True) follows Godefroy et al. (2012) §3.1: rescaling by the 1st harmonic ellipse area, reorientation using ZXZ Euler angles, phase shift, and direction correction.

When return_orientation_scale=True with 3D normalized data, 5 values are appended to the output: [alpha, beta, gamma, phi, scale], where (alpha, beta, gamma) are ZXZ Euler angles (in radians) of the 1st harmonic ellipse orientation, phi is the phase angle, and scale is the normalization factor (sqrt(pi * a1 * b1) for norm_method="area", or a1 for norm_method="semi_major_axis").

References

[Kuhl_Giardina_1982]

Kuhl, F.P., Giardina, C.R. (1982) Elliptic Fourier features of a closed contour. Comput. Graph. Image Process. 18: 236–258. https://doi.org/10.1016/0146-664X(82)90034-X

[Lestrel_1997]

Lestrel, P.E., 1997. Introduction and overview of Fourier descriptors, in: Fourier Descriptors and Their Applications in Biology. Cambridge University Press, pp. 22–44. https://doi.org/10.1017/cbo9780511529870.003

[Lestrel_et_al_1997]

Lestrel, P.E., Read, D.W., Wolfe, C., 1997. Size and shape of the rabbit orbit: 3-D Fourier descriptors, in: Lestrel, P.E. (Ed.), Fourier Descriptors and Their Applications in Biology. Cambridge University Press, pp. 359–378. https://doi.org/10.1017/cbo9780511529870.017

[Godefroy_et_al_2012]

Godefroy, J.E., Bornert, F., Gros, C.I., Constantinesco, A., 2012. Elliptical Fourier descriptors for contours in three dimensions: A new tool for morphometrical analysis in biology. C. R. Biol. 335, 205–213. https://doi.org/10.1016/j.crvi.2011.12.004

fit(X, y=None)[source]#

Fit the model (no-op for stateless transformer).

Parameters:
Xignored
yignored
Returns:
self
fit_transform(X, y=None, t=None)[source]#

Fit and transform in a single step.

Overridden to support metadata routing of t.

Parameters:
Xlist of array-like of shape (n_coords_i, n_dim)

Coordinate values of n_samples.

yignored
tlist of array-like, optional

Per-sample parameterization. Passed to transform.

Returns:
X_transformedndarray of shape (n_samples, n_features_out)
get_feature_names_out(input_features: None | npt.ArrayLike = None) np.ndarray[source]#

Get output feature names.

Parameters:
input_featuresignored
Returns:
feature_names_outndarray of str objects

Transformed feature names.

get_metadata_routing()#

Get metadata routing of this object.

Please check User Guide on how the routing mechanism works.

Returns:
routingMetadataRequest

A MetadataRequest encapsulating routing information.

get_params(deep=True)#

Get parameters for this estimator.

Parameters:
deepbool, default=True

If True, will return the parameters for this estimator and contained subobjects that are estimators.

Returns:
paramsdict

Parameter names mapped to their values.

inverse_transform(X_transformed, t_num=100, as_frame=False)[source]#

Inverse analysis of elliptic Fourier analysis.

Parameters:
X_transformedarray-like of shape (n_samples, n_features)
Elliptic Fourier coefficients. Accepted lengths per sample:
  • 2D: 4*(n_harmonics+1) or 4*(n_harmonics+1)+2 (psi, scale).

  • 3D: 6*(n_harmonics+1) or 6*(n_harmonics+1)+5 (alpha, beta, gamma, phi, scale).

Orientation/scale columns, if present, are ignored for reconstruction.

t_numint, default = 100

Number of coordinate values.

as_framebool, default = False

If True, return pd.DataFrame.

Returns:
X_coordsarray-like of shape (n_samples, t_num, n_dim) or pd.DataFrame

Coordinate values reconstructed from the elliptic Fourier coefficients.

set_inverse_transform_request(*, X_transformed: bool | None | str = '$UNCHANGED$', as_frame: bool | None | str = '$UNCHANGED$', t_num: bool | None | str = '$UNCHANGED$') EllipticFourierAnalysis#

Configure whether metadata should be requested to be passed to the inverse_transform method.

Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with enable_metadata_routing=True (see sklearn.set_config()). Please check the User Guide on how the routing mechanism works.

The options for each parameter are:

  • True: metadata is requested, and passed to inverse_transform if provided. The request is ignored if metadata is not provided.

  • False: metadata is not requested and the meta-estimator will not pass it to inverse_transform.

  • None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.

  • str: metadata should be passed to the meta-estimator with this given alias instead of the original name.

The default (sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.

Added in version 1.3.

Parameters:
X_transformedstr, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED

Metadata routing for X_transformed parameter in inverse_transform.

as_framestr, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED

Metadata routing for as_frame parameter in inverse_transform.

t_numstr, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED

Metadata routing for t_num parameter in inverse_transform.

Returns:
selfobject

The updated object.

set_output(*, transform=None)#

Set output container.

See Introducing the set_output API for an example on how to use the API.

Parameters:
transform{“default”, “pandas”, “polars”}, default=None

Configure output of transform and fit_transform.

  • “default”: Default output format of a transformer

  • “pandas”: DataFrame output

  • “polars”: Polars output

  • None: Transform configuration is unchanged

Added in version 1.4: “polars” option was added.

Returns:
selfestimator instance

Estimator instance.

set_params(**params)#

Set the parameters of this estimator.

The method works on simple estimators as well as on nested objects (such as Pipeline). The latter have parameters of the form <component>__<parameter> so that it’s possible to update each component of a nested object.

Parameters:
**paramsdict

Estimator parameters.

Returns:
selfestimator instance

Estimator instance.

set_transform_request(*, t: bool | None | str = '$UNCHANGED$') EllipticFourierAnalysis#

Configure whether metadata should be requested to be passed to the transform method.

Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with enable_metadata_routing=True (see sklearn.set_config()). Please check the User Guide on how the routing mechanism works.

The options for each parameter are:

  • True: metadata is requested, and passed to transform if provided. The request is ignored if metadata is not provided.

  • False: metadata is not requested and the meta-estimator will not pass it to transform.

  • None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.

  • str: metadata should be passed to the meta-estimator with this given alias instead of the original name.

The default (sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.

Added in version 1.3.

Parameters:
tstr, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED

Metadata routing for t parameter in transform.

Returns:
selfobject

The updated object.

transform(X: list[npt.ArrayLike] | npt.ArrayLike, t: npt.ArrayLike = None) npt.ArrayLike[source]#

Elliptic Fourier Analysis.

Parameters:
X{list of array-like, array-like} of shape (n_samples, n_coords, n_dim)

Coordinate values of n_samples. The i-th array-like of shape (n_coords_i, n_dim) represents coordinate values of the i-th sample.

tlist of array-like of shape (n_coords_i,), optional

Parameters indicating the position on the outline of n_samples. The i-th element corresponds to each coordinate value in the i-th element of X. If None, arc-length parameterization is computed automatically.

Returns:
X_transformedndarray of shape (n_samples, n_features_out)

Elliptic Fourier coefficients.

  • 2D (return_orientation_scale=False): [a_0..a_n, b_0..b_n, c_0..c_n, d_0..d_n] length = 4 * (n_harmonics + 1).

  • 2D (return_orientation_scale=True): Same as above with [psi, scale] appended (length +2).

  • 3D (return_orientation_scale=False): [a_0..a_n, b_0..b_n, c_0..c_n, d_0..d_n, e_0..e_n, f_0..f_n] length = 6 * (n_harmonics + 1).

  • 3D (return_orientation_scale=True): Same as above with [alpha, beta, gamma, phi, scale] appended (length +5).