Локально инвертировать полином

20

Вызов

Если дан многочлен pс действительными коэффициентами порядка 1и степени n, найдите другой qне более чем nтакой многочлен степени , который (p∘q)(X) = p(q(X)) ≡ X mod X^(n+1), или другими словами, такой, p(q(X)) = X + h(X)где где h- произвольный многочлен с ord(h) ≥ n+1. Полином qоднозначно определяется p.

Для полинома , p(X) = a(n)*X^n + a(n+1)*X^(n+1) + ... + a(m)*X^mгде n <= mи a(n) ≠ 0, a(m) ≠ 0мы говорим , nявляется порядок из pи mявляется степень из p.

Упрощение : можно предположить, что pимеет целочисленные коэффициенты и a(1)=1(так p(X) = X + [some integral polynomial of order 2]). В этом случае qтоже есть интегральные коэффициенты.

Цель этого упрощения - избежать проблем с числами с плавающей запятой. Однако для иллюстрации приведен неинтегральный пример.

Примеры

  • Рассмотрим ряд Тейлора, exp(x)-1 = x + x^2/2 + x^3/6 + x^4/24 + ...а ln(x+1) = x - x^2/2 + x^3/3 - x^4/4 + ...затем очевидно ln(exp(x)-1+1)= x. Если мы просто рассмотрим многочлены Тейлора степени 4 из этих двух функций , которые мы получаем с обозначениями снизу (см testcases) p = [-1/4,1/3,-1/2,1,0]и q = [1/24, 1/6, 1/2, 1,0]и(p∘q)(X) ≡ X mod X^5

  • Рассмотрим полином p(X) = X + X^2 + X^3 + X^4. Тогда q(X) = X - X^2 + X^3 - X^4мы получаем

    (p∘q)(X) = p(q(X)) = X - 2X^5 + 3X^6 - 10X^7 +...+ X^16 ≡ X mod X^5
    

Testcases

Здесь входные и выходные полиномы записываются в виде списков коэффициентов (с коэффициентом монома наивысшей степени первым, с постоянным членом последним):

p = [4,3,2,0];  q=[0.3125,-.375,0.5,0]

Интегральные тестовые случаи:

p = [1,0]; q = [1,0]

p = [9,8,7,6,5,4,3,2,1,0]; q = [4862,-1430,429,-132,42,-14,5,-2,1,0]

p = [-1,3,-3,1,0]; q = [91,15,3,1,0]
flawr
источник

Ответы:

5

Python 2 + sympy, 128 байт

Мы локально инвертируем полином, предполагая, что q (x) = x, составляя его с p, проверяя коэффициент для x 2 и вычитая его из q. Скажем, коэффициент равен 4, тогда новый многочлен становится q (x) = x - 4x 2 . Затем мы снова составим это с p, но ищем коэффициент для x 3 . И т.д...

from sympy import*
i=input()
p=Poly(i,var('x'));q=p*0+x
n=2
for _ in i[2:]:q-=compose(p,q).nth(n)*x**n;n+=1
print q.all_coeffs()
orlp
источник
2

Mathematica, 45 байт

Normal@InverseSeries[#+O@x^(#~Exponent~x+1)]&

Да, у Mathematica есть встроенный для этого ....

Безымянная функция, принимающая в качестве входных данных многочлен от переменной x, например, -x^4+3x^3-3x^2+xдля последнего контрольного примера, и возвращающий полином с аналогичным синтаксисом, например, x+3x^2+15x^3+91x^4для последнего контрольного примера.

#+O@x^(#~Exponent~x+1)превращает вход #в объект степенного ряда, усеченный до степени #; InverseSeriesделает то, что говорит; и Normalпревращает полученный усеченный ряд степеней обратно в полином. (Мы могли бы сохранить эти начальные 7 байтов, если бы ответ в форме x+3x^2+15x^3+91x^4+O[x]^5был приемлемым. Действительно, если бы это был приемлемый формат для ввода и вывода, то InverseSeriesодно было бы 13-байтовое решение.)

Грег Мартин
источник
2

JavaScript (ES6), 138 байт

a=>a.reduce((r,_,i)=>[...r,i<2?i:a.map(l=>c=p.map((m,j)=>(r.map((n,k)=>p[k+=j]=m*n+(p[k]||0)),m*l+(c[j]||0)),p=[]),c=[],p=[1])&&-c[i]],[])

Порт ответа @ orlp. Ввод / вывод осуществляется в виде массивов коэффициентов в обратном порядке, т. Е. Первые два коэффициента всегда равны 0 и 1.

Нил
источник