Calcule la iteración n-ésima de un polinomio para un valor específico; fⁿ (x)


19

Dada una función polinómica f (por ejemplo, como una lista p de coeficientes reales en orden ascendente o descendente), un entero no negativo n , y un valor real x , devuelve:

   f n ( x )

es decir, el valor de f ( f ( f (... f ( x ) ...))) para n aplicaciones de f en x .

Use precisión y redondeo razonables.

Las soluciones que toman f como una lista de coeficientes probablemente serán las más interesantes, pero si puede tomar f como una función real (reduciendo así este desafío al trivial "aplicar una función n veces"), siéntase libre de incluirlo después de su solución no trivial.

Casos de ejemplo

p  = [1,0,0]o f  = x^2,  n  = 0,  x  = 3:  f 0 (3) =3

p  = [1,0,0]o f  = x^2,  n  = 1,  x  = 3:  f 1 (3) =9

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 0,  x  = 2.3:  f 0 (2.3) =2.3

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 1,  x  = 2.3:  f 1 (2.3) =-8.761

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 2,  x  = 2.3:  f 2 (2.3) =23.8258

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 3,  x  = 2.3:  f 3 (2.3) =-2.03244

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 4,  x  = 2.3:  f 4 (2.3) =1.08768

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 5,  x  = 2.3:  f 5 (2.3) =-6.38336

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 6,  x  = 2.3:  f 6 (2.3) =14.7565

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 7,  x  = 2.3:  f 7 (2.3) =-16.1645

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 8,  x  = 2.3:  f 8 (2.3) =59.3077

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 9,  x  = 2.3:  f 9 (2.3) =211.333

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 10,  x  = 2.3:  f 10 (2.3) =3976.08

p  = [0.1,-2.3,-4]o f  = 0.1x^2-2.3x-4,  n  = 11,  x  = 2.3:  f 11 (2.3) =1571775

p  = [-0.1,2.3,4]o f  = −0.1x^2+2.3x+4,  n  = 0,  x  = -1.1:  f 0 (-1.1) =-1.1

p  = [-0.1,2.3,4]o f  = −0.1x^2+2.3x+4,  n  = 1,  x  = -1.1:  f 1 (-1.1) =1.349

p  = [-0.1,2.3,4]o f  = −0.1x^2+2.3x+4,  n  = 2,  x  = -1.1:  f 2 (-1.1) =6.92072

p  = [-0.1,2.3,4]o f  = −0.1x^2+2.3x+4,  n  = 14,  x  = -1.1:  f 14 (-1.1) =15.6131

p  = [0.02,0,0,0,-0.05]o f  = 0.02x^4-0.05,  n  = 25,  x  = 0.1:  f 25 (0.1) =-0.0499999

p  = [0.02,0,-0.01,0,-0.05]o f  = 0.02x^4-0.01x^2-0.05,  n  = 100,  x  = 0.1:  f 100 (0.1) =-0.0500249



¿Puede mi respuesta Jelly tomar un enlace Jelly y considerarlo una "función", por ejemplo?
Erik the Outgolfer

@EriktheOutgolfer Originalmente requería entrada como lista de coeficientes para evitar tales soluciones triviales. Sin embargo, lo relajé por pedido. Le sugiero que publique la versión de la lista y agregue la versión trivial como una nota (u opuesta).
Adám

Ya publiqué la versión de la lista, pero la versión de la función es mucho más corta.
Erik the Outgolfer

@EriktheOutgolfer Sí, obviamente. Ver mi nota agregada.
Adám

Respuestas:


7

Octava , 49 bytes

@(p,x,n)(f=@(r,m){@()p(r(r,m-1)),x}{~m+1}())(f,n)

Pruébalo en línea!

O, tomando coeficientes:

Octava , 75 57 bytes

@(p,x,n)(f=@(f,n){@()polyval(p,f(f,n-1)),x}{~n+1}())(f,n)

Pruébalo en línea!

Un agradecimiento especial para Suever en StackOverflow, por esta respuesta hace un tiempo a una pregunta mía, que demuestra que es posible una función anónima recursiva.

Esto define una función anónima, que es un contenedor para una función anónima recursiva ; algo que no es un concepto nativo de Octave, y requiere una indexación de matriz de celdas elegante.

Como beneficio adicional, la segunda versión es una buena lección de alcance variable en Octave. Todas las instancias de rpueden ser reemplazadas legalmente por f, lo que simplemente sobrescribe lo existente fen el ámbito más local (similar para n)

Explicación

@(p,x,n)(f=@(r,m){@()p(r(r,m-1)),x}{~m+1}())(f,n)
@(p,x,n)         .                ..    .  ..   .   % Defines main anonymous function    
        (f=@(r,m).                ..    .  ).   .   % Defines recursive anonymous function
                 .                ..    .   .   .   %  r: Handle ('pointer') to recursive function
                 .                ..    .   .   .   %  m: Current recursion depth (counting from n to 0)
                 .                ..    .   (f,n)   % And call it, with
                 .                ..    .           %  r=f (handle to itself)
                 .                ..    .           %  m=n (initial recursion)
                 {                }{    }           % Create and index into cell array
                                    ~m+1            %  Index: for m>0: 1; for m==0: 2.
                                ,x                  %  Index 2: final recursion, just return x.
                  @()                               %  Index 1: define anonymous function, taking no inputs.
                     p(        )                    %   which evaluates the polynomial 
                       r(     )                     %    of the recursive function call
                         r,m-1                      %     which is called with r 
                                                    %     and recursion depth m-1 
                                                    %     (until m=0, see above)
                                         ()         % Evaluate the result of the cell array indexing operation.
                                                    %  which is either the anonymous function
                                                    %  or the constant `x`.

La clave para esto es que las funciones anónimas no se evalúan cuando se definen. Entonces, el @(), que parece un poco superfluo ya que define una función anónima que se llama ()directamente después, es realmente estrictamente necesario. No se llama a menos que lo seleccione la instrucción de indexación.

Octava , 39 bytes (forma aburrida)

function x=f(p,x,n)for i=1:n;o=p(o);end

Solo para completar, la solución Octave con el bytecount más corto. Bostezo. .


Intentaré releer esto otra vez, pero aún no lo entiendo. Como gran fan de Octave solo puedo decir, gran trabajo +1.
Michthan

2
@Michthan Intentaré dar una mejor explicación, pero es, con mucho, la octava más concisa que he escrito. Por lo general, los nombres de las funciones son la mayoría del conteo de bytes. Es casi Lisp.
Sanchises

1
@Michthan Con suerte, la nueva explicación tiene algún sentido, viéndola en una vista 'explotada'.
Sanchises

4

Mathematica, 56 47 28 bytes

Nest[x\[Function]x#+#2&~Fold~#,##2]&

\[Function] ocupa 3 bytes en UTF-8.

Toma los parámetros en orden p,x,n.

p (parámetro 1) está en orden creciente de grado.

Obviamente, si fse puede tomar como una función, esto se puede reducir solo a Nest.


¿Necesitas revertir los coeficientes?
Giuseppe

@Giuseppe Es por eso que hay Reverseen el código.
user202729

@ user202729 Creo que puede tomar los coeficientes en el orden que desee, ya sea ascendente o descendente.
Erik the Outgolfer

Se nos permite tomarlos en orden creciente o decreciente de grado, creo. (No conozco nada de Mathematica)
Giuseppe

Sí, puede tomarlos en el orden deseado: en
Adám

4

Casco , 5 bytes

←↓¡`B

Pruébalo en línea!

La idea clave aquí es que evaluar un polinomio en un punto x es equivalente a realizar una conversión de base de base x .

Bcuando se le da una base y una lista de dígitos realiza la conversión de base. Aquí usamos su versión invertida, para tomar primero la lista de dígitos y aplicarle parcialmente esta función. Obtenemos entonces una función que calcula el valor del polinomio dado en un punto, la segunda parte de esta solución trata de iterar esta función la cantidad correcta de veces:

Casco , 3 bytes

←↓¡

¡ es la función "iterar", toma una función y un punto de partida y devuelve la lista infinita de valores obtenidos iterando la función.

toma un número (el tercer argumento de este desafío) y elimina esa cantidad de elementos desde el comienzo de la lista.

devuelve el primer elemento de la lista resultante.



3

Ruby , 42 bytes

->c,n,x{n.times{x=c.reduce{|s,r|s*x+r}};x}

C es la lista de coeficientes en orden descendente

Versión trivial, donde f es una función lambda ( 26 bytes ):

->f,n,x{n.times{x=f[x]};x}

# For example:
# g=->f,n,x{n.times{x=f[x]};x}
# p g[->x{0.02*x**4-0.01*x**2-0.05},100,0.1]

Pruébalo en línea!


3

JavaScript (ES6),  52 49 44  42 bytes

Guardado 5 bytes gracias a GB y 2 bytes más gracias a Neil

Toma la entrada en la sintaxis de curry como (p)(n)(x), donde p es la lista de coeficientes en orden descendente.

p=>n=>g=x=>n--?g(p.reduce((s,v)=>s*x+v)):x

Casos de prueba


Si p está en orden descendente, puede reducir usando s * x + v e ignorar i.
GB

En ese caso, ¿puede omitir el ,0de la reducción?
Neil

@Neil Buena captura. :-)
Arnauld

2

J , 15 bytes

0{(p.{.)^:(]{:)

Pruébalo en línea!

Toma el polinomio como una lista de coeficientes de potencias ascendentes.

Explicación

0{(p.{.)^:(]{:)  Input: polynomial P (LHS), [x, n] (RHS)
            {:   Tail of [x, n], gets n
           ]     Right identity, passes n
  (    )^:       Repeat n times starting with g = [x, n]
     {.            Head of g
   p.              Evaluate P at that value
                   Return g = [P(head(g))]
0{               Return the value at index 0

2

05AB1E , 10 9 bytes

-1 byte gracias a Erik the Outgolfer

sF³gݨm*O

Pruébalo en línea!

Toma x como primer argumento, n como segundo y p en orden ascendente como tercero.

Explicación

sF³gݨm*O
s         # Forces the top two input arguments to get pushed and swaped on the stack
 F        # Do n times...
  ³        # Push the third input (the coefficients)
   g       # Get the length of that array...
    ݨ     # and create the range [0 ... length]
      m    # Take the result of the last iteration to these powers (it's just x for the first iteration)
       *   # Multiply the resuling array with the corresponding coefficients
         O # Sum the contents of the array
          # Implicit print

1
Puedes quitar el segundo ³.
Erik the Outgolfer

También (This is in case n is 0 so x is on the stack)está mal, todavía necesita el spara n distinto de cero.
Erik the Outgolfer

Si eso es verdad. Estaba pensando más en la línea de reemplazar ¹².with spara que se pueda empujar x a la pila en 1 byte sin necesidad de repetir al menos una vez. Probablemente debería haberlo redactado mejor ^^ '. ¡También gracias por el -1!
Datboi

Quise decir que aún lo necesitaría, ya que 05AB1E usa la última entrada para entrada implícita si todas las entradas se han leído.
Erik the Outgolfer

" sF³gݨm³O" y en la explicación también ...
Erik the Outgolfer

2

Haskell , 15 bytes

((!!).).iterate

Pruébalo en línea!

Gracias a totalmente humano por 11 bytes de ambas soluciones

Esto define una función tácita que toma una función como su primer argumento y ncomo su segundo argumento, y compone esa función consigo misma nveces. Esto se puede llamar con un argumento xpara obtener el valor final. Gracias a la magia del curry, esto es equivalente a una función que toma tres argumentos.


Tomar una lista de coeficientes en lugar de un argumento de función:

Haskell , 53 bytes

((!!).).iterate.(\p x->sum$zipWith(*)p[x^i|i<-[0..]])

Pruébalo en línea!

Esto es lo mismo que el código anterior, pero está compuesto con una función lambda que convierte una lista de coeficientes en una función polinómica. Los coeficientes se toman en orden inverso de los ejemplos, como potencias ascendentes de x.



El TIO del segundo debe tomar una lista como argumento, no como una función;) Aunque puede guardar un puñado de bytes usando un pliegue como este (tenga en cuenta que el polinomio cero no puede ser, []pero debe ser algo similar [0]o similar )
ბიმო

2

APL (Dyalog) , 20 9 bytes

{⊥∘⍵⍣⎕⊢⍺}

Pruébalo en línea!

Esto toma xcomo argumento izquierdo, los coeficientes de la función como argumento derecho, y nde STDIN.

Al mirar hacia atrás después de mucho tiempo, me di cuenta de que podía simplificar el cálculo utilizando la conversión de base .


APL (Dyalog), 5 bytes

Si podemos tomar la función como una función APL Dyalog, entonces esto puede ser de 5 bytes.

⎕⍣⎕⊢⎕

Toma x, ny luego la función como entrada de STDIN.


2

R , 96 58 55 52 bytes

f=function(n,p,x)`if`(n,f(n-1,p,x^(seq(p)-1)%*%p),x)

Pruébalo en línea!

Explicación:

seq(p)genera la lista 1, 2, ..., length(p)cuando pes un vector, también lo seq(p)-1son los exponentes del polinomio, por x^(seq(p)-1)lo tanto, es equivalente a x^0(siempre igual a 1) , x^1, x^2, ...y calcular un producto de punto %*%con pevalúa el polinomio en x.

Además, si Pse toma como una función, entonces serían 38 bytes:

function(n,P,x)`if`(n,f(n-1,P,P(x)),x)

Y nosotros, por supuesto, siempre se puede generar PporP=function(a)function(x)sum(x^(seq(a)-1)*a)



1

Python 3 , 70 69 bytes

f=lambda p,n,x:n and f(p,n-1,sum(c*x**i for i,c in enumerate(p)))or x

Toma pen orden ascendente, es decir, si pes [0, 1, 2]entonces el polinomio correspondiente es p(x) = 0 + 1*x + 2*x^2. Solución de recursión simple.

Pruébalo en línea!


1

C # (.NET Core) , 82 bytes

using System.Linq;f=(p,n,x)=>n<1?x:p.Select((c,i)=>c*Math.Pow(f(p,n-1,x),i)).Sum()

Pruébalo en línea!

Toma una lista de coeficientes en el orden opuesto de los casos de prueba (¿orden creciente?) Para que su índice en la matriz sea igual a la potencia x a la que debe elevarse.

Y la versión trivial en 30 bytes:

f=(p,n,x)=>n<1?x:f(p,n-1,p(x))

Pruébalo en línea!

Toma un delegado y lo aplica recursivamente n veces.


1

MATL , 11 bytes

ii:"ZQ6Mw]&

Pruébalo en línea!

Ligeramente menos interesante que mi respuesta de Octave, aunque creo que hay un malabarismo inteligente de entradas para asegurarse de que n=0funcione como se esperaba.


1

Julia 0.6.0 (78 bytes)

using Polynomials;g(a,n,x)=(p=Poly(a);(n>0&&(return g(a,n-1,p(x)))||return x))

Explicaciones:

El paquete Polinomios se explica por sí mismo: crea polinomios. Después de eso es una recursión bastante básica.

Para tener un polinomio: -4.0 - 2.3 * x + 0.1 * x ^ 2 la entrada adebe ser comoa = [-4, -2.3, 0.1]


1

Axioma, 91 bytes

f(n,g,x)==(for i in 1..n repeat(v:=1;r:=0;for j in 1..#g repeat(r:=r+v*g.j;v:=v*x);x:=r);x)

sangrado

fn(n,g,x)==
     for i in 1..n repeat
          v:=1; r:=0
          for j in 1..#g repeat(r:=r+v*g.j;v:=v*x)
          x:=r
     x

la entrada para polinomia g es una lista de números en el reverso del ejemplo de ejercicio. por ejemplo

[1,2,3,4,5]  

representaría la polinomia

1+2*x+3*x^2+4*x^3+5*x^4

prueba:

(3) -> f(0,[0,0,1],3)
   (3)  3
                                                    Type: PositiveInteger
(4) -> f(1,[0,0,1],3)
   (4)  9
                                                    Type: PositiveInteger
(5) -> f(0,[-4,-2.30,0.1],2.3)
   (5)  2.3
                                                              Type: Float
(6) -> f(1,[-4,-2.30,0.1],2.3)
   (6)  - 8.7610000000 000000001
                                                              Type: Float
(7) -> f(2,[-4,-2.30,0.1],2.3)
   (7)  23.8258121
                                                              Type: Float
(8) -> f(9,[-4,-2.30,0.1],2.3)
   (8)  211.3326335688 2052491
                                                              Type: Float
(9) -> f(9,[-4,-2.30,0.1,0,0,0,0,1],2.3)
   (9)  0.4224800431 1790652974 E 14531759
                                                              Type: Float
                                   Time: 0.03 (EV) + 0.12 (OT) = 0.15 sec
(10) -> f(2,[-4,-2.30,0.1,0,0,0,0,1],2.3)
   (10)  44199336 8495528344.36
                                                              Type: Float


1

C ++ 14, 71 bytes

Como lambda genérico sin nombre, regresando a través del xparámetro:

[](auto C,int n,auto&x){for(auto t=x;t=0,n--;x=t)for(auto a:C)t=a+x*t;}

Ungolfed y testcase:

#include<iostream>
#include<vector>

using namespace std;

auto f=
[](auto C,int n,auto&x){
 for(
  auto t=x; //init temporary to same type as x
  t=0, n--; //=0 at loop start, also check n
  x=t       //apply the result
  )
  for(auto a:C)
   t=a+x*t; //Horner-Scheme
}
;


int main() {
 vector<double> C = {0.1,-2.3,-4};//{1,0,0};
 for (int i = 0; i < 10; ++i) {
  double x=2.3;
  f(C, i, x);
  cout << i << ": " << x << endl;
 }
}

0

QBIC , 19 bytes

[:|:=:*c^2+:*c+:}?c

Toma entradas como

  • Numero de iteraciones
  • valor inicial de x
  • Luego las 3 partes del polinomio

Salida de muestra:

Command line: 8 2.3 0.1 -2.3 -4
 59.30772

0

Clojure, 66 bytes

#(nth(iterate(fn[v](apply +(map *(iterate(partial * v)1)%3)))%2)%)

Ejemplo completo:

(def f #(nth(iterate(fn[v](apply +(map *(iterate(partial * v)1)%3)))%2)%))
(f 10 2.3 [-4 -2.3 0.1])
; 3976.0831439050253

Componer una función es de 26 bytes:

#(apply comp(repeat % %2))

(def f #(apply comp(repeat % %2)))
((f 10 #(apply + (map * [-4 -2.3 0.1] (iterate (partial * %) 1)))) 2.3)
; 3976.0831439050253

0

Japt , 18 bytes

Bastante sencillo, hace lo que el desafío dice en la lata.

o r_VË*ZpVÊ-EÉÃx}W
o                  // Take `n` and turn it into a range [0,n).
  r_            }W // Reduce over the range with initial value of `x`.
    VË             // On each iteration, map over `p`, yielding the item
      *Z           // times the current reduced value
        pVÊ-EÉ     // to the correct power,
              Ãx   // returning the sum of the results.

Toma entradas con el fin n, p, x.

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.