Exemple #1
0
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);
}
Exemple #2
0
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);
}