def test_supremum(): # Normal flow data = np.array([1, 0, 3, 2]) assert smath.supremum(1, data) == 2 # Doesn't exist assert smath.supremum(3, data) is None # Empty data assert smath.supremum(1, np.array([])) is None
def get_next_time(self, t_0): """Get time from *t_0* when the trajectory will have travelled more than pixel size.""" if self.stationary: return np.inf * q.s elif not self.bound: raise TrajectoryError("Trajectory not bound") u_0 = self.get_parameter(t_0) distances = self.get_distances(u_0=u_0) # Use the same parameter for distances and trajectory so that we can directly use the # parameter for time calculation. This is however an approximation and if the distance # spline doesn't have enough points it can cause inaccuracies. dtck = interp.splprep(distances, u=self.parameter, s=0)[0] def shift_spline(sgn): t, c, k = dtck c = np.array(c) + sgn * self._pixel_size.simplified.magnitude return t, c, k t_1 = t_2 = np.inf lower_tck = shift_spline(1) upper_tck = shift_spline(-1) # Get the +/- distance roots (we can traverse the trajectory backwards) lower = interp.sproot(lower_tck) upper = interp.sproot(upper_tck) # Combine lower and upper into one list of roots for every dimension roots = [np.concatenate((lower[i], upper[i])) for i in range(3)] # Mix all dimensions, they are not necessary for obtaining the minimum # parameter difference roots = np.concatenate(roots) # Filter roots to get only the infimum and supremum based on u_0 smallest = smath.infimum(u_0, roots) greatest = smath.supremum(u_0, roots) # Get next time for both directions if smallest is not None: t_1 = self._get_next_time(t_0, smallest) if t_1 is None: t_1 = np.inf if greatest is not None: t_2 = self._get_next_time(t_0, greatest) if t_2 is None: t_2 = np.inf # Next time is the smallest one which is greater than t_0. # Get a supremum and if the result is not infinity there # is a time in the future for which the trajectory moves # the associated object more than *distance*. closest_time = smath.supremum(t_0.simplified.magnitude, [t_1, t_2]) return closest_time * q.s
def _get_next_time(self, t_0, u_0): """ Get the next time when the trajectory parameter will be at position *u_0*. There can be multiple results but only the closest one is returned. """ if self.stationary: return np.inf * q.s t, c, k = self._time_tck c = c - (self.length.magnitude * u_0) shifted_tck = t, c, k roots = interp.sproot(shifted_tck, mest=100) if len(roots) == 0: return np.inf * q.s return smath.supremum(t_0.simplified.magnitude, roots)