0

約 1,000,000,000,000 までの小さな素数は、さまざまな情報源から容易に入手できます。Prime Pages (utm.edu)には最初の 5000 万個の素数のリストがあり、primos.mat.br10^12 まであり、primsieve.orgで利用可能なプログラムのようなプログラムはさらに上位です。

ただし、2 ^ 64 に近い数になると、primes.utm.eduの Primes の 2 の累乗よりわずかに小さいページに記載されている素数は 10 個しかなく、それだけのようです。

そこで見つかった素数性テストは、double に適合しない数の処理を拒否し、他の場所 (他の場所) は拒否に失敗し、ゴミを印刷するだけです。primesieve.org プログラムは、2^64 より少なくとも約 400 億少ない数を扱うことを拒否しています。これは、コーディングの品質に対する信頼を正確に刺激するものではありません。どこでも同じ結果: nada、zilch、niente。

ふるいの歯車と歯車は 2^62 付近できしみ始めます。したがって、信頼できる参照データが不足している/存在しないため、検証が最も困難な場合、実装をテストする必要性が最も高くなります。primesieve.org プログラムは、少なくとも 2^63 程度まで動作する唯一のプログラムのようですが、上記の問題があるため、あまり信頼していません。

では、2^64 に近いふるいが適切に動作することをどのように検証できるのでしょうか? 2^64、2^63 などの 2 のべき乗のすぐ下と上の 100 万 (または 1000 万または 1 億) の素数の信頼できるリストはありますか? それとも、そのようなシーケンスを生成する、または素数または素数のリストを検証できる、信頼できる (信頼できる、検証済みの、多くのことをやり遂げた) プログラムはありますか?

ふるいが検証されると、興味深い範囲の負荷の合計/チェックサムを含む便利なリストを作成するために使用できますが、そのようなリストがないと状況は難しいようです...

PS: 私は、 primsieve.org ターボふるいの上限をUINT64_MAX - 10 * UINT32_MAX、または 0xFFFFFFF600000009と判断しました。つまり、これまでのところ、10 * UINT32_MAX の最も高い素数だけが参照データをまったく持っていないことを意味します...

4

3 に答える 3

2

事前に計算されたリストを探す代わりに、ふるいの出力を別のふるいと比較できます。Tomás Oliveira e Silva によって書かれた優れたふるいは、次の Web サイトで入手できます。http://sweet.ua.pt/tos/software/prime_sieve.html .

コードをテストするもう 1 つの方法は、ふるいが素数として報告するすべての数の素数性をテストすることです (または逆に、ふるいが素数として報告しないすべての数の非素数性をテストします)。これを行う良い方法は、Baillie-Wagstaff 検定です。Thomas R による高品質の実装を見つけることができます。http://www.trnicely.net/misc/bpsw.html .

http://www.janfeitsma.nl/math/psp2/index にある Jan Feitsma の擬素数の表にも興味があるかもしれません。これは 2 64まで完全です。

于 2014-11-06T19:37:53.033 に答える
1

まず、あなたのプログラムを共有し、正確さに取り組んでくれてありがとう。私はテストを行うことが重要だと考えており、サイズの境界近くでのふるい分けは、コードの作業に時間を費やしたものでした。

「どこでも同じ結果: nada、zilch、niente.」あなたは十分に一生懸命見ていません。これを行うツールはたくさんあります。プライムシーブが 2^64-1 まで行かないのは残念ですが、それは他に何もないという意味ではありません。

「では、2^64 に近いふるいが適切に動作することをどのように確認できるでしょうか?」私が行ったことの 1 つは、2^64-1 付近の開始点/終了点のすべての組み合わせを実行するエッジケース テストを作成し、多くのメソッドがすべて同じ結果を生成することを確認することです。これは、これらの素数のリストを開始することに依存していますが、これらを取得する方法はたくさんあります。これは、この範囲でふるいをテストするだけでなく、開始/終了条件をテストして、そこに問題がないことを確認します.

2^64 以下の 100 万個の素数を生成するいくつかの方法:

time perl -Mntheory=:all -E 'forprimes { say } ~0-44347170,~0' | md5sum

1M の素数を生成するのに ~2 秒かかります。別のコード (Perl または GMP) の使用を強制したり、素数性テストを使用したりすることができます。これを行う方法はたくさんありますis_provable_prime($n)。たとえば、単にループして . Math::Primality を含む他の Perl モジュールもありますが、それらははるかに低速です。

echo 'forprime(i=2^64-44347170,2^64-1,print(i))' | time gp -f -q | md5sum

1M の素数を生成するのに ~13 秒かかります。Perl モジュールと同様に、決定論的ルーチンである isprime の呼び出しをループするなど、多くの代替方法があります (Pari/GP の古いバージョンではないことを前提としています)。

#include <stdio.h>
#include <gmp.h>
int main(void) {
  mpz_t n;
  mpz_init_set_str(n,"18446744073665204445",10);
  mpz_nextprime(n, n);
  while (mpz_sizeinbase(n,2) < 65) {
    /* If you don't trust mpz_nextprime, one could add this:
     * if (!mpz_probab_prime_p(n, 100))
     *   { fprintf(stderr, "Bad nextprime!\n"); return -1; }
     */
    gmp_printf("%Zd\n",n);
    mpz_nextprime(n, n);
  }
  mpz_clear(n);
  return 0;
}

約 30 秒かかり、同じ結果が得られます。これは、25 のプリセット ランダム ベース MR テストを BPSW や証明方法の 1 つほど信頼していないため、より疑わしいですが、結果が一致しているため、この場合は問題ではありません。余分な 100 のテストを追加することは時間的に非常にコストがかかりますが、誤った結果が得られる可能性は非常に低くなります (塩基が重複していると思われるため、これも無駄です)。

from sympy import nextprime
n = 2**64-44347170;
n = nextprime(n)
while n < 2**64:
  print n
  n = nextprime(n)

Python の SymPy を使用します。残念ながら、primrange は 2^64-1 を指定するとクレイジーなメモリを使用するため、使用できません。単純な nextprime メソッドを実行するのは理想的ではありません。約 5 分かかりますが、同じ結果が生成されます (現在の SymPy isprime は 46 の素数ベースを使用します。これは、2^64 未満の決定論的な結果に必要な数よりもはるかに多いです)。

他にも FLINT や GAP などのツールがあります。

Windows を使用しているため、世界は不安定で、多くのことが正しく機能していないことに気付きました。Windows で Perl の ntheory をテストしましたが、コマンド プロンプトから Cygwin と Strawberry Perl の両方で同じ結果が得られました。GMP が正しく機能すると仮定すると、GMP コードは同じように機能するはずです。

編集追加: 結果が比較方法のいずれかと一致しない場合は、2 つのうちの 1 つ (または両方) が間違っています。間違っているのは比較コードかもしれません! エラーを見つけて報告すると、誰にとっても役立ちます。可能性は低いですが、両方とも同じように間違っている可能性があります。そのため、できるだけ多くの他の情報源と比較したいと考えています。私にとっては、比較する「ゴールデン」コードを 1 つ選ぶよりも堅牢です。特に、完全にテストされていない奇妙なプラットフォームを使用している場合.


BPSW の場合、いくつかの実装があります。

  • パリ。AES Lucas は、Pari のソース コードに含まれているため、移植性が高いかどうかはわかりません。
  • TRいいですね。強力なルーカス、スタンドアロン コード。
  • デビッド・クリーバー。スタンダード、ストロング、エクストラストロングのルーカス。スタンドアロン ライブラリ、非常にわかりやすく、非常に使いやすい。
  • x86_64 の asm Montgomery 数学を含む私の非 GMP コード。もちろん、bigint コードよりもかなり高速です。
  • 私のGMPコード。標準、ストロング、AES、またはエクストラストロング ルーカス。他の bigint コードよりも高速です。また、他の Frobenius および他の複合性テストもあります。スタンドアロンにすることができます。
  • 私は LibTomMath を使用するバージョンを持っており、これを Perl6 VM の 1 つに入れたいと考えています。LTM を使用したい場合にのみ興味深いものです。

Feitsma データに対して検証済みのすべて。私は周りにももっと多くの実装があると確信しています。FLINT には非常に高速なバリエーションがありますが、実際には BPSW ではありません (ただし、2^64 未満の数値については検証されています)。

于 2014-11-24T10:48:24.847 に答える
0

一般に、試行分割よりも単純な手法を使用しないか、非常に忍耐強くする必要があります。 (gp/PARI ドキュメント)

64 ビット整数の場合、試行除算は単純なふるいの何百万倍もかかります。ましてや、Kim Walisch のプログラム ( primsieve.org ) のようなサラブレッドは桁違いに高速です。

私が確認したい参照ふるい (スタンドアロンの .cpp @ pastebin があります) は、2^64 に近いふるい分けを行うと、1 秒あたり約 100 万個の素数を見つけますが、gmp 実装から取り出した試用除算コードでは、1 つでも見つけるのに 20 秒かかります。 . トライアル除算を事前にふるいにかけられた素数 (素数ごとに 1 バイトのデルタとして保存され、反復を高速化するため) に制限すると、桁違いに高速化されますが、それでも私のラップトップでは 1 秒あたり 1 素数未満しか出力されません。

したがって、Kindle、電話、トースターなど、手に入れることができるすべてのコアを使用したとしても、トライアル部門はホメオパシー量の参照データしか配信できません。

Miller-Rabinや user448810 によってリンクされたBaillie-PSWなどのより高度なテストは、試行分割よりも数桁高速です。2^64 までの数の場合、Baillie-PSW は決定論的であることが検証されています (そのしきい値を下回る強い擬似素数はありません)。Miller-Rabin は、最初の 12 個の素数が base として使用される場合、または Jim Sinclar によって発見された 7-base セットが使用される場合、2^64 まで決定論的である場合とそうでない場合があります (つまり、'net はその趣旨のステートメントを提供しますが、明らかに証拠はありません) 。 .

Baillie-PSW が検証済みで、起動が速いため、良い選択のようです。残念ながら、ふるいよりも数桁も複雑であるため、多くの手間をかけずにコンパイルできる、または理想的にはバイナリとして利用できる、信頼できる実装を見つけることがさらに重要になります。

Thomas Nicely のBaillie-PSW ページにはgmpを使用するソース コードがあり、gp/PARIは gmp または独自のコードを使用できます。gmp の代わりにMPIRが使用されたとしても、Windows の MinGW のような風変わりで風変わりなプラットフォームで gmp コードを構築するのは簡単ではないため、後者はバイナリとしても利用できます。

これで大量のデータが得られますが、ふるいを検証するにはまだ十分ではありません。primsieve.org の上限 (10 * 2^32 の数値) によって残された空白領域をカバーするには桁違いに遅すぎるためです。

ここで、Will Ness の bigint アイデアが登場します。ふるいの動作は、複数の独立したソースからの参照データを使用して、最大 1,000,000,000,000 まで検証できます。インデックス変数を 32 ビットから 64 ビットに切り替えると、上位領域でコードが混乱する原因となる可能性のある境界ケースのほとんどが排除され、uint64_t でさえその限界に近づく場所はごくわずかしか残りません。これらの場所を徹底的に検査し、Baillie-PSW の取り組みから派生したテスト ケースで寛大にカバーすることで、ふるいコードが適切であるというかなり高い信頼を得ることができます。10^12 から上限までの範囲で primesieve.org に対する大量の検証を追加すると、ふるいの実装を信頼できると見なすのに十分なはずです。

ふるいが稼働していれば、任意の範囲を大量のデータで簡単にカバーできます。または、ダイジェストを使用して、あらゆるサイズと形状のニーズに対応できる定型化/圧縮された検証手段として。前述のデモ .cppで使用しているものですが、私の実際のコードでは、一般的な作業用に最適化されたダイジェスト実装と、ファクター シーブ ビットマップの迅速な自己チェック用に 128 ビットの特別な生メモリ チェックサムを組み合わせて使用​​しています。

まとめ

于 2014-11-11T09:01:46.790 に答える