Let
Based on the Taylor series expansion (around 0), we have:
So,
Besides,
The problem now is how to get
Based on some calculation, we can get:
Based on the derivatives calculated above, we can observe a pattern in the coefficients. Let's organize them in the following table:
The table shows the coefficients of terms of the form
| 0 | |||||
| 1 | |||||
| 2 | |||||
| 3 | |||||
| 4 |
If you find the derivatives yourself, you may find that any of the coefficient,
For
For
To get
and
So we can have the program.
const N: usize = 10000;
const PRECISION: u32 = 256;
use rug::{Float, Integer};
fn main() {
println!("Calculating pi with {} terms...", N);
let mut cur_n = 2;
let mut vec = vec![Integer::new(); N + 10];
let mut collector: Vec<Integer> = Vec::with_capacity(N / 2 + 10);
collector.push(Integer::from(1));
vec[0] = Integer::from(-1);
vec[2] = Integer::from(-1);
while cur_n <= N {
if cur_n % 2 == 0 {
for i in (1..cur_n + 2).step_by(2) {
vec[i] = Integer::new();
}
for i in (0..cur_n + 1).step_by(2) {
let k = vec[i].clone();
vec[i + 1] += (i + cur_n - 1) * &k;
if i >= 1 {
vec[i - 1] += i * k;
}
}
collector.push(std::mem::take(&mut vec[0]));
// println!("collector added: {}", collector[collector.len() - 1]);
} else {
for i in (0..cur_n + 2).step_by(2) {
vec[i] = Integer::new();
}
for i in (1..cur_n + 1).step_by(2) {
let k = vec[i].clone();
vec[i + 1] += (i + cur_n - 1) * &k;
vec[i - 1] += i * k;
}
}
cur_n += 1;
}
let mut pi = Float::with_val(PRECISION, 0);
let mut factorial_base = Integer::from(1);
let mut factorial_cap = Integer::from(2);
for i in 0..collector.len() {
pi += Float::with_val(PRECISION, std::mem::take(&mut collector[i]))
/ Float::with_val(PRECISION, factorial_base.clone());
factorial_base = factorial_base * &factorial_cap;
factorial_base = factorial_base * (&factorial_cap + Integer::from(1));
factorial_cap += 2;
// println!("pi_{} = {:.16}", i, pi);
}
pi *= 4;
println!("pi = {}", pi);
}I wrote this in hurry so it's not really optimized. Sorry about that.
Calculating pi with 10000 terms...
pi = 3.141593717260361692706004115729853061820382289134097618662650072056492604360802That's quite near... I mean, in Astronomy they use 3 as
Just kidding. This infinite series converges slowly, but it uses a quite basic method. I know there're better ways like Trigonometric Functions and Binomial Theorem, but I don't know how to use them. I'm new to calculus.