Berechnen Sie die n-te Iteration eines Polynoms für einen bestimmten Wert. fⁿ (x)


19

Bei gegebener Polynomfunktion f (z. B. als Liste p reeller Koeffizienten in aufsteigender oder absteigender Reihenfolge) geben eine nicht negative ganze Zahl n und ein reeller Wert x Folgendes zurück:

   f n ( x )

dh der Wert von f ( f ( f (… f ( x )…))) für n Anwendungen von f auf x .

Verwenden Sie eine angemessene Präzision und Rundung.

Lösungen, bei denen f als Liste von Koeffizienten verwendet wird, sind wahrscheinlich die interessantesten. Wenn Sie jedoch f als tatsächliche Funktion verwenden können (wodurch diese Herausforderung auf das triviale " n- malige Anwenden einer Funktion " reduziert wird ), können Sie sie gerne einbeziehen nach Ihrer nicht-trivialen Lösung.

Beispielfälle

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



Kann meine Jelly-Antwort einen Jelly-Link verwenden und ihn beispielsweise als "Funktion" betrachten?
Erik der Outgolfer

@EriktheOutgolfer Ich habe ursprünglich eine Eingabe als Koeffizientenliste benötigt, um solche trivialen Lösungen zu vermeiden. Allerdings habe ich es auf Wunsch gelockert. Ich schlage vor, dass Sie die Listenversion veröffentlichen und die einfache Version als Notiz (oder Gegenteil) hinzufügen.
Adám

Ich habe die Listenversion bereits gepostet, aber die Funktionsversion ist viel kürzer.
Erik der Outgolfer

@EriktheOutgolfer Ja, natürlich. Siehe meine hinzugefügte Notiz.
Adám

Antworten:


7

Oktave , 49 Bytes

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

Probieren Sie es online!

Oder Koeffizienten nehmen:

Octave , 75 57 Bytes

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

Probieren Sie es online!

Ein besonderer Dank geht an Suever bei StackOverflow für die vor einiger Zeit auf meine Frage gestellte Antwort , die beweist, dass eine rekursive anonyme Funktion möglich ist.

Dies definiert eine anonyme Funktion, die ein Wrapper für a ist rekursive anonyme Funktion fungiert . Dies ist kein natives Octave-Konzept und erfordert eine ausgefallene Indizierung des Zellen-Arrays.

Als Bonus ist die zweite Version eine schöne Lektion in variablem Scoping in Octave. Alle Instanzen von rkönnen legal durch ersetzt werden f, die dann einfach die im lokalsten Bereich vorhandenen überschreiben f(ähnlich wie bei n).

Erläuterung

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

Der Schlüssel dazu ist, dass anonyme Funktionen bei ihrer Definition nicht ausgewertet werden. Das @(), was etwas überflüssig erscheint, da es eine anonyme Funktion definiert, die ()direkt nach aufgerufen wird, ist also eigentlich unbedingt notwendig. Es wird nur aufgerufen, wenn es von der Indexierungsanweisung ausgewählt wird.

Oktave , 39 Bytes (langweilig)

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

Der Vollständigkeit halber die Octave-Lösung mit dem kürzesten bytecount. Gähnen. .


Ich werde es ein weiteres Mal versuchen, aber ich verstehe es immer noch nicht ganz. Als großer Octave-Fan kann ich nur sagen, großartiger Job +1.
Michthan

2
@Michthan Ich werde versuchen, eine bessere Erklärung zu finden, aber es ist bei weitem die knappste Oktave, die ich geschrieben habe - normalerweise machen Funktionsnamen den größten Teil der Byteanzahl aus. Es ist fast Lisp.
Sanchises

1
@Michthan Hoffentlich macht die neue Erklärung Sinn, wenn man sie in einer Explosionsansicht betrachtet.
Sanchises

4

Mathematica, 56 47 28 Bytes

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

\[Function] dauert 3 Bytes in UTF-8.

Nimm die Parameter in die richtige Reihenfolge p,x,n.

p (Parameter 1) ist in aufsteigender Reihenfolge.

Wenn fals eine Funktion genommen werden kann, kann dies offensichtlich nur auf reduziert werden Nest.


Müssen Sie die Koeffizienten umkehren?
Giuseppe

@ Giuseppe Deshalb gibt es Reverseim Code.
user202729

@ user202729 Ich denke, Sie können die Koeffizienten in beliebiger Reihenfolge nehmen, entweder aufsteigend oder absteigend.
Erik der Outgolfer

Ich glaube, wir dürfen sie in aufsteigender oder absteigender Reihenfolge annehmen. (Ich kenne Mathematica überhaupt nicht)
Giuseppe

Ja, Sie können sie in der gewünschten Reihenfolge nehmen: in aufsteigender oder absteigender Reihenfolge
Adám

4

Schale , 5 Bytes

←↓¡`B

Probieren Sie es online!

Die Schlüsselidee hierbei ist, dass die Bewertung eines Polinoms an einem Punkt x der Durchführung einer Basisumwandlung von der Basis x entspricht .

BWenn eine Basis und eine Liste von Ziffern angegeben sind, wird eine Basiskonvertierung durchgeführt. Hier verwenden wir die gespiegelte Version, um zuerst die Ziffernliste zu nehmen und diese Funktion teilweise anzuwenden. Wir erhalten dann eine Funktion, die den Wert des gegebenen Polynoms zu einem bestimmten Zeitpunkt berechnet. Der zweite Teil dieser Lösung befasst sich mit der korrekten Anzahl von Iterationen dieser Funktion:

Schale , 3 Bytes

←↓¡

¡ Ist die "iterate" -Funktion, wird eine Funktion und ein Startpunkt verwendet und die unendliche Liste der Werte zurückgegeben, die durch Iteration der Funktion erhalten wurden.

Nimmt eine Zahl (das dritte Argument dieser Herausforderung) und löscht so viele Elemente vom Anfang der Liste.

Gibt das erste Element der resultierenden Liste zurück.



3

Ruby , 42 Bytes

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

C ist die Liste der Koeffizienten in absteigender Reihenfolge

Trivialversion, wobei f eine Lambda-Funktion ist ( 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]

Probieren Sie es online!


3

JavaScript (ES6),  52 49 44  42 Byte

5 Bytes dank GB und 2 weitere Bytes dank Neil gespart

Nimmt Eingaben in der aktuellen Syntax als an (p)(n)(x), wobei p die Liste der Koeffizienten in absteigender Reihenfolge ist.

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

Testfälle


Wenn p in absteigender Reihenfolge ist, können Sie mit s * x + v reduzieren und i ignorieren.
GB

Können Sie in diesem Fall das ,0aus der Reduzierung weglassen ?
Neil

@ Neil Guter Fang. :-)
Arnauld

2

J , 15 Bytes

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

Probieren Sie es online!

Nimmt das Polynom als eine Liste von Koeffizienten aufsteigender Potenzen.

Erläuterung

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 dank Erik dem Outgolfer

sF³gݨm*O

Probieren Sie es online!

Nimmt x als erstes Argument, n als zweites und p in aufsteigender Reihenfolge als drittes.

Erläuterung

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
Sie können die zweite entfernen ³.
Erik der Outgolfer

Ist auch (This is in case n is 0 so x is on the stack)falsch, du brauchst noch das sfür nicht null n.
Erik der Outgolfer

Ja, das ist wahr. Ich dachte mehr an das Ersetzen von ¹².with, sdamit es die Aufgabe bekommt, x zu dem Stapel zu schieben, der in 1 Byte ausgeführt wird, ohne mindestens einmal eine Schleife durchführen zu müssen. Hätte das wohl besser formulieren sollen ^^ '. Danke auch für die -1!
Datboi

Ich meinte, dass Sie es immer noch brauchen würden, da 05AB1E die letzte Eingabe für implizite Eingaben verwendet, wenn alle Eingaben gelesen wurden.
Erik der Outgolfer

" sF³gݨm³O" und in der Erklärung auch ...
Erik der Outgolfer

2

Haskell , 15 Bytes

((!!).).iterate

Probieren Sie es online!

Dank totalhuman für 11 Bytes aus beiden Lösungen

This defines a tacit function that takes a function as its first argument and n as its second argument, and composes that function with itself n times. This can then be called with an argument x to get the final value. Thanks to the magic of currying, this is equivalent to one function taking three arguments.


Taking a list of coefficients instead of a function argument:

Haskell, 53 bytes

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

Try it online!

This is the same as the above code, but composed with a lambda function that converts a list of coefficients into a polynomial function. The coefficients are taken in reverse order from the examples - as ascending powers of x.



The TIO of the second one should take a list as argument, not a function ;) Though you can save a handful of bytes by using a fold like this (note that the zero-polynomial can't be [] but must be something like [0] or similar).
ბიმო

2

APL (Dyalog), 20 9 bytes

{⊥∘⍵⍣⎕⊢⍺}

Try it online!

This takes x as the left argument, the coefficients of the function as the right argument, and n from STDIN.

Looking back at this after many a long time, I realised I could simplify the calculation by using base conversion .


APL (Dyalog), 5 bytes

If we can take the function as a Dyalog APL function, then this can be 5 bytes.

⎕⍣⎕⊢⎕

Takes x, n and then the function as input from 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)

Try it online!

Explanation:

seq(p)erzeugt die Liste, 1, 2, ..., length(p)wenn pein Vektor ist, ebenso seq(p)-1wie die Exponenten des Polynoms, ist daher x^(seq(p)-1)äquivalent x^0(immer gleich 1) , x^1, x^2, ...und berechnet ein Skalarprodukt %*%mit pdem Polynom bei x.

Wenn dies Pals Funktion verwendet wird, sind dies zusätzlich 38 Bytes:

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

Und wir können natürlich immer erzeugen PdurchP=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

Nimmt pin aufsteigender Reihenfolge, dh wenn pist, [0, 1, 2]dann ist das entsprechende Polynom p(x) = 0 + 1*x + 2*x^2. Einfache Rekursionslösung.

Probieren Sie es online!


1

C # (.NET Core) , 82 Byte

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

Probieren Sie es online!

Nimmt eine Liste von Koeffizienten in der entgegengesetzten Reihenfolge von den Testfällen (aufsteigende Reihenfolge?), So dass deren Index im Array gleich der Potenz ist, auf die x angehoben werden sollte.

Und die Trivialversion in 30 Bytes:

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

Probieren Sie es online!

Nimmt einen Delegaten und wendet ihn n-mal rekursiv an.


1

MATL , 11 Bytes

ii:"ZQ6Mw]&

Probieren Sie es online!

Etwas weniger interessant als meine Octave-Antwort, obwohl ich denke, dass einige kluge Eingaben aufeinander abgestimmt sind, um sicherzustellen, dass n=0alles wie erwartet funktioniert.


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

Erklärungen:

Das Paket Polynome ist ziemlich selbsterklärend: Es erzeugt Polynome. Danach ist es eine ziemlich grundlegende Rekursion.

Um ein Polynom zu haben: -4.0 - 2.3 * x + 0.1 * x ^ 2 amuss die Eingabe wie folgt seina = [-4, -2.3, 0.1]


1

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

eingerückt

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

die Eingabe für die Polynomie g ist eine Liste von Zahlen in umgekehrter Reihenfolge zum Übungsbeispiel. beispielsweise

[1,2,3,4,5]  

es würde die Polinomie darstellen

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

Prüfung:

(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

Als generisches unbenanntes Lambda, das über den xParameter zurückgegeben wird:

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

Ungolfed und Testfall:

#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

Übernimmt Eingaben als

  • Anzahl der Iterationen
  • Startwert von x
  • Dann die 3 Teile des Polynoms

Beispielausgabe:

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

Vollständiges Beispiel:

(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

Das Erstellen einer Funktion umfasst 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

Ziemlich unkompliziert, macht was die Herausforderung verspricht.

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.

Nimmt Eingaben , um n, p, x.

Probieren Sie es online!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.