I have some code that approximates a solution recusively, what it actually does is not important, but it works towards r' == rt by varying mg (m guess, starting with 4.0 because I "know" that ought to be in the ballpark).
solve_m f ar st qt = solve_m' f ar st qt 4.0
where
solve_m' f ar st qt mg
| rd > precis = f' (mg - sf)
| rd < (-precis) = f' (mg + sf)
| otherwise = mg
where
f' = solve_m' f ar st qt
rt = st + qt
r' = f st ar mg
rd = rt - r'
sf = abs(rd)
What I would like to be able to do is count the number of cycles, I know the right way to do this is with the State monad, but what is the most elegant way to fit the put/get into a function like this? Make f' a do block? Or is it simply to add a counter solve_m' and return (counter, mg)?
Thanks!
Edit: This seems to be basically what I want, and no Monads necessary:
solve_m f ar st qt = (last (series), length(series))
where
series = takeWhile termPred (iterate solve_m' 4.0)
termPred m' = (abs (rt - (f st ar m'))) > precis
rt = st + qt
solve_m' mg
| rt > r' = (mg - sf)
| rt < r' = (mg + sf)
where
r' = f st ar mg
rd = rt - r'
sf = abs(rd)
Still looks a little messy (repeated code) but I'll tidy it up... This is getting me acceptable results in 1/10000th of the iterations of the code it will replace!
Without looking at your algorithm, the generic way to do this is divide up your termination criteria from the iterative algorithm:
terminationPred :: a -> Bool
algorithm :: a -> a
then use either iterate and takeWhile:
itermediates = takeWhile (not . terminationPred) . iterate algorithm
resultAndRecursions :: a -> (a, Int)
resultAndRecursions a = (last (intermediates a), length (intermediates a) - 1)
-- you'd want to make your own safe function here, not use last and length
or unfold:
intermediates = unfoldr op
where
op a | terminationPred a = Nothing
| otherwise = let a' = algorithm a
in Just (a', a')
EDIT: also notice these two intermediates are slightly different in that the first maintains the base case (the input a
, hence the - 1
) while the second does not and thus would have a minor difference in the complementary resultAndRecursions
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With