Source code for symforce.cam.camera_util

# ----------------------------------------------------------------------------
# SymForce - Copyright 2022, Skydio, Inc.
# This source code is under the Apache 2.0 license found in the LICENSE file.
# ----------------------------------------------------------------------------

import numpy as np

from symforce import typing as T


[docs]def compute_odd_polynomial_critical_point( coefficients: T.Iterable[T.Scalar], max_x: float ) -> float: """ Compute the critical points of the odd polynomial given by: f(x) = x + c0 * x^3 + c1 * x^5 + ... This will return the first real-valued critical point in the range [0, max]. If no real-valued critical points are found in this range, return max. Args: coefficients: the coefficients of the polynomial max_x: the maximum value to be returned if no real-valued critical points are found in [0, max_x] """ # Build the coefficients for np.polynomial. full_poly_coeffs = [0.0, 1.0] for k in coefficients: full_poly_coeffs.extend([0.0, float(k)]) critical_points = np.polynomial.Polynomial(np.array(full_poly_coeffs)).deriv().roots() # NOTE(aaron): This is a tolerance on the result of `np.roots` so it doesn't really have # anything to do with epsilon or anything. Could be worth investigating the actual error # properties on that, but the docs don't say ROOTS_REAL_TOLERANCE = 1e-10 real_critical_points = critical_points[abs(critical_points.imag) < ROOTS_REAL_TOLERANCE].real real_critical_points_in_interval = np.sort( real_critical_points[np.logical_and(real_critical_points > 0, real_critical_points < max_x)] ) if real_critical_points_in_interval.size == 0: return max_x else: return real_critical_points_in_interval[0]