Skip to content

Commit 5852d80

Browse files
committed
implement Euler's phi function
1 parent 8922b91 commit 5852d80

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

src/main/java/de/tilman_neumann/jml/Divisors.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project.
3-
* Copyright (C) 2018-2024 Tilman Neumann - tilman.neumann@web.de
3+
* Copyright (C) 2018-2026 Tilman Neumann - tilman.neumann@web.de
44
*
55
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
66
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
@@ -511,4 +511,27 @@ public static BigInteger getBiggestDivisorBelowSqrtN(BigInteger n, SortedMap<Big
511511
SortedSet<BigInteger> smallDivisors = getSmallDivisors(n, factors);
512512
return smallDivisors.last();
513513
}
514+
515+
516+
/**
517+
* Computes Euler's phi(n), which is the number of k with 1<=k<=n that are coprime to n.
518+
* Formula: phi(n) = n * prod_{p|n} 1-1/p
519+
*
520+
* @param n
521+
* @return phi(n)
522+
*/
523+
public static BigInteger computeEulerPhi(BigInteger n) {
524+
if (n.equals(I_0)) return I_0;
525+
526+
SortedMap<BigInteger, Integer> factors = FactorAlgorithm.getDefault().factor(n);
527+
BigInteger num = I_1;
528+
BigInteger den = I_1;
529+
for (Map.Entry<BigInteger, Integer> entry : factors.entrySet()) {
530+
BigInteger divisor = entry.getKey();
531+
num = num.multiply(divisor.subtract(I_1));
532+
den = den.multiply(divisor);
533+
}
534+
return n.multiply(num).divide(den);
535+
}
536+
514537
}

src/test/java/de/tilman_neumann/jml/DivisorsTest.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project.
3-
* Copyright (C) 2018-2024 Tilman Neumann - tilman.neumann@web.de
3+
* Copyright (C) 2018-2026 Tilman Neumann - tilman.neumann@web.de
44
*
55
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
66
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
@@ -19,6 +19,8 @@
1919
import java.math.BigInteger;
2020
import java.util.List;
2121

22+
import org.apache.logging.log4j.LogManager;
23+
import org.apache.logging.log4j.Logger;
2224
import org.junit.BeforeClass;
2325
import org.junit.Test;
2426

@@ -31,6 +33,8 @@
3133
*/
3234
public class DivisorsTest {
3335

36+
private static Logger LOG = LogManager.getLogger(DivisorsTest.class);
37+
3438
@BeforeClass
3539
public static void setup() {
3640
ConfigUtil.initProject();
@@ -46,4 +50,16 @@ public void testSumOfDivisorsForSmallIntegers() {
4650
assertEquals(BigInteger.valueOf(reference.get(i)), Divisors.sumOfDivisors_v1(n));
4751
}
4852
}
53+
54+
@Test
55+
public void testEulerPhiForSmallArguments() {
56+
// reference data from https://oeis.org/A000010, starts at n=1
57+
List<Integer> reference = List.of(1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16, 6, 18, 8, 12, 10, 22, 8, 20, 12, 18, 12, 28, 8, 30, 16, 20, 16, 24, 12, 36, 18, 24, 16, 40, 12, 42, 20, 24, 22, 46, 16, 42, 20, 32, 24, 52, 18, 40, 24, 36, 28, 58, 16, 60, 30, 36, 32, 48, 20, 66, 32, 44);
58+
for (int i=0; i<reference.size(); i++) {
59+
BigInteger n = BigInteger.valueOf(i+1);
60+
BigInteger phi = Divisors.computeEulerPhi(n);
61+
LOG.trace("i=" + i + ": phi = " + phi);
62+
assertEquals(BigInteger.valueOf(reference.get(i)), phi);
63+
}
64+
}
4965
}

0 commit comments

Comments
 (0)