草庐IT

最短线性递推式求解与有理函数重建

Entropy Increaser 2023-04-08 原文

这一算法来自于我们对“线性递推式拟合”的视角转换,其后得到的算法是自然的。

引理 1. 如果两个有理分式 p 1 / q 1 , p 2 / q 2 p_1/q_1, p_2/q_2 p1/q1,p2/q2 均有 deg ⁡ p < n , deg ⁡ q ≤ n \deg p<n, \deg q\leq n degp<n,degqn 且展开式 p 1 / q 1 ≡ p 2 / q 2 ( m o d x 2 n ) p_1/q_1 \equiv p_2/q_2 \pmod {x^{2n}} p1/q1p2/q2(modx2n),那么 p 1 / q 1 = p 2 / q 2 p_1/q_1 = p_2/q_2 p1/q1=p2/q2

证明. 通分,等价于 p 1 q 2 = q 1 p 2 p_1q_2=q_1p_2 p1q2=q1p2,由两边次数均 < 2 n <2n <2n,而同余式保留了全部信息。

这一引理告诉我们,若一个 n n n 阶线性递推式确实拟合了其前 2 n 2n 2n 项,那么通分之后就一定是“最小”的。

为了解决这一问题,我们首先将问题适当泛化:

「有理函数重建」(Rational Function Reconstruction):给定域上的多项式 f ( x ) , M ( x ) f(x),M(x) f(x),M(x),设 deg ⁡ M = n \deg M = n degM=n,当多项式 p , q p,q p,q 满足 deg ⁡ q ≤ n − k , deg ⁡ p < k \deg q \leq n-k, \deg p < k degqnk,degp<k 时,若 p ≡ q f ( m o d M ) p\equiv qf \pmod M pqf(modM),那么称 p , q p,q p,q 是一个 ( k , n − k ) (k,n-k) (k,nk) 有理逼近。

接下来,我们将发现任何一个 k k k,都存在 ( k , n − k ) (k,n-k) (k,nk) 有理逼近。将同余式写作 p ≡ q f + M t p\equiv qf + Mt pqf+Mt,这诱导我们考虑欧几里得过程:最初有
[ f M ] = [ 1 0 0 1 ] [ f M ] \begin{bmatrix} f\\ M \end{bmatrix}= \begin{bmatrix} 1 & 0\\ 0 & 1\\ \end{bmatrix} \begin{bmatrix} f\\ M \end{bmatrix} [fM]=[1001][fM]
在欧几里得的过程中,有中间量
[ A B ] = [ X A Y A X B Y B ] [ f M ] \begin{bmatrix} A\\ B \end{bmatrix}= \begin{bmatrix} X_A & Y_A\\ X_B & Y_B\\ \end{bmatrix} \begin{bmatrix} f\\ M \end{bmatrix} [AB]=[XAXBYAYB][fM]
不妨设 k − 1 = deg ⁡ A ≥ deg ⁡ B = m k-1=\deg A \ge \deg B=m k1=degAdegB=m,那么我们接下来进行多项式取模,就应当逐步将 A A A 的度数从 < k <k <k 降到 < m <m <m,然后交换 A , B A,B A,B。此时我们归纳假设 deg ⁡ X A , deg ⁡ X B ≤ n − k \deg X_A, \deg X_B \leq n-k degXA,degXBnk,那么由于辗转相除 A − d B A-dB AdB 的系数有 deg ⁡ d < k − m \deg d < k-m degd<km,可知 f f f 的系数 X A − d X B X_A-dX_B XAdXB,那么新的系数为 X A − d X B , X B X_A-dX_B,X_B XAdXB,XB。度数均 < n − m < n-m <nm
我们现在设 k ′ = m + 1 , m ′ = deg ⁡ ( A − d B ) k'=m+1,m'=\deg (A-dB) k=m+1,m=deg(AdB),也就有新的系数的度数均 ≤ n − k ′ \le n-k' nk。注意我们每次辗转相除后得到的 ( k , n − k ) (k,n-k) (k,nk) 有理逼近的 k k k 是一段区间,且刚好拼出了 1 ∼ n 1\sim n 1n 的所有整数。取对应的 p = A , q = X A p=A,q=X_A p=A,q=XA 即可。

辗转相除过程的这个序列通过 HALF-GCD 算法可以在 Θ ( n log ⁡ 2 n ) \Theta(n\log ^2n) Θ(nlog2n) 时间内计算。严格来说,我们是通过 HALF-GCD 算法计算出的矩阵列,可以算出任何一个阶段的有理函数重建。但对于我们对线性递推式的计算而言,只做 n n n 消到 n / 2 n/2 n/2 这第一轮刚好足够我们求出信息。

不过这里似乎 p , q p,q p,q 是可能有 x x x 的幂的,但如果将引理 1 稍微改改就会发现,如果我们给的数列真的有一个递推式,那就算 p , q p,q p,q x x x 的幂,通分之后肯定还是正确的。

有关最短线性递推式求解与有理函数重建的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  3. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  4. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  5. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  6. ruby-on-rails - 将字符串转换为 ruby​​-on-rails 中的函数 - 2

    我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。

  7. ruby - 在 ruby​​ 中使用 .try 函数和 .map 函数 - 2

    我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法

  8. ruby - 是否可以从也在该模块中的类内部调用模块函数 - 2

    在这段Ruby代码中:ModuleMClassC当我尝试运行时出现“'M:Module'的未定义方法'helper'”错误c=M::C.new("world")c.work但直接从另一个类调用M::helper("world")工作正常。类不能调用在定义它们的同一模块中定义的模块函数吗?除了将类移出模块外,还有其他解决方法吗? 最佳答案 为了调用M::helper,你需要将它定义为defself.helper;结束为了进行比较,请查看以下修改后的代码段中的helper和helper2moduleMclassC

  9. ruby - 将运算符传递给函数? - 2

    也许这听起来很荒谬,但我想知道这对Ruby是否可行?基本上我有一个功能...defadda,bc=a+breturncend我希望能够将“+”或其他运算符(例如“-”)传递给函数,这样它就类似于...defsuma,b,operatorc=aoperatorbreturncend这可能吗? 最佳答案 两种可能性:以方法/算子名作为符号:defsuma,b,operatora.send(operator,b)endsum42,23,:+或者更通用的解决方案:采取一个block:defsuma,byielda,bendsum42,23,

  10. ruby - 我可以在 Ruby 1.9.x 中使用无参数函数吗? - 2

    所以我正在研究RubyKoans,而且我遇到了一个我认为是ruby1.9.x特有的问题。deftest_calling_global_methods_without_parenthesesresult=my_global_method2,3assert_equal5,resultend我明白了:james@tristan:~/code/ruby_projects/ruby_koans$rake(in/home/james/code/ruby_projects/ruby_koans)cdkoans/home/james/.rvm/rubies/ruby-1.9.2-p180/bin/ru

随机推荐