/*CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C C
C GENERATE FAREY SERIES C
C 06/11/07 (DKC) C
C C
C This subroutine computes the fractions in a Farey series after two given C
C successive fractions. The algorithm uses the following theorems; C
C C
C (1) Suppose h/k and h'/k' are successive fractions in a Farey series of C
C order n where k' > k and denote [(n - k')/(k' - k)] by l. If l <> 0, C
C the next l fractions in the Farey series correspond to the remaining C
C lattice points on the line through (h,k) and (h',k') and are C
C (h' + (h' - h)*i)/(k' + (k' - k)*i), i=1,2,3,...,l. C
C C
C (2) If h/k and h'/k' are successive fractions in a Farey series and k' > C
C k, the fraction in the Farey series after the fractions corresponding C
C to the lattice points on the line through (h,k) and (h',k') is C
C (h' - h)/(k' - k). C
C C
C (3) Suppose h/k and h'/k' are successive fractions in a Farey series of C
C order n where k > k' and denote [{(2k' - n - 1)/(k - k')}/2] by l. C
C ({A} denotes the smallest integer greater than A.) If l > 0, the C
C next l fractions in the Farey series correspond to the next l C
C lattice points on the line through (h,k) and (h',k') and are C
C (h' - (h - h')*i)/(k' - (k - k')*i), i=1,2,3,...,l. C
C C
C (4) The fraction after the successive fractions h/k and h'/k' in a Farey C
C series of order n is (j*h' - h)/(j*k' - k) where j=[(n + k)/k']. C
C C
C If the denominators of the given successive fractions are increasing, the C
C first two theorems can be used to find the next pair of successive C
C fractions where the denominators are decreasing. The last two theorems C
C can then be used to find the next pair of successive fractions where the C
C denominators are increasing, etc. Similar logic applies when the C
C denominators of the given successive fractions are decreasing. C
C C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC*/
void harfar(unsigned int N, unsigned int M, unsigned int *R,
unsigned int NUM, unsigned int DEN, unsigned int OLDNUM,
unsigned int OLDDEN) {
unsigned int TNUM,TDEN,II,K;
int I;
//
// STORE CURRENT FRACTIONS
//
R[2*M]=OLDNUM;
R[2*M+1]=OLDDEN;
M=M+1;
R[2*M]=NUM;
R[2*M+1]=DEN;
if(DEN==1) goto L600;
TNUM=OLDNUM;
TDEN=OLDDEN;
if(DEN>OLDDEN) goto L400;
//
// DECREASE IN DENOMINATOR
//
I=2*DEN-N;
if(I<0) goto L200;
OLDNUM=OLDNUM-NUM;
OLDDEN=OLDDEN-DEN;
L100: K=(I+OLDDEN-1)/OLDDEN;
K=K/2;
if(K==0) goto L200;
for (II=0; II<K; II++) {
NUM=NUM-OLDNUM;
DEN=DEN-OLDDEN;
M=M+1;
R[2*M]=NUM;
R[2*M+1]=DEN;
}
//
// INCREASE IN DENOMINATOR
//
L200: TNUM=NUM;
TDEN=DEN;
L300: K=(N+OLDDEN)/DEN;
NUM=K*NUM-OLDNUM;
DEN=K*DEN-OLDDEN;
M=M+1;
R[2*M]=NUM;
R[2*M+1]=DEN;
//
L400: OLDNUM=NUM-TNUM;
OLDDEN=DEN-TDEN;
K=(N-DEN)/OLDDEN;
if(K==0) goto L500;
for (II=0; II<K; II++) {
NUM=NUM+OLDNUM;
DEN=DEN+OLDDEN;
M=M+1;
R[2*M]=NUM;
R[2*M+1]=DEN;
}
L500: TNUM=OLDNUM;
TDEN=OLDDEN;
OLDNUM=NUM-OLDNUM;
OLDDEN=DEN-OLDDEN;
NUM=TNUM;
DEN=TDEN;
M=M+1;
R[2*M]=NUM;
R[2*M+1]=DEN;
I=2*DEN-N;
if(I>0) goto L100;
if(DEN!=1) goto L300;
//
L600: return;
}