Question

In: Advanced Math

factorize the integer 2896753 by using the Quadratic Sieve method

factorize the integer 2896753 by using the Quadratic Sieve method

Solutions

Expert Solution

Code Language: Java

 import java.util.Scanner; import java.util.ArrayList; import java.util.HashSet; /* **This program will run a quadratic sieve to **factor some numbers** 
*/ public class QuadraticSieve { //This is the range the matrix runs on. //50,000 works great because it works for all numbers //in the range of long without being too large private static final long SIEVERANGE = 50000; //This is a private class //to be used as a touple for //saving an ArrayList and it's integer index //and some other things private static class Pair<X, Y> { private final X x; private final Y y; public Pair(X x, Y y) { this.x = x; this.y = y; } public X getX(){ return x;} public Y getY(){ return y;} } public static void main(String[] args) { //Grab number N to be factored long n;         //Grab the factor base long factorbase; //take from command line                //if no factobase is given, assume 1000         if(args.length == 1)    {               n = Long.parseLong(args[0]);            factorbase = 1000;      } else if(args.length == 2) { n = Long.parseLong(args[0]); factorbase = Long.parseLong(args[1]); } //else take from scanner else { Scanner input = new Scanner(System.in); System.out.println("Enter an N: "); n = input.nextLong();     System.out.println("Enter a factorbase: "); factorbase = input.nextLong(); } //Find R long R = (long)Math.sqrt(n); //generate a list of primes up to factorbase ArrayList<Integer> primes = eratosthenesSieve(factorbase); //for(int i = 0; i < primes.size(); i++) //System.out.println(primes.get(i) + " "); //generate a list that satisfies the eqn ArrayList<Long> bSmooth = findSmoothness(n); ArrayList<Long> residues = calcResiduals(primes, bSmooth); //Refactor and Gauss ArrayList<Pair<ArrayList<Long>, Integer>> refactoredResidual       = refactor(residues, bSmooth, primes); //reduce the matrix mod 2 ArrayList<Pair<ArrayList<Integer>, Integer>> reducedResidual         = reduceModTwo(refactoredResidual); //print reduced residual matrix //System.out.println("Reduced matrix is: "); //int i = 0; //for(Pair<ArrayList<Integer>,Integer> pair : reducedResidual) //{ //System.out.print(i + " "); //System.out.print("["); //for(long j : pair.getX()) //System.out.print(j + ", "); //System.out.println("]"); //i++; //} //perform Gauss-Jordan elimination on the matrix //build list of hits I.E. (Index, r1, r2, r3, etc) ArrayList<ArrayList<Integer>> gaussHits = gauss(reducedResidual); //rebuild equation HashSet<Long> factors = rebuildEquation(gaussHits, n); System.out.print("The factors are: " ); for(long factor : factors) System.out.print(factor + ", "); System.out.println(); } /** * This method will perform an eratostheness Sieve to calculate all primes * under the input factobase * * @param size This is the size to create the array of primes * @return     An ArrayList of primes under size */ public static ArrayList<Integer> eratosthenesSieve(long size) { ArrayList<Integer> primes = new ArrayList<Integer>(); //populate a list with i = 2 to n for(int i = 2; i < size; i++) primes.add(i); //set p equal to 2? int p = 2; //loop while(Math.pow(p, 2) < size) { for(int i = primes.indexOf(p) + 1; i < primes.size(); i++) { ////System.out.println(primes.get(i) +": divided by " + p); if(primes.get(i) % p == 0) { primes.remove(i); } } p++; } primes.add(0, -1); return primes; } /** *This method will find the smooth numbers between the range *specified * *@param numToFactor       the input number we are factoring *@return      An ArrayList of longs representing the smooth values found */ public static ArrayList<Long> findSmoothness(long numToFactor) { //Offset = R. Change later ArrayList<Long> Qs = new ArrayList<Long>(); //System.out.println("Root is " + Math.sqrt(numToFactor)                                        //+ "\tindex\t" + "(r+n)^2\t" + "(r+n)^2 - N)"); for(long i = -SIEVERANGE; i <= SIEVERANGE; i++) { //store log of Q possibly long Q = ((long)(Math.pow((Math.sqrt(numToFactor) + i), 2))); long save = Q - numToFactor; Qs.add(save); //System.out.println(i +"\t" + (Qs.size() - 1) + "\t" + Q + "\t" + save); } return Qs; } /** *This method will determine which numbers are smooth by repeatedly dividing *by primes in the factor base to obtain residuals of each number. * *@param smoothlist An ArrayList of smooth *@return        An ArrayList of longs representing the newly calculated residuals */ public static ArrayList<Long> calcResiduals(ArrayList<Integer> primes,                                                                                          ArrayList<Long> smoothlist) { //ArrayList<Pair<Integer, Integer>> residuals  //= new ArrayList<Pair<Integer,Integer>>(); ArrayList<Long> copy = new ArrayList<Long>(); for(long i : smoothlist) copy.add(i); int start; for(int i : primes) { if(i == -1) continue; //System.out.println("Sieve with " + i); for(int j = 0; j < copy.size(); j++) { if(copy.get(j) % i == 0)      { start = j; int index = j; do{ long temp = copy.get(j); while(temp != 0 && temp % i == 0) { //System.out.println("Temp: " + temp + "\ti: " + i                                                                  //+ "temp % i = " + (temp%i)); //System.out.println("Divide\t" + i + "\t "                                                              //+(j-(smoothlist.size()/2)) + "\t "                                                            //+ temp + "\t" + (temp / i)); temp = temp / i; } copy.set(j, temp); j = (j + i) % copy.size(); } while(j != start);   } } //System.out.print("Array ["); /* for(long num : copy) { //System.out.print(num + ", "); } */ //System.out.println("]"); } //Take abs value of the array for(int i = 0; i < copy.size(); i++) copy.set(i, Math.abs(copy.get(i))); return copy; } /** *This method will create a matrix of the prime factorization of numbers *that are smooth over the factorbase. *It stores the exponents of each prime factor of each number. * *@param Residues      An ArrayList of reisdues calculated from *                      calcResidues *@param original   the original ArrayList of the smooth numbers *@param primes     the list of primes up to the factorbase  *@return       an ArrayList of pairs containing the rows and their *           corresponding integer index in case the rows get *              rearranged later */ public static ArrayList<Pair<ArrayList<Long>,Integer>>                            refactor(ArrayList<Long> residues, ArrayList<Long> original,                                                 ArrayList<Integer> primes) { //initialize arraylist and fill with zero arryalists ArrayList<Pair<ArrayList<Long>, Integer>> exponents  = new ArrayList<Pair<ArrayList<Long>, Integer>>(); //cheating long zero = 0; for(int i = 0; i < residues.size(); i++) { if(residues.get(i) == 1) { ArrayList<Long> exponent = new ArrayList<Long>(); for(int index = 0; index < primes.size(); index++) exponent.add(zero);                 //System.out.println("Smooth\t" + (i - (original.size()/2))                                              //+ "\t" + i + "\t" + original.get(i)); long temp = original.get(i);    if(temp < 0)         {       temp = temp * -1;       exponent.set(0,new Long(1));    } //pIndex set to 1 to skip the "prime" -1 for(int pIndex = 1; pIndex < primes.size(); pIndex++) { while(temp % primes.get(pIndex) == 0)     {       //System.out.println("DIVIDE\t" + pIndex +"\t" + primes.get(pIndex) + "\t" + temp);     temp = temp / primes.get(pIndex);       exponent.set(pIndex, (exponent.get(pIndex))+1);         }               } exponents.add(new Pair<ArrayList<Long>, Integer>(exponent, i)); } //System.out.print("["); /* if(exponents.size() > 0) { for(long whatever : exponents.get(exponents.size() -1).getX()) { //System.out.print(whatever +", "); } //System.out.println("]"); } */ } return exponents; } /** *This method reduces the prime factorization matrix mod 2 * (so the matrix only stores the parity of the exponents). * *@param      An ArrayList of Pairs representing the matrix and the indices *@return  An ArrayList of Pairs of ArrayLists and their corresponding *           indices (in case of the loss of the index from reduction */ public static ArrayList<Pair<ArrayList<Integer>, Integer>> reduceModTwo                                                                                   (ArrayList<Pair<ArrayList<Long>,                                                                                     Integer>> matrix) { ArrayList<Pair<ArrayList<Integer>, Integer>> modTwo        = new ArrayList<Pair<ArrayList<Integer>, Integer>>(); for(int i = 0; i < matrix.size(); i++) { //System.out.print("Row: " + i + "\t["); for(int j = 0; j < matrix.get(i).getX().size(); j++) { //System.out.print(matrix.get(i).getX().get(j) + ", "); matrix.get(i).getX().set(j, matrix.get(i).getX().get(j) % 2); } //System.out.print("]\nReduced\t["); //for(long temp : matrix.get(i).getX()) //System.out.print(temp + ", "); //System.out.println("]"); } for(Pair<ArrayList<Long>, Integer> pair : matrix) { ArrayList<Integer> ints = new ArrayList<Integer>(); for(long number : pair.getX()) ints.add((int)number); modTwo.add(new Pair<ArrayList<Integer>, Integer>(ints, pair.getY())); } return modTwo; } /** *This method uses Gaussian elimination to return a list *of row combinations that sum to zero. These represent *products that are square and can be used to rebuild the equation x^2 = y^2. * *@param array    The array to perform gauss elimination on *@returns     An ArrayList of ArrayLists representing the row reduction *                     operations performed on the matrix */ public static ArrayList<ArrayList<Integer>> gauss                             (ArrayList<Pair<ArrayList<Integer>,Integer>> array) { ArrayList<Pair<ArrayList<Integer>, ArrayList<Integer>>> reducedMatrix   = new ArrayList<Pair<ArrayList<Integer>, ArrayList<Integer>>>(); //initialize ArrayList for(int i = 0; i < array.size(); i++) { ArrayList<Integer> rowReductions = new ArrayList<Integer>(); //first value in the index is the original index of said row rowReductions.add(array.get(i).getY()); reducedMatrix.add(new Pair<ArrayList<Integer>,                                                ArrayList<Integer>>(array.get(i).getX(),                                                                                       rowReductions)); } int j = 0; for(int i = 0; i < reducedMatrix.size(); i++) { if(j >= reducedMatrix.get(i).getX().size()) break; if(reducedMatrix.get(i).getX().get(j) == 0) { //index of the next row that has a 1 to swap for the zero int oneRow; for(oneRow = i + 1; oneRow < reducedMatrix.size(); oneRow++) { //break at 1 to preserve oneRow for swapping if(reducedMatrix.get(oneRow).getX().get(j) == 1) break; } //if it's not equal to the size, we did find a 1 if(oneRow < reducedMatrix.size()) { //one found, swap rows Pair<ArrayList<Integer>, ArrayList<Integer>> temp           = reducedMatrix.get(i); reducedMatrix.set(i, reducedMatrix.get(oneRow)); reducedMatrix.set(oneRow, temp); } //else move to the next column else { i--; j++; continue; } } //else we have 1, zero out the column for(int row = i + 1; row < reducedMatrix.size(); row++) { if(reducedMatrix.get(row).getX().get(j) == 0) continue; reducedMatrix.get(row).getX().set(j,0); reducedMatrix.get(row).getY().add(i); } j++; } ArrayList<ArrayList<Integer>> zeroSums = new ArrayList<ArrayList<Integer>>(); for(int i = 0; i < reducedMatrix.size(); i++) { for(j = 0; j < reducedMatrix.get(i).getX().size(); j++) { if(reducedMatrix.get(i).getX().get(j) != 0) { //break out of the loop by ending condition j = reducedMatrix.get(i).getX().size(); continue; } } zeroSums.add(reducedMatrix.get(i).getY()); } return zeroSums; } /** * This method will rebuild the equation x^2 = y^2 * *@param bigN         The number to be factored *@param gaussHits     The matrix of row reduce operations from gauss *@return                 A HashSet containing the factors of N */ public static HashSet<Long> rebuildEquation                              (ArrayList<ArrayList<Integer>> gaussHits, long bigN) { long R = ((long)(Math.sqrt(bigN))) / SIEVERANGE; HashSet<Long> factors = new HashSet<Long>(); for(ArrayList<Integer> hit : gaussHits) { int lhs = 1; int rhs = 1; for(int num = 1; num < hit.size(); num++) { lhs *= Math.pow(R + (hit.get(num)- R), 2); rhs *= Math.pow(R + (hit.get(num) - R), 2) - bigN; } long x = (long)(Math.sqrt(Math.abs(lhs))); long y = (long)(Math.sqrt(Math.abs(rhs))); if(x == y) continue; long factor1 = (gcd(bigN, (x+y))); long factor2 = (gcd(bigN, (x-y))); ////System.out.print("Hit\t["); //for(long number : hit) // //System.out.print(number + ", "); //System.out.println("]\n LHS: " + lhs + ".\t RHS: " + rhs); //System.out.println("X: " + x + "\tY: " + y); //System.out.println("gcd(" + bigN +", " + (x+y) +": " + factor1 + //"\ngcd(" + bigN + ", " + (x-y) + ": " + factor2); factors.add(Math.abs(factor1)); factors.add(Math.abs(factor2)); //check if the factors make other factors! if(bigN % factor1 == 0) factors.add(Math.abs(bigN/factor1)); if(bigN % factor2 == 0) factors.add(Math.abs(bigN/factor2)); if(factors.size() > 1) factors = completeFactors(factors); } return factors; } /*** *This method divides all factors by other factors to ensure *that all prime factors are listed in the output. * *@param factors    This is the list of factors so far *@return                     A HashSet of all factors factored from the original                                             factors */ public static HashSet<Long> completeFactors(HashSet<Long> factors) { HashSet<Long> newFactors = new HashSet<Long>(); for(long fact : factors) newFactors.add(fact); for(long fact : factors) for(long fact2 : factors) if(fact > fact2 && fact % fact2 == 0) newFactors.add(fact / fact2); return newFactors; } /** * This method will run the euclidean algorithm to * factor two integer into their greatest common denominator * *@param a     An integer to be reduced *@param b      An integer to be reduced *@return       The greatest common denominator between a and b */ public static long gcd(long a, long b) { while(b != 0) { long t = b; b = a % b; a = t; } return a; } }

Output: The factors are 1, 2357, 2896753, 1229


Related Solutions

Method: ArrayList<Integer> diff(ArrayList<Integer> list1, ArrayList<Integer> list2) diff() method accepts two ArrayLists of Integer and returns the...
Method: ArrayList<Integer> diff(ArrayList<Integer> list1, ArrayList<Integer> list2) diff() method accepts two ArrayLists of Integer and returns the union of elements in two lists. For example: list1 contains elements [1, 2, 3, 4, 5] list2 contains elements [3, 4, 5, 6, 7] Diff() method should return an array list with elements [1, 2, 3, 4, 5, 6, 7].
Can someone please write me a header file in c++ using the quadratic probing hash method...
Can someone please write me a header file in c++ using the quadratic probing hash method that will work with this program? #include "hash.h" #include <algorithm> #include <cstdlib> #include <ctime> #include <iostream> #include <list> using namespace std; const size_t KEYS_COUNT = 1000; // Number of keys to generate for testing string random_key(); class HashCheck { private: size_t count; Hash hash; public: HashCheck(Hash& h) { count = 0; hash = h; } void operator() (const string key) { if (hash[key] !=...
Write a recursive method that displays an integer value reversely on the console using the following...
Write a recursive method that displays an integer value reversely on the console using the following header: public static void reverseDisplay(int value) For example, reverseDisplay(12345) displays 54321. Write a test program that prompts the user to enter an integer, invokes the method above, and displays its reversal.
1) Solve the given quadratic equation by using Completing the Square procedure and by Quadratic formula...
1) Solve the given quadratic equation by using Completing the Square procedure and by Quadratic formula ( you must do it both ways). Show all steps for each method and put your answer in simplest radical form possible. 2) Which part of the Quadratic Formula can help you to find the Nature of the roots for the Quadratic Equation. Explain how you can find the nature of the roots and provide one Example for each possible case with solution.
How many methods are there for solving quadratic equations? And which is a preferred method?
How many methods are there for solving quadratic equations? And which is a preferred method?
Write a RECURSIVE method that receives as a parameter an integer named n. The method will...
Write a RECURSIVE method that receives as a parameter an integer named n. The method will output n # of lines of stars. For example, the first line will have one star, the second line will have two stars, and so on. The line number n will have "n" number of ****** (stars) so if n is 3 it would print * ** *** The method must not have any loops!
Write a program that generates all prime numbers between 2 and 1000, using the Sieve of...
Write a program that generates all prime numbers between 2 and 1000, using the Sieve of Eratosthenes method. You can find many articles that describe the method for finding primes in this manner on the Internet. Display all the prime values. This program should be in assembly language.
Using C# Create a class named Inches To Feet. Its Main()method holds an integer variable named...
Using C# Create a class named Inches To Feet. Its Main()method holds an integer variable named inches to which you will assign a value. Create a method to which you pass inches. The method displays inches in feet and inches. For example, 67 inches is 5 feet 7 inches.
Create a class using C# named InchesToFeet. Its Main()method holds an integer variable named inches to...
Create a class using C# named InchesToFeet. Its Main()method holds an integer variable named inches to which you will assign a value. Create a method to which you pass inches. The method uses 2 ref parameters: feet, inches left of type int and a parameter that is not ref of type int to which you pass inchesinches. For example, 67 inches is 5 feet 7 inches.
Solve the following linear integer programming model using the Cutting Plane method. Show all relevant work...
Solve the following linear integer programming model using the Cutting Plane method. Show all relevant work in your solution report. Maximize Z = x1 + x2 Subject to 3x1 + 2x2 < 5 x2 < 2 x1, x2 > 0 and integer.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT