Vektorisieren der Taylorentwicklung

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
mm96
User
Beiträge: 30
Registriert: Donnerstag 26. November 2020, 23:24

Hallo zusammen,

ich habe einen kleinen Schnipsel für die Taylorreihe des Sinus:

Code: Alles auswählen

def S(x, n):
    j = np.reshape(np.arange(n + 1), (-1, 1))
    Series = (-1)**j*x**(2*j + 1)/factorial(2*j + 1)
    return np.sum(Series, axis=0)
    
def main():
    x = np.array([0, np.pi/4, np.pi/2, np.pi])
    n = 10
    test = abs(S(x, n) - np.sin(x)) < 1e-3
    print(test.all())

import numpy as np
from scipy.special import factorial

if __name__ == '__main__':
    main()
Kann man den jetzt noch so modifizieren, dass man verschiedene Ordnungen n als Array übergeben kann und ein Array aus den momentan zurückgegebenen Arrays erhält?

Meine Versuche endeten dabei, z. B. für

Code: Alles auswählen

n = np.array([1, 2])
ein Array mit Subarrays verschiedener Länge (als Laufindizes der Summe) zu erstellen:

Code: Alles auswählen

j = [[[0], [1]], [[0], [1], [2]]]
(bzw. das hab ich nicht mehr hingekriegt...)

Viele Grüße
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Importe stehen am Anfang der Datei, nicht am Ende.
Variablennamen werden nach Konvention komplett klein geschrieben. Funktionsnamen werden auch klein geschrieben, und sollten aussagekräftig sein.
Wenn Du die Tayor-Serie bis zur Ordnung n berechnest, dann hast Du ja auch automatisch alle niedrigeren Ordnungen berechnet.
Also, wenn Du die Werte alle ausrechnen willst, mußt Du nur sum durch cumsum ersetzen:

Code: Alles auswählen

import numpy as np
from scipy.special import factorial

def sin_taylor(x, n):
    j = np.arange(n + 1).reshape(-1, 1)
    terms = (-1)**j * x**(2*j + 1) / factorial(2*j + 1)
    return np.cumsum(terms, axis=0)
    
def main():
    x = np.linspace(0, 5, 10000)
    max_error = abs(sin_taylor(x, 10) - np.sin(x)).max(axis=1)
    print(max_error)

if __name__ == '__main__':
    main()
mm96
User
Beiträge: 30
Registriert: Donnerstag 26. November 2020, 23:24

Vielen Dank für die Verbesserungen!
Die schon berechneten Werte hätte ich nie auf die anderen n-Werte bezogen, das ist der Hammer :D.

Tatsächlich brauch ich gar nicht alle, aber ich denk das lässt sich einfach über eine Indizierung von cumsum lösen:

Code: Alles auswählen

def sin_taylor(x, n):
    nmax = np.max(n)
    j = np.reshape(np.arange(nmax + 1), (-1, 1))
    terms = (-1)**j*x**(2*j + 1)/factorial(2*j + 1)
    return np.cumsum(terms, axis = 0)[n]
    
sin_approx = sin_taylor(x, array([1,4,10]))
Danke nochmal!
Antworten