Farey Sequence

Farey sequence is a sequence which is generated for order n. The sequence has all rational numbers in range [0/0 to 1/1] sorted in increasing order such that the denominators are less than or equal to n and all numbers are in reduced forms i.e., 4/4 cannot be there as it can be reduced to 1/1.

Examples:

F1 = 0/1, 1/1
F2 = 0/1, 1/2, 1/1
F3 = 0/1, 1/3, 1/2, 2/3, 1/1
.
.
F7 = 0/1, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 2/5,
     3/7, 1/2, 4/7, 3/5, 2/3, 5/7, 3/4, 4/5,
     5/6, 6/7, 1/1

Farey sequence is used in rational approximations of irrational numbers, ford circles and
in Riemann hypothesis (See this for more details)



How to generate Farey Sequence of given order?
The idea is simple, we consider every possible rational number from 1/1 to n/n. And for every generated rational number, we check if it is in reduced form. If yes, then we add it to Farey Sequence. A rational number is in reduced form if GCD of numerator and denominator is 1.

Below is C++ implementation based on above idea.

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to print Farey Sequence of given order
#include <bits/stdc++.h>
using namespace std;
  
// class for x/y (a term in farey sequence
class Term {
public:
    int x, y;
  
    // Constructor to initialize x and y in x/y
    Term(int x, int y)
        : x(x), y(y)
    {
    }
};
  
// Cmparison function for sorting
bool cmp(Term a, Term b)
{
    // Comparing two ratio
    return a.x * b.y < b.x * a.y;
}
  
// GCD of a and b
int gcd(int a, int b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
  
// Function to print Farey sequence of order n
void farey(int n)
{
    // Create a vector to store terms of output
    vector<Term> v;
  
    // One by one find and store all terms except 0/1 and n/n
    // which are known
    for (int i = 1; i <= n; ++i) {
        for (int j = i + 1; j <= n; ++j)
  
            // Checking whether i and j are in lowest term
            if (gcd(i, j) == 1)
                v.push_back(Term(i, j));
    }
  
    // Sorting the term of sequence
    sort(v.begin(), v.end(), cmp);
  
    // Explicitly printing first term
    cout << "0/1 ";
  
    // Printing other terms
    for (int i = 0; i < v.size(); ++i)
        cout << v[i].x << "/" << v[i].y << " ";
  
    // explicitely printing last term
    cout << "1/1";
}
  
// Driver program
int main()
{
    int n = 7;
    cout << "Farey Sequence of order " << n << " is\n";
    farey(n);
    return 0;
}

chevron_right


Output:

Farey Sequence of order 7 is
0/1 1/7 1/6 1/5 1/4 2/7 1/3 2/5 3/7 1/2 4/7 
3/5 2/3 5/7 3/4 4/5 5/6 6/7 1/1

Time complexity of above approach is O(n2 Log n) where O(log n) is an upper bound on time taken by Euclid’s algorithm for GCD.

Farey Sequence has below properties [See wiki for details]

A term x/y can be recursively evaluated using previous two terms. Below is the formula to compute xn+2/yn+2 from xn+1/yn+1 and xn/yn.

x[n+2] = floor((y[n]+n) / y[n+1])x[n+1]– x[n]      
y[n+2] = floor((y[n]+n) / y[n+1])y[n+1]– y[n]    

We can use above properties to optimize.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// Efficient C++ program to print Farey Sequence of order n
#include <bits/stdc++.h>
using namespace std;
  
// Optimized function to print Farey sequence of order n
void farey(int n)
{
    // We know first two terms are 0/1 and 1/n
    double x1 = 0, y1 = 1, x2 = 1, y2 = n;
  
    printf("%.0f/%.0f %.0f/%.0f", x1, y1, x2, y2);
  
    double x, y = 0; // For next terms to be evaluated
    while (y != 1.0) {
        // Using recurrence relation to find the next term
        x = floor((y1 + n) / y2) * x2 - x1;
        y = floor((y1 + n) / y2) * y2 - y1;
  
        // Print next term
        printf(" %.0f/%.0f", x, y);
  
        // Update x1, y1, x2 and y2 for next iteration
        x1 = x2, x2 = x, y1 = y2, y2 = y;
    }
}
  
// Driver program
int main()
{
    int n = 7;
    cout << "Farey Sequence of order " << n << " is\n";
    farey(n);
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Efficient Python3 program to print
# Farey Sequence of order n
import math
  
# Optimized function to print Farey 
# sequence of order n
def farey(n):
      
    # We know first two terms are 
    # 0/1 and 1/n
    x1 = 0
    y1 = 1
    x2 = 1
    y2 = n;
      
    print(x1, end = "") 
    print("/", end = "")
    print(y1, x2, end = "") 
    print("/", end = "") 
    print(y2, end = " ");
  
    # For next terms to be evaluated
    x = 0;
    y = 0
    while (y != 1.0):
          
        # Using recurrence relation to
        # find the next term
        x = math.floor((y1 + n) / y2) * x2 - x1;
        y = math.floor((y1 + n) / y2) * y2 - y1;
  
        # Print next term
        print(x, end = "")
        print("/", end = "")
        print(y, end = " ");
  
        # Update x1, y1, x2 and y2 for 
        # next iteration
        x1 = x2; 
        x2 = x; 
        y1 = y2; 
        y2 = y;
  
# Driver Code
n = 7;
print("Farey Sequence of order", n, "is");
farey(n);
  
# This code is contributed by mits

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// Efficient php program to print
// Farey Sequence of order n
  
// Optimized function to print 
// Farey sequence of order n
function farey($n)
{
      
    // We know first two 
    // terms are 0/1 and 1/n
    $x1 = 0; 
    $y1 = 1; 
    $x2 = 1; 
    $y2 = $n;
      
        echo $x1, "/", $y1
             " ", $x2, "/"
             $y2, " ";
  
    // For next terms
    // to be evaluated
    $x;
    $y = 0; 
    while ($y != 1.0)
    {
          
        // Using recurrence relation to
        // find the next term
        $x = floor(($y1 + $n) / $y2) * $x2 - $x1;
        $y = floor(($y1 + $n) / $y2) * $y2 - $y1;
  
        // Print next term
        echo $x, "/", $y, " ";
  
        // Update x1, y1, x2 and
        // y2 for next iteration
        $x1 = $x2
        $x2 = $x
        $y1 = $y2
        $y2 = $y;
    }
}
  
    // Driver Code
    $n = 7;
    echo "Farey Sequence of order ", $n, " is\n";
    farey($n);
  
// This code is contributed by ajit
?>

chevron_right



Output:

Farey Sequence of order 7 is
0/1 1/7 1/6 1/5 1/4 2/7 1/3 2/5 3/7 1/2 4/7 
3/5 2/3 5/7 3/4 4/5 5/6 6/7 1/1

Time Complexity of this solution is O(n)

References:
https://en.wikipedia.org/wiki/Farey_sequence

This article is contributed by Utkarsh Trivedi. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up

Improved By : jit_t, Mithun Kumar



Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.