V
V
Vitaly Pukhov2015-03-23 06:55:47
Mathematics
Vitaly Pukhov, 2015-03-23 06:55:47

Is the algorithm for determining the non-simplicity of a number with 3 operations useful?

I studied one theory, it turned out to be true in 75-80% of cases. That is, for any number with a probability of 75%, the algorithm says that it is not prime, while only 3 mathematical operations are performed, no cycles, etc. The algorithm remains true with the same probability for any number of characters, checked in a very wide range. It can speed up other algorithms for checking for simplicity, that is, before checking with complex algorithms, you can run it and say with 75% that the number is not prime and do not check further. The question is, does anyone need such a miracle, or is there no use with such an error?
The algorithm is simple, there are certain numbers, when divided by which the remainder of the division will be a prime number in 75% of cases, so if the remainder of the division turned out to be not a prime number, we can assume that it is composite.

class MayBePrime
    {
        static bool[] charr = null;
        static int prime = 30030;//30030 для быстрого старта, ниже точность. Произведение первых простых чисел
        static public bool isMayBePrime(System.Numerics.BigInteger x)
        {
            if (charr == null)
            {
                charr = new bool[prime];
                for (int i = 0; i < prime; i++)
                {
                    if (NOD(prime, i) == 1)
                    {
                        charr[i] = true;
                    }
                    else
                    {
                        charr[i] = false;
                    }
                }
            }
            BigInteger n = x % prime;
            int n2 = 0;
            n2 = (int)n;
            if (charr[n2])
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    static public int NOD(int a, int b)
        {
            if (a == 0) return b;
            if (b == 0) return a;
            if (a == b) return a;
            if (a == 1 || b == 1) return 1;
            if ((a % 2 == 0) && (b % 2 == 0)) return 2 * NOD(a / 2, b / 2);
            if ((a % 2 == 0) && (b % 2 != 0)) return NOD(a / 2, b);
            if ((a % 2 != 0) && (b % 2 == 0)) return NOD(a, b / 2);
            return NOD(b, Math.Abs(a - b));
        }
    }

Answer the question

In order to leave comments, you need to log in

3 answer(s)
M
Mrrl, 2015-03-23
@Neuroware

I hope that the remainder is still taken from division by 390, and not by 389 - otherwise there is no point in the code at all.
So, we have 77 primes less than 390. Four of them - 2,3,5,13 - are nothing more than garbage, giving extra algorithm runs. Indeed, if x%390==3, then x is divisible by 3, which means it is composite. The remaining 73 numbers are fine.
It turns out such a picture. For a prime x, the value x%390 is some number coprime to 390. Moreover, these remainders are more or less evenly distributed (in the picture they look like red bars). There are 96 of these remainders
. If x is a prime number, then with a probability of 73/96 the remainder will be a prime number, and the algorithm will honestly say "rather, a prime number." With a probability of 23/96 - those same 25% - the remainder will be composite, and the algorithm will make a mistake.
If x is composite, then the probability that the number will be declared "rather prime" will be equal to 77/390-1/ln(x) (the first term is the probability that the remainder turned out to be prime, and the second is the proportion of prime numbers in the vicinity of x ).
You can easily get rid of the error of the first type: for this, you need to put in the charr array not prime numbers, but numbers coprime with 390. Then if the algorithm says "composite", then it is.
It was possible to take N=30030=2*3*5*7*11*13 instead of 390. If the array is filled with numbers relatively prime to N, then 4 out of 5 numbers will be screened out as composite numbers, and there will be no false screening of prime numbers at all.

B
bobrovskyserg, 2015-03-23
@bobrovskyserg

An arbitrarily chosen number, not exceeding 10^5, with a probability of 90% composite. Further more.
However, open your way.
UPDATE

def main(*mods):
    lo = 10 ** 5
    hi = 10 ** 9
    sieve = [1] * hi
    sieve[0] = sieve[1] = 0
    for i in range(int(hi ** 0.5) + 1):
        if sieve[i]:
            for j in range(i * i, hi, i):
                sieve[j] = 0
    primes = sum(sieve[lo:])
    for mod in mods:
        counter = [0] * 4
        for i in range(lo, hi):
            counter[sieve[i] * 2 + sieve[i % mod]] += 1
        print('\n{:>17n}\nprime \ check    0        1\n'
              '      0       {:7.3f}  {:7.3f}\n'
              '      1       {:7.3f}  {:7.3f}\n'.format(
            mod, *[float(i) / primes for i in counter]))

main(30029, 30030, 30047)

30029
prime \ check    0        1
      0        16.650    2.019
      1         0.892    0.108


            30030
prime \ check    0        1
      0        17.104    1.564
      1         0.437    0.563


            30047
prime \ check    0        1
      0        16.650    2.018
      1         0.892    0.108

So, we have:
According to Mrrl , the denominator 30030 really fits much more than its nearest simple neighbors. And yet, does the algorithm give any gain?
On the one hand, he discards almost half (0.437) of primes, erroneously declaring them to be composite.
But if this filter is inserted into a real cryptoalgorithm, it will only worsen cryptographic strength - half of the simple known types will be thrown out of consideration.
On the other hand, on the lo..hi range, the content of primes is about 5%, and the algorithm produces primes to composites in a ratio of more than 1:3, which is noticeably better.
On the third hand, what the author called "only 3 mathematical operations" results in a preliminary calculation of a sieve 30030 numbers long. With streaming simple searches, this seems to be a little, but can it be done better with the same costs?
Yes, you can:
from itertools import cycle

def MillerRabin(n):
    return True  # допустим, здесь реализован тест Рабина-Миллера

def getprime(startsfrom):
    primes = (2, 3, 5, 7, 11, 13)
    mod = 1
    for p in primes:
        mod *= p  # итого mod = 30030
    steps, x0 = [], mod - 1
    for x in range(mod, x0 + mod + 1):
        if all(x % p for p in primes):
            steps.append(x - x0)
            x0 = x
    print(len(steps) / mod)  # 0.1918 - мы отсеяли 4/5 чисел 
    # входного потока, не потеряв ни единого простого. 
    # по итогу имеем те же 25% простых во входном потоке 
    # на интервале 10^5..10^9

    n = startsfrom // mod * mod - 1
    for step in cycle(steps):
        n += step
        if n > startsfrom and MillerRabin(n):
            return n


print(getprime(10 ** 500))
# 10^500+961

S
SeptiM, 2015-03-23
@SeptiM

I'll try to guess the algorithm. Does this work for the number 41041?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question