diff -r 4e09b7829b51 -r f40dfaf2166d src/bisection_tree/btfn.rs --- a/src/bisection_tree/btfn.rs Tue Nov 01 09:24:45 2022 +0200 +++ b/src/bisection_tree/btfn.rs Fri Nov 18 10:29:50 2022 +0200 @@ -573,7 +573,7 @@ &self, aggregator : &Bounds, cube : &Cube, - data : &Vec, + data : &[G::Id], generator : &G, step : usize ) -> RefinerResult, Self::Result> { @@ -630,7 +630,7 @@ &self, aggregator : &Bounds, cube : &Cube, - data : &Vec, + data : &[G::Id], generator : &G, step : usize ) -> RefinerResult, Self::Result> { @@ -658,7 +658,13 @@ // The data is refined enough, so return new hopefully better bounds // and the minimiser. let res = (x, v); - let bounds = Bounds(v, v); + let l = aggregator.lower(); + let bounds = if l > v { + eprintln!("imprecision!"); + Bounds(l, l) + } else { + Bounds(v, v) + }; RefinerResult::Uncertain(bounds, Some(res)) } } @@ -701,7 +707,7 @@ &self, aggregator : &Bounds, _cube : &Cube, - _data : &Vec, + _data : &[G::Id], _generator : &G, step : usize ) -> RefinerResult, Self::Result> { @@ -735,7 +741,7 @@ &self, aggregator : &Bounds, _cube : &Cube, - _data : &Vec, + _data : &[G::Id], _generator : &G, step : usize ) -> RefinerResult, Self::Result> { @@ -759,6 +765,21 @@ } } +// FIXME: The most likely reason for the “Refiner failure” expectation in the methods below +// is numerical inaccuracy: the `glb` maintained in `HeapContainer` (`refine.rs`) becomes bigger +// than the *upper bound* of nodes attempted to be inserted into the `heap` in the container. +// But the `glb` is there exactly to prevent that. Due to numerical inaccuracy, however, a +// newly subdivided node may have lower upper bound than the original lower bound that should +// have been above the `glb` since the node was picked from the queue. Due to the subdivision +// process, if a node whose lower bound is at the `glb` is picked, all of its refined subnodes +// should have lower bound at least the old `glb`, so in a single-threaded situation there should +// always be nodes above the `glb` in the queue. In a multi-threaded situation a node below the +// `glb` may be picked by some thread. When that happens, that thread inserts no new nodes into +// the queue. If the queue empties as a result of that, the thread goes to wait for other threads +// to produce results. Since some node had a node whose lower bound was above the `glb`, eventually +// there should be a result, or new nodes above the `glb` inserted into the queue. Then the waiting +// threads can also continue processing. If, however, numerical inaccuracy destroyes the `glb`, +// the queue may run out, and we get “Refiner failure”. impl BTFN where BT : BTSearch>, G : SupportGenerator,