Skip to main content

Formulating unique assignments recursively.

Project description

Recursive-Matching

An algorithm designed to formulate unique assignments with the highest (default) or lowest values found by recursively matching and rematching pairs to assert the best matching pair.

This algorithm differs from the Hungarian Algorithm which seeks to formulate assignments based on the minimum (default) or maximum sum of the assignments. The hungarian algorithm has the following properties which may not be ideal for certain applications.

  • The assignments formulated with the maximum sum does not always guarantee individual assignments with the highest possible outcome.
  • The assignments formulated with the minimum sum does not always guarantee individual assignments with the lowest possible outcome.

Application

Computer Vision

Consider the following figure which shows a set of ground truth (blue) bounding boxes and a set of prediction (red) bounding boxes.

Computer Vision Sample

Visually, it is clear which ground truth bounding box closely correlates to the prediction bounding box.

Graphically, the coordinates of the bounding boxes are as follows.

Ground Truths

  • G0 [10, 110, 60, 140]
  • G1 [20, 60, 50, 90]
  • G2 [60, 40, 100, 100]
  • G3 [100, 10, 160, 70]
  • G4 [20, 100, 50, 140]

Predictions

  • P0 [120, 100, 160, 140]
  • P1 [30, 80, 70, 130]
  • P2 [70, 30, 90, 90]
  • P3 [90, 20, 150, 60]
  • P4 [20, 100, 50, 140]

The ground truth to prediction bounding boxes are matched as follows.

  • (G0, P1)
  • (G2, P2)
  • (G3, P3)
  • (G4, P4)

The IoU (intersection over union) is a metric that best describes how well a bounding box intersects with another which is the metric used to measure the best matches between a set of bounding boxes.

In this example, given a set of ground truth and prediction bounding boxes, an IoU 2D matrix is generated which is taken as an input to the recursive matching algorithm to find the best matches for the ground truth and prediction bounding boxes.

The recursive matching algorithm will match based on the highest IoU matches which differs from the hungarian algorithm where the assignments are based on the maximum sum overall where the individual matches may not be the maximum within a set of options.

For more information, see /python/demo.ipynb

Changelog

  • Feb 06, 2025 [v1.0]: First release - python implementation.
  • Mar 02, 2025 [v1.0.1]: Rust implementation, doc fixes, python file name changes.
  • Mar 20, 2025 [v1.0.2]: C implementation, python error message changes.

Modules

The algorithm will be implemented in three languages: Python, Rust, C.

Python

This implementation can be found under /python. However, it can be installed via pip with the following command.

pip install recursive-matching

To use the module, first import the algorithm.

from matching import recursive_match

The following is an example deployment of the algorithm.

import numpy as np

matrix = np.array([
        [0.,         0.,         0.,         0.,         0.        ],
        [0.20689655, 0.07407407, 0.04761905, 0.,         0.23076923],
        [0.,         0.,         0.38461538, 0.,         0.,        ],
        [0.,         0.,         0.04347826, 0.5,        0.,        ],
        [0.5,        0.,         0.,         0.,         1.,        ]
    ], dtype=np.float32)
    
matches = recursive_match(matrix=matrix)
print(f"{matches=}")

Rust

This implementation can be found under /rust. To use the crate, add the following to your Cargo.toml.

[dependencies]
recursive_matching = "1.0.1"

Next import the crate.

use recursive_matching::recursive_match;
use ndarray::{array, Array2};

let mut matrix: Array2<f32> = array![
    [0.0, 0.0, 0.0, 0.0, 0.0,],
    [0.20689655, 0.07407407, 0.04761905, 0.0, 0.23076923],
    [0.0, 0.0, 0.38461538, 0.0, 0.0],
    [0.0, 0.0, 0.04347826, 0.5, 0.0],
    [0.5, 0.0, 0.0, 0.0, 1.0]
];

let matches = recursive_match(&mut matrix, 1 as usize, true, false);

println!("Matches: {:?}", matches);

C

This implementation can be found under /c. See the following usage of the library implemented under main.c

Include the following libraries.

#include <stdio.h>
#include <stdbool.h>
#include "matrix.h"
#include "lib.h"
float data[5][5] = {
    {0.0, 0.0, 0.0, 0.0, 0.0,},
    {0.20689655, 0.07407407, 0.04761905, 0.0, 0.23076923},
    {0.0, 0.0, 0.38461538, 0.0, 0.0},
    {0.0, 0.0, 0.04347826, 0.5, 0.0},
    {0.5, 0.0, 0.0, 0.0, 1.0}
};

Matrix* matrix = create_matrix(5, 5, data);
if (!matrix)
    return 1; // Error occured.

int* matches = recursive_match(matrix, 1, true, false);

printf("Matches: [");
for (int i = 0; i < matrix->rows; i++)
    printf("%d ", matches[i]);
printf("]\n");

// Free allocated memory.
free_matrix(matrix);

To build the library the following command is used.

cd c/matching
make

License

This project is licensed under the GPL v3.0 License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

recursive-matching-1.1.0.tar.gz (9.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

recursive_matching-1.1.0-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

File details

Details for the file recursive-matching-1.1.0.tar.gz.

File metadata

  • Download URL: recursive-matching-1.1.0.tar.gz
  • Upload date:
  • Size: 9.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for recursive-matching-1.1.0.tar.gz
Algorithm Hash digest
SHA256 fe546ede9e47be027a5db6d0412161256ceab3a90b87d8b1b8f0de274ac52e53
MD5 8fda1e665ea9af63c111a8291eeba628
BLAKE2b-256 c297c97404e28b64bb6b183548d7e6c48a1a5a852f72691897abc1e50c5178f9

See more details on using hashes here.

File details

Details for the file recursive_matching-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for recursive_matching-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b6e30157df239444a6357ac00aeba753498b89e0c481f9c0516931b86f9f41f1
MD5 52a5b4cb02b23306ace9df6bc3d6dabb
BLAKE2b-256 6f018d900d5ae8780ccc790a4e25d839b0635b9c14e0a70dc122d4dfc9ca02c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page