Skip to content

Commit 363f021

Browse files
committed
new unit test for quadratic residues mod p^n, renamed some classes
1 parent adf1101 commit 363f021

File tree

5 files changed

+132
-96
lines changed

5 files changed

+132
-96
lines changed

src/main/java/de/tilman_neumann/jml/quadraticResidues/QuadraticResiduesModBPowNTest02.java

-87
This file was deleted.

src/main/java/de/tilman_neumann/jml/quadraticResidues/QuadraticResiduesModBPowN.java src/main/java/de/tilman_neumann/jml/quadraticResidues/QuadraticResiduesModPPowN.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
*
3030
* @author Tilman Neumann
3131
*/
32-
public class QuadraticResiduesModBPowN {
32+
public class QuadraticResiduesModPPowN {
3333

34-
private static final Logger LOG = LogManager.getLogger(QuadraticResiduesModBPowN.class);
34+
private static final Logger LOG = LogManager.getLogger(QuadraticResiduesModPPowN.class);
3535

3636
private static final boolean DEBUG = false;
3737

src/main/java/de/tilman_neumann/jml/quadraticResidues/QuadraticResiduesModBPowNTest01.java src/main/java/de/tilman_neumann/jml/quadraticResidues/QuadraticResiduesModPPowNTest01.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
*
2727
* @author Tilman Neumann
2828
*/
29-
public class QuadraticResiduesModBPowNTest01 {
29+
public class QuadraticResiduesModPPowNTest01 {
3030

31-
private static final Logger LOG = LogManager.getLogger(QuadraticResiduesModBPowNTest01.class);
31+
private static final Logger LOG = LogManager.getLogger(QuadraticResiduesModPPowNTest01.class);
3232

3333
private static final int P = 23;
3434

src/test/java/de/tilman_neumann/jml/quadraticResidues/QuadraticResiduesModBPowNPerformanceTest.java src/test/java/de/tilman_neumann/jml/quadraticResidues/QuadraticResiduesModPPowNPerformanceTest.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
*
2727
* @author Tilman Neumann
2828
*/
29-
public class QuadraticResiduesModBPowNPerformanceTest {
29+
public class QuadraticResiduesModPPowNPerformanceTest {
3030

31-
private static final Logger LOG = LogManager.getLogger(QuadraticResiduesModBPowNPerformanceTest.class);
31+
private static final Logger LOG = LogManager.getLogger(QuadraticResiduesModPPowNPerformanceTest.class);
3232

3333
/**
3434
* Test.
@@ -47,17 +47,17 @@ private static void testPerformance(int p, int nMax) {
4747
LOG.info("v1: n = " + n + ": Computed " + quadraticResidues_v1.size() + " quadratic residues mod " + p + "^" + n + " in " + (t1-t0) + "ms");
4848

4949
t0 = System.currentTimeMillis();
50-
List<Long> quadraticResidues_v2 = QuadraticResiduesModBPowN.getQuadraticResiduesModBPowN(p, n);
50+
List<Long> quadraticResidues_v2 = QuadraticResiduesModPPowN.getQuadraticResiduesModBPowN(p, n);
5151
t1 = System.currentTimeMillis();
5252
LOG.info("v2: n = " + n + ": Computed " + quadraticResidues_v2.size() + " quadratic residues mod " + p + "^" + n + " in " + (t1-t0) + "ms");
5353

5454
t0 = System.currentTimeMillis();
55-
List<Long> quadraticResidues_v3 = QuadraticResiduesModBPowN.getQuadraticResiduesModBPowN_testAll(p, n);
55+
List<Long> quadraticResidues_v3 = QuadraticResiduesModPPowN.getQuadraticResiduesModBPowN_testAll(p, n);
5656
t1 = System.currentTimeMillis();
5757
LOG.info("v3: n = " + n + ": Computed " + quadraticResidues_v3.size() + " quadratic residues mod " + p + "^" + n + " in " + (t1-t0) + "ms");
5858

5959
t0 = System.currentTimeMillis();
60-
List<Long> quadraticResidues_v4 = QuadraticResiduesModBPowN.getQuadraticResiduesModBPowN_testAll_v2(p, n);
60+
List<Long> quadraticResidues_v4 = QuadraticResiduesModPPowN.getQuadraticResiduesModBPowN_testAll_v2(p, n);
6161
t1 = System.currentTimeMillis();
6262
LOG.info("v4: n = " + n + ": Computed " + quadraticResidues_v4.size() + " quadratic residues mod " + p + "^" + n + " in " + (t1-t0) + "ms");
6363
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* 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 - [email protected]
4+
*
5+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
6+
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10+
*
11+
* You should have received a copy of the GNU General Public License along with this program;
12+
* if not, see <http://www.gnu.org/licenses/>.
13+
*/
14+
package de.tilman_neumann.jml.quadraticResidues;
15+
16+
import static org.junit.Assert.assertEquals;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
import java.util.TreeSet;
21+
22+
import org.apache.logging.log4j.Logger;
23+
import org.junit.BeforeClass;
24+
import org.junit.Test;
25+
import org.apache.logging.log4j.LogManager;
26+
27+
import de.tilman_neumann.util.ConfigUtil;
28+
29+
/**
30+
* QA tests for quadratic residue computations modulo p^n for odd primes p.
31+
*
32+
* Resulting sequences:
33+
* n= 3: 1, 2, 4, 11, 31, 92, 274, 821, 2461, 7382, 22144, 66431, 199291, 597872, 1793614, ...
34+
* = A039300(n), Number of distinct quadratic residues mod 3^n.
35+
* n= 5: 1, 3, 11, 53, 261, 1303, 6511, 32553, 162761, 813803, 4069011, ...
36+
* = A039302(n), Number of distinct quadratic residues mod 5^n.
37+
* n= 7: 1, 4, 22, 151, 1051, 7354, 51472, 360301, ...
38+
* = A039304(n), Number of distinct quadratic residues mod 7^n.
39+
* n=11: 1, 6, 56, 611, 6711, 73816, 811966, ... (not in OEIS)
40+
*
41+
* @author Tilman Neumann
42+
*/
43+
public class QuadraticResiduesModPPowNTest {
44+
45+
private static final Logger LOG = LogManager.getLogger(QuadraticResiduesModPPowNTest.class);
46+
47+
private static final boolean DEBUG = false;
48+
private static final boolean SHOW_ELEMENTS = false;
49+
50+
// the prime bases to test
51+
private int[] pArray = new int[] {3, 5, 7, 11};
52+
53+
private static final int[] nMaxForP = new int[20];
54+
55+
@SuppressWarnings("unchecked")
56+
private static ArrayList<Integer>[] correctCountsForP = new ArrayList[20];
57+
58+
@BeforeClass
59+
public static void setup() {
60+
ConfigUtil.initProject();
61+
62+
computeCorrectCounts(3, 13);
63+
computeCorrectCounts(5, 9);
64+
computeCorrectCounts(7, 7);
65+
computeCorrectCounts(11, 6);
66+
}
67+
68+
private static void computeCorrectCounts(int p, int nMax) {
69+
nMaxForP[p] = nMax;
70+
// reference computation is brute force
71+
ArrayList<Integer> correctCounts = new ArrayList<Integer>();
72+
for (int n=0; n<=nMax; n++) {
73+
long m = (long) Math.pow(p, n);
74+
TreeSet<Long> quadraticResidue = QuadraticResidues.getQuadraticResidues(m);
75+
if (DEBUG) LOG.info("n = " + n + " has " + quadraticResidue.size() + " quadratic residues modulo " + p + "^" + n + (SHOW_ELEMENTS ? ": " + quadraticResidue : ""));
76+
correctCounts.add(quadraticResidue.size());
77+
}
78+
LOG.info("correctCounts modulo " + p + "^n = " + correctCounts);
79+
correctCountsForP[p] = correctCounts;
80+
}
81+
82+
@Test
83+
public void testV2() {
84+
for (int p : pArray) {
85+
ArrayList<Integer> counts = new ArrayList<Integer>();
86+
for (int n=0; n<=nMaxForP[p]; n++) {
87+
List<Long> quadraticResidue = QuadraticResiduesModPPowN.getQuadraticResiduesModBPowN(p, n);
88+
if (DEBUG) LOG.debug("v2: n = " + n + " has " + quadraticResidue.size() + " quadratic residues modulo " + p + "^" + n + (SHOW_ELEMENTS ? ": " + quadraticResidue : ""));
89+
counts.add(quadraticResidue.size());
90+
}
91+
LOG.info("v2 counts modulo " + p + "^n = " + counts);
92+
assertEquals(correctCountsForP[p], counts);
93+
}
94+
}
95+
96+
@Test
97+
public void testV3() {
98+
for (int p : pArray) {
99+
ArrayList<Integer> counts = new ArrayList<Integer>();
100+
for (int n=0; n<=nMaxForP[p]; n++) {
101+
List<Long> quadraticResidue = QuadraticResiduesModPPowN.getQuadraticResiduesModBPowN_testAll(p, n);
102+
if (DEBUG) LOG.debug("v3: n = " + n + " has " + quadraticResidue.size() + " quadratic residues modulo " + p + "^" + n + (SHOW_ELEMENTS ? ": " + quadraticResidue : ""));
103+
counts.add(quadraticResidue.size());
104+
}
105+
LOG.info("v3 counts modulo " + p + "^n = " + counts);
106+
assertEquals(correctCountsForP[p], counts);
107+
}
108+
}
109+
110+
@Test
111+
public void testV4() {
112+
for (int p : pArray) {
113+
ArrayList<Integer> counts = new ArrayList<Integer>();
114+
for (int n=0; n<=nMaxForP[p]; n++) {
115+
List<Long> quadraticResidue = QuadraticResiduesModPPowN.getQuadraticResiduesModBPowN_testAll_v2(p, n);
116+
if (DEBUG) LOG.debug("v3: n = " + n + " has " + quadraticResidue.size() + " quadratic residues modulo 3^" + n+ (SHOW_ELEMENTS ? ": " + quadraticResidue : ""));
117+
counts.add(quadraticResidue.size());
118+
}
119+
LOG.info("v4 counts modulo " + p + "^n = " + counts);
120+
assertEquals(correctCountsForP[p], counts);
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)