static void MyQuadraticsTest() { BigInteger N = 9028325; int B = 35; SieveRequest sievereq = new SieveRequest(); QuadraticSieve.InitSievingRequest(N, B, x => x * x - N, sievereq); QuadraticSieve.SegmentSievingRequest((int)N.Sqrt() + 1, B << 5, sievereq); SievingData sievedat = new SievingData(); QuadraticSieve.Sieve(sievereq, sievedat); SieveResult sieveres = new SieveResult(); QuadraticSieve.CreateFormattedSievingResult(sievereq, sievedat, sieveres); printarr(sieveres.V); printarr(sieveres.SmoothRelations); Console.WriteLine(); SolveRequest solvereq = new SolveRequest(); QuadraticSieve.InitSolveRequest(sievereq.B, sieveres.V.Count, solvereq); QuadraticSieve.AddDataToSolveRequest(sieveres, solvereq); printarr(solvereq.Coefficients); Console.WriteLine(); QuadraticSieve.Gaussian(solvereq); printarr(solvereq.Coefficients); Console.WriteLine("First free = " + solvereq.FirstFree); }
static void Main(string[] args) { QuadraticSieve.primeSupply = new derpy(); BigInteger N = 90283; int B = 14; SieveRequest sievereq = new SieveRequest(); QuadraticSieve.InitSievingRequest(N, B, x => x * x - N, sievereq); QuadraticSieve.SegmentSievingRequest(0, 60, sievereq); SievingData sievedat = new SievingData(); QuadraticSieve.EvaluatePoly(sievereq, sievedat); QuadraticSieve.Sieve(sievereq, sievedat); SieveResult sieveres = new SieveResult(); QuadraticSieve.CreateFormattedSievingResult(sievereq, sievedat, sieveres); printarr(sieveres.V); printarr(sieveres.SmoothRelations); Console.WriteLine(); SolveRequest solvereq = new SolveRequest(); QuadraticSieve.InitSolveRequest(sievereq.B, sieveres.V.Count, solvereq); QuadraticSieve.AddDataToSolveRequest(sieveres, solvereq); printarr(solvereq.Coefficients); Console.WriteLine(); QuadraticSieve.Gaussian(solvereq); printarr(solvereq.Coefficients); Console.ReadLine(); }
public static void EvaluatePoly(SieveRequest sievereq, SievingData sievedat) { sievedat.V = new BigInteger[sievereq.L]; for (int i = 0; i < sievereq.L; i++) { sievedat.V[i] = sievereq.polyFunction(i + sievereq.AStart + StartIdx); } }
/// <summary> /// Generates data to be sieved from the given SieveRequest /// </summary> /// <param name="sievereq"></param> /// <param name="sievedat">The SieveData object to fill with data</param> public static void EvaluatePoly(SieveRequest sievereq, SievingData sievedat) { sievedat.V = new BigInteger[sievereq.L]; for (int i = 0; i < sievereq.L; i++) { sievedat.V[i] = sievereq.polyFunction(i + sievereq.AStart + sievereq.StartIdx); } }
public static void CreateFormattedSievingResult(SieveRequest sievereq, SievingData sievedat, SieveResult sieveres) { sieveres.SourceRequest = sievereq; sieveres.SmoothRelations = new List <BinaryVector>(); sieveres.V = new List <BigInteger>(); for (int i = 0; i < sievereq.L; i++) { //if number only consisted of primes that were sieved, then it is smooth if (sievedat.V[i] == 1) { sieveres.V.Add(sievereq.polyFunction(i + sievereq.AStart + StartIdx)); sieveres.SmoothRelations.Add(sievedat.Coefficients[i]); } } }
//really weird sieving method public static void Sieve(SieveRequest sievereq, SievingData sievedat) { //get data first EvaluatePoly(sievereq, sievedat); //make transposed matrix (each BinaryVector holds the factorization for a number) sievedat.Coefficients = new BinaryVector[sievereq.L]; //loop through each prime for (int i = 0; i < sievereq.B; i++) { //get value of prime int interval = sievereq.PrimeIntervals[i]; //loop through each solution of the quadratic residue for (int j = 0; j < sievereq.PrimeStarts[i].Count; j++) { //remap start location to this sieving interval int remappedStart = (interval - (StartIdx - sievereq.PrimeStarts[i][j])) % interval; if (remappedStart < 0) { remappedStart = remappedStart + interval; } //sieve out each prime for (int k = remappedStart; k < sievereq.L; k += interval) { //attempt to save memory by not initializating the arrayelements that haven't been used yet //NOTE: this doesn't work, because at least half of the elements will have been visited if (Object.ReferenceEquals(sievedat.Coefficients[k], null)) { sievedat.Coefficients[k] = new BinaryVector(sievereq.B); } //divide out the whole prime power while (sievedat.V[k] % interval == 0) { sievedat.Coefficients[k][i] = sievedat.Coefficients[k][i] + 1; sievedat.V[k] = sievedat.V[k] / interval; } } } } }
/// <summary> v cQ1 /// Initializes a SievingRequest based on given parameters, and finds the quadratic residues for primes specified /// </summary> /// <param name="N">The number to factor</param> /// <param name="B">The limit for smooth numbers</param> /// <param name="f">The polynomial to sieve</param> /// <param name="sievereq">The SieveRequest that will be initialized</param> public static void InitSievingRequest(BigInteger N, int B, PolynomialFunction f, SieveRequest sievereq) { sievereq.AStart = (int)N.Sqrt() + 1; sievereq.StartIdx = 0; sievereq.polyFunction = f; sievereq.L = primeSupply[B]; SievingData sievedat = new SievingData(); EvaluatePoly(sievereq, sievedat); List<List<int>> tmpPrimeStarts = new List<List<int>>(); List<int> tmpPrimeIntervals = new List<int>(); for (int pI = 0; pI < B; pI++) { int p = primeSupply[pI]; List<int> tmp = new List<int>(); for (int a = 0; a < p; a++) { if (sievedat.V[a] % p == 0) { tmp.Add(a); } } if (tmp.Count > 0) { tmpPrimeIntervals.Add(p); tmpPrimeStarts.Add(tmp); } } sievereq.PrimeIntervals = tmpPrimeIntervals.ToArray(); sievereq.PrimeStarts = tmpPrimeStarts.ToArray(); sievereq.B = sievereq.PrimeIntervals.Length; }
/// <summary> /// Sieves data in the sievedat object /// </summary> /// <param name="sievereq"></param> /// <param name="sievedat"></param> public static void Sieve(SieveRequest sievereq, SievingData sievedat) { sievedat.Coefficients = new BinaryVector[sievereq.L]; for (int i = 0; i < sievereq.B; i++) { int interval = sievereq.PrimeIntervals[i]; for (int j = 0; j < sievereq.PrimeStarts[i].Count; j++) { int remappedStart = (interval - (sievereq.StartIdx - sievereq.PrimeStarts[i][j])) % interval; if (remappedStart < 0) remappedStart = remappedStart + interval; for (int k = remappedStart; k < sievereq.L; k += interval) { if (Object.ReferenceEquals(sievedat.Coefficients[k], null)) sievedat.Coefficients[k] = new BinaryVector(sievereq.B); while (sievedat.V[k] % interval == 0) { sievedat.Coefficients[k][i] = sievedat.Coefficients[k][i] + 1; sievedat.V[k] = sievedat.V[k] / interval; } } } } }
/// <summary> /// Gets a segment of a sieve request /// </summary> /// <param name="startIdx">The start index of the segment</param> /// <param name="L">The length of the segment</param> /// <param name="sievereq">The SieveRequest to cut</param> public static void SegmentSievingRequest(int startIdx, int L, SieveRequest sievereq) { sievereq.StartIdx = startIdx; sievereq.L = L; }
/// <summary> /// Formats data in a SieveData object into a proper SieveResult /// </summary> /// <param name="sievereq"></param> /// <param name="sievedat">The data to be formatted</param> /// <param name="sieveres">The SieveResult object where the formatted data will be put</param> public static void CreateFormattedSievingResult(SieveRequest sievereq, SievingData sievedat, SieveResult sieveres) { sieveres.SourceRequest = sievereq; sieveres.SmoothRelations = new List<BinaryVector>(); sieveres.V = new List<BigInteger>(); for (int i = 0; i < sievereq.L; i++) { if (sievedat.V[i] == 1) { sieveres.V.Add(sievereq.polyFunction(i + sievereq.AStart + sievereq.StartIdx)); sieveres.SmoothRelations.Add(sievedat.Coefficients[i]); } } }
public static void SegmentSievingRequest(int startIdx, int L, SieveRequest sievereq) { StartIdx = startIdx; sievereq.L = L; }
public static void InitSievingRequest(BigInteger N, int B, PolynomialFunction f, SieveRequest sievereq) { sievereq.AStart = (int)N.Sqrt() + 1; StartIdx = 0; sievereq.polyFunction = f; //the max amount of data we need to find the quadratic residues is the Bth prime (the highest one) sievereq.L = primeSupply[B]; SievingData sievedat = new SievingData(); EvaluatePoly(sievereq, sievedat); List <List <int> > tmpPrimeStarts = new List <List <int> >(); List <int> tmpPrimeIntervals = new List <int>(); for (int pI = 0; pI < B; pI++) { int p = primeSupply[pI]; List <int> tmp = new List <int>(); for (int a = 0; a < p; a++) { if (sievedat.V[a] % p == 0) { //we found a quadratic residue (there are two for each prime that isn't 2) tmp.Add(a); } } if (tmp.Count > 0) { //if the ith value is divisible by the prime k, then every k results after that will also be divisible tmpPrimeIntervals.Add(p); tmpPrimeStarts.Add(tmp); } } sievereq.PrimeIntervals = tmpPrimeIntervals.ToArray(); sievereq.PrimeStarts = tmpPrimeStarts.ToArray(); //remove primes with no quadratic residues sievereq.B = sievereq.PrimeIntervals.Length; }