{"record":{"id":"3d2e1c3a1b090b13","repo":"AtsushiSakai/PythonRobotics","slug":"x-coordinates-must-be-sorted-in-ascending-order","errorCode":null,"errorMessage":"x coordinates must be sorted in ascending order","messagePattern":"x coordinates must be sorted in ascending order","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"PathPlanning/CubicSpline/cubic_spline_planner.py","lineNumber":50,"sourceCode":"    >>> y = [1.7, -6, 5, 6.5, 0.0]\n    >>> sp = CubicSpline1D(x, y)\n    >>> xi = np.linspace(0.0, 5.0)\n    >>> yi = [sp.calc_position(x) for x in xi]\n    >>> plt.plot(x, y, \"xb\", label=\"Data points\")\n    >>> plt.plot(xi, yi , \"r\", label=\"Cubic spline interpolation\")\n    >>> plt.grid(True)\n    >>> plt.legend()\n    >>> plt.show()\n\n    .. image:: cubic_spline_1d.png\n\n    \"\"\"\n\n    def __init__(self, x, y):\n\n        h = np.diff(x)\n        if np.any(h < 0):\n            raise ValueError(\"x coordinates must be sorted in ascending order\")\n\n        self.a, self.b, self.c, self.d = [], [], [], []\n        self.x = x\n        self.y = y\n        self.nx = len(x)  # dimension of x\n\n        # calc coefficient a\n        self.a = [iy for iy in y]\n\n        # calc coefficient c\n        A = self.__calc_A(h)\n        B = self.__calc_B(h, self.a)\n        self.c = np.linalg.solve(A, B)\n\n        # calc spline coefficient b and d\n        for i in range(self.nx - 1):\n            d = (self.c[i + 1] - self.c[i]) / (3.0 * h[i])\n            b = 1.0 / h[i] * (self.a[i + 1] - self.a[i]) \\","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/AtsushiSakai/PythonRobotics/blob/1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d/PathPlanning/CubicSpline/cubic_spline_planner.py#L32-L68","documentation":"CubicSpline's constructor computes np.diff(x) and rejects any negative difference, i.e. x points not sorted ascending. Spline math requires monotonically increasing knots.","triggerScenarios":"Constructing CubicSpline(x, y) with x out of order, e.g. [0, 2, 1, 3], or with duplicate/unsorted waypoint data from a file.","commonSituations":"Waypoints collected from GPS or user input in arbitrary order, or data shuffled during preprocessing before spline fitting.","solutions":["Sort points by x before construction: order = np.argsort(x); CubicSpline(x[order], y[order]).","Fix the data source to emit monotonically increasing x.","Validate np.all(np.diff(x) > 0) before calling."],"exampleFix":"# before\nsp = CubicSpline(x, y)  # x unsorted\n\n# after\norder = np.argsort(x)\nsp = CubicSpline(x[order], y[order])","handlingStrategy":"validation","validationCode":"import numpy as np\nassert np.all(np.diff(x) > 0), 'x must be strictly ascending'","typeGuard":"def sorted_ascending(x) -> bool:\n    import numpy as np\n    return bool(np.all(np.diff(x) > 0))","tryCatchPattern":null,"preventionTips":["Sort waypoints by x (keeping y aligned) before spline fitting.","Validate np.diff monotonicity in data-loading tests."],"tags":["spline-interpolation","numpy","input-validation"],"backgroundTag":"unsorted-input-data","analyzedSha":"1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d","analyzedAt":"2026-08-28T13:23:33.733Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}