次のプログラムを実行しようとしています。このプログラムは、係数が +1 または -1 のみの d までの次数の多項式の根を計算し、それをファイルに保存します。
d = 20; n = 18000;
f[z_, i_] := Sum[(2 Mod[Floor[(i - 1)/2^k], 2] - 1) z^(d - k), {k, 0, d}];
ここで、f[z,i] は、2 進数でカウントするプラスまたはマイナス符号を持つ z の多項式を返します。d=2 としましょう。
f[z,1] = -z 2 - z - 1
f[z,2] = -z 2 - z + 1
f[z,3] = -z 2 + z - 1
f[z,4] = - z 2 + z + 1
DistributeDefinitions[d, n, f]
ParallelDo[
Do[
root = N[Root[f[z, i], j]];
{a, b} = Round[n ({Re[root], Im[root]}/1.5 + 1)/2];
{i, 1, 2^d}],
{j, 1, d}]
これを読んでもあまり楽しくないかもしれませんが、とにかく比較的短いです。関連する部分に切り詰めようとしましたが、ここでは何が問題なのかまったくわかりません。f[z,i] のすべてのルートを計算し、それらを四捨五入して n グリッドの点に対応させ、そのデータをさまざまなファイルに保存します。
何らかの理由で、Mathematica のメモリ使用量が徐々に増加し、すべてのメモリ (このマシンでは 6 GB) がいっぱいになります。その後、計算は非常にゆっくりと続行されます。どうしてこれなの?
ここで何がメモリを使い果たしているのかわかりません - 私の唯一の推測はファイルのストリームがメモリを使い果たしたということでしたが、そうではありません: 2GB のファイルにデータを追加しようとしましたが、そのための目立ったメモリ使用量はありませんでした. ここで Mathematica が大量のメモリを使用する理由はまったくないようです.
d の値が小さい場合 (たとえば 15)、動作は次のようになります。4 つのカーネルが実行されています。すべてが ParallelDo ループを実行する (それぞれが一度に j の値を実行する) と、すべてがそのループを 1 回通過し終わるまで、メモリ使用量が増加します。次にそのループを通過するとき、メモリ使用量はまったく増加しません。計算は最終的に終了し、すべて問題ありません。
また、非常に重要なことに、計算が停止すると、メモリ使用量は元に戻りません。別の計算を開始すると、次のことが起こります。
- メモリ使用量がまだ増加しているときに前回の計算が停止した場合は、増加し続けます (基本的に計算で同じポイントに到達するには、再び増加し始めるまでに時間がかかる場合があります)。
- メモリ使用量が増加していないときに前回の計算が停止した場合、それ以上増加しません。
編集:この問題は、 f の相対的な複雑さに起因しているようです。より簡単な多項式に変更すると、問題が解決するようです。問題は、Mathematica が i の特定の値に対して f[z,i] を記憶しているが、f[z,i] := を設定していることだと思いました。f[z,i] のルートを計算した直後に、代入がそもそも存在しなかったと不平を言い、メモリはまだ使用されています。
f がメモリを消費すると想像できる唯一の残りのものであるため、実際には非常に不可解ですが、内側の Do ループで f を定義し、根が計算されるたびにそれをクリアしても問題は解決しません。