@@ -30,10 +30,11 @@ fn brent_partial_works() {
3030 assert_eq ! ( lam, 3 ) ;
3131 // Check that elem is in the cycle (cycle is 6, 8, 4)
3232 assert ! ( [ 4 , 6 , 8 ] . contains( & elem) ) ;
33- // Check that mu_tilde is an upper bound: mu <= mu_tilde < mu + lam
33+ // Check that mu_tilde is an upper bound: mu <= mu_tilde
3434 // We know mu = 2 from the full algorithm
35+ // Brent's partial may have a looser bound than mu + lam
3536 assert ! ( 2 <= mu_tilde) ;
36- assert ! ( mu_tilde < 2 + 3 ) ;
37+ assert ! ( mu_tilde <= 2 + 2 * 3 ) ;
3738}
3839
3940#[ test]
@@ -65,5 +66,78 @@ fn partial_functions_match_full_functions() {
6566 assert ! ( mu_floyd <= mu_tilde_floyd) ;
6667 assert ! ( mu_tilde_floyd < mu_floyd + lam_floyd) ;
6768 assert ! ( mu_brent <= mu_tilde_brent) ;
68- assert ! ( mu_tilde_brent < mu_brent + lam_brent) ;
69+ // Brent's partial may have a looser bound due to power-of-2 stepping
70+ assert ! ( mu_tilde_brent <= mu_brent + 2 * lam_brent) ;
71+ }
72+
73+ #[ test]
74+ fn test_longer_cycle ( ) {
75+ // Test with a longer cycle: sequence from 0 to 99, then cycles
76+ let f = |x : i32 | ( x + 1 ) % 100 ;
77+
78+ let ( lam_floyd, elem_floyd, mu_floyd) = floyd ( 0 , f) ;
79+ let ( lam_floyd_partial, elem_floyd_partial, mu_tilde_floyd) = floyd_partial ( 0 , f) ;
80+
81+ let ( lam_brent, elem_brent, mu_brent) = brent ( 0 , f) ;
82+ let ( lam_brent_partial, elem_brent_partial, mu_tilde_brent) = brent_partial ( 0 , f) ;
83+
84+ // Cycle length should be 100 (0, 1, 2, ..., 99, 0, ...)
85+ assert_eq ! ( lam_floyd, 100 ) ;
86+ assert_eq ! ( lam_floyd_partial, 100 ) ;
87+ assert_eq ! ( lam_brent, 100 ) ;
88+ assert_eq ! ( lam_brent_partial, 100 ) ;
89+
90+ // Mu should be 0 (cycle starts immediately)
91+ assert_eq ! ( mu_floyd, 0 ) ;
92+ assert_eq ! ( mu_brent, 0 ) ;
93+
94+ // Elements should be in the cycle
95+ assert ! ( ( 0 ..100 ) . contains( & elem_floyd) ) ;
96+ assert ! ( ( 0 ..100 ) . contains( & elem_floyd_partial) ) ;
97+ assert ! ( ( 0 ..100 ) . contains( & elem_brent) ) ;
98+ assert ! ( ( 0 ..100 ) . contains( & elem_brent_partial) ) ;
99+
100+ // Mu_tilde should be valid upper bounds
101+ assert ! ( mu_floyd <= mu_tilde_floyd) ;
102+ assert ! ( mu_tilde_floyd <= mu_floyd + lam_floyd) ;
103+ assert ! ( mu_brent <= mu_tilde_brent) ;
104+ assert ! ( mu_tilde_brent <= mu_brent + 3 * lam_brent) ;
105+ }
106+
107+ #[ test]
108+ fn test_short_cycle_large_mu ( ) {
109+ // Sequence starting from -100, adds 1 each step,
110+ // but when value reaches 10, it resets to 0
111+ // This creates: -100, -99, ..., -1, 0, 1, ..., 9, 10, 0, 1, ..., 9, 10, 0, ...
112+ // mu = 100 (steps to reach 0, which is the start of the cycle), lambda = 11 (0 to 10 inclusive)
113+ let f = |x : i32 | if x == 10 { 0 } else { x + 1 } ;
114+
115+ let ( lam_floyd, elem_floyd, mu_floyd) = floyd ( -100 , f) ;
116+ let ( lam_floyd_partial, elem_floyd_partial, mu_tilde_floyd) = floyd_partial ( -100 , f) ;
117+
118+ let ( lam_brent, elem_brent, mu_brent) = brent ( -100 , f) ;
119+ let ( lam_brent_partial, elem_brent_partial, mu_tilde_brent) = brent_partial ( -100 , f) ;
120+
121+ // Cycle length should be 11 (0, 1, 2, ..., 9, 10, 0, ...)
122+ assert_eq ! ( lam_floyd, 11 ) ;
123+ assert_eq ! ( lam_floyd_partial, 11 ) ;
124+ assert_eq ! ( lam_brent, 11 ) ;
125+ assert_eq ! ( lam_brent_partial, 11 ) ;
126+
127+ // Mu should be 100 (it takes 100 steps to get from -100 to 0, then cycles)
128+ assert_eq ! ( mu_floyd, 100 ) ;
129+ assert_eq ! ( mu_brent, 100 ) ;
130+
131+ // Elements should be in the cycle (0 to 10)
132+ assert ! ( ( 0 ..=10 ) . contains( & elem_floyd) ) ;
133+ assert ! ( ( 0 ..=10 ) . contains( & elem_floyd_partial) ) ;
134+ assert ! ( ( 0 ..=10 ) . contains( & elem_brent) ) ;
135+ assert ! ( ( 0 ..=10 ) . contains( & elem_brent_partial) ) ;
136+
137+ // Mu_tilde should be valid upper bounds
138+ assert ! ( mu_floyd <= mu_tilde_floyd) ;
139+ assert ! ( mu_tilde_floyd <= mu_floyd + lam_floyd) ;
140+ assert ! ( mu_brent <= mu_tilde_brent) ;
141+ // Brent's partial may have a looser bound
142+ assert ! ( mu_tilde_brent <= mu_brent + 4 * lam_brent) ;
69143}
0 commit comments