coco_pipe.dim_reduction.evaluation.geometry¶
Trajectory geometry metrics and smoothing utilities.
This module provides small, generic helpers for analyzing ordered trajectories in embedded spaces. The functions are reducer-agnostic and operate on standard NumPy arrays rather than domain-specific container types.
Functions¶
- moving_average
Smooth a one-dimensional timecourse with a valid-mode moving average.
- trajectory_acceleration
Compute instantaneous acceleration magnitude from second-order derivatives.
- trajectory_speed
Compute instantaneous speed from first-order trajectory differences.
- trajectory_curvature
Compute geometric curvature from first- and second-order derivatives.
- trajectory_dispersion
Compute within-group trajectory spread across time.
- trajectory_displacement
Compute displacement from the initial trajectory state across time.
- trajectory_path_length
Compute total or cumulative path length.
- trajectory_separation
Compute time-resolved group separation across time using a selected method.
- trajectory_tortuosity
Compute the ratio between path length and net displacement.
- trajectory_turning_angle
Compute local turning angles between consecutive trajectory segments.
Author: Hamza Abdelhedi (hamza.abdelhedi@umontreal.ca)
Functions¶
|
Smooth a one-dimensional array with a valid-mode moving average. |
|
Calculate instantaneous acceleration magnitude. |
|
Calculate instantaneous trajectory speed. |
|
Calculate geometric curvature of a trajectory. |
|
Calculate trajectory path length. |
|
Calculate displacement from the initial state across time. |
|
Calculate trajectory tortuosity. |
|
Calculate local turning angles between consecutive trajectory segments. |
|
Calculate within-group trajectory dispersion across time. |
|
Calculate time-resolved separation between labeled trajectory groups. |
Module Contents¶
- coco_pipe.dim_reduction.evaluation.geometry.moving_average(arr: numpy.ndarray, window: int) numpy.ndarray[source]¶
Smooth a one-dimensional array with a valid-mode moving average.
- Parameters:
arr (np.ndarray of shape (n_samples,)) – Input array to smooth.
window (int) – Size of the smoothing window. Must be a positive integer no larger than the array length.
- Returns:
Smoothed array. The output length is
n_samples - window + 1. Ifwindow == 1, a copy of the input is returned.- Return type:
np.ndarray
- Raises:
ValueError – If
arris not one-dimensional, ifwindowis not positive, or ifwindowis larger than the input length.
See also
trajectory_speedFirst-order trajectory dynamics without smoothing.
trajectory_turning_angleLocal directional changes along a trajectory.
Examples
>>> import numpy as np >>> moving_average(np.array([1, 2, 3, 4, 5]), window=3) array([2., 3., 4.])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_acceleration(traj: numpy.ndarray, dt: float = 1.0) numpy.ndarray[source]¶
Calculate instantaneous acceleration magnitude.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
dt (float, default=1.0) – Uniform time step between consecutive samples.
- Returns:
Acceleration-magnitude timecourse aligned with the input time axis.
- Return type:
np.ndarray of shape (…, n_times)
- Raises:
ValueError – If
trajhas fewer than two dimensions, contains fewer than three time points, or ifdt <= 0.
See also
trajectory_speedFirst-order trajectory dynamics.
trajectory_curvatureGeometric bending of a trajectory.
trajectory_turning_angleLocal directional changes between segments.
Examples
>>> import numpy as np >>> t = np.linspace(0.0, 2.0, 3) >>> traj = np.stack([t**2, np.zeros_like(t)], axis=1) >>> trajectory_acceleration(traj, dt=1.0).shape (3,)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_speed(traj: numpy.ndarray, dt: float = 1.0) numpy.ndarray[source]¶
Calculate instantaneous trajectory speed.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
dt (float, default=1.0) – Uniform time step between consecutive samples.
- Returns:
Instantaneous speed timecourse. The final value is padded with the last computed speed so that the output length matches the number of time points.
- Return type:
np.ndarray of shape (…, n_times)
- Raises:
ValueError – If
trajhas fewer than two dimensions, contains fewer than two time points, or ifdt <= 0.
Notes
This function computes the norm of the first difference along the time axis, divided by
dt.See also
trajectory_accelerationSecond-order trajectory dynamics.
trajectory_path_lengthTotal or cumulative traveled distance.
trajectory_displacementDistance from the initial state across time.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [2.0, 0.0]]) >>> trajectory_speed(traj) array([1., 1., 1.])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_curvature(traj: numpy.ndarray) numpy.ndarray[source]¶
Calculate geometric curvature of a trajectory.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
- Returns:
Curvature timecourse aligned with the input time axis.
- Return type:
np.ndarray of shape (…, n_times)
- Raises:
ValueError – If
trajhas fewer than two dimensions or fewer than two time points.
Notes
For vector-valued trajectories, curvature is computed from first and second derivatives using the generalized formula
sqrt(||v||^2 ||a||^2 - (v . a)^2) / ||v||^3.The implementation assumes uniformly spaced samples.
See also
trajectory_turning_angleDiscrete local directional change.
trajectory_tortuosityPath inefficiency relative to net displacement.
trajectory_speedFirst-order trajectory dynamics.
Examples
>>> import numpy as np >>> t = np.linspace(0, 2 * np.pi, 100) >>> traj = np.stack([np.cos(t), np.sin(t)], axis=1) >>> k = trajectory_curvature(traj) >>> k.shape (100,)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_path_length(traj: numpy.ndarray, *, cumulative: bool = False) numpy.ndarray[source]¶
Calculate trajectory path length.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
cumulative (bool, default=False) – If
True, return cumulative path length aligned with the input time axis. Otherwise return total path length for each trajectory.
- Returns:
Total path length with shape
(...)whencumulative=False, or cumulative path length with shape(..., n_times)whencumulative=True.- Return type:
np.ndarray
See also
trajectory_displacementDistance from the initial state across time.
trajectory_tortuosityRatio of path length to net displacement.
trajectory_speedFirst-order local motion magnitude.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [2.0, 0.0]]) >>> trajectory_path_length(traj) np.float64(2.0)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_displacement(traj: numpy.ndarray) numpy.ndarray[source]¶
Calculate displacement from the initial state across time.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
- Returns:
Euclidean displacement from the first time point at each time index.
- Return type:
np.ndarray of shape (…, n_times)
See also
trajectory_path_lengthTotal or cumulative traveled distance.
trajectory_tortuosityRatio of traveled distance to final displacement.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0]]) >>> trajectory_displacement(traj) array([0. , 1. , 1.41421356])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_tortuosity(traj: numpy.ndarray, eps: float = 1e-08) numpy.ndarray[source]¶
Calculate trajectory tortuosity.
Tortuosity is defined as total path length divided by net displacement from the initial to the final state.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
eps (float, default=1e-8) – Small constant used to identify near-zero displacement.
- Returns:
Tortuosity for each trajectory. Stationary trajectories return
1.0; trajectories with nonzero path length but near-zero net displacement returnnp.inf.- Return type:
np.ndarray of shape (…)
See also
trajectory_path_lengthTotal traveled distance along the path.
trajectory_displacementNet displacement from start to end.
trajectory_curvatureLocal geometric bending.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [2.0, 0.0]]) >>> trajectory_tortuosity(traj) np.float64(1.0)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_turning_angle(traj: numpy.ndarray) numpy.ndarray[source]¶
Calculate local turning angles between consecutive trajectory segments.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
- Returns:
Turning-angle timecourse in radians. The first and last time points are padded with the nearest interior angle to preserve length.
- Return type:
np.ndarray of shape (…, n_times)
See also
trajectory_curvatureContinuous geometric bending.
trajectory_speedLocal motion magnitude.
trajectory_path_lengthTotal or cumulative traveled distance.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0]]) >>> trajectory_turning_angle(traj) array([1.57079633, 1.57079633, 1.57079633])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_dispersion(traj: numpy.ndarray, labels: numpy.ndarray | None = None) Dict[str, numpy.ndarray] | numpy.ndarray[source]¶
Calculate within-group trajectory dispersion across time.
- Parameters:
traj (np.ndarray of shape (n_trials, n_times, n_dims)) – Trial trajectory tensor.
labels (np.ndarray of shape (n_trials,), optional) – Optional group label for each trial. If omitted, a single global dispersion timecourse is returned.
- Returns:
Global dispersion timecourse when
labelsis omitted, otherwise a mapping from label to dispersion timecourse.- Return type:
np.ndarray or dict[str, np.ndarray]
See also
trajectory_separationUnified separation entrypoint.
trajectory_separationUse
method="within_between_ratio"for normalized separation.
Examples
>>> import numpy as np >>> traj = np.zeros((2, 3, 2)) >>> traj[1, :, 0] = 1.0 >>> trajectory_dispersion(traj) array([0.5, 0.5, 0.5])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_separation(traj: numpy.ndarray, labels: numpy.ndarray, method: str = 'centroid', **kwargs) Dict[Tuple[str, str], numpy.ndarray][source]¶
Calculate time-resolved separation between labeled trajectory groups.
- Parameters:
traj (np.ndarray of shape (n_trials, n_times, n_dims)) – Trajectory tensor containing one trajectory per trial.
labels (np.ndarray of shape (n_trials,)) – Class label for each trial.
method ({"centroid", "within_between_ratio", "mahalanobis",) – “distributional”, “margin”}, default=”centroid” Separation definition to compute.
**kwargs (dict) – Additional keyword arguments forwarded to the selected separation method.
- Returns:
Mapping from label pairs to separation timecourses of shape
(n_times,).- Return type:
dict[tuple[str, str], np.ndarray]
- Raises:
ValueError – If the inputs are invalid or if an unsupported separation method is requested.
Notes
This is the high-level separation entrypoint for trajectory-group comparison. It dispatches to the more specific separation primitives in this module.
Supported methods:
"centroid": Euclidean distance between label centroids."within_between_ratio": Between-centroid distance normalized by within-group dispersion."mahalanobis": Covariance-aware centroid separation."distributional": Energy-distance separation between trial clouds."margin": Nearest-cross minus nearest-within margin separation.
See also
trajectory_dispersionWithin-group spread used by some separation methods.
Examples
>>> import numpy as np >>> traj = np.zeros((4, 5, 2)) >>> labels = np.array(["A", "A", "B", "B"]) >>> sep = trajectory_separation(traj, labels, method="centroid") >>> list(sep.keys()) [('A', 'B')]