Saturday, April 23, 2022

Computing the totient function by prime factorisation

The totient function $\phi(x)$ could be implemented by using prime factorisation, rather then manually iterating through all the totatives of a number. Then the only issue is making sure that the prime factorisation algorithm is fast, but I think that is going to be pretty good since it comes from apache commons math.

import org.apache.commons.math3.primes.Primes;
import org.apache.commons.math3.util.ArithmeticUtils;
import org.apache.commons.collections4.multiset.HashMultiSet;
import java.util.ArrayList;

public class Totatives {

    public static boolean isCoprime(int n, int m) {
        return (ArithmeticUtils.gcd(n,m) == 1);
    }

    public static ArrayList totatives(int n) {
        var rval = new ArrayList();

        for(int i = 1; i <= n; i++) {
            if(isCoprime(i,n)) {
                rval.add(i);
            }
        }

        return rval;
    }

    public static int totativesCount(int n) {
        return totatives(n).size();
    }

    public static int eulersTotientFunction(int n) {
        if(n == 1) {
            return 1;
        }

        HashMultiSet m = new HashMultiSet(Primes.primeFactors(n));
        var s = m.entrySet();

        int rval = 1;

        for(var i : s) {
            int p = i.getElement();
            int k = i.getCount();
            rval *= (Math.pow(p,k)-Math.pow(p,k-1));
        }

        return rval;
    }

    public static void main(String[] args) {

        // test for equality
        for(int i = 1; i < 100; i++) {
            if(eulersTotientFunction(i) != totativesCount(i)) {
                System.out.println("Failed at: " + i);
            }
        }

    }

}

The one issue with the primeFactors method is that it outputs a List rather then a Multiset, so I like that we can call to the apache commons collections library to convert it into the appropriate multiset data type for our computations. Iterating over the entry set produces the primes and their multiplicities which is what we need to compute the totient function.

No comments:

Post a Comment