Calculate Pi in C up to a few million digits - c

I am actually very new to C, but for a project, I'd like to be able to calculate the value of Pi from 1 million to at least 32 million decimal places.
Basically, like what SuperPi/HyperPi does for benchmarking a CPU.
But obviously, the standard C library is incapable of this.
What library can I use, and what algorithm do I use for this task?
And precision too, anyone can cook up a rand() bloat and call it the "Ultimate value of Pi".
My compiler is GCC, so if possible, I'd like the library to be able to compile on it(I have the BigNum library).

I'v used the quadratic algorithm from there with success. I'd suggest MPFR for the library part.

As for the algorithm, see http://en.wikipedia.org/wiki/Chudnovsky_algorithm. For a library to deal with bignums, check http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic#Libraries. Have fun.

Related

improving computationnal speed of a kalman filter in Matlab

I am computing a statistical model in Matlab which has to run about 200 kalman filter per iteration, and I want to iterate the modelat least 10 000 times which suggest that I should run it at least 2 000 000 times. I am therefore searching for a way to optimize the computationnal speed of Matlab on this part. I have already gone operation per operation to try to optimize the computation in Matlab using all the tricks which could be used but I would like to go further...
I am not familiar with C/C++ but I read that mex-file could be usefull in some cases. Anyone could tell me if it would be Worth going into this direction ???
Thanks...
Writing mex files will definitely speed up the entire process, but you will not be able to use a lot of the built in MATLAB functions. You are limited to what you can do in C++ and C. Of course you can write your own functions, as long as you know how to.
The speed increase mainly comes from the fact the mex files are compiled and not interpreted line by line as are standard MATLAB scripts. Once you compile the mex you can call it the same way you do any other MATLAB function.
For a class I took in college I had to write my own image scaling function, I had initially written it in a standard script and it would take a couple seconds to complete on large images, but when I wrote it in C in a mex it would complete in less than 0.1 seconds.
MEX Files Documentation
If you you are not familiar at all with C/C++ this will be hard going. Hopefully you have some experience with another language besides Matlab? You can try learning/copying from the many included examples, but you'll really need to figure out the basics first.
One thing in particular. If you use mex you'll need some way to obtain decent random numbers for your Kalman filter noise. You might be surprised, but a very large percentage of your calculation time will likely be in generating random numbers for noise (depending on the complexity of your filter it could be > 50%).
Don't use the default random number generators in C/C++.
These are not suitable for scientific computation, especially when generating vast numbers of values as you seem to need. Your first option is to pass in a large array of random numbers generated via randn in Matlab to your mex code. Or look into including the C code Mersenne Twister algorithm itself and find/implement a scheme for generating normal random numbers from the uniform ones (log-polar is simplest, but Ziggurat will be faster). This is not too hard. I've done it myself and the Double precision SIMD-oriented Fast Mersenne Twister (dSFMT) is actually 2+ times faster than Matlab's current implementation for uniform variates.
You could use parfor loops or the parallel computing toolbox in general to speedup your calculations. Did you already checked whether MATLAB is using 100% CPU?

Vectorized Trig functions in C?

I'm looking to calculate highly parallelized trig functions (in block of like 1024), and I'd like to take advantage of at least some of the parallelism that modern architectures have.
When I compile a block
for(int i=0; i<SIZE; i++) {
arr[i]=sin((float)i/1024);
}
GCC won't vectorize it, and says
not vectorized: relevant stmt not supported: D.3068_39 = __builtin_sinf (D.3069_38);
Which makes sense to me. However, I'm wondering if there's a library to do parallel trig computations.
With just a simple taylor series up the 11th order, GCC will vectorize all the loops, and I'm getting speeds over twice as fast as a naive sin loop (with bit-exact answers, or with 9th order series, only a single bit off for the last two out of 1600 values, for a >3x speedup). I'm sure someone has encountered a problem like this before, but when I google, I find no mentions of any libraries or the like.
A. Is there something existing already?
B. If not, advice for optimizing parallel trig functions?
EDIT: I found the following library called "SLEEF": http://shibatch.sourceforge.net/ which is described in this paper and uses SIMD instructions to calculate several elementary functions. It uses SSE and AVX specific code, but I don't think it will be hard to turn it into standard C loops.
Since you said you were using GCC it looks like there are some options:
http://gruntthepeon.free.fr/ssemath/
This uses SSE and SSE2 instructions to implement it.
http://www.gamasutra.com/view/feature/4248/designing_fast_crossplatform_simd_.php
This has an alternate implementation. Some of the comments are pretty good.
That said, I'd probably look into GPGPU for a solution. Maybe writing it in CUDA or OpenCL (If I remember correctly CUDA supports the sine function). Here are some libraries that look like they might make it easier.
https://code.google.com/p/slmath/
https://code.google.com/p/thrust/
Since you are looking to calculate harmonics here, I have some code that addressed a similar problem. It is vectorized already and faster than anything else I have found. As a side benefit, you get the cosine for free.
What platform are you using? Many libraries of this sort already exist:
Intel's provides the Vector Math Library (VML) with icc.
Apple provides the vForce library as part of the Accelerate framework.
HP provides their own Vector Math Library for Itanium (and may other architectures, too).
Sun provided libmvec with their compiler tools.
...
Instead of the taylor series, I would look at the algorithms fdlibm uses. They should get you as much precision with fewer steps.
My answer was to create my own library to do exactly this called vectrig: https://github.com/jeremysalwen/vectrig

Adding very large numbers [duplicate]

What is the easiest way to handle huge numbers in C? I need to store values in the Area 1000^900, or in more human readable form 10^2700.
Does anybody know of an easy way to do that? Any help would really be appreciated!
Use libgmp:
GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating-point numbers. There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on...
Since version 6, GMP is distributed under the dual licenses, GNU LGPL v3 and GNU GPL v2...
GMP's main target platforms are Unix-type systems, such as GNU/Linux, Solaris, HP-UX, Mac OS X/Darwin, BSD, AIX, etc. It also is known to work on Windows in both 32-bit and 64-bit mode...
There are a few libraries to help you do this (arbitrary precision mathematics):
BigDigits;
iMath;
decNumber; and
no doubt others.
Assuming this isn't work related (ie you're doing it for fun or its a hobby or just an oportunity to learn something), coding up a library for arbitrary precision maths is a relatively interesting project. But if you need to absolutely rely on it and aren't interested in the nuts and bolts just use a library.
There are a number of libraries for handling huge numbers around. Do you need integer or floating point arithmetic?
You could look at the code built into Python for the task.
You could look at the extensions for Perl for the task.
You could look at the code in OpenSSL for the task.
You could look at the GNU MP (multi-precision) library - as mentioned by kmkaplan.
You can also try the BIGNUMs of openssl, see https://www.openssl.org/docs/man1.0.2/man3/bn.html, https://www.openssl.org/docs/man1.1.1/man3/, Convert a big number given as a string to an OpenSSL BIGNUM for details.

Bignum library, slow prime generator

I am developing a bignum library: http://pastebin.com/nFgF3zjW
I implemented the Miller-Rabin algorithm (isprime()), but it is extremely slow, compared to for example OpenSSL's BN_is_prime_fasttest.
I tried profiling and the functions that are executed the most are bn_shr_atomic and bn_cmp.
Any idea how I can make this faster?
The GNU Multiple Precision Arithmetic library implements Miller-Rabin. It's documentation is located here:
http://gmplib.org/manual/Number-Theoretic-Functions.html#Number-Theoretic-Functions
I would suggest examining their implementation for pointers on speeding up your computation. However, arbitrary precision arithmetic is inherently going to be slower than working with numbers that fit in registers.
Edit:
There is also a trade-off between the algorithm used and the quality of the resulting probability. That said, I'm not sure what test OpenSSL uses.
Big guess: If you really want to use your own library, I'd first replace the division algorithm by the long division.
To validate my guess: you have cmp and shr in the inner loop of your divison, are those calls the major contributor in your profile or do they come from somewhere else? In general, when you profile you should first look at higher level functions which are big contributor, changing algorithms there is usually more benefical than tuning low level functions.

BigInteger in C?

What is the easiest way to handle huge numbers in C? I need to store values in the Area 1000^900, or in more human readable form 10^2700.
Does anybody know of an easy way to do that? Any help would really be appreciated!
Use libgmp:
GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating-point numbers. There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on...
Since version 6, GMP is distributed under the dual licenses, GNU LGPL v3 and GNU GPL v2...
GMP's main target platforms are Unix-type systems, such as GNU/Linux, Solaris, HP-UX, Mac OS X/Darwin, BSD, AIX, etc. It also is known to work on Windows in both 32-bit and 64-bit mode...
There are a few libraries to help you do this (arbitrary precision mathematics):
BigDigits;
iMath;
decNumber; and
no doubt others.
Assuming this isn't work related (ie you're doing it for fun or its a hobby or just an oportunity to learn something), coding up a library for arbitrary precision maths is a relatively interesting project. But if you need to absolutely rely on it and aren't interested in the nuts and bolts just use a library.
There are a number of libraries for handling huge numbers around. Do you need integer or floating point arithmetic?
You could look at the code built into Python for the task.
You could look at the extensions for Perl for the task.
You could look at the code in OpenSSL for the task.
You could look at the GNU MP (multi-precision) library - as mentioned by kmkaplan.
You can also try the BIGNUMs of openssl, see https://www.openssl.org/docs/man1.0.2/man3/bn.html, https://www.openssl.org/docs/man1.1.1/man3/, Convert a big number given as a string to an OpenSSL BIGNUM for details.

Resources