Seite 1 von 1

Vektorisieren der Taylorentwicklung

Verfasst: Dienstag 3. Mai 2022, 14:04
von mm96
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

Re: Vektorisieren der Taylorentwicklung

Verfasst: Dienstag 3. Mai 2022, 14:19
von Sirius3
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()

Re: Vektorisieren der Taylorentwicklung

Verfasst: Dienstag 3. Mai 2022, 14:51
von mm96
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!