void subset_points(point_t p[], const size_t n, const size_t k) { assert(monotonicity(p, n) == NON_MONOTONIC); if(k == n) return; assert(k <= n); size_t max_idx = point_max_index(p, n); if(max_idx != 1) { /* Always keep the points before and after max_idx */ const size_t n_before = max_idx - 1; const size_t s = n_before * sizeof(point_t); point_t *buf = malloc(s); memcpy(buf, p, s); memmove(p, p + max_idx - 1, sizeof(point_t) * 3); memcpy(p + 3, buf, s); free(buf); } sort_by_like(p + 3, n - 3); sort_by_t(p, k); }
void subset_points(point_t p[], const size_t n, const size_t k) { sort_by_t(p, n); if (k == n) return; assert(k < n); curve_type_t curvature = classify_curve(p, n); assert(curvature == CRV_ENC_MAXIMA || curvature == CRV_MONO_DEC); if (curvature == CRV_MONO_DEC) { /* Keep leftmost k - 1 points, which are already in place, and * the rightmost point (for matching the asymptote). */ p[k - 1] = p[n - 1]; return; } /* Otherwise, the curvature is CRV_ENC_MAXIMA. Keep the maximum * and its neighbors and sort the rest by likelihood. */ assert(n >= 3); size_t max_idx = point_max_index(p, n); if (max_idx > 1) { const size_t n_before = max_idx - 1; const size_t s = n_before * sizeof(point_t); point_t *buf = malloc(s); memcpy(buf, p, s); memmove(p, p + max_idx - 1, sizeof(point_t) * 3); memcpy(p + 3, buf, s); free(buf); } if (k > 3) { sort_by_like(p + 3, n - 3); } sort_by_t(p, k); }