有理生成関数の係数を見つける


12

数値のシーケンスをべき級数の係数として記述する場合、そのべき級数はそのシーケンスの(通常の)生成関数(またはGf)と呼ばれます。つまり、ある関数F(x)と一連の整数a(n)について次のようになっている場合:

a(0) + a(1)x + a(2)x^2 + a(3)x^3 + a(4)x^4 + ... = F(x)

次にF(x)はの生成関数ですa。たとえば、幾何級数は次のことを示しています。

1 + x + x^2 + x^3 + x^4 + ... = 1/(1-x)

したがって、の生成関数は1, 1, 1, ...です1/(1-x)。上記の式の両側を微分して乗算するxと、次の等式が得られます。

x + 2x^2 + 3x^3 + 4x^4 + ... = x/(1-x)^2

したがって、の生成関数は1, 2, 3, ...ですx/(1-x)^2。関数の生成は非常に強力なツールであり、それらを使用して多くの便利なことができます。簡単な紹介はここにありますが、本当に徹底的な説明のために、素晴らしい本生成機能があります。


この課題では、入力として有理関数(整数係数を持つ2つの多項式の商)を、最初に分子、次に分母の2つの整数係数の配列として受け取ります。たとえば、関数f(x) = x / (1 - x - x^2)[0, 1], [1, -1, -1]入力のようにエンコードされます。

この入力が与えられると、プログラムは、生成関数に等しいべき級数の係数をx、の係数から始めて、1行ごとに無限に出力する必要がありますx^2


例:

[1], [1, -1] -> 1, 1, 1, 1, 1, 1, 1, ...
[1], [2, -2] -> 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, ...
[0, 1], [1, -2, 1] -> 1, 2, 3, 4, 5, 6, 7, 8, ...
[0, 1], [1, -1, -1] -> 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
[1], [1, -2] -> 1, 2, 4, 8, 16, 32, 64, 128, ...
[0, 1, 1], [1, -3, 3, -1] -> 1, 4, 9, 16, 25, 36, ...

Crap、私の言語はこれのためにシーケンス用に構築されていますが、多次元配列入力を実際に行うことはできません:(
Stephen

2
私は本当にこの仕様に対して数学的に十分な気がありません、私たちの一般の人々のために素人の説明をもっと投稿できる可能性はありますか?
Skidsdev


1
@trichoplaxこれは、分子を常に1に強制しますが、これは同じではありません。たとえば、私の最後の例である正方形を表現することはできません。
orlp

1
これを言い換える別の方法は、一般的な線形再帰を評価することです。そのようにして、この質問を一般化し、将来の繰り返し質問のduのターゲットとして役立つかもしれません。
ピーターテイラー

回答:



3

Mathematica、64 83 90 バイト

Do[Echo@Limit[D[#/#2/i!&@@Fold[x#+#2&]/@#,{x,i}],x->0],{i,∞}‌​]&

@ngenisisと@Jenny_mathyに感謝します!

2つのリストとして入力してください。

Alt+.結果を確認するには、実行を終了する必要があります。高速出力により、フロントエンドがクラッシュする可能性があります。

83バイトバージョン(@Jenny_mathy):

i=1;v=Tr[#*x^Range@Length@#]&;While[1<2,Echo@Limit[D[v@#/v@#2/i!,{x,i}],x->0];i++]&

83バイト:i = 1; v = Tr [#* x ^ Range @ Length @#]&; While [1 <2、Echo @ Limit [D [v @#/ v @#2 / i !, {x、i}]、x-> 0]; i ++]&
J42161217

@Jenny_mathyわざわざごめんなさい。最初のコメントには、不明瞭なUnicode文字がいくつか含まれていることがわかりました。クリーンアップしたら、コードは問題ありません。
キーガン

3
64バイト:Do[Echo@Limit[D[#/#2/i!&@@Fold[x#+#2&]/@#,{x,i}],x->0],{i,∞}]&。これは、入力が2つのリストのリストであり、係数が次数の降順であることを前提としています。のみ内蔵の私が何をすべきかを知っているvんですInternal`FromCoefficientList
ngenisis

これを繰り返し実行しても機能しますか?iラムダの中に入れるには、いくつかの余分な括弧が必要になると思います。(一方で、無限のリストを印刷することが目標である場合、繰り返し実行する能力が関連しているかどうかはよくわかりません。これに関してメタコンセンサスがありましたか?)
Julian Wolf

@ngenisis:どのバージョンを使用していますか?v10.0では、あなたのソリューションが私に与えてくれIterator {i,∞} does not have appropriate boundsます。
ジュリアン・ウルフ

1

CJam(22バイト)

{\{(W$(@\/_pW*f*.+1}g}

オンラインデモ。既存の回答の多くと同様に、これには出力の0番目の係数が含まれていることに注意してください。

解剖

{           e# Define a block which takes numerator N and denominator D as arguments
  \         e# Flip to put D at the bottom, since that won't change
  {         e# Infinite loop:
    (       e#   Pop the first element of (the modified) N
    W$(     e#   Copy D and pop its first element
            e#   Stack: D N[1:] N[0] D[1:] D[0]
    @\/     e#   Bring N[0] to top, flip, divide
            e#   Stack: D N[1:] D[1:] N[0]/D[0]
    _p      e#   Print a copy
    W*f*.+  e#   Multiply by -1, multiply all, pointwise add
            e#   Stack: D N[1:]-(N[0]/D[0])*D[1:]
  1}g
}

0

Mathematica、 86 79バイト

f=x^Range@Length@#.#&;For[n=1,8>3,Print@SeriesCoefficient[f@#/f@#2,{x,0,n++}]]&

入力を2つの個別のリスト(分子係数、分母係数)として受け取ります。入力を係数のリストとしてではなく、多項式の一部として直接取得できる場合、これを大幅に短縮できます。

Dov11では無限の境界で動作するようです。これをローカルでテストすることはできませんが、その場合は、このソリューションを75バイトに短縮できます

f=x^Range@Length@#.#&;Do[Print@SeriesCoefficient[f@#/f@#2,{x,0,n}],{n,∞}]&

最後のテストケースは0で始まりません。
J4216121717

@Jenny_mathy:撮影してくれてありがとう。テストケースは、ゼロではなく最初から開始することを期待しているように見えます。これにより、数バイトを節約できるはずです。
ジュリアン・ウルフ

@Jenny_mathy:テストケースは不安定だと思う。のn代わりに1から開始0すると、ソリューションと同じ結果が得られます。起動時、この溶液が通過する最後のテストケース、第2に、しかし、失敗両方n0から
ジュリアン・ウルフ


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.