Calcular a n-ésima iteração de um polinômio para um valor específico; fⁿ (x)


19

Dada uma função polinomial f (por exemplo, como uma lista p de coeficientes reais em ordem crescente ou decrescente), um número inteiro não negativo n e um valor real x , retornam:

   f n ( x )

ou seja, o valor de f ( f ( f (… f ( x )…))) para n aplicações de f em x .

Use precisão e arredondamento razoáveis.

As soluções que tomam f como uma lista de coeficientes provavelmente serão as mais interessantes, mas se você conseguir tomar f como uma função real (reduzindo esse desafio ao trivial "aplicar uma função n vezes"), fique à vontade para incluí-la após a sua solução não trivial.

Casos de exemplo

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

p  = [-0.1,2.3,4]ou 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]ou 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]ou f  = 0.02x^4-0.01x^2-0.05,  n  = 100,  x  = 0.1:  f 100 (0,1) =-0.0500249



A minha resposta Jelly pode pegar um link Jelly e considerá-lo uma "função", por exemplo?
Erik the Outgolfer

@EriktheOutgolfer Inicialmente, solicitei entrada como lista de coeficientes para evitar essas soluções triviais. No entanto, relaxei a pedido. Sugiro que você publique a versão da lista e adicione a versão trivial como uma nota (ou oposta).
Adám 04/08/19

Já publiquei a versão da lista, mas a versão da função é muito menor.
Erik the Outgolfer

@EriktheOutgolfer Sim, obviamente. Veja minha nota adicionada.
Adám 04/08/19

Respostas:


7

Oitava , 49 bytes

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

Experimente online!

Ou, tomando coeficientes:

Oitava , 75 57 bytes

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

Experimente online!

Um agradecimento especial a Suever no StackOverflow, por esta resposta há algum tempo em uma pergunta minha, provando que uma função anônima recursiva é possível.

Isso define uma função anônima, que é um invólucro para uma função anônima recursiva ; algo que não é um conceito nativo do Oitava e requer alguma indexação sofisticada de matriz de células.

Como bônus, a segunda versão é uma boa lição de escopo de variáveis ​​no Octave. Todas as instâncias de rpodem ser legalmente substituídas por f, que simplesmente substituem as existentes fno escopo mais local (semelhante para n)

Explicação

@(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`.

A chave para isso é que funções anônimas não são avaliadas quando definidas. Portanto, o @(), que parece um pouco supérfluo, pois define uma função anônima que é chamada ()diretamente depois, é realmente estritamente necessário. Não é chamado, a menos que seja selecionado pela instrução de indexação.

Oitava , 39 bytes (maneira chata)

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

Por uma questão de integridade, a solução Octave com o menor número de bytes. Bocejar. .


Vou tentar reler isso outra vez, mas ainda não entendi direito .. Como grande fã do Oitava, só posso dizer, ótimo trabalho +1.
Michthan

2
@ Michthan, tentarei dar uma explicação melhor, mas é de longe a oitava mais concisa que escrevi - geralmente, os nomes das funções são a maioria da contagem de bytes. É quase Lisp.
Sanchises

11
@ Michthan Felizmente, a nova explicação faz algum sentido, olhando para ela de uma forma 'explodida'.
Sanchises

4

Mathematica, 56 47 28 bytes

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

\[Function] leva 3 bytes em UTF-8.

Pegue os parâmetros em ordem p,x,n.

p (parâmetro 1) está em ordem crescente de grau.

Obviamente, se fpode ser tomado como uma função, isso pode ser reduzido apenas para Nest.


Você precisa reverter os coeficientes?
Giuseppe

@ Giuseppe É por isso que existe Reverseno código.
user202729

@ user202729 Acho que você pode obter os coeficientes na ordem que desejar, crescente ou decrescente.
Erik the Outgolfer

Estamos autorizados a tomá-los em ordem crescente ou decrescente de grau, acredito. (Eu não sei Mathematica em tudo)
Giuseppe

Sim, você pode levá-los na ordem desejada: em
Adám 04/08/17

4

Casca , 5 bytes

←↓¡`B

Experimente online!

A idéia principal aqui é que avaliar um polinômio no ponto x é equivalente a realizar a conversão de base da base x .

Bquando recebe uma base e uma lista de dígitos, realiza a conversão da base. Aqui usamos sua versão invertida, para pegar a lista de dígitos primeiro e aplicar parcialmente essa função a ela. Obtemos então uma função que calcula o valor do polinômio fornecido em um ponto; a segunda parte desta solução lida com a iteração dessa função pela quantidade correta de vezes:

Casca , 3 bytes

←↓¡

¡ é a função "iterar", pega uma função e um ponto de partida e retorna a lista infinita de valores obtidos iterando a função.

pega um número (o terceiro argumento deste desafio) e descarta muitos elementos desde o início da lista.

retorna o primeiro elemento da lista resultante.



3

Ruby , 42 bytes

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

C é a lista de coeficientes em ordem decrescente

Versão trivial, em que f é uma função 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]

Experimente online!


3

JavaScript (ES6),  52 49 44  42 bytes

Economizou 5 bytes graças a GB e mais 2 bytes graças a Neil

Recebe entrada na sintaxe de currying como (p)(n)(x), onde p é a lista de coeficientes em ordem decrescente.

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

Casos de teste


Se p estiver em ordem decrescente, você poderá reduzir usando s * x + ve ignorar i.
GB

Nesse caso, você pode omitir o ,0da redução?
Neil

@ Neil Boa captura. :-)
Arnauld

2

J , 15 bytes

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

Experimente online!

Toma o polinômio como uma lista de coeficientes de potências ascendentes.

Explicação

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 graças a Erik, o Outgolfer

sF³gݨm*O

Experimente online!

Toma x como primeiro argumento, n como segundo ep em ordem crescente como terceiro.

Explicação

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

11
Você pode remover o segundo ³.
Erik the Outgolfer

Também (This is in case n is 0 so x is on the stack)está errado, você ainda precisa sde n diferente de zero.
Erik the Outgolfer

Sim, é verdade. Eu estava pensando mais ao longo da linha de substituição de ¹².with, spara conseguir o trabalho de enviar x para a pilha feita em 1 byte sem precisar fazer loop pelo menos uma vez. Provavelmente deveria ter escrito isso melhor ^^ '. Também obrigado pelo -1!
Datboi 04/08/19

Eu quis dizer que você ainda precisaria disso, pois 05AB1E usa a última entrada para entrada implícita se todas as entradas tiverem sido lidas.
Erik the Outgolfer

" sF³gݨm³O" e na explicação também ...
Erik, o Outgolfer

2

Haskell , 15 bytes

((!!).).iterate

Experimente online!

Graças ao totallyhuman por 11 bytes de ambas as soluções

Isso define uma função tácita que assume uma função como seu primeiro argumento e ncomo seu segundo argumento, e compõe essa função consigo mesmo nvezes. Isso pode ser chamado com um argumento xpara obter o valor final. Graças à magia do curry, isso é equivalente a uma função que recebe três argumentos.


Tomando uma lista de coeficientes em vez de um argumento de função:

Haskell , 53 bytes

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

Experimente online!

É o mesmo que o código acima, mas composto com uma função lambda que converte uma lista de coeficientes em uma função polinomial. Os coeficientes são obtidos em ordem inversa dos exemplos - como potências ascendentes de x.



O TIO do segundo deve ter uma lista como argumento, não como função;) Embora você possa salvar um punhado de bytes usando uma dobra como esta (observe que o polinômio zero não pode ser, []mas deve ser algo parecido [0]ou semelhante )
ბიმო

2

APL (Dyalog) , 20 9 bytes

{⊥∘⍵⍣⎕⊢⍺}

Experimente online!

Isso leva xcomo argumento à esquerda, os coeficientes da função como argumento à direita en partir de STDIN.

Olhando para trás, depois de muito tempo, percebi que poderia simplificar o cálculo usando a conversão base .


APL (Dyalog), 5 bytes

Se pudermos assumir a função como uma função Dyalog APL, isso pode ser de 5 bytes.

⎕⍣⎕⊢⎕

Toma xn e , em seguida, a função 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)

Experimente online!

Explicação:

seq(p)gera a lista 1, 2, ..., length(p)quando pé um vetor, assim seq(p)-1como os expoentes do polinômio, portanto x^(seq(p)-1)é equivalente a x^0(sempre igual a 1) , x^1, x^2, ...e computa um produto pontual %*%com pavalia o polinômio emx .

Além disso, se Pconsiderado como uma função, isso seria 38 bytes:

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

E é claro que sempre podemos gerar 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 pem ordem crescente, ou seja, se pfor [0, 1, 2], o polinômio correspondente é p(x) = 0 + 1*x + 2*x^2. Solução de recursão simples.

Experimente online!


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()

Experimente online!

Leva uma lista de coeficientes na ordem oposta aos casos de teste (ordem crescente?) Para que seu índice na matriz seja igual à potência x deve ser aumentada para.

E a versão trivial em 30 bytes:

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

Experimente online!

Pega um delegado e o aplica recursivamente n vezes.


1

MATL , 11 bytes

ii:"ZQ6Mw]&

Experimente online!

Um pouco menos interessante que a minha resposta do Oitava, embora eu ache que há algum malabarismo inteligente de entradas para garantir que n=0funcione conforme o esperado.


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))

Explicações:

Os polinômios do pacote é bastante auto-explicativo: ele cria polinômios. Depois disso, é uma recursão bastante básica.

Para ter um polinômio: -4,0 - 2,3 * x + 0,1 * x ^ 2, a entrada adeve 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)

recuado

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

a entrada para a polinomia g é uma lista de números no verso do exemplo de exercício. por exemplo

[1,2,3,4,5]  

representaria a polinomia

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

teste:

(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érica e sem nome, retornando pelo 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 e 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

  • Número de iterações
  • valor inicial de x
  • Em seguida, as 3 partes do polinômio

Saída de amostra:

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)%)

Exemplo 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

A composição de uma função tem 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

Bem simples, faz o que o desafio diz na 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 em ordem n, p, x.

Experimente online!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.