Skip to content

Commit

Permalink
Updated birthday coefficients
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaCappelletti94 committed Sep 10, 2024
1 parent 8bb3fb4 commit 162542b
Show file tree
Hide file tree
Showing 14 changed files with 4,094 additions and 8,085 deletions.
90 changes: 45 additions & 45 deletions hash_list_correction/gap_hash_correction.csv
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
precision,bits,rate_of_improvement,uncorrected_error,corrected_error
4,4,88.86,0.10,0.00
4,5,114.84,0.19,0.00
4,6,321.85,0.21,0.00
5,4,374.00,0.10,0.00
5,5,171.85,0.15,0.00
5,6,91.44,0.15,0.00
6,4,237.23,0.09,0.00
6,5,88.95,0.10,0.00
6,6,140.74,0.12,0.00
7,4,95.07,0.06,0.00
7,5,105.34,0.08,0.00
7,6,191.71,0.10,0.00
8,4,107.41,0.04,0.00
8,5,138.87,0.05,0.00
8,6,196.99,0.06,0.00
9,4,217.83,0.02,0.00
9,5,330.99,0.03,0.00
9,6,399.49,0.04,0.00
10,4,68.54,0.02,0.00
10,5,142.40,0.02,0.00
10,6,208.17,0.03,0.00
11,4,192.85,0.01,0.00
11,5,154.71,0.02,0.00
11,6,250.10,0.02,0.00
12,4,196.71,0.01,0.00
12,5,308.11,0.01,0.00
12,6,390.63,0.02,0.00
13,4,244.59,0.01,0.00
13,5,242.39,0.01,0.00
13,6,448.92,0.01,0.00
14,4,346.10,0.01,0.00
14,5,278.19,0.01,0.00
14,6,629.92,0.01,0.00
15,4,529.22,0.00,0.00
15,5,275.43,0.01,0.00
15,6,1108.07,0.01,0.00
16,4,699.21,0.00,0.00
16,5,1037.62,0.01,0.00
16,6,740.38,0.01,0.00
17,4,634.79,0.00,0.00
17,5,718.83,0.00,0.00
17,6,490.78,0.01,0.00
18,4,549.52,0.00,0.00
18,5,447.08,0.00,0.00
18,6,1994.33,0.01,0.00
4,4,34.54,0.10,0.00
4,5,12.91,0.19,0.01
4,6,52.81,0.21,0.00
5,4,60.29,0.10,0.00
5,5,45.72,0.15,0.00
5,6,31.58,0.15,0.00
6,4,208.68,0.09,0.00
6,5,31.29,0.10,0.00
6,6,44.81,0.12,0.00
7,4,38.90,0.07,0.00
7,5,116.65,0.09,0.00
7,6,111.08,0.12,0.00
8,4,147.23,0.06,0.00
8,5,155.03,0.08,0.00
8,6,56.54,0.11,0.00
9,4,78.23,0.06,0.00
9,5,50.94,0.08,0.00
9,6,62.57,0.10,0.00
10,4,235.59,0.05,0.00
10,5,72.32,0.07,0.00
10,6,239.29,0.10,0.00
11,4,66.73,0.04,0.00
11,5,272.52,0.07,0.00
11,6,269.94,0.09,0.00
12,4,165.10,0.05,0.00
12,5,414.81,0.07,0.00
12,6,1206.77,0.09,0.00
13,4,292.16,0.05,0.00
13,5,489.75,0.07,0.00
13,6,469.96,0.09,0.00
14,4,573.18,0.05,0.00
14,5,1510.12,0.07,0.00
14,6,1476.07,0.09,0.00
15,4,1554.05,0.05,0.00
15,5,1751.94,0.07,0.00
15,6,1665.32,0.09,0.00
16,4,398.07,0.05,0.00
16,5,644.39,0.07,0.00
16,6,622.48,0.09,0.00
17,4,815.35,0.05,0.00
17,5,1391.01,0.07,0.00
17,6,1709.16,0.09,0.00
18,4,1876.76,0.05,0.00
18,5,2064.07,0.07,0.00
18,6,2135.24,0.09,0.00
1 change: 1 addition & 0 deletions hash_list_correction/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use switch_hash::compute_switch_hash_correction;
mod gap_hash;
use gap_hash::compute_gap_hash_correction;
mod utils;
mod ramer_douglas_peucker;

fn main() {
compute_switch_hash_correction();
Expand Down
221 changes: 221 additions & 0 deletions hash_list_correction/src/ramer_douglas_peucker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
//! Submodule providing the Ramer-Douglas-Peucker algorithm for line simplification.
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct Point {
x: f64,
y: f64,
}

impl From<(f64, f64)> for Point {
fn from((x, y): (f64, f64)) -> Self {
Self { x, y }
}
}

impl Point {
fn distance_to(&self, other: &Point) -> f64 {
((self.x - other.x).powi(2) + (self.y - other.y).powi(2)).sqrt()
}

/// Get the x-coordinate of the point
pub fn x(&self) -> f64 {
self.x
}

/// Get the y-coordinate of the point
pub fn y(&self) -> f64 {
self.y
}
}

// Compute the perpendicular distance from point 'p' to the line segment from 'start' to 'end'
fn perpendicular_distance(point: &Point, start: &Point, end: &Point) -> f64 {
let line_length = start.distance_to(end);
if line_length == 0.0 {
return point.distance_to(start);
}

// Compute the projection of 'p' onto the line segment
let t = ((point.x - start.x) * (end.x - start.x) + (point.y - start.y) * (end.y - start.y))
/ line_length.powi(2);

// If the projection is outside the line segment, return the distance to the closest endpoint
if t < 0.0 {
point.distance_to(start)
} else if t > 1.0 {
point.distance_to(end)
} else {
// Otherwise, return the distance to the line
let projection = Point {
x: start.x + t * (end.x - start.x),
y: start.y + t * (end.y - start.y),
};
point.distance_to(&projection)
}
}

/// Recursive function for the Ramer-Douglas-Peucker algorithm
///
/// # Arguments
/// * `points` - The list of points to simplify
/// * `tolerance` - The maximum distance from the simplified line
/// * `max_points` - The maximum number of points to return
pub fn rdp(points: &[Point], tolerance: f64, max_points: usize) -> Vec<Point> {
if points.len() < 2 {
return points.to_vec();
}

// Find the point with the maximum distance from the line segment connecting the first and last points
let (index, max_distance) = points
.iter()
.enumerate()
.skip(1)
.take(points.len() - 2)
.map(|(i, point)| {
(
i,
perpendicular_distance(point, &points[0], &points[points.len() - 1]),
)
})
.fold((0, 0.0), |(max_index, max_dist), (i, dist)| {
if dist > max_dist {
(i, dist)
} else {
(max_index, max_dist)
}
});

// If the maximum distance is greater than the tolerance, recursively simplify
if max_distance > tolerance && max_points > 2 {
let mut result1 = rdp(&points[..=index], tolerance, max_points / 2);
let mut result2 = rdp(&points[index..], tolerance, max_points / 2);

// Combine the results, removing the duplicate point at index
result1.pop();
result1.append(&mut result2);

result1
} else {
// If no point is farther than the tolerance, return just the endpoints
vec![points[0], points[points.len() - 1]]
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_no_simplification() {
let points = vec![
Point { x: 0.0, y: 0.0 },
Point { x: 1.0, y: 0.0 },
Point { x: 2.0, y: 0.0 },
Point { x: 3.0, y: 0.0 },
Point { x: 4.0, y: 0.0 },
];

let tolerance = 0.001;
let simplified = rdp(&points, tolerance, 10);

// With a low tolerance, no simplification should occur
assert_eq!(simplified.len(), 2);
assert_eq!(simplified, [points[0], points[points.len() - 1]]);
}

#[test]
fn test_full_simplification() {
let points = vec![
Point { x: 0.0, y: 0.0 },
Point { x: 1.0, y: 0.0 },
Point { x: 2.0, y: 0.0 },
Point { x: 3.0, y: 0.0 },
Point { x: 4.0, y: 0.0 },
];

let tolerance = 1.0;
let simplified = rdp(&points, tolerance, 10);

// All points are on a straight line, so the algorithm should return just the endpoints
assert_eq!(simplified.len(), 2);
assert_eq!(simplified, vec![points[0], points[points.len() - 1]]);
}

#[test]
fn test_partial_simplification() {
let points = vec![
Point { x: 0.0, y: 0.0 },
Point { x: 1.0, y: 0.1 },
Point { x: 2.0, y: -0.1 },
Point { x: 3.0, y: 5.0 },
Point { x: 4.0, y: 6.0 },
Point { x: 5.0, y: 7.0 },
];

let tolerance = 1.0;
let simplified = rdp(&points, tolerance, 10);

assert_eq!(simplified.len(), 4);
assert_eq!(simplified, vec![points[0], points[2], points[3], points[5]]);
}

#[test]
fn test_high_tolerance() {
let points = vec![
Point { x: 0.0, y: 0.0 },
Point { x: 1.0, y: 2.0 },
Point { x: 2.0, y: 1.0 },
Point { x: 3.0, y: 4.0 },
Point { x: 4.0, y: 3.0 },
Point { x: 5.0, y: 6.0 },
];

let tolerance = 5.0;
let simplified = rdp(&points, tolerance, 10);

// With a high tolerance, the algorithm should return just the first and last points
assert_eq!(simplified.len(), 2);
assert_eq!(simplified, vec![points[0], points[points.len() - 1]]);
}

#[test]
fn test_single_point() {
let points = vec![Point { x: 0.0, y: 0.0 }];

let tolerance = 0.1;
let simplified = rdp(&points, tolerance, 10);

// A single point cannot be simplified
assert_eq!(simplified.len(), 1);
assert_eq!(simplified, points);
}

#[test]
fn test_two_points() {
let points = vec![Point { x: 0.0, y: 0.0 }, Point { x: 1.0, y: 1.0 }];

let tolerance = 0.1;
let simplified = rdp(&points, tolerance, 10);

// Two points cannot be simplified further
assert_eq!(simplified.len(), 2);
assert_eq!(simplified, points);
}

#[test]
fn test_identical_points() {
let points = vec![
Point { x: 0.0, y: 0.0 },
Point { x: 0.0, y: 0.0 },
Point { x: 0.0, y: 0.0 },
Point { x: 0.0, y: 0.0 },
];

let tolerance = 0.1;
let simplified = rdp(&points, tolerance, 10);

// If all points are the same, the algorithm should return just one point
assert_eq!(simplified.len(), 2);
assert_eq!(simplified, vec![points[0], points[0]]);
}
}
Loading

0 comments on commit 162542b

Please sign in to comment.