def prediction_upperbound()

in scripts/compute_upperbound.py [0:0]


def prediction_upperbound(seq_of_landmarks, goldstandard_features, neighborhood, boundaries, loc, actions=None, step_fn=step_agnostic, action_space=[]):
    depth = len(seq_of_landmarks)

    if actions is not None:
        assert len(actions) == depth - 1

    if len(action_space) == 4:
        paths = init_paths_agnostic(neighborhood, boundaries, goldstandard_features)
    else:
        paths = init_paths_aware(neighborhood, boundaries, goldstandard_features)

    for i in range(4):
        for j in range(4):
            path = dict()
            path['loc'] = [boundaries[0] + i, boundaries[1] + j, 0]
            path['seq_of_landmarks'] = [goldstandard_features.get(neighborhood, path['loc'])]
            paths.append(path)

    for d in range(depth-1):
        new_paths = list()
        for path in paths:
            for act in action_space:
                if actions is None or actions[d] == act:
                    path_new = copy.deepcopy(path)
                    path_new['loc'] = step_fn(act, path['loc'], boundaries)
                    path_new['seq_of_landmarks'].append(goldstandard_features.get(neighborhood, path_new['loc']))
                    new_paths.append(path_new)
        paths = new_paths

    loc2cnt = dict()
    for path in paths:
        if all([l1 == l2 for l1, l2 in zip(path['seq_of_landmarks'], seq_of_landmarks)]):
            if (path['loc'][0], path['loc'][1]) in loc2cnt:
                loc2cnt[(path['loc'][0], path['loc'][1])] += 1
            else:
                loc2cnt[(path['loc'][0], path['loc'][1])] = 1

    # find maximum
    selected_loc = max(loc2cnt.items(), key=operator.itemgetter(1))[0]
    acc = float(selected_loc[0] == loc[0] and selected_loc[1] == loc[1])
    return acc