Invertir localmente un polinomio

20

Desafío

Dado un polinomio pcon coeficientes reales de orden 1y grado n, encontrar otro polinomio qde grado a lo sumo nde tal manera que (p∘q)(X) = p(q(X)) ≡ X mod X^(n+1), o dicho de otro modo tal que p(q(X)) = X + h(X)cuando hes un polinomio arbitrario con ord(h) ≥ n+1. El polinomio qestá determinado únicamente por p.

Para un polinomio p(X) = a(n)*X^n + a(n+1)*X^(n+1) + ... + a(m)*X^mdonde n <= my a(n) ≠ 0, a(m) ≠ 0decimos que nes el orden de py mes el grado de p.

Simplificación : puede suponer que ptiene coeficientes enteros, y a(1)=1(entonces p(X) = X + [some integral polynomial of order 2]). En este caso también qtiene coeficientes integrales.

El propósito de esta simplificación es evitar los problemas con los números de coma flotante. Sin embargo, existe un ejemplo no integral con fines ilustrativos.

Ejemplos

  • Considere la serie de Taylor exp(x)-1 = x + x^2/2 + x^3/6 + x^4/24 + ...y ln(x+1) = x - x^2/2 + x^3/3 - x^4/4 + ...luego, obviamente ln(exp(x)-1+1)= x. Si sólo consideramos los polinomios de Taylor de grado 4 de esas dos funciones que obtenemos con la anotación desde abajo (ver casos de prueba) p = [-1/4,1/3,-1/2,1,0]y q = [1/24, 1/6, 1/2, 1,0]y(p∘q)(X) ≡ X mod X^5

  • Considera el polinomio p(X) = X + X^2 + X^3 + X^4. Entonces para q(X) = X - X^2 + X^3 - X^4obtener

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

Casos de prueba

Aquí los polinomios de entrada y salida se escriben como listas de coeficientes (con el coeficiente del monomio de mayor grado primero, el término constante al final):

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

Casos de prueba integrales:

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]
falla
fuente

Respuestas:

5

Python 2 + sympy, 128 bytes

Invertimos localmente el polinomio suponiendo que q (x) = x, componiéndolo con p, verificando el coeficiente para x 2 y restándolo de q. Digamos que el coeficiente fue 4, entonces el nuevo polinomio se convierte en q (x) = x - 4x 2 . Luego componimos esto nuevamente con p, pero buscamos el coeficiente para x 3 . Etc ...

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
fuente
2

Mathematica, 45 bytes

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

Sí, Mathematica tiene una función para eso ...

Función sin nombre que toma como entrada un polinomio en la variable x, como -x^4+3x^3-3x^2+xpara el último caso de prueba, y devuelve un polinomio con una sintaxis similar, como x+3x^2+15x^3+91x^4para el último caso de prueba.

#+O@x^(#~Exponent~x+1)convierte la entrada #en un objeto de serie de potencia, truncado al grado de #; InverseSerieshace lo que dice; y Normalconvierte la serie de potencia truncada resultante en un polinomio. (Podríamos guardar esos 7 bytes iniciales si una respuesta en el formulario x+3x^2+15x^3+91x^4+O[x]^5fuera aceptable. De hecho, si ese fuera un formato aceptable tanto para entrada como para salida, entonces InverseSeriessolo sería una solución de 13 bytes).

Greg Martin
fuente
2

JavaScript (ES6), 138 bytes

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]],[])

Puerto de la respuesta de @ orlp. La E / S tiene la forma de conjuntos de coeficientes en orden inverso, es decir, los dos primeros coeficientes son siempre 0 y 1.

Neil
fuente