Character Computing mit Python. Teil 1. Die Grundlagen

Bild

Bei der Lösung der Probleme der mathematischen Modellierung von Prozessen und Objekten ist es oft sehr praktisch, Python-Algorithmen mithilfe symbolischer Berechnungen zu verwenden. Basierend auf der SymPy-Bibliothek kann Python Gleichungen und Systeme erfolgreich lösen, integrieren und differenzieren, Grenzen berechnen, in Reihen erweitern und Reihen summieren, Ausdrücke vereinfachen und nach Lösungen für Differentialgleichungen und -systeme suchen.

Bei Verwendung symbolischer Berechnungen hat der Benutzer die Möglichkeit, das Programm während seiner Ausführung zu steuern, indem er gültige Funktionen mit einer bestimmten Anzahl von Variablen eingibt.

Als Lehrer der Disziplin "Computer Engineering and Programming" stelle ich den Schülern im Modul Programmieren in Python die Möglichkeiten dieser Sprache für die wissenschaftliche Forschung vor. Ihre Aufmerksamkeit gilt einer Reihe von Artikeln, in denen Sie sich mit symbolischem Computing in Python vertraut machen können. Ich möchte sofort warnen, dass diese Artikel keine absolute Einzigartigkeit beanspruchen, da sie auf der Grundlage von Materialien aus verschiedenen Quellen gesammelt werden. Ihr Ziel ist es, den Schülern die Grundlagen des symbolischen Rechnens beizubringen.

Der allererste Schritt in Richtung Symbolic Computing besteht darin, die Funktionen des SymPy-Moduls mit pip, dem Python-Paketverwaltungssystem, zu importieren. Wenn Sie damit umgehen können, fahren wir mit der Deklaration der Variablen fort.

Hinweis Um den Datensatz zu verkürzen, wird die folgende Zeile nicht in allen folgenden Beispielen angezeigt : from sympy import *

Explizite Deklaration von Zeichenvariablen


Für symbolische Berechnungen mit dem SymPy- Modul müssen symbolische Variablen und Funktionen als solche deklariert werden. In mathematischen Computerprogrammen wie Mathematica oder Maple werden Variablen sofort als symbolisch betrachtet. In Python müssen sie zwangsweise als symbolisch deklariert werden. Dies kann auf verschiedene Arten erfolgen. Am einfachsten ist es, die Funktionen symbole () oder var () zu verwenden. Die erste Funktion gibt einen Verweis auf ein Zeichenobjekt als Variable zurück. Die zweite, ohne Zuweisung, erstellt eine Zeichenvariable.

Codebeispiel
>>> x,y,a,b = symbols('xya b') #    ,      >>> f=a**3*x + 3*a**2*x**2/2 + a*x**3 + x**4/4 #  f    >>> type(f) <class 'sympy.core.add.Add'> >>> var('u,v') (u, v) >>> f=sin(u)**2+tan(v) #  f    >>> type(f) <class 'sympy.core.add.Add'> 


Der Hauptunterschied zwischen den Funktionen Symbolen () und Var () besteht darin, dass die erste Funktion einen Verweis auf das Symbolobjekt zurückgibt. Für die zukünftige Verwendung muss es einer beliebigen Variablen zugewiesen werden. Die zweite, ohne Zuweisung, erstellt eine Zeichenvariable.
In den Funktionen Symbolen () und Var () können Sie Symbolvariablen mit einem Index deklarieren:

Codebeispiel
 >>> x=symbols('x:9'); x #    0  9 (x0, x1, x2, x3, x4, x5, x6, x7, x8) >>> x=symbols('x5:10'); x #    5  9 (x5, x6, x7, x8, x9) >>> x=var('x:9'); x #    0  9 (x0, x1, x2, x3, x4, x5, x6, x7, x8) >>> x=var('x5:10'); x #    5  9 (x5, x6, x7, x8, x9) 


Sie können Symbolvariablen auch direkt in den Funktionen symbolen () und var () einen Typ zuweisen und Einschränkungen auferlegen. Manchmal funktionieren offensichtliche Transformationen ohne solche Einschränkungen nicht. Vergleichen Sie beispielsweise:

Codebeispiel
 >>> x = symbols('x', integer=True) #   >>> sqrt(x**2) Abs(x) >>> x = symbols('x', positive = True, integer=True) >>> sqrt(x**2) x >>> x = symbols('x') >>> sqrt(x**2) #  x,  x≥0 sqrt(x**2) >>> x = var('x', integer=True) >>> sqrt(x**2) Abs(x) >>> x = var('x', positive = True, integer=True) >>> sqrt(x**2) x >>> x = var('x') >>> sqrt(x**2) #  x,  x≥0 sqrt(x**2) 


Verwenden Sie das Argument seq = True, um einen Container für ein einzelnes Zeichen zu erstellen :

 >>> symbols('x',seq=True) (x,) 

Bestimmen gültiger Werte für Zeichenvariablen:

 >>> x, y, z = symbols('x,y,z', real=True) >>> x.is_real and y.is_real and z.is_real True 

Funktion s ()


Manchmal können Zeichenausdrücke eher als numerische Python-Konstanten als als SymPy interpretiert werden. Verwenden Sie daher zum Deklarieren symbolischer Variablen sowie zum Konvertieren numerischer Konstanten in symbolische Variablen die Funktion S (). Vergleichen Sie beispielsweise:

 >>> expr = x**2 + sin(y) + S(10)/2; expr x**2 + sin(y) + 5 >>> type(10) <class 'int'> >>> type(S(10)) #    <class 'sympy.core.numbers.Integer'> 

Der Unterschied zwischen einer Python-Konstante und einer Zeichenkonstante besteht darin, dass eine Zeichenkonstante mit einem bestimmten Genauigkeitsgrad berechnet werden kann, wie im folgenden Beispiel gezeigt, verglichen mit der Standardfunktion round () :

 z=1/7; z #   z    0.14285714285714285 z1=S(1)/7; z1 1/7 z2=z1.n(30); z2 #   z2    30   0.142857142857142857142857142857 z3=round(z1,30); z3 0.14285714285714285 

Charakternamen


Wenn Sie in der aktuellen Sitzung ständig symbolische Mathematik verwenden müssen, können Sie allgemeine symbolische Namen aus dem Modul sympy.abc importieren :

Codebeispiel
 >>> import sympy.abc >>> dir(sympy.abc) ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_clash', '_clash1', '_clash2', 'a', 'alpha', 'b', 'beta', 'c', 'chi', 'd', 'delta', 'division', 'e', 'epsilon', 'eta', 'exec_', 'f', 'g', 'gamma', 'greeks', 'h', 'i', 'iota', 'j', 'k', 'kappa', 'l', 'lamda', 'm', 'mu', 'n', 'nu', 'o', 'omega', 'omicron', 'p', 'phi', 'pi', 'print_function', 'psi', 'q', 'r', 'rho', 's', 'sigma', 'string', 'symbols', 't', 'tau', 'theta', 'u', 'upsilon', 'v', 'w', 'x', 'xi', 'y', 'z', 'zeta'] 


Der Variablenname kann mit dem Befehl del name1, name2, .. aus dem Namespace entfernt werden:

 >>> type(x) <class 'sympy.core.symbol.Symbol'> >>> del x,y >>> x NameError: name 'x' is not defined 

Um die Werte der Standardkonstanten sowie die Namen einiger Funktionen wiederherzustellen, müssen Sie das Sympy-Modul neu laden.

 >>> from sympy import * 

Methode subs (...)


Es ist zu beachten, dass beim Schreiben eines symbolischen Ausdrucks dessen Vereinfachung automatisch durchgeführt werden kann, zum Beispiel:

 >>> a,b,c,d,x,y,z,u,v,w = symbols('abcdxyzuv w') >>> x - z + 20 -z- 15 + 3*sin(pi/2)+2*z x + 8 

Die subs (...) -Methode wird verwendet, um einen Zeichenausdruck für bestimmte Werte von Variablen zu berechnen, zum Beispiel:

 >>> a, x = symbols('a x') >>> f= a**3*x + 3*a**2*x**2/2 + a*x**3 + x**4/4 >>> f.subs(a,1) #   f   a    x**4/4 + x**3 + 3*x**2/2 + x 

Wenn zwei Argumente in der subs-Methode verwendet werden, werden sie als subs (alt, neu) interpretiert, d.h. Der alte Bezeichner alt wird durch den neuen neuen ersetzt. Das Argument für die subs () -Methode kann eine Sequenz sein, die Paare (alt, neu) enthalten muss, oder es kann ein symbolischer Ausdruck sein, zum Beispiel:

 >>> a,b,c,d,x,y,z = symbols('abcdxy z') >>> f=a*x**3 +b*y**2 + c*z+d >>> f.subs([(a,1),(b,2),(c,3),(d,4)]) #   a=1, b=2, c=3, d=4 x**3 + 2*y**2 + 3*z + 4 >>> pr= x**3+4*x**2+6*x+10 >>> pr.subs(x,1/x) #     10 + 6/x + 4/x**2 + x**(-3) 

Lassen Sie uns Ihre Aufmerksamkeit auf die folgende Besonderheit der Arbeit mit Variablen (symbolische und gewöhnliche Variablen von Python) lenken. Führen Sie den folgenden Code aus:

 >>> x='Hello' >>> pr=x+'world' >>> pr 'Helloworld' >>> x='AAA' #   x   >>> pr 'Helloworld' 

Hier gilt die Regel: Wenn sich die Variable geändert hat, wird der zuvor erstellte Ausdruck, der diese Variable enthält, nicht automatisch neu berechnet. Diese Regel funktioniert auch für reguläre Python-Variablen.

Fraktionsoperationen


Das SymPy-Modul kann Berechnungen mit Brüchen durchführen und diese auf einen gemeinsamen Nenner bringen. Vergleichen Sie beispielsweise:

 >>> S(1)/3+S(2)/5 11/15 >>> 1/3+2/5 0.7333333333333334 

Mit den Funktionen Rational (Zähler, Nenner) und Integer (...) werden rationale Brüche ohne Dezimalrundung erstellt:

 >>> z=Rational(1, 7)+Rational(2, 5); z 19/35 >>> Integer(1)/Integer(5) 1/5 >>> 1/5 0.2 >>> z=Integer(1)/Integer(5)+Rational(2, 7); z 17/35 

Rundungsberechnung


Beim symbolischen Rechnen funktioniert die Regel - wenn nichts gesagt wird, nicht abrunden. Sehen Sie, wie Python im ersten Fall den Ausdruck transformiert, aber die Quadratwurzel im Antwortdatensatz belässt und keine Rundung durchführt. Im zweiten Fall ist das Ergebnis ungefähr, da eine der Zahlen mit einem Dezimalpunkt angegeben wird:

 >>> sqrt(20) 2*sqrt(5) >>> sqrt(20.0) #        4.47213595499958 

Für jedes Zeichenobjekt gibt es eine evalf (...) ( eval uate f loat) -Methode, die ihre Dezimaldarstellung zurückgibt:

 >>> sqrt(20).evalf() #  sqrt()  sympy 4.47213595499958 >>> E.evalf() 2.71828182845905 

Die Methode evalf ([n, ...]) kann ein Argument verwenden, das die Genauigkeit des Ergebnisses angibt (n = Anzahl der signifikanten Stellen).

 >>> sqrt(20).evalf(30) 4.47213595499957939281834733746 >>> pi.evalf(20) 3.1415926535897932385 

Sie müssen sich auch immer daran erinnern, dass echte Arithmetik kein genaues Ergebnis liefert. Vergleichen Sie:

 >>> from sympy import * >>> one=S('one') >>> one = cos(1)**2 + sin(1)**2 >>> one.evalf() #  1 1.00000000000000 >>> (one-1).evalf() #    0 -0.e-124 

Wenn bekannt ist, dass das Ergebnis einen Berechnungsfehler enthält, können Sie ihn mit der Option chop = True der Methode evalf () löschen. In diesem Fall wird ein sehr kleiner Wert des Real- oder Imaginärteils des Ergebnisses durch Null ersetzt. Nehmen Sie das vorherige Beispiel:

 >>> (one-1).evalf() #    0 -0.e-124 >>> (one - 1).evalf(chop=True) 0 

Unendlichkeit


Nach dem Ausführen der ersten Zeile aus dem Sympy-Import * wird das Unendlichkeitssymbol oo (zwei Buchstaben „o“) verfügbar, mit dem Sie auch bestimmte Operationen ausführen können:

 >>> oo+1 oo >>> 1000000<oo True >>> 1/oo 0 

Das Unendlichkeitssymbol wird hauptsächlich von den Funktionen limit () und integrate () verwendet, wenn Integrationslimits festgelegt werden, die in einem der folgenden Artikel behandelt werden.

Fazit


Die im Artikel berücksichtigten symbolischen Berechnungen unterscheiden sich von numerischen Methoden darin, dass die Ergebnisse weiter untersucht werden können, um beispielsweise die Extrema von Funktionen zu bestimmen, Gleichungen mit eingebetteten Variablen zu lösen usw.

Ich hoffe, mein Artikel ist für alle nützlich, die sich für Python-Programmierung interessieren, für Studenten und für diejenigen, die an wissenschaftlicher Forschung beteiligt sind.

Source: https://habr.com/ru/post/de423731/


All Articles