/*CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C C GENERATE FAREY SERIES C C 06/11/07 (DKC) C C C C The Farey series Fn of order n is the ascending series of irreducible C C fractions between 0 and 1 whose denominators do not exceed n. The next C C fraction in the series is computed from the current fraction using Haros' C C theorem that if h/k and h'/k' are successive fractions in a Farey series, C C k*h' - h*k' = 1. Lagrange's algorithm is used to solve the Diophantine C C equation k*x - h*y = 1. The execution time of the algorithm is C C proportional to n*n*log2(n). C C C C The "Q" array is used to store partial quotients. The numbers generating C C the most partial quotients are two successive Fibonacci numbers. These C C numbers can be defined by the recurrence relation f(i+1) = f(i) + f(i-1), C C i=1,2,3,..., f(0)=f(1)=1. To hold the partial quotients generated by the C C j-1 and j th Fibonacci numbers, the dimension of the "Q" array must be at C C least j-1. The sixteenth Fibonacci number is 1597, so an array size of 20 C C is more than adequate for computing Farey series of orders less than 1000. C C (The "E" and "F" arrays are used to store the convergents and must be as C C large as the "Q" array.) C C C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC*/ void lagrange2(unsigned int N, unsigned int D, unsigned int O, unsigned int *ND) { unsigned int A,B,R,I,J,Q[400],E[400],F[400]; // // SOLVE D*X - N*Y = 1 USING LAGRANGE'S ALGORITHM; // FIND QUOTIENTS USING EUCLID'S GREATEST COMMON DIVISOR ALGORITHM // A=N; B=D; I=0; L300: I=I+1; Q[I-1]=B/A; R=B-Q[I-1]*A; if(R==0) goto L400; B=A; A=R; goto L300; // // COMPUTE CONVERGENTS // L400: A=Q[0]-1; B=1; if(I==1) goto L600; A=A+1; if(I==2) goto L600; E[0]=A; F[0]=B; A=A*Q[1]+1; B=Q[1]; if(I==3) goto L500; E[1]=A; F[1]=B; for (J=3; J<I; J++) { A=A*Q[J-1]+E[J-3]; B=B*Q[J-1]+F[J-3]; E[J-1]=A; F[J-1]=B; } if(I==(I/2)*2) goto L600; // // SOLUTION OF D*X - N*Y = -1; ADJUST SOLUTION // L500: A=D-A; B=N-B; // // COMPUTE NEXT FRACTION; // FIND R SUCH THAT O - D < A + D*R <= O // L600: R=(O-A)/D; N=B+N*R; D=A+D*R; ND[0]=N; ND[1]=D; return; }