1- use approx:: relative_eq;
1+ use approx:: { relative_eq, relative_ne } ;
22use indexmap:: { IndexMap , IndexSet } ;
33use itertools:: { Either , Itertools } ;
44use nalgebra:: { DMatrix , DVector } ;
@@ -19,6 +19,7 @@ pub struct Solver {
1919 var_to_constraints : IndexMap < Var , IndexSet < ConstraintId > > ,
2020 solved_vars : IndexMap < Var , f64 > ,
2121 inconsistent_constraints : IndexSet < ConstraintId > ,
22+ invalid_rounding : IndexSet < Var > ,
2223}
2324
2425fn round ( x : f64 ) -> f64 {
@@ -57,6 +58,11 @@ impl Solver {
5758 & self . inconsistent_constraints
5859 }
5960
61+ #[ inline]
62+ pub fn invalid_rounding ( & self ) -> & IndexSet < Var > {
63+ & self . invalid_rounding
64+ }
65+
6066 pub fn unsolved_vars ( & self ) -> IndexSet < Var > {
6167 IndexSet :: from_iter ( ( 0 ..self . next_var ) . map ( Var ) . filter ( |& v| !self . is_solved ( v) ) )
6268 }
@@ -95,11 +101,15 @@ impl Solver {
95101 let ( coeff, var) = constraint. coeffs [ 0 ] ;
96102 let val = -constraint. constant / coeff;
97103 if let Some ( old_val) = self . solved_vars . get ( & var) {
98- if ! relative_eq ! ( * old_val, val, epsilon = EPSILON ) {
104+ if relative_ne ! ( * old_val, val, epsilon = EPSILON ) {
99105 self . inconsistent_constraints . insert ( constraint_id) ;
100106 }
101107 } else {
102- self . solved_vars . insert ( var, val) ;
108+ let rounded_val = round ( val) ;
109+ if relative_ne ! ( val, rounded_val, epsilon = EPSILON ) {
110+ self . invalid_rounding . insert ( var) ;
111+ }
112+ self . solved_vars . insert ( var, rounded_val) ;
103113 }
104114 self . constraints . swap_remove ( & constraint_id) ;
105115 for constraint in self
@@ -146,8 +156,7 @@ impl Solver {
146156 if !self . solved_vars . contains_key ( & Var ( i) )
147157 && relative_eq ! ( recons, 1. , epsilon = EPSILON )
148158 {
149- let val = round ( sol[ ( i as usize , 0 ) ] ) ;
150- self . solved_vars . insert ( Var ( i) , val) ;
159+ self . solved_vars . insert ( Var ( i) , sol[ ( i as usize , 0 ) ] ) ;
151160 }
152161 }
153162 for ( id, constraint) in self . constraints . iter_mut ( ) {
@@ -158,6 +167,16 @@ impl Solver {
158167 self . inconsistent_constraints . insert ( * id) ;
159168 }
160169 }
170+ for i in 0 ..self . next_var {
171+ if let Some ( val) = self . solved_vars . get_mut ( & Var ( i) ) {
172+ let rounded_val = round ( * val) ;
173+ if relative_ne ! ( * val, rounded_val, epsilon = EPSILON ) {
174+ self . invalid_rounding . insert ( Var ( i) ) ;
175+ } else {
176+ * val = rounded_val;
177+ }
178+ }
179+ }
161180 self . constraints
162181 . retain ( |_, constraint| !constraint. coeffs . is_empty ( ) ) ;
163182 }
0 commit comments