Skip to content

Commit 2d77b54

Browse files
committed
implement searchFactors() for TDiv63
1 parent 5a6f0de commit 2d77b54

File tree

6 files changed

+170
-8
lines changed

6 files changed

+170
-8
lines changed

src/main/java/de/tilman_neumann/jml/factor/tdiv/TDiv.java

Lines changed: 2 additions & 3 deletions
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-2025 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.
@@ -76,8 +76,7 @@ public void factor(BigInteger N, SortedMultiset<BigInteger> primeFactors) {
7676
}
7777

7878
/**
79-
* Tries to find small factors of a positive, possibly large argument N by doing trial division
80-
* by all primes p &lt;= pLimit.
79+
* Try to find small factors of a positive, possibly large argument N by doing trial division by all primes p <= pLimit.
8180
*
8281
* @param args
8382
* @param result a pre-initialized data structure to add results to

src/main/java/de/tilman_neumann/jml/factor/tdiv/TDiv31.java

Lines changed: 15 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 Tilman Neumann - tilman.neumann@web.de
3+
* Copyright (C) 2018-2025 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.
@@ -16,6 +16,8 @@
1616
import java.math.BigInteger;
1717

1818
import de.tilman_neumann.jml.factor.FactorAlgorithm;
19+
import de.tilman_neumann.jml.factor.base.FactorArguments;
20+
import de.tilman_neumann.jml.factor.base.FactorResult;
1921
import de.tilman_neumann.jml.primes.exact.AutoExpandingPrimesArray;
2022
import de.tilman_neumann.util.SortedMultiset;
2123

@@ -53,6 +55,18 @@ public void factor(BigInteger Nbig, SortedMultiset<BigInteger> primeFactors) {
5355
}
5456
}
5557
}
58+
59+
/**
60+
* Try to find small factors of a positive argument N by doing trial division by all primes p <= pLimit.
61+
*
62+
* @param args
63+
* @param result a pre-initialized data structure to add results to
64+
*/
65+
@Override
66+
public void searchFactors(FactorArguments args, FactorResult result) {
67+
if (args.NBits > 31) throw new IllegalArgumentException(getName() + ".searchFactors() does not work for N>31 bit, but N=" + args.N + " has " + args.NBits + " bit");
68+
throw new UnsupportedOperationException(); // not required because this class overwrites factor()
69+
}
5670

5771
@Override
5872
public BigInteger findSingleFactor(BigInteger N) {

src/main/java/de/tilman_neumann/jml/factor/tdiv/TDiv31Barrett.java

Lines changed: 15 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-2025 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 org.apache.logging.log4j.LogManager;
2020

2121
import de.tilman_neumann.jml.factor.FactorAlgorithm;
22+
import de.tilman_neumann.jml.factor.base.FactorArguments;
23+
import de.tilman_neumann.jml.factor.base.FactorResult;
2224
import de.tilman_neumann.jml.primes.exact.AutoExpandingPrimesArray;
2325
import de.tilman_neumann.util.SortedMultiset;
2426

@@ -97,6 +99,18 @@ public void factor(BigInteger Nbig, int Nexp, SortedMultiset<BigInteger> primeFa
9799
primeFactors.add(BigInteger.valueOf(N), Nexp);
98100
}
99101
}
102+
103+
/**
104+
* Try to find small factors of a positive argument N by doing trial division by all primes p <= pLimit.
105+
*
106+
* @param args
107+
* @param result a pre-initialized data structure to add results to
108+
*/
109+
@Override
110+
public void searchFactors(FactorArguments args, FactorResult result) {
111+
if (args.NBits > 31) throw new IllegalArgumentException(getName() + ".searchFactors() does not work for N>31 bit, but N=" + args.N + " has " + args.NBits + " bit");
112+
throw new UnsupportedOperationException(); // not required because this class overwrites factor()
113+
}
100114

101115
@Override
102116
public BigInteger findSingleFactor(BigInteger N) {

src/main/java/de/tilman_neumann/jml/factor/tdiv/TDiv31Inverse.java

Lines changed: 15 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 Tilman Neumann - tilman.neumann@web.de
3+
* Copyright (C) 2018-2025 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.
@@ -16,6 +16,8 @@
1616
import java.math.BigInteger;
1717

1818
import de.tilman_neumann.jml.factor.FactorAlgorithm;
19+
import de.tilman_neumann.jml.factor.base.FactorArguments;
20+
import de.tilman_neumann.jml.factor.base.FactorResult;
1921
import de.tilman_neumann.jml.primes.exact.AutoExpandingPrimesArray;
2022
import de.tilman_neumann.util.SortedMultiset;
2123

@@ -88,6 +90,18 @@ public void factor(BigInteger Nbig, int Nexp, SortedMultiset<BigInteger> primeFa
8890
primeFactors.add(BigInteger.valueOf(N), Nexp);
8991
}
9092
}
93+
94+
/**
95+
* Try to find small factors of a positive argument N by doing trial division by all primes p <= pLimit.
96+
*
97+
* @param args
98+
* @param result a pre-initialized data structure to add results to
99+
*/
100+
@Override
101+
public void searchFactors(FactorArguments args, FactorResult result) {
102+
if (args.NBits > 31) throw new IllegalArgumentException(getName() + ".searchFactors() does not work for N>31 bit, but N=" + args.N + " has " + args.NBits + " bit");
103+
throw new UnsupportedOperationException(); // not required because this class overwrites factor()
104+
}
91105

92106
@Override
93107
public BigInteger findSingleFactor(BigInteger N) {

src/main/java/de/tilman_neumann/jml/factor/tdiv/TDiv63.java

Lines changed: 61 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 Tilman Neumann - tilman.neumann@web.de
3+
* Copyright (C) 2018-2025 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.
@@ -13,9 +13,14 @@
1313
*/
1414
package de.tilman_neumann.jml.factor.tdiv;
1515

16+
import static de.tilman_neumann.jml.base.BigIntConstants.I_2;
17+
1618
import java.math.BigInteger;
19+
import java.util.SortedMap;
1720

1821
import de.tilman_neumann.jml.factor.FactorAlgorithm;
22+
import de.tilman_neumann.jml.factor.base.FactorArguments;
23+
import de.tilman_neumann.jml.factor.base.FactorResult;
1924
import de.tilman_neumann.jml.primes.exact.AutoExpandingPrimesArray;
2025
import de.tilman_neumann.util.SortedMultiset;
2126

@@ -68,6 +73,61 @@ public void factor(BigInteger Nbig, SortedMultiset<BigInteger> primeFactors) {
6873
primeFactors.add(BigInteger.valueOf(N));
6974
}
7075
}
76+
77+
/**
78+
* Try to find small factors of a positive argument N by doing trial division by all primes p <= pLimit.
79+
*
80+
* @param args
81+
* @param result a pre-initialized data structure to add results to
82+
*/
83+
@Override
84+
public void searchFactors(FactorArguments args, FactorResult result) {
85+
if (args.NBits > 63) throw new IllegalArgumentException(getName() + ".searchFactors() does not work for N>63 bit, but N=" + args.N + " has " + args.NBits + " bit");
86+
87+
long N = args.N.longValue();
88+
int Nexp = args.exp;
89+
SortedMap<BigInteger, Integer> primeFactors = result.primeFactors;
90+
91+
// Remove multiples of 2:
92+
int lsb = Long.numberOfTrailingZeros(N);
93+
if (lsb > 0) {
94+
primeFactors.put(I_2, lsb*Nexp);
95+
N >>>= lsb;
96+
}
97+
98+
if (N == 1) return;
99+
100+
SMALL_PRIMES.ensureLimit(pLimit);
101+
102+
int p_i;
103+
for (int i=1; (p_i=SMALL_PRIMES.getPrime(i))<=pLimit; i++) {
104+
int exp = 0;
105+
while (N%p_i == 0) {
106+
N /= p_i;
107+
exp++;
108+
}
109+
if (exp > 0) {
110+
// At least one division has occurred, add the factor(s) to the result map
111+
addToMap(BigInteger.valueOf(p_i), exp*Nexp, primeFactors);
112+
// Check if we are done
113+
if (p_i *(long)p_i > N) {
114+
// the remaining N is 1 or prime
115+
if (N>1) addToMap(BigInteger.valueOf(N), Nexp, primeFactors);
116+
result.smallestPossibleFactor = p_i; // may be helpful in following factor algorithms
117+
return;
118+
}
119+
}
120+
}
121+
122+
result.smallestPossibleFactor = p_i; // may be helpful in following factor algorithms
123+
result.untestedFactors.add(BigInteger.valueOf(N), Nexp); // we do not know if the remaining N is prime or composite
124+
}
125+
126+
private void addToMap(BigInteger N, int exp, SortedMap<BigInteger, Integer> map) {
127+
Integer oldExp = map.get(N);
128+
// replaces old entry if oldExp!=null
129+
map.put(N, (oldExp == null) ? exp : oldExp+exp);
130+
}
71131

72132
@Override
73133
public BigInteger findSingleFactor(BigInteger N) {

src/main/java/de/tilman_neumann/jml/factor/tdiv/TDiv63Inverse.java

Lines changed: 62 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-2025 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.
@@ -13,12 +13,17 @@
1313
*/
1414
package de.tilman_neumann.jml.factor.tdiv;
1515

16+
import static de.tilman_neumann.jml.base.BigIntConstants.I_2;
17+
1618
import java.math.BigInteger;
19+
import java.util.SortedMap;
1720

1821
import org.apache.logging.log4j.Logger;
1922
import org.apache.logging.log4j.LogManager;
2023

2124
import de.tilman_neumann.jml.factor.FactorAlgorithm;
25+
import de.tilman_neumann.jml.factor.base.FactorArguments;
26+
import de.tilman_neumann.jml.factor.base.FactorResult;
2227
import de.tilman_neumann.jml.primes.bounds.PrimeCountUpperBounds;
2328
import de.tilman_neumann.jml.primes.exact.AutoExpandingPrimesArray;
2429
import de.tilman_neumann.util.SortedMultiset;
@@ -133,6 +138,62 @@ public void factor(BigInteger Nbig, SortedMultiset<BigInteger> primeFactors) {
133138
primeFactors.add(BigInteger.valueOf(N));
134139
}
135140
}
141+
142+
/**
143+
* Try to find small factors of a positive argument N by doing trial division by all primes p <= pLimit.
144+
*
145+
* @param args
146+
* @param result a pre-initialized data structure to add results to
147+
*/
148+
// TODO this is a copy from TDiv63. Optimize it for this class.
149+
@Override
150+
public void searchFactors(FactorArguments args, FactorResult result) {
151+
if (args.NBits > 63) throw new IllegalArgumentException(getName() + ".searchFactors() does not work for N>63 bit, but N=" + args.N + " has " + args.NBits + " bit");
152+
153+
long N = args.N.longValue();
154+
int Nexp = args.exp;
155+
SortedMap<BigInteger, Integer> primeFactors = result.primeFactors;
156+
157+
// Remove multiples of 2:
158+
int lsb = Long.numberOfTrailingZeros(N);
159+
if (lsb > 0) {
160+
primeFactors.put(I_2, lsb*Nexp);
161+
N >>>= lsb;
162+
}
163+
164+
if (N == 1) return;
165+
166+
SMALL_PRIMES.ensureLimit(pLimit);
167+
168+
int p_i;
169+
for (int i=1; (p_i=SMALL_PRIMES.getPrime(i))<=pLimit; i++) {
170+
int exp = 0;
171+
while (N%p_i == 0) {
172+
N /= p_i;
173+
exp++;
174+
}
175+
if (exp > 0) {
176+
// At least one division has occurred, add the factor(s) to the result map
177+
addToMap(BigInteger.valueOf(p_i), exp*Nexp, primeFactors);
178+
// Check if we are done
179+
if (p_i *(long)p_i > N) {
180+
// the remaining N is 1 or prime
181+
if (N>1) addToMap(BigInteger.valueOf(N), Nexp, primeFactors);
182+
result.smallestPossibleFactor = p_i; // may be helpful in following factor algorithms
183+
return;
184+
}
185+
}
186+
}
187+
188+
result.smallestPossibleFactor = p_i; // may be helpful in following factor algorithms
189+
result.untestedFactors.add(BigInteger.valueOf(N), Nexp); // we do not know if the remaining N is prime or composite
190+
}
191+
192+
private void addToMap(BigInteger N, int exp, SortedMap<BigInteger, Integer> map) {
193+
Integer oldExp = map.get(N);
194+
// replaces old entry if oldExp!=null
195+
map.put(N, (oldExp == null) ? exp : oldExp+exp);
196+
}
136197

137198
/**
138199
* {@inheritDoc}

0 commit comments

Comments
 (0)