2

私は次のコードを持っており、途方もなく遅いことを除いて、私がやりたいことを正確に実行します。コードを「手動で」処理する場合、つまり、コードを部分に分割して個別に処理する場合を除いて、それほど気になりません。ほぼ瞬時です。

これが私のコードです:

Coefficient[Product[Sum[x^(j*Prime[i]), {j, 0, Floor[q/Prime[i]]}], 
                        {i, 1, PrimePi[q]}], x, q]

明確にするために追加された画像:

ここに画像の説明を入力

合計を最適化しようとしていると思いますが、よくわかりません。それを止める方法はありますか?

さらに、私の係数はすべて正であり、x^q 番目の係数だけが必要なので、Mathematica にそれよりも大きいすべての指数を破棄させ、それらのすべての乗算を行わないようにする方法はありますか?

4

2 に答える 2

5

私はあなたが何を望んでいるのか誤解しているかもしれませんが、係数は に依存するのでq、特定の について評価してほしいと思いますq。私は(あなたのように)製品と合計を最適化するのに時間がかかるのではないかと思ったので、書き直しました。あなたは次のようなものを持っていました:

With[{q = 80}, Coefficient[\!\(
\*UnderoverscriptBox[\(\[Product]\), \(i = 1\), \(PrimePi[q]\)]\((
\*UnderoverscriptBox[\(\[Sum]\), \(j = 0\), \(\[LeftFloor]
\*FractionBox[\(q\), \(Prime[i]\)]\[RightFloor]\)]
\*SuperscriptBox[\(x\), \(j*Prime[i]\)])\)\), x, q]] // Timing
(*
-> {8.36181, 10003}
*)

純粋に構造的な操作で書き直しました

With[{q = 80},
 Coefficient[Times @@ 
 Table[Plus @@ Table[x^(j*Prime[i]), {j, 0, Floor[q/Prime[i]]}],
        {i, 1, PrimePi[q]}], x, q]] // Timing
(*
-> {8.36357, 10003}
*)

(これは項のリストを作成してから乗算するだけなので、記号分析は実行されません)。

多項式を構築するのは一瞬ですが、数千の項があるためCoefficient、適切な係数を持っていることを確認するために多くの時間を費やしている可能性があります。実際にはExpand、多項式を ing することでこれを解決できます。したがって:

 With[{q = 80}, Coefficient[Expand[\!\(
 \*UnderoverscriptBox[\(\[Product]\), \(i = 1\), \(PrimePi[q]\)]\((
 \*UnderoverscriptBox[\(\[Sum]\), \(j = 0\), \(\[LeftFloor]
 \*FractionBox[\(q\), \(Prime[i]\)]\[RightFloor]\)]
 \*SuperscriptBox[\(x\), \(j*Prime[i]\)])\)\)], x, q]] // Timing
 (*
 -> {0.240862, 10003}
 *)

それは私の方法でも機能します。

要約Expandすると、式の前で、係数を取得する前に貼り付けてください。

于 2011-06-26T19:21:14.270 に答える
1

Coefficient元のコードが遅いのは、非常に大きな式(単純に拡張するとメモリに収まらない式)でも機能するように作られているためだと思います。

元の多項式は次のとおりです。

poly[q_, x_] := Product[Sum[ x^(j*Prime[i]), 
                            {j, 0, Floor[q/Prime[i]]}], {i, 1, PrimePi[q]}]

大きすぎないようにする方法を参照してくださいq。多項式を展開すると、より多くのメモリが消費され、かなり遅くなります。

In[2]:= Through[{LeafCount, ByteCount}[poly[300, x]]] // Timing
        Through[{LeafCount, ByteCount}[Expand@poly[300, x]]] // Timing
Out[2]= { 0.01, { 1859,   55864}}
Out[3]= {25.27, {77368, 3175840}}

それでは、3つの異なる方法で係数を定義し、それらの時間を計りましょう。

coeff[q_]    := Module[{x}, Coefficient[poly[q, x], x, q]]
exCoeff[q_]  := Module[{x}, Coefficient[Expand@poly[q, x], x, q]]
serCoeff[q_] := Module[{x}, SeriesCoefficient[poly[q, x], {x, 0, q}]]

In[7]:= Table[   coeff[q],{q,1,30}]//Timing
        Table[ exCoeff[q],{q,1,30}]//Timing
        Table[serCoeff[q],{q,1,30}]//Timing
Out[7]= {0.37,{0,1,1,1,2,2,3,3,4,5,6,7,9,10,12,14,17,19,23,26,30,35,40,46,52,60,67,77,87,98}}
Out[8]= {0.12,{0,1,1,1,2,2,3,3,4,5,6,7,9,10,12,14,17,19,23,26,30,35,40,46,52,60,67,77,87,98}}
Out[9]= {0.06,{0,1,1,1,2,2,3,3,4,5,6,7,9,10,12,14,17,19,23,26,30,35,40,46,52,60,67,77,87,98}}

In[10]:=    coeff[100]//Timing
          exCoeff[100]//Timing
         serCoeff[100]//Timing
Out[10]= {56.28,40899}
Out[11]= { 0.84,40899}
Out[12]= { 0.06,40899}

だからSeriesCoefficient間違いなく行く方法です。もちろん、あなたが私よりも組み合わせ論に少し優れていて、次のプライムパーティション式(oeis)を知っている場合を除きます。

In[13]:= CoefficientList[Series[1/Product[1-x^Prime[i],{i,1,30}],{x,0,30}],x]
Out[13]= {1,0,1,1,1,2,2,3,3,4,5,6,7,9,10,12,14,17,19,23,26,30,35,40,46,52,60,67,77,87,98}

In[14]:= f[n_]:=Length@IntegerPartitions[n,All,Prime@Range@PrimePi@n]; Array[f,30]
Out[14]= {0,1,1,1,2,2,3,3,4,5,6,7,9,10,12,14,17,19,23,26,30,35,40,46,52,60,67,77,87,98}
于 2011-06-26T23:24:19.203 に答える