@@ -65,19 +65,22 @@ impl SparseIndex {
65
65
}
66
66
}
67
67
68
- /// Represents a maximum (upper envelope) of a collection of linear functions of a variable,
69
- /// evaluated using the convex hull trick with square root decomposition.
70
- pub struct PiecewiseLinearFn {
68
+ /// Represents a maximum (upper envelope) of a collection of linear functions of one
69
+ /// variable, evaluated using an online version of the convex hull trick.
70
+ /// It combines the offline algorithm with square root decomposition, resulting in an
71
+ /// asymptotically suboptimal but simple algorithm with good amortized performnce:
72
+ /// For N inserts interleaved with Q queries, a threshold of N/sqrt(Q) yields
73
+ /// O(N sqrt Q + Q log N) time complexity. If all queries come after all inserts,
74
+ /// any threshold less than N (e.g., 0) yields O(N + Q log N) time complexity.
75
+ pub struct PiecewiseLinearConvexFn {
71
76
recent_lines : Vec < ( f64 , f64 ) > ,
72
77
sorted_lines : Vec < ( f64 , f64 ) > ,
73
78
intersections : Vec < f64 > ,
74
79
merge_threshold : usize ,
75
80
}
76
81
77
- impl PiecewiseLinearFn {
78
- /// For N inserts interleaved with Q queries, a threshold of N/sqrt(Q) yields
79
- /// O(N sqrt Q + Q log N) time complexity. If all queries come after all inserts,
80
- /// any threshold less than N (e.g., 0) yields O(N + Q log N) time complexity.
82
+ impl PiecewiseLinearConvexFn {
83
+ /// Initializes with a given threshold for re-running the convex hull algorithm
81
84
pub fn with_merge_threshold ( merge_threshold : usize ) -> Self {
82
85
Self {
83
86
recent_lines : vec ! [ ] ,
@@ -210,7 +213,7 @@ mod test {
210
213
[ 1 , -1 , -2 , -1 , 0 , 1 ] ,
211
214
] ;
212
215
for threshold in 0 ..=lines. len ( ) {
213
- let mut func = PiecewiseLinearFn :: with_merge_threshold ( threshold) ;
216
+ let mut func = PiecewiseLinearConvexFn :: with_merge_threshold ( threshold) ;
214
217
assert_eq ! ( func. evaluate( 0.0 ) , -1e18 ) ;
215
218
for ( & ( slope, intercept) , expected) in lines. iter ( ) . zip ( results. iter ( ) ) {
216
219
func. max_with ( slope as f64 , intercept as f64 ) ;
0 commit comments