Tuesday, December 10, 2013

Project Euler Problem 448 and an Intro to the GMP library:PART 1

This post contains my solution to project euler problem 448, . The GMP library is for arbitrary precision arithmetic calculations. Now why would I have to pull that out to solve this problem. Well, problem 448 deals with large numbers and I also want to get acquainted with that library. So here's an algorithm in pseudocode that will eventually become a solution to that problem.
int gcd(int a, int b){
    if b==0 return a;
    else return gcd(b, a mod b);
}

int lcm(int a, int b){
    return gcd(a,b)/(a*b);
}

int Avglcm(int n){
    int sum;
    for i=1 to n
        sum += lcm(i,n)
    return (sum/n);
}

SumAvg(int n){
    int total;
    for j=1 to n
        total +=Avglcm(j);
    return total;   
}
Normally, these subroutines would be sufficient to give to a main function and then just calculate the desired values. However, the values we are dealing with are pretty big and I want the optimal performance for this algorithm. So I need the Gnu MP library. Here's a link to the online manual: https://gmplib.org/manual/index.html#Top We are interested in basic number-theoretic functions: lcm and gcd. But before we go that far we need to know how to interact with the library. There's no getting around the fact that we need to read the GMP Basics. So here is bullet-pointed version:

  • GMP functions generally have output arguments before input arguments.  This means a function like mpz_mul(x,y,z) assigns y*z to x
  • For variables, it gets even more weird: not only do you have declare a variable of a gmp type, say "mpz_t n;" you also have to initialize n with something like "mpz_init(n);" now its ready to use.
  • Strangest of all is that all of these functions have a signature like so: void mpz_func(result, op1,op2), which means they all return void. As someone from javaland, these weirds me out. I m guessing there is a convention here that if there is no return statement, the last calculation is returned by default.
  • We are also interested in basic integer I/O. The GMP library has *printf functions for every gmp type. GMP adds the format specifiers: ‘Z’, ‘Q’ and ‘F’ for mpz_t, mpq_t and mpf_t respectively, ‘M’ for mp_limb_t, and ‘N’ for an mp_limb_t array. ‘Z’, ‘Q’, ‘M’ and ‘N’ behave like integers. ‘Q’ will print a ‘/’ and a denominator, if needed. ‘F’ behaves like a float. The section on formatted I/O even has nice examples, such as:"mpz_t z; gmp_printf ("%s is an mpz %Zd\n", "here", z);" This is probably something we'll have use for.

No comments:

Post a Comment