예제 #1
0
def _compute_responses(rec_set1, rec_set2, *, metric=dist_rec_bounds):
    best_responses = defaultdict(lambda: Interval(float('inf'), float('inf')))
    for r1, r2 in product(rec_set1, rec_set2):
        d, d_response = metric(r1, r2), best_responses[r1]
        best_responses[r1] = Interval(min(d.bot, d_response.bot),
                                      min(d.top, d_response.top))
    return best_responses
예제 #2
0
def discretized_and_pointwise_hausdorff(recset1, recset2, k=3):
    xs = list(fn.mapcat(lambda r: r.discretize(k), recset1))
    ys = list(fn.mapcat(lambda r: r.discretize(k), recset2))

    error1 = max(r.error + r.shortest_edge for r in recset1)
    error2 = max(r.error + r.shortest_edge for r in recset2)
    error = error1 + error2
    d12 = pointwise_hausdorff(xs, ys)

    return Interval(max(d12 - error, 0), d12 + error)
예제 #3
0
def directed_hausdorff(recs1, recs2, *, metric=dist_rec_bounds):
    responses = _compute_responses(recs1, recs2)
    values = bind(responses).Values()

    d = Interval(max(values[0].collect()), max(values[1].collect()))

    # TODO: can this be tightened?
    potential_moves = {r for r in recs1 if responses[r] & d}

    def is_required(r2):
        return any(responses[r1] & metric(r1, r2) for r1 in potential_moves)

    required_responses = {r2 for r2 in recs2 if is_required(r2)}
    return d, (potential_moves, required_responses)
예제 #4
0
def oracle_hausdorff_bounds2(recset1, recset2, f1, f2, eps=1e-1, k=3):
    refiner1 = edge_length_guided_refinement(recset1, f1)
    refiner2 = edge_length_guided_refinement(recset2, f2)

    while True:
        xs = list(fn.mapcat(lambda r: r.discretize(k), recset1))
        ys = list(fn.mapcat(lambda r: r.discretize(k), recset2))

        error1 = max(r.error + shortest_edge(r) for r in recset1)
        error2 = max(r.error + shortest_edge(r) for r in recset2)
        error = error1 + error2
        d12 = pointwise_hausdorff(xs, ys)

        yield Interval(max(d12 - error, 0), d12 + error)

        recset1 = fn.first(filter(lambda xs: -xs[0][0] <= eps, refiner1))
        recset2 = fn.first(filter(lambda xs: -xs[0][0] <= eps, refiner2))
        recset1, recset2 = [r for _, r in recset1], [r for _, r in recset2]
        eps /= 2
예제 #5
0
def _midpoint(i):
    mid = i.bot + (i.top - i.bot) / 2
    return Interval(mid, mid)
예제 #6
0
def dist_rec_bounds(r1, r2):
    return Interval(dist_rec_lowerbound(r1, r2), dist_rec_upperbound(r1, r2))