How to get a prime of a given length in Sage? - primes

How can I get a random prime of a given bit length in Sage?
For example, to get a 512-bit prime, I tried
p = random_prime(2^512)
but according to the documentation:
The command random_prime(a, True) will return a random prime between 2 and a
so I can't use it, since I need a prime of an exact length.

sage: random_prime?
Signature: random_prime(n, proof=None, lbound=2)
Docstring:
Returns a random prime p between lbound and n (i.e. lbound <= p <=
n). The returned prime is chosen uniformly at random from the set
of prime numbers less than or equal to n.
INPUT:
* "n" - an integer >= 2.
* "proof" - bool or None (default: None) If False, the function
uses a pseudo-primality test, which is much faster for really big
numbers but does not provide a proof of primality. If None, uses
the global default (see "sage.structure.proof.proof")
* "lbound" - an integer >= 2 lower bound for the chosen primes
So is this sufficient?
sage: random_prime(2^512-1,False,2^511)
7484165189517896027318192121767201416039872004910529422703501933303497309177247161202453673508851750059292999942026203470027056226694857512284815420448467
sage: is_prime(7484165189517896027318192121767201416039872004910529422703501933303497309177247161202453673508851750059292999942026203470027056226694857512284815420448467)
True

Related

need help about sieve of eratosthenes in free pascal

my teacher gave me this :
n<=10^6;
an array of n integer :ai..an(ai<=10^9);
find all prime numbers .
he said something about sieve of eratosthenes,and I read about it,also the wheel factorization too,but I still couldn't figure it out how to get the program (fpc) to run in 1s.??
as I know it's impossible,but still want to know your opinion .
and with the wheel factorization ,a 2*3 circle will treat 25 as a prime number,and I wanna ask if there is a way to find out the first number of the wheel treated wrong as a prime number.
example:2*3*5 circle ,how to find the first composite number treated as aprime number??
please help..and sorry for bad english.
A proper Sieve of Eratosthenes should find the primes less than a billion in about a second; it's possible. If you show us your code, we'll be happy to help you find what is wrong.
The smallest composite not marked by a 2,3,5-wheel is 49: the next largest prime not a member of the wheel is 7, and 7 * 7 = 49.
I did it now and it's finding primes up to 1000000 in a few milliseconds, without displaying all those numbers.
Declare an array a of n + 1 bools (if it is zero-based). At the beginning 0th and 1st element are false, all others are true (false is not a prime).
The algorithm looks like that:
i = 2;
while i * i <= n
if a[i] == true
j = i * i;
while j < n
a[j] = false;
j = j + i;
i = i + 1;
In a loop the condition is i * i <= n because you start searching from i * i (smaller primes than that was found already by one of other primes) so square root of i must not be bigger than n. You remove all numbers which are multiplies of primes up to n.
Time complexity is O(n log log n).
If you want to display primes, you display indexes which values in array are true.
Factorization is usefull if you want to find e.g. all semiprimes from 0 to n (products of two prime numbers). Then you find all smallest prime divisors from 0 to n/2 and check for each number if it has prime divisor and if number divided by its prime divisor has zero divisors. If so - it is a semiprime. My program wrote like that was calculating 8 times faster than first finding all primes and then multiplying them and saving result in an array.

Find the perfect square in the string

A perfect square is taken in binary and some bits are replaced with "?" for example 1??, the number would be 4.(or 1????000???0000)
I need to find that perfect square.(there will be only such possible number)
number of '?'s in the string be n
To find that number what I am doing is iterating through 2**n numbers(111,110,101,100) and checking if it is a perfect square. I am using following function to check if it is a perfect square.
bool issqr(int n){
int d=(int)(sqrt(n));
if(d*d==n) return true;
else return false;
}
Even though in python I did it, it is taking a lot of time, so I shifted to C++ using only bit operations for populating 2**n numbers(which was much faster than the python version)
but this fails if the number has more than 64 bits
How to avoid this problem? How can I do the same thing if a number has say 120 bits.
(10100110???1?1?01?1?011000?1100?00101000?1?11001101100110001010111?0?1??0110?110?01?1100?1?0110?1?10111?01?0111000?10??101?01)
Rather than re-writing in C++ you should first have looked at improving your algorithm. The lowest possible answer is the square root from the original value with all '?' replace by 0 rounded up, the highest possible answer is the square root of the pattern with the '?'s replaced by 1 rounded down. Find those two values, iterate through them, square and check against the pattern.
This is faster both because you are iterating through many fewer numbers and because you aren't calculating any square roots in the loop: squaring is much easier.
You don't need to compare string to check for a match:
mask = int(pattern.replace('0', '1').replace('?', '0'), 2)
test = int(pattern.replace('?', '0'), 2)
def is_match(n):
return (n&mask)==test
So putting it all together:
def int_sqrt(x):
if x < 0:
raise ValueError('square root not defined for negative numbers')
n = int(x)
if n == 0:
return 0
a, b = divmod(n.bit_length(), 2)
x = 2**(a+b)
while True:
y = (x + n//x)//2
if y >= x:
return x
x = y
def find_match(pattern):
lowest = int(pattern.replace('?', '0'), 2)
highest = int(pattern.replace('?', '1'), 2)
mask = int(pattern.replace('0', '1').replace('?', '0'), 2)
lowsqrt = int_sqrt(lowest)
if lowsqrt*lowsqrt != lowest:
lowsqrt += 1
highsqrt = int_sqrt(highest)
for n in range(lowsqrt, highsqrt+1):
if (n*n & mask)==lowest:
return n*n
print(find_match('1??1??1'))
print(find_match('1??0??1'))
print(find_match('1??????????????????????????????????????????????????????????????????????1??0??1'))
Output:
121
81
151115727461209345152081
N.B. This only works in Python 3.x, the last test will overflow range in Python 2.x
From my understanding, given an integer n you are trying to find a square number sq that matches :
2n - 1 < sq < 2n+1 - 1
This condition is the mathematic translation of "my number must have the form 1????" where there are n "?".
First, you can notice that if n is even, the number 2n is a perfect square and matches your condition (in binary, it is the number 1000...000 - n zeroes -).
If n is uneven (say n = 2.p + 1), then 2n+1 is a perfect square ((2p+1)2). Computing the following number will give you a perfect square :
(2p+1 - 1)2
To satisfy the first inequality, p must satisfy :
2n - 1 < (2p+1 - 1)2
Then
0 < 2n+1 - 2p+2 + 1 - 2n + 1,
Finally,
2n + 2 - 2p+2 > 0
Or
22p - 2p+1 + 1 > 0
If we consider the function that matches p with f(p) such that :
f(p) = 22p - 2p+1 + 1
This function is defined for each positive real number, and is strictly increasing. Moreover, f(0) = 0. Finally, the initial condition is satisfied when p > 0 !
For p = 0 - or n = 1 -, the problem does not have a valid solution.
You don't need to iterate trough all the 2**n numbers to find the perfect square, in fact you only need one fractional square operation:
Say you have integer n and you want to find the largest perfect square smaller or equal than n, let's call it m.
Then:
d = (int)sqrt(n);
m = d*d;
Explanation:
Assume there is a perfect square m' larger than m , this implies there is an integer d' so that: d' > d and d'*d' = m'.
But d' >=d+1 and (d+1)*(d+1) > n so m' > n in contradiction to our requirement m' <= n.
Now to your question:
in order to find the perfect squares just change to "1" all of the "?" and find the perfect square if it conforms to your string you got the number you're looking for, if not change just enough "?" from the msb to "0" so that the resulting number is smaller or equal to the perfect square you just found, and keep going until you find the perfect square or run out of options.
Your operations may be returning something too large for an integer...
http://www.cplusplus.com/doc/tutorial/variables/

Find {E1,..En} (E1+E2+..En=N, N is given) with the following property that E1* E2*..En is Maximum

Given the number N, write a program that computes the numbers E1, E2, ...En with the following properties:
1) N = E1 + E2 + ... + En;
2) E1 * E2 * ... En is maximum.
3) E1..En, are integers. No negative values :)
How would you do that ? I have a solution based on divide et impera but i want to check if is optimal.
Example: N=10
5,5 S=10,P=25
3,2,3,2 S=10,P=36
No need for an algorithm, mathematic intuition can do it on its own:
Step 1: prove that a result set with numbers higher than 3 is at most as good as a result set with only 3's and 2's
Given any number x in your result set, one might consider whether it would be better to divide it into two numbers.
The sum should still be x.
When x is even, The maximum for t (x - t) is reached when t = x/2 , and except for the special case x = 2, then it is greater than x, and for the special case x = 4, equal to x (see note 1).
When x is odd, The maximum for t (x - t) is reached when t = (x ± 1)/2.
What does this show? Only that you should only have 3's and 2's in your final set, because otherwise it is suboptimal (or equivalent to an optimal set).
Step 2: you should have as many 3's as possible
Now, as 3² > 2³, you should have as many 3's as possible as long as the remainder is not 1.
Conclusion: for every N >= 3:
If N = 0 mod 3, then the result set is only 3's
If N = 1 mod 3, then the result set has one pair of 2's (or a 4) and the rest is 3's
If N = 2 mod 3, then the result set has one 2 and the rest is 3's
Please correct this post. The times when I was writing well-structured mathematical proofs is far away...
Note 1: (2,4) is the only pair of distinct integers such that x^y = y^x. You can prove that with:
x^y = y^x
y ln(x) = x ln(y)
ln(x)/x = ln(y) / y
and the function ln(t)/t is strictly decreasing after its global maximum, reached between 2 and 3, so if you want two distinct integers such that ln(x)/x = ln(y)/y, one of them must be lower or equal to 2. From that you can infer that only (2,4) works
This is not a complete solution, but might help.
First off note that if you fix n, and two of the terms E_i and E_j differ by more than one (for example 3 and 8), then you can do better by "equalizing" them as much as possible, i.e., if the number p = E_i + E_j is even, you do better both terms by p/2. If p is odd, you do better by replacing them with p/2 and p/2+1 (where / is integer division).
That said, then if you knew what the optimal number of terms, n, was, you'd be done: let all E_i's equal N/n and N/n+1 (again integer division), so that their sum is still N (this is now a straightforward problem).
So the question now is what is the optimal n. Suppose for the moment that you are allowed to use real numbers. Then the solution would be N/n for each term and you could write the product as (N/n)^n. If you differentiate this with respect to n and find its root you find that n should be equal to N/e (where e is the Neper number, also known as Euler's number, e = 2.71828....). Therefore, I'd look for a solution where either n = floor(N/e) or n = floor(N/e)+1, and then choose all the E_i's equal to either N/n or N/n+1, as above.
Hope that helps.
The Online Encycolpedia of Integer Sequences gives a recurrence relation for the solution to this problem.
I'll leave it up to someone else to compare complexities. Not sure I can figure out the complexity of OP's method.

while (i<=sqrt(static_cast<double>(n))

In the "C++ Without Fear: A Beginner's Guide That Makes You Feel Smart" book, in Chapter (2): Decisions, Decisions, you can see this lin of code as part of the prime number program:
while (i<=sqrt(static_cast<double>(n))
Provided that "i" was initialized to "2", and "n" is the user's input.
Why are we comparing to the "sqrt" of "n" and not to "n" itself?
Thanks.
Because you won't get any factors for non-primes which are > sqrt(n) (you would have already found the other, smaller factor).
It's a really bad test though, it would be much better to write it as:
while (i*i <= n)
Because if a number has factors other than itself and 1, then at least one of those factors will be less than the number's sqrt.
while (i<=sqrt(static_cast<double>(n))
Is equivalent to
while(n >= i*i)
Why the author choose the first solution may depend on other parts of the code.
The code goes like this:
i = 2;
while (i <= sqrt(static_cast<double>(n)) {
if (n % i == 0) is_prime = false;
i++;
}
So the loop is checking if n is divisible by i without remainder. Obviously, only has to check this up to (and including) the square root of n (because if n / p = q then also n / q = p).
Algorithmically it is correct to check possible factors up to the square root of your target.
If N is a number that may or may not be prime, if there are no factors (not including 1) up to sqrt(N) then N must be prime. sqrt(N) itself may well be its only prime factor (eg 9 which is 3*3).
If we are going to test to see if 17 is prime, we know that sqrt(17) is just above 4. 2, 3 and 4 do not divide into 17 so it must be prime as 5 is greater.
This must be the case because 17/5 will be less than 5 and would have to be a factor too, but we know there are no factors less than 5.
Programmatically of course the code is not optimal, as you would not use doubles and square-roots but something like (i*i <= N)

Find a prime number?

To find whether N is a prime number we only need to look for all numbers less or equal to sqrt(N). Why is that? I am writing a C code so trying to understand a reason behind it.
N is prime if it is a positive integer which is divisible by exactly two positive integers, 1 and N. Since a number's divisors cannot be larger than that number, this gives rise to a simple primality test:
If an integer N, greater than 1, is not divisible by any integer in the range [2, N-1], then N is prime. Otherwise, N is not prime.
However, it would be nice to modify this test to make it faster. So let us investigate.
Note that the divisors of N occur in pairs. If N is divisible by a number M, then it is also divisible by N/M. For instance, 12 is divisble by 6, and so also by 2. Furthermore, if M >= sqrt(N), then N/M <= sqrt(N).
This means that if no numbers less than or equal to sqrt(N) divide N, no numbers greater than sqrt(N) divide N either (excepting 1 and N themselves), otherwise a contradiction would arise.
So we have a better test:
If an integer N, greater than 1, is not divisible by any integer in the range [2, sqrt(N)], then N is prime. Otherwise, N is not prime.
if you consider the reasoning above, you should see that a number which passes this test also passes the first test, and a number which fails this test also fails the first test. The tests are therefore equivalent.
A composite number (one that is not prime, or 1) has at least 1 pair of factors, and it is guaranteed that one of the numbers from each pair is less than or equal to the square root of the number (which is what you are asking about).
If you square the square root of the number, you get the number itself (sqrt(n) * sqrt(n) = n), so if you made one of the numbers bigger (than sqrt(n)) you would have to make the other one smaller. If you then only check the numbers 2 through sqrt(n) you will have checked all of the possible factors, since each of those factors will be paired with a number that is greater than sqrt(n) (except of course if the number is in fact a square of some other number, like 4, 9, 16, etc...but that doesn't matter since you know they aren't prime; they are easily factored by sqrt(n) itself).
The reason is simple, any number bigger than the sqrt, will cause the other multiplier, to be smaller than the sqrt. In such case, you should have already check it.
Let n=a×b be composite.
Assume a>sqrt(n) and b>sqrt(n).
a×b > sqrt(n)×sqrt(n)
a×b > n
But we know a×b=n, therefore a<sqrt(n) or b<sqrt(n).
Since you only need to know a or b to show n is composite, you only need to check the numbers up to sqrt(n) to find such a number.
Because in the worst case, number n can be expresed as a2.
If the number can be expressed diferently, that men that one of divisors will be less than a = sqrt(n), but the other can be greater.