The Chudnovsky Algorithm is a fast method for calculating the digits of . Here is the definition:
The complexity of the algorithm is very high. It involves multiple factorials, exponents and calculations with large numbers. You should not directly implement the it as its definition, since the program will be pretty slow. Here shows some optimization of the algorithm for computations.
Mathematical Optimizations
can be factorized from the infinite sum as a constant to be computed first before the summation. Such factorization reduces the computation of that constant to only one time. The equation then becomes:
It can be then changed into surd form.
We can further divide 12 by both sides. The equation then becomes:
According to the exponential rule , we can compute in the denominator first, which is equal to .
The can also be factorized with the part above. Since , we can move it to the denominator. Then, factorize the exponent from and , which results in . Now, the equation becomes:
Programmatic Optimizations
You won’t just hard implement the entire algorithm into a program. Every time a loop executes, it recalculates everything within the summation, which includes multiple factorials, exponential calculations, etc. There is a way to highly optimize this, is to accumulate the values according to the index of the sum.
The first one is . Let’s define it as the constant , where is the variable of the sum. Since is always here, we can define it as the base, or the initial value when the index of the sum is zero. Notice that when the index is zero, will be multiplied and become zero.
Now, as the index grows, will be added more and more times. Each time the index is increased by one, it will be added once. Hence, the constant is as the following:
The second one is . Let’s define it as the constant . The number of times is multiplied increases by one as the index of sum increases by one. When the index is 0, the exponent is 0 and the result will be 1. Therefore, the base is 1. Now the constant is as the following:
The most difficult part to optimize is . Since there is no addition or subtraction in this term, there will be only accumulation of multiplication. Let’s define it as the constant . Instead of thinking how we can accumulate, let’s directly simplify to find out what we need to multiply each time the index of sum is increased by one.
It is safe to cancel the terms, because must be negative and fractional to result terms in 0, which is impossible. As a result, the constant is as the following:
Notice that multiplication is still going on with the constant. Therefore, further optimizations can be done. Let’s define a new constant . It will be used to accumulate the value of the second term in . Although you can accumulate the value of all three terms, it will be more expensive than accumulating one only, as you will have to do more additions, and use more memory.
Storing one only is more optimized, since we can produce the value for other terms by comparing and manipulating the base or initial value of the term, provided that the addition and subtraction are cheap.
There is a pattern going on with those terms, is that the first term has the constant four smaller than the constant in the second term, and the third term has the constant four larger than the constant in the second term. Using this pattern to find out the value for the first and third term is the most optimal, for less bits are manipulated, though it won’t matter much.
Now, we can change the definition of .
Hence, the new definition is:
Finally, the Chudnovsky Algorithm is optimized both mathematically and programmatically. For higher readability, let’s define . Here is the summary of the optimized algorithm.