HGBaker> Perhaps someone has already done this.
The sensor on my bike outputs both cadence (crank speed in revs/sec) and wheel speed (revs/sec). I'm trying to infer which gear the bike is in by looking at the ratio of these two numbers.
My plan was to use the equivalent of Scheme's "rationalize" function (which uses a continued fraction algorithm internally), which produces an exact fraction which is within some epsilon of a given number -- in this case the wheel/crank speed. This should give me an approximation to the ratio (#front teeth)/(#rear teeth).
http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html
Unfortunately, there is enough error in the measurements of the crank speed and the wheel speed so that the output isn't stable.
So far, we haven't utilized any information about which chainrings (front teeth) and cogs (rear teeth) are mounted on the bike, except for the fact that each must have an integer # of teeth.
Of course, I can always make up a table of all of the gears and simply find the closest one & output it. But if the number of cogs grows large and the number of chainrings grows large (we're mathematicians, after all!), we'd rather not search a large table.
Suppose now that we have upper & lower limits on the teeth on the chainrings (28 to 52) and the cogs (12 to 26), but otherwise don't know how many chainrings or cogs are mounted on the bike.
How do we modify the continued fraction algorithm used within rationalize to produce fractions with numerators and denominators in the appropriate range ?
I sent a long msg on this, 3 MAR 05. Upshot: CF may not be best. ------------(quote from msg)-------- A trickier problem, for which the mediant algorithm seems better suited: What is the nearest fraction to x with numerator <= a and denominator <= b? E.g., (farint pi 999) 355 113 (farint pi 999 112) 333 106 But notice I said "for hand computation" For some reason (personal stupidity?), the iterated mediant is ugly to code. The following was maybe my sixth try: (defun farint (x &optional (nhi 400) (dhi nhi) (ln 0) (ld 1) (hn 1) (hd 0)) (if (> (+ ln hn) (* (+ ld hd) x)) (let* ((m (min (if (= 0 ln) nhi (floor(- nhi hn) ln)) (floor (- dhi hd) ld))) (d (- (* x ld) ln)) (k (if (= 0 d) m (ceiling (- hn (* x hd)) d)))) (if (< k m) (farint x nhi dhi (setf hn (+ (* k ln) hn)) (setf hd (+ (* k ld) hd)) (- hn ln) (- hd ld)) (let* ((n (+ (* m ln) hn)) (d (+ (* m ld) hd))) (if (< (* 2 d ld x) (+ (* ld n) (* ln d))) (values ln ld) (values n d))))) (let* ((m (min (floor (- nhi ln) hn) (if (= 0 hd) dhi (floor (- dhi ld) hd)))) (d (- hn (* x hd))) (k (if (= 0 d) m (ceiling (- (* x ld) ln) d)))) (if (< k m) (farint x nhi dhi (- (setf ln (+ (* k hn) ln)) hn) (- (setf ld (+ (* k hd) ld)) hd) ln ld) (let* ((n (+ (* m hn) ln)) (d (+ (* m hd) ld))) (if (< (* 2 d hd x) (+ (* hd n) (* hn d))) (values n d) (values hn hd))))))) Presumably the two outer branches can be obnubilated into something half as long and twice as turbid. --rwg -----------(End quote from msg)------- The text file from which I manuallly recovered this has been damaged (I suspect by an antivirus program) by the deletion of the first character of every line! For the hand algorithm, click on Rectangle Arithmetic at http://www.tweedledum.com/rwg/ --rwg