| |

Calculating pi on Python

Calculating the Digits of Pi: Benchmarking the Bailey–Borwein–Plouffe (BBP) formula and the Chudnovsky algorithm

Don’t judge me; what do you do on a Wednesday night?

I asked ChatGPT to spit out some Python code to calculate pi to 1,000 digits. Then asked if it could speed it up. Computing the digits of π (pi) is a fascinating exercise in both mathematical theory and computational prowess. There are It described two different methods. I asked ChatGPT to provide a benchmark. Here is some of the detail it provided.

There are several methods to calculate π, each with its strengths and peculiarities. In this post, we’ll explore two prominent algorithms: the Bailey–Borwein–Plouffe (BBP) formula and the Chudnovsky algorithm, implemented with the mpmath library in Python. We’ll also discuss their performance, especially for generating a large number of digits.

The Bailey–Borwein–Plouffe (BBP) Formula

The BBP formula is notable for allowing the extraction of individual hexadecimal (base-16) digits of π without needing to calculate the preceding digits. This makes it unique and efficient for certain applications, though it’s not typically the fastest for generating a large number of consecutive digits.

Here’s how the BBP algorithm works in Python:

import decimal
from decimal import Decimal, getcontext

def bbp_algorithm(n):
    """Generate the first n digits of pi using the BBP formula."""
    getcontext().prec = n + 2
    pi = Decimal(0)
    k = 0
    while k < n:
        pi += (Decimal(1) / (16 ** k)) * (
            Decimal(4) / (8 * k + 1) -
            Decimal(2) / (8 * k + 4) -
            Decimal(1) / (8 * k + 5) -
            Decimal(1) / (8 * k + 6)
        )
        k += 1
    return str(pi)

def main():
    num_digits = 10000  # Adjust the number of digits to test
    pi_str = bbp_algorithm(num_digits)
    print(f"First {num_digits} digits of pi:\n{pi_str[:50]}...")

if __name__ == "__main__":
    main()

The Chudnovsky Algorithm

The Chudnovsky algorithm is highly efficient for generating a large number of digits of π. It converges rapidly, making it a go-to choice for high-precision calculations. When implemented with the mpmath library, it leverages advanced optimizations to handle the arithmetic operations involved.

Here’s the Chudnovsky algorithm implemented with mpmath:

import mpmath

def chudnovsky_mpmath(digits):
    """Compute pi to the specified number of digits using the Chudnovsky algorithm with mpmath."""
    mpmath.mp.dps = digits + 10  # Set precision slightly higher
    pi = mpmath.pi
    return str(pi)

def main():
    num_digits = 10000  # Adjust the number of digits to test
    pi_str = chudnovsky_mpmath(num_digits)
    print(f"First {num_digits} digits of pi:\n{pi_str[:50]}...")

if __name__ == "__main__":
    main()

Benchmarking the Algorithms

To determine which algorithm performs better for our purposes, we can benchmark them by measuring the time taken to compute a specific number of digits. Here’s a combined script that benchmarks both the BBP and Chudnovsky algorithms:

import time

def benchmark_algorithm(algorithm, digits):
    """Benchmark the specified algorithm."""
    start_time = time.time()
    result = algorithm(digits)
    end_time = time.time()
    return end_time - start_time, result

def main():
    num_digits = 10000  # Adjust the number of digits to test

    bbp_time, bbp_result = benchmark_algorithm(bbp_algorithm, num_digits)
    chudnovsky_time, chudnovsky_result = benchmark_algorithm(chudnovsky_mpmath, num_digits)

    print(f"BBP algorithm time for {num_digits} digits: {bbp_time:.6f} seconds")
    print(f"Chudnovsky algorithm (mpmath) time for {num_digits} digits: {chudnovsky_time:.6f} seconds")

    # Optionally, verify the first few digits of the results for sanity check
    print(f"First 50 digits of Pi (BBP): {bbp_result[:50]}")
    print(f"First 50 digits of Pi (Chudnovsky, mpmath): {chudnovsky_result[:50]}")

if __name__ == "__main__":
    main()

Results and Analysis

When running the benchmark on an older Intel i3 processor, we obtained the following results for computing 10,000 digits of π:

  • BBP Algorithm: Approximately 91.56 seconds
  • Chudnovsky Algorithm (mpmath): Approximately 0.011 seconds

These results show a stark contrast in performance. The BBP algorithm, while fascinating for its ability to extract specific digits, is not optimized for generating long sequences of digits. On the other hand, the Chudnovsky algorithm with mpmath is incredibly efficient, leveraging rapid convergence and advanced optimizations to deliver results almost instantaneously.

Conclusion

For anyone looking to compute a large number of digits of π, the Chudnovsky algorithm with mpmath is the clear choice. It combines mathematical elegance with computational efficiency, making it suitable for high-precision arithmetic.

On the flip side, the BBP formula remains an interesting and useful method for scenarios where specific digit extraction is required without computing all preceding digits.

I asked ChatGPT to make it faster still and expected next jumps might require more effort – ChatGPT provided code written in C but as it is late, that may be another Wednesday evening.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *