Polynomapproximationen einer Sinuswelle finden


16

Ich möchte die durch gegebene Sinuswelle approximieren, indem ich einen polynomialen Wellenformer auf eine einfache Dreieckswelle anwende , die von der Funktion erzeugt wirdsin(πx)

T(x)=14|12mod(12x+14, 1)|

Dabei ist der Bruchteil von :mod(x,1)x

mod(x,y)y(xyxy)

Eine Taylor-Serie könnte als Waveshaper verwendet werden.

S1(x)=πx2πx233!+πx255!πx277!

Angesichts der obigen Funktionen eine annehmbare Approximation einer Sinuswelle. Aber wir müssen auf die 7. Potenz der Reihe aufsteigen, um ein vernünftiges Ergebnis zu erzielen, und die Peaks sind ein wenig niedrig und haben keine Steigung von genau Null.S1(T(x))

Anstelle der Taylor-Reihe könnten wir einen Polynom-Wellenformer verwenden, der einige Regeln befolgt.

  • Muss -1, -1 und + 1, + 1 durchlaufen.
  • Die Steigung bei -1, -1 und +1, +1 muss Null sein.
  • Muss symmetrisch sein.

Eine einfache Funktion, die unseren Anforderungen entspricht:

S2(x)=3x2x32

Die Graphen von S2(T(x)) und sin(πx) sind ziemlich ähnlich, aber nicht so ähnlich wie die Taylor-Reihe. Zwischen den Peaks und Nulldurchgängen weichen sie sichtbar etwas ab. Eine schwerere und genauere Funktion, die unseren Anforderungen entspricht:

S3(x)=x(x25)216

Dies ist wahrscheinlich nah genug für meine Zwecke, aber ich frage mich, ob es eine andere Funktion gibt, die der Sinuswelle näher kommt und die rechnerisch billiger ist. Ich habe ziemlich gute Kenntnisse darüber, wie man Funktionen findet, die die drei oben genannten Anforderungen erfüllen, aber ich bin mir nicht sicher, wie man Funktionen findet, die diese Anforderungen erfüllen und auch einer Sinuswelle am ehesten entsprechen.

Welche Methoden gibt es, um Polynome zu finden, die eine Sinuswelle imitieren (wenn sie auf eine Dreieckwelle angewendet werden)?


Zur Verdeutlichung suche ich nicht unbedingt nur nach ungeraden symmetrischen Polynomen, obwohl dies die einfachste Wahl ist.

Etwas wie die folgende Funktion könnte auch meine Bedürfnisse erfüllen:

S4(x)=3x2+x24+x44

Dies erfüllt die Anforderungen im negativen Bereich, und eine stückweise Lösung könnte verwendet werden, um es auch auf den positiven Bereich anzuwenden; beispielsweise

3x2P(x,2)4P(x,4)4

wobei die vorzeichenbehaftete Potenzfunktion ist .P

Ich würde mich auch für Lösungen interessieren, die die vorzeichenbehaftete Potenzfunktion verwenden, um gebrochene Exponenten zu unterstützen, da dies uns einen weiteren "Drehknopf" gibt, ohne einen weiteren Koeffizienten hinzuzufügen.

a0x +a1P(x, p1)

Mit den richtigen Konstanten könnte dies möglicherweise eine sehr gute Genauigkeit ohne die Schwere von Polynomen fünfter oder siebter Ordnung erzielen. Hier ist ein Beispiel, das die hier beschriebenen Anforderungen mit einigen handverlesenen Konstanten erfüllt: .a0=1.666¯,a1=0.666¯,p1=2.5

5x2P(x, 52)3

Tatsächlich sind diese Konstanten sehr nahe an und und . Wenn Sie diese einstecken, entsteht etwas, das einer Sinuswelle sehr nahe kommt.π21π2e

π2x +(1π2)P(x,e)

Anders ausgedrückt sieht sehr nahe an zwischen 0,0 und π / 2,1 aus. Irgendwelche Gedanken zur Bedeutung davon? Vielleicht kann ein Tool wie Octave dabei helfen, die "besten" Konstanten für diesen Ansatz zu finden. sin(x)xxe6sin(x)


1
Also, was ist Ihre Fehlerbegriff Definition für "enger"? Soweit ich das beurteilen kann, ist die von Ihnen angegebene Taylor-Reihe der minimale L²-Fehler, der für eine endliche Anzahl von Koeffizienten angenähert wird. (Ich denke.)
Marcus Müller

2
Was ist übrigens Ihr Ziel? Es könnte wirklich hilfreich sein, uns mitzuteilen, warum Sie nach einem Polynomwellenformer suchen, auf welcher technologischen Basis und mit welchen Hauptzielen Sie sich für die Approximation einsetzen.
Marcus Müller

@ MarcusMüller Ich bin bereit, die Genauigkeit der Taylor-Serie für etwas deutlich Billigeres zu opfern, wenn es von einer Sinuswelle zum menschlichen Ohr nicht zu unterscheiden ist. Die Peaks der Taylorreihen-Approximation stören mich ebenfalls. Ich bin daran interessiert, etwas zu finden, das "enger" ist als die beiden anderen Funktionen, die ich aufgelistet habe. Ich vermute, es wird nicht billiger als . S2
Gast

1
"Für das menschliche Ohr" ist hier entscheidend :) Warum "stören" dich die Spitzen? Nochmals: Geben Sie uns eine Vorstellung davon, warum / zu welchem ​​Zweck und unter welchen Einschränkungen Sie dies tun. Ohne genügend Hintergrund ist Ihre Frage einfach zu weit gefasst, um richtig beantwortet zu werden!
Marcus Müller

1
Warum fängst du mit einer Dreieckswelle an? Sinusgeneratoren sind einfach und gebräuchlich, Rechteckwellen werden trivial auf die Grundschwingung gefiltert usw.
Carl Witthoft

Antworten:


10

Vor ungefähr einem Jahrzehnt habe ich dies für eine ungenannte Musiksynthesizer-Firma gemacht, die F & E nicht weit von meiner Wohnung in Waltham, MA, entfernt hatte. (Ich kann mir nicht vorstellen, wer sie sind.) Ich habe die Koeffizienten nicht.

aber versuch das:

f(x)sin(π2x)for 1x+1=π2x(a0+a1x2+a2x4)

Dies garantiert, dass .f(x)=f(x)

Um zu gewährleisten, dass dann istf(x)|x=±1=0

f(x)=π2(a0+3a1x2+5a2x4)

(1)a0+3a1+5a2=0

Das ist die erste Einschränkung. Um sicherzustellen, dass dann|f(±1)|=1

(2)a0+a1+a2=2π

Das ist die zweite Einschränkung. Die Beseitigung und die Lösung von Gleichungen. (1) und (2) für in Bezug auf (was angepasst werden muss):a 2 a 1a0a2a1

a0=52π12a1

a2=12π12a1

Jetzt haben Sie nur noch einen Koeffizienten, , um die beste Leistung zu erzielen:a1

f(x)=π2x((52π12a1)+a1x2(12π+12a1)x4)

Auf diese Weise würde ich drehen, um die beste Leistung für einen Sinusoszillator zu erzielen. Ich würde die obige und die Symmetrie der Sinuswelle auf einstellen und genau einen ganzen Zyklus in einen Puffer mit einer Potenz von zwei Punkten (z. B. 128, ist mir egal) legen und die FFT darauf ausführen perfekter Zyklus. x = 1a1x=1

Das FFT-Ergebnis Bin 1 ist die Stärke des Sinus und sollte etwa . Jetzt können Sie einstellen , um die Verzerrung der 3. Harmonischen zu erhöhen und zu verringern. Ich würde mit damit . Das ist in Bin 3 der FFT-Ergebnisse. Die Verzerrung der 5. Harmonischen (Wert in Bin 5) ist jedoch von Bedeutung (sie steigt, wenn die 3. Harmonische sinkt). Ich würde so einstellen , dass die Stärke der 5. Harmonischen gleich der 3. Harmonischen ist. Es wird ungefähr -70 dB von der 1. Harmonischen sein (wie ich mich erinnere). Dies ist die am besten klingende Sinuswelle aus einem billigen, ungeradzahligen Polynom mit 3 Koeffizienten 5. Ordnung.N/2a 15a1a01a1a15π2a01a1

Jemand anderes kann den MATLAB-Code schreiben. Wie klingt das für dich?


Ich werde definitiv keine Zeit haben, das MATLABING zu machen, um nach dem optimalen suchen, so dass die 3. Harmonische gleich der 5. Harmonischen ist, ungefähr 70 dB unter der Grundwelle (1. Harmonische). jemand anderes muss das tun. Es tut uns leid. a1
Robert Bristow-Johnson

Tolle Antwort, die ich immer noch verdaue. Eigentlich beginnt man sich zu fragen, ob es ein Polynom mit 3 Koeffizienten, 5. Ordnung und ungerader Symmetrie sein muss ... Könnte Ihr f '(x) tatsächlich f (x) sein und ein stückweiser Deal um 0 sein? Grobe Skizze hier . Vielleicht ist es das, was Ced im Sinn hat? Ich hole euch immer noch ein.
Gast

Dies ist ein schöner Ansatz. Ich frage mich, ob Sie, anstatt die FFT zu nehmen und iterativ zu lösen, die Chebyshev-Polynome dritter und fünfter Ordnung aus Ihrem und dann die beiden gleichsetzen und nach auflösen könnten . a 1f(x)a1
Schneller

Muss im Halbschlaf gewesen sein , als ich das geschrieben „Skizze“ bedeuten , dass ich so etwas wie zu tun dies , aber korrigiert durch ± 1 und habe Null Neigung zu laufen (kann einfach und die Ableitung, Geige , um mit ihm, integriere sie wieder). Ich bin nicht sicher, ob es einen Vorteil gegenüber der fünften Ordnung gibt, nur etwas, worüber ich noch nicht nachgedacht hatte.
Gast

1
Das ist wirklich eine brillante Lösung, es hat nur eine Weile gedauert, bis es funktioniert. Ich hoffe, dass das richtige Markieren niemanden davon abhält, mitzukommen und den Code zu schreiben.
Gast

9

Was normalerweise gemacht wird, ist eine Annäherung, die eine Norm des Fehlers minimiert, oft die -Norm (wo der maximale Fehler minimiert ist) oder die -Norm (wo der mittlere quadratische Fehler minimiert ist). -Näherung erfolgt mit dem Remez-Austauschalgorithmus . Ich bin mir sicher, dass Sie Open Source Code finden können, der diesen Algorithmus implementiert. In diesem Fall halte ich jedoch eine sehr einfache (diskrete) -Optimierung für ausreichend. Lassen Sie uns einen Blick auf Matlab / Octave-Code und die Ergebnisse werfen: L 2 L LL2Ll2

x = Linienraum (0, pi / 2300); % Raster auf [0, pi / 2]
x = x (:);
% überbestimmtes lineares Gleichungssystem
% (nur mit ungeraden Potenzen)
A3 = [x, x. ^ 3];
A5 = [x, x, 3, x, 5];
b = sin (x);
% im Sinn von l2 lösen
c3 = A3 \ b;
c5 = A5 \ b;
f3 = A3 * c3; % Annäherung 3. Ordnung
f5 = A5 * c5; % Näherung 5. Ordnung

Die folgende Abbildung zeigt die Approximationsfehler für die -Ordnung und für die -Ordnungsnäherungen. Die maximalen Approximationsfehler sind und jeweils. 5 t h3rd5th8.8869e-031.5519e-04

Bildbeschreibung hier eingeben

Die optimalen Koeffizienten sind

c3 =
   0.988720369237930
  -0.144993929056091

und

c5 =
   0.99976918199047515
  -0.16582163562776930
   0,00757183954143367

Die Annäherung dritter Ordnung ist also

(1)sin(x)0.988720369237930x0.144993929056091x3,x[π/2,π/2]

und die Annäherung fünfter Ordnung ist

(2)sin(x)0.99976918199047515x0.16582163562776930x3+0.00757183954143367x5,x[π/2,π/2]

BEARBEITEN:

Ich habe mir Näherungen mit der vorzeichenbehafteten Potenzfunktion angesehen, wie in der Frage vorgeschlagen, aber die beste Näherung ist kaum besser als die oben gezeigte Näherung dritter Ordnung. Die Näherungsfunktion ist

(3)f(x)=x1p(π2)1pxp,x[0,π/2]

wobei die Konstanten so gewählt wurden, dass und . Die Leistung wurde optimiert, um den kleinsten maximalen Fehler im Bereich . Es wurde gefunden, dass der optimale Wert für . Die folgende Abbildung zeigt die Approximationsfehler für die Approximation dritter Ordnung und für die neue Approximation :f ' ( π / 2 ) = 0 p [ 0 , π / 2 ] p p = 2,774 ( 1 )f(0)=1f(π/2)=0p[0,π/2]pp=2.774(1)(3)

Bildbeschreibung hier eingeben

Der maximale Approximationsfehler der Approximation ist , es ist jedoch zu beachten, dass die Approximation dritter Ordnung nur diesen Fehler nahe bei überschreitet und dass sein Approximationsfehler zum größten Teil tatsächlich kleiner als der der vorzeichenbehafteten Potenzfunktion ist .π(3)4.5e-3π/2

EDIT 2:

Wenn Sie nichts dagegen haben, können Sie auch die Sinus-Näherungsformel von Bhaskara I verwenden , die einen maximalen Näherungsfehler von 1.6e-3:

(4)sin(x)16x(πx)5π24x(πx),x[0,π/2]

Das ist sehr hilfreich, danke. Dies ist das erste Mal, dass ich Octave benutze. Ich habe das meiste verfolgt, aber wie sind Sie zu den Näherungsfehlern und Maximalwerten gekommen?
Gast

1
@Guest: Die Fehler sind einfach b-f3und b-f5sind. Verwenden Sie den plotBefehl, um sie zu zeichnen.
Matt L.

1
@Guest: Und die Maxima, die du von max(abs(b-f3))und bekommst max(abs(b-f5)).
Matt L.

@Guest: Ich habe mit der vorzeichenbehafteten Potenzfunktion herumgespielt, aber das Ergebnis ist nicht wesentlich besser als die Annäherung dritter Ordnung, die ich zuvor hatte. Schau dir meine bearbeitete Antwort an. Würde die Komplexität einen so großen Unterschied machen?
Matt L.

Danke, dass du es dir angesehen hast. Komplexität ist keine große Sache, nur neugierig, wie genau die Approximation bei relativ geringer Komplexität sein kann. Ich bin mir nicht ganz sicher, wie du auf (3) gekommen bist, aber es funktioniert gut. Ich müsste stattdessen 2,752 für verwenden p, da alles darüber die Peaks über 1 (Clipping) senden wird.
Gast

7

Beginnen Sie mit einem ansonsten allgemeinen parametrisierten Polynom ungerader Symmetrie 5. Ordnung:

f(x)=a0x1+a1x3+a2x5=x(a0+a1x2+a2x4)=x(a0+x2(a1+a2x2))

Jetzt legen wir einige Einschränkungen für diese Funktion fest. Die Amplitude sollte an den Spitzen 1 sein, mit anderen Worten . Setzt für gibt:f(1)=11x

(1)a0+a1+a2=1

Das ist eine Einschränkung. Die Steigung an den Spitzen sollte Null sein, mit anderen Worten . Die Ableitung von istf(1)=0f(x)

a0+3a1x2+5a2x4

und das Ersetzen von ergibt unsere zweite Einschränkung:1x

(2)a0+3a1+5a2=0

Jetzt können wir unsere beiden Bedingungen verwenden, um nach und zu lösena1a2a0

(3)a1=522a0a2=a032

a0a0π2

Parameteroptimierung

Nachfolgend sind einige Optimierungen der Koeffizienten aufgeführt, die zu diesen relativen Amplituden der Harmonischen im Vergleich zur Grundfrequenz (1. Harmonische) führen:

Vergleich von Annäherungen

In der komplexen Fourier-Reihe :

k=ckei2πPkx,

P-P=4x=1f(x)1x1,kth

ck=1P11+P({f(x)if x<1f(x2)if x1)ei2πPkxdx.

2cos(x)=eix+eixk>02|ck|,

2|ck|=24|13({f(x)if x<1f(x2)if x1)ei2π4kxdx|=12|11f(x)eiπ2kxdx13f(x2)eiπ2kxdx|=12|11f(x)eiπ2kxdx11f(x+22)eiπ2k(x+2)dx|=12|11f(x)eiπ2kxdx11f(x)eiπ2k(x+2)dx|=12|11f(x)(eiπ2kxeiπ2k(x+2))dx|=12|eiπ2x11f(x)(eiπ2kxeiπ2k(x+2))dx|=12|11f(x)(eiπ2k(x1)eiπ2k(x+1))dx|

|eix|=1x.kkf(x)

=|48((1)k1)(16a0(π2k210)5×(5π2k248))π6k6|

5. Ordnung, stetige Ableitung

a02|ck|

a0=3×(132375π2130832)16×(15885π216354)1.569778813,a1=522a0=79425π2654168×(15885π2+16354)0.6395576276,a2=a032=15885π216×(15885π216354)0.06977881382.

1367961615885π616354π41.0000714201890678.99 dBkth(1(1)k)|8177k279425|142496k6.

7. Ordnung, stetige Ableitung

Ebenso ist die optimale Polynomnäherung 7. Ordnung mit den gleichen Anfangsbedingungen und der 3., 5. und 7. Harmonischen auf dem niedrigstmöglichen gleichen Pegel:

f(x)=a0x1+a1x3+a2x5+a3x7=x(a0+a1x2+a2x4+a3x7)=x(a0+x2(a1+x2(a2+a3x2)))

a0=2a2+4a3+321.570781972,a1=4a2+6a3+120.6458482979,a2=347960025π4405395408π216×(281681925π4405395408π2+108019280)0.07935067784,a3=16569525π416×(281681925π4405395408π2+108019280)0.004284352588.

2293523251200281681925π8405395408π6+108019280π40.9999983752,11555395123.8368 dBkth(1(1)k)|1350241k450674426k2+347960025|597271680k8

5. Ordnung

{3,5,7,9}

f(x)=a0x1+a1x3+a2x5a0=1a1a21.570034357a1=3×(2436304π22172825π4)8×(1303695π41827228π2+537160)0.6425216143a2=1303695π416×(1303695π41827228π2+537160)0.07248725712

10804305921303695π61827228π4+537160π20.9997773320.726377791.52 dB,7260833103310027392.6 dBkth(1(1)k)|67145k42740842k2+19555425|33763456k6.

x=±1x±1.002039940.x=10.004905799828k,

7. Ordnung

Eine Näherung 7. Ordnung ohne kontinuierliche Ableitung kann auf ähnliche Weise gefunden werden. Der Ansatz erfordert das Testen von 120 verschiedenen Lösungen und wurde am Ende dieser Antwort vom Python-Skript automatisiert. Die beste Lösung ist:

f(x)=a0x1+a1x3+a2x5+a3x7a0=1a1a2a31.5707953785726114835a1=5×(4374085272375π66856418226992π4+2139059216768π2)16×(2124555703725π63428209113496π4+1336912010480π2155807094720)0.64590724797262922190a2=2624451163425π63428209113496π416×(2124555703725π63428209113496π4+1336912010480π2155807094720)0.079473610232926783079a3=124973864925π616×(2124555703725π63428209113496π4+1336912010480π2155807094720)0.0043617408329090447344

169918012823961602124555703725π83428209113496π6+1336912010480π4155807094720π21.0000024810802368487.502400688077133.627 dB.kth(1(1)k)|162299057k6+16711400131k4428526139187k2+2624451163425|4424948250624k8.

Python-Quelle

from sympy import symbols, pi, solve, factor, binomial

numEq = 3 # Number of equations
numHarmonics = 6 # Number of harmonics to evaluate

a1, a2, a3, k = symbols("a1, a2, a3, k")
coefficients = [a1, a2, a3]
harmonicRelativeAmplitude = (2*pi**4*a1*k**4*(pi**2*k**2-12)+4*pi**2*a2*k**2*(pi**4*k**4-60*pi**2*k**2+480)+6*a3*(pi**6*k**6-140*pi**4*k**4+6720*pi**2*k**2-53760)+pi**6*k**6)*(1-(-1)**k)/(2*k**8*(2*pi**4*a1*(pi**2-12)+4*pi**2*a2*(pi**4-60*pi**2+480)+6*a3*(pi**6-140*pi**4+6720*pi**2-53760)+pi**6))

harmonicRelativeAmplitudes = []
for i in range(0, numHarmonics) :
    harmonicRelativeAmplitudes.append(harmonicRelativeAmplitude.subs(k, 3 + 2*i))

numCandidateEqs = 2**numHarmonics
numSignCombinations = 2**numEq
useHarmonics = range(numEq + 1)

bestSolution = []
bestRelativeAmplitude = 1
bestUnevaluatedRelativeAmplitude = 1
numSolutions = binomial(numHarmonics, numEq + 1)*2**numEq
solutionIndex = 0

for i in range(0, numCandidateEqs) :
    temp = i
    candidateNumHarmonics = 0
    j = 0
    while (temp) :
        if (temp & 1) :
            if candidateNumHarmonics < numEq + 1 :
                useHarmonics[candidateNumHarmonics] = j
            candidateNumHarmonics += 1
        temp >>= 1
        j += 1
    if (candidateNumHarmonics == numEq + 1) :
        for j in range(0,  numSignCombinations) :
            eqs = []
            temp = j
            for n in range(0, numEq) :
                if temp & 1 :
                    eqs.append(harmonicRelativeAmplitudes[useHarmonics[0]] - harmonicRelativeAmplitudes[useHarmonics[1+n]])
                else :
                    eqs.append(harmonicRelativeAmplitudes[useHarmonics[0]] + harmonicRelativeAmplitudes[useHarmonics[1+n]])
                temp >>= 1
            solution = solve(eqs, coefficients, manual=True)
            solutionIndex += 1
            print "Candidate solution %d of %d" % (solutionIndex, numSolutions)
            print solution
            solutionRelativeAmplitude = harmonicRelativeAmplitude
            for n in range(0, numEq) :                
                solutionRelativeAmplitude = solutionRelativeAmplitude.subs(coefficients[n], solution[0][n])
            solutionRelativeAmplitude = factor(solutionRelativeAmplitude)
            print solutionRelativeAmplitude
            solutionWorstRelativeAmplitude = 0
            for n in range(0, numHarmonics) :
                solutionEvaluatedRelativeAmplitude = abs(factor(solutionRelativeAmplitude.subs(k, 3 + 2*n)))
                if (solutionEvaluatedRelativeAmplitude > solutionWorstRelativeAmplitude) :
                    solutionWorstRelativeAmplitude = solutionEvaluatedRelativeAmplitude
            print solutionWorstRelativeAmplitude
            if (solutionWorstRelativeAmplitude < bestRelativeAmplitude) :
                bestRelativeAmplitude = solutionWorstRelativeAmplitude
                bestUnevaluatedRelativeAmplitude = solutionRelativeAmplitude                
                bestSolution = solution
                print "That is a new best solution!"
            print

print "Best Solution is:"
print bestSolution
print bestUnevaluatedRelativeAmplitude
print bestRelativeAmplitude

Dies ist eine Variation von Roberts Antwort und der Weg, den ich letztendlich eingeschlagen habe. Ich lasse es hier, falls es jemand anderem hilft.
Gast

wow, es analytisch zu lösen. Ich würde nur MATLAB und eine FFT verwenden und irgendwie nach der Antwort suchen.
das hast du sehr gut gemacht.
Robert Bristow-Johnson

2
eigentlich @OlliNiemitalo, ich denke -79 dB ist gut genug für die Implementierung eines digitalen Synthesizer-Sinusoszillators. es kann durch eine Dreieckswelle angetrieben werden, die leicht aus dem abs-Wert eines Sägezahns erzeugt wird, der am leichtesten mit einem Festpunkt-Phasenakkumulator erzeugt wird.
Niemand wird einen Unterschied zwischen dieser polynomischen Sinuswelle 5. Ordnung und einem reinen Sinus hören.
Robert Bristow-Johnson

1
fff

1
f0

5

Fragen Sie dies aus theoretischen Gründen oder für eine praktische Anwendung?

In der Regel ist die beste Antwort, wenn die Berechnung einer Funktion über einen endlichen Bereich teuer ist, eine Reihe von Nachschlagetabellen.

Ein Ansatz ist die Verwendung von Best-Fit-Parabeln:

n = Boden (x * N + .5);

d = x * N - n;

i = n + N / 2;

y = L_0 + L_1 [i] * d + L_2 [i] * d * d;

Indem Sie die Parabel an jedem Punkt finden, der die Werte für d mit -1/2, 0 und 1/2 erfüllt, anstatt die Ableitungen bei 0 zu verwenden, stellen Sie eine kontinuierliche Approximation sicher. Sie können auch den x-Wert anstelle des Array-Index verschieben, um mit Ihren negativen x-Werten umzugehen.

Ced

===============================================

Nachverfolgen:

Der Aufwand und die Ergebnisse, mit denen gute Annäherungen gefunden wurden, sind sehr beeindruckend. Ich war gespannt, wie sich meine langweilige und langweilige stückweise parabolische Lösung vergleichen ließe. Es ist nicht überraschend, dass es viel besser geht. Hier sind die Ergebnisse:

   Methode Minimum Maximum Mean RMS
  -------- -------- -------- -------- --------
     Leistung -8.48842 1.99861 -4.19436 5.27002
    OP S_3 -2.14675 0.00000 -1.20299 1.40854
     Bhask -1.34370 1.63176 -0.14367 0.97353
     Verhältnis -0,24337 0,22770 -0,00085 0,16244
     rbj 5 -0,06724 0,15519 -0,00672 0,04195
    Olli5C -0.16367 0.20212 0.01003 0.12668
     Olli5 -0,26698 0,00000 -0,15177 0,16402
    Olli7C -0.00213 0,00000 -0.00129 0,00143
     Olli7 -0.00005 0.00328 0.00149 0.00181
    Para16 -0.00921 0.00916 -0.00017 0.00467
    Para32 -0,00104 0,00104 -0,00001 0,00053
    Para64 -0.00012 0.00012 -0.00000 0.00006

π/2

xxe6

Die Linie rbj 5 entspricht der c5-Lösung von Matt L.

Die Werte 16, 32 und 64 geben die Anzahl der Intervalle mit Parabelanpassungen an. Natürlich gibt es in der ersten Ableitung an jeder Intervallgrenze unbedeutende Diskontinuitäten. Die Werte der Funktion sind jedoch stetig. Das Erhöhen der Anzahl von Intervallen erhöht nur den Speicherbedarf (und die Initialisierungszeit), nicht jedoch den für die Approximation erforderlichen Rechenaufwand, der geringer ist als bei allen anderen Gleichungen. Ich habe Zweierpotenzen gewählt, weil eine Festkommaimplementierung in solchen Fällen eine Division durch die Verwendung eines UND retten kann. Außerdem wollte ich nicht, dass die Zählung mit der Teststichprobe übereinstimmt.

Ich habe das Python-Programm von Olli Niemitalo ausgeführt und dieses als Teil des Ausdrucks erhalten: "Kandidatenlösung 176 von 120" Ich fand das seltsam, also erwähne ich es.

Wenn jemand möchte, dass ich eine der anderen Gleichungen aufnehme, lass es mich bitte in den Kommentaren wissen.

Hier ist der Code für die stückweisen parabolischen Approximationen. Das gesamte Testprogramm ist zu lang zum Posten.

# ====================================== ===========================
def FillParab (argArray, argPieceCount):

# y = ad ^ 2 + bd + c

# ym = a .25 - b .5 + c
# y = c
# yp = a.25 + b.5 + c

# c = y
# b = yp - ym
# a = (yp + ym - 2y) * 2

# ---- Nachschlagearrays berechnen

        theStep = pi * .5 / float (argPieceCount - 1)
        theHalf = theStep * .5

        theL0 = Nullen (argPieceCount)
        theL1 = Nullen (argPieceCount)
        theL2 = Nullen (argPieceCount)

        für k im Bereich (0, argPieceCount):
         x = float (k) * theStep

         ym = sin (x - theHalf)
         y = sin (x)
         yp = sin (x + theHalf)

         theL0 [k] = y
         theL1 [k] = yp - ym
         theL2 [k] = (yp + ym - 2,0 * y) * 2

# ---- Mach die Füllung

        theN = len (argArray)

        theFactor = pi * .5 / float (theN - 1)

        für i im Bereich (0, theN):
         x = float (i) * theFactor

         kx = x / theStep
         k = int (kx + .5)
         d = kx - k

         argArray [i] = theL0 [k] + (theL1 [k] + theL2 [k] * d) * d

# ====================================== ===========================

======================================

Anhang

S3


Gute Arbeit! Ich habe diesen Fehler behoben ("176 von 120").
Olli Niemitalo

xxe6ef0(x)=|x|asign(x)b=f0(1)f1(x)=f0(x)bxc=1f1(1)f2(x)=f1(x)ca223

f0(x)ax1ax+1a

a0xa1xa0x+a1x a013a1109
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.