Velkommen til Sympy!#

Denne side giver en kort genopfriskning af brugen af Sympy. Hvis du allerede kender Sympy godt, kan du springe denne side over og fortsætte til demoen tilhørende første semesteruge. Hvis du derimod kunne tænke dig en mere detaljeret og i dybdegående gennemgang af Sympy, refererer vi til denne demo fra Matematik 1a-kurset.

Sympy er et Python-bibliotek, der kan hjælpe dig med beregninger og matematisk arbejde i løbet af dit semester med Matematik 1b.

Sympy er en forkortelse for “Symbolic Python”. I Python hentes pakken sympy, som lader Python arbejde med symbolske variable og løse symbolske ligninger. Når nødvendigt vil vi også introducere andre pakker. Det følgende er ikke tænkt som en guide i grundlæggende Python-programmering, men vi kommer til at berøre de fleste værktøjer til løsning og visualisering af matematiske problemstillinger og udfordringer, både i teoretisk og anvendt brug.

Sympy importeres og forberedes ved følgende kodelinjer - vi starter med denne preambel i alle vores Sympy-demoer:

from sympy import *         # Importerer hele Sympy-pakken
from dtumathtools import *  # Importerer dtumathtools-pakken til plots
init_printing()             # Initialiserer pæn Latex-output

Symbolske og numeriske variable#

Python (uden Sympy) udfører beregninger numerisk. Det betyder, at alle tal og variable skal repræsenteres af et endeligt antal 0’er og 1’er. Studiet af numerisk matematik inde i computere overlader vi til andre kurser, men det er relevant at være klar over visse uventede situationer, der kan opstå heraf.

Vi er for eksempel alle enige om, at

(2)#\[\begin{equation} 0.3-(0.2+0.1) = 0. \end{equation}\]

Men Python er ikke altid enig i dette:

0.3-(0.2+0.1)
../_images/74d2ea4ae6251692e6558a2b6961e4939990fbedbf8c8899631926cf6a2dd1a8.png

Outputtet er ikke nøjagtigt \(0.0\), og hvis vi spørger, om udtrykket er identisk med \(0.0\), får vi

0 == 0.3-(0.2+0.1)
False

Så vi skal være varsomme i forbindelse med bl.a. logiske sammenligninger, når decimaltal er involveret.

Mange sådanne problemer kan undgås ved at lade Sympy håndtere matematikken! Benyt S(tal) på enten tæller eller nævner, eller benyt Rational(tæller, nævner), og pludselig håndteres matematikken ordentligt af Sympy:

Rational(3,10)-(S(2)/10 + 1/S(10))
../_images/651416cddb7ade65e68d31c70e7a3dbe2ef01977dfec97a06aaaa159fde31487.png
Rational(3,10)-(S(2)/10 + S(1)/10) == 0
True

Det er også relevant at kunne løse ligninger så som

(3)#\[\begin{equation} 3\,x^2-x = 0. \end{equation}\]

Ligninger som denne kan løses ved brug af symbolske variable med Sympy. En Python-variabel kan gøres symbolsk med en af kommandoerne Symbol() eller symbols(). Variabler kan defineres med antagelser ved tilføjelse af et passende argument til disse kommandoer så som \(x\in \mathbb{Z}\) med integer=True, \(x\in \mathbb{C}\) med complex=True (bruges som standard) og \(x\in \mathbb{R}\) med complex=False eller real=True. Et par eksempler:

x = symbols('x', complex=True)
3*x**2-x
../_images/8ed8e04512f0a645115fbb1503c164b2752c27e179ee60f7f281c667e16f109d.png
l, p, t = symbols('lambda, phi, theta', real=True)
t**2 + sin(l)/tan(p)
../_images/5acd1bbaff14f350a581803194fdcbbbdadf21f40f9758d5845cea09f06bb06c.png
x_liste = symbols('x0:3')
x_liste
../_images/81fcdb11b5ae9d7b67431130f7fe1fcb21f311b500fe0be8500c8faacae40221.png

Med symbolske udtryk kan vi løse ligninger med kommandoen solve() eller (bedre) solveset():

solveset(3*x**2-x)
../_images/676bb1d1edd9ea0f8c40a8f80cc9d3b01eac360ca7e2b9994bc586d9539ad3a7.png

Bemærk, at \(3x^2 - x\) er et udtryk og ikke en ligning, der kan “løses”. Når solve eller solveset kaldes med kun et udtryk og ikke andet, så tilføjer Python som standard en nul-højreside, hvilket betyder, at vi herover faktisk løser ligningen \(3x^2-x=0\). Har din ligning en højreside, der ikke er nul, bør man først oprette ligningen med Eq(venstreside,højreside):

min_ligning = Eq(3*x**2-x, p+27)
min_ligning
../_images/8f7809cfe0192cdcb0a94f6e0d6634b083865a4105c71d7081777d15165f5f8d.png

Da ligningen indeholder adskillige ubekendte (symboler), skal man angive, hvilken variabel Python skal løse ligningen for:

solveset(min_ligning, x)
../_images/57ff0bc256d2dcba34b7294da992016eebcbaf448b021d6633d88905c2f4f3a9.png

Funktioner og plots#

Sympy har også et stort bibliotek til funktioner og plots. Her vises kort et par eksempler på plots.

plot(x**2-x+3)
../_images/d0412bbef0bc40cfab1720f8aeb9e0b74b1bd168e5e0575cfed4858f554352fb.png
<sympy.plotting.backends.matplotlibbackend.matplotlib.MatplotlibBackend at 0x7f94d914fb10>

Dine plots kan tilpasses i stor stil:

p = plot(x+3,-x**2+3,x**2+3*x+3, (x,-2,2), show=False)
p[0].line_color = 'red'
p[1].line_color = 'green'
p[2].line_color = 'blue'
p.xlabel = "x-aksen"
p.ylabel = "y-aksen"
p.title = "Et meget flot plot"
p[0].label = '$f_0(x)=x+3$'
p[1].label = '$f_1(x)=-x^2+3$'
p[2].label = '$f_2(x)=x^2+3x+3$'
p.legend = True
p.ylim = (0,8)
p.show()
../_images/18f8f9fc6bbd4f70a5ef6c8c4bc988a2aabbc70c7efe10a44f9725ae1e4885fe.png

Plots behandles i flere detaljer i senere demoer.

Ekstra Hints#

I det følgende deler vi nogle hints, der vil gøre din brug af Sympy og Jupyter Notebooks nemmere og bedre.

Markdown og Code#

Som allerede vist kan man i Jupyter Notebooks skrive i to forskellige modes: Markdown og Code. Når en Code-celle er i fokus, arbejder man i Python. Man kan indsætte så mange linjer i cellen, som man vil - den sidste linje i en celle bliver printet/vist.

y = Symbol('y', complex=True)
sqrt(y**2+2)
../_images/75ea39bb0a2972fb4bdae514470450bdffbe125671583da48c6ff05a813fb9da.png

Skriv adskillige ting komma-seperaret i den sidste linje i en celle, og de udskrives/vises alle:

udtryk = sqrt(y**2+2)
udtryk, udtryk.subs({y:2/3}) <= 1.6
../_images/bd9eeb583d38121ed4a9017da4ed67d4c41187957dc8d72f922b256712c52c19.png

En celle eksekveres (køres) ved tastaturgenvejene Ctrl+Enter eller Shift+Enter (sidstnævnte flytter fokus videre til næste celle efter kørsel).

Glem ikke, at alle code-celler, der køres, “huskes” uanset deres rækkefølge i dokumentet. Det betyder, at man risikerer utilsigtede outputs, hvis man pludselig eksekverer tidligere celler. For eksempel:

y ** 2
../_images/c5770923046af9b8d73f48bb4aa11231145f66608a27ff866fda0969a2dadf1f.png
# Når du har kørt denne celle, så prøv at køre forrige celle igen
y = 2

Python-kommandoer virker ikke korrekt og kan give fejl, hvis de benyttes forkert (fx med forkerte argumenter eller syntaksfejl), og ofte også når der ikke er nogen løsning til det, du forsøger at gøre. (Nogle gange er en fejlmelding fra Python dog netop, hvad du ønsker at se.) Hvis et symbol fx ikke kan transponeres, vil en fejl blive vist, hvis du forsøger:

y = Symbol('y')
y.Transpose()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[18], line 2
      1 y = Symbol('y')
----> 2 y.Transpose()

AttributeError: 'Symbol' object has no attribute 'Transpose'

Vi kan “opfange” og håndtere denne fejl bedre med en try/except-struktur:

try:
    y.Transpose()
except:
    print("Symboler kan ikke transponeres!")

Man kan evt. benytte dette til at undgå problemer med fx script-filer, hvori ingen kode kan køres pga. en tidlig kodefejl.

Behjælpelige tips og tricks#

Genstart: Hvis du vil have Python til at glemme alle gemte variabler, så som når y har fået værdien 2, kan du genstarte Python-kernen (led efter noget à la “main Notebook Editor toolbar” i VS Code lige over editorvinduet). “Clear Outputs” i VS Code skjuler alle outputs uden at rydde hukommelsen.

Tastaturgenveje: En essentiel tastaturgenvej, når man bruger VS Code, er Ctrl+Shift+P (på Mac: ⇧⌘P). Den åbner søgefunktionen, der kan fremsøge kommandoer. Tast blot, hvad du har brug for, når du fx vil oprette en ny celle, eksekvere hele dokumentet eller oprette en ny fil. Du kan endda nemt oprette egne tilpassede tastaturgenveje til det, det bruger ofte.

Tastaturgenveje, som har været særligt brugbare i udarbejdelsen af disse demoer, er:

  • Opret nye celler (søg simpelthen efter insert cell below)

  • Skift celle-type fra Code til Markdown (change cell to code og change cell to markdown)

  • Genstart notebook og kør alle celler fra toppen af (restart the kernel, then re-run the whole notebook)

Latex: I disse demoer viser vi eksempler, der benytter pæn formattering af matematisk indhold i og mellem tekstlinjer. Dette gøres med LaTeX-kode, en markdown-syntaks vi i høj grad anbefaler, at du lærer til dine videnskabelige rapporter, afleveringer og projekter. Matematik kan skrives inline, dvs. på samme linje som teksten, ved at latex-koden startes og sluttes med Dollar-tegn, $...$. Benyttes to Dollar-tegn $$...$$ opnås en centreret og større version af fx en ligning på sin egen linje - dette opnås også ved i stedet for Dollar-tegn at oprette et egentligt ligningsmiljø med \begin{equation}...\end{equation}.

Funktioner: Du bør sørge for at have godt styr på arbejde med Python-funktioner. Hvis du løser en opgave ved en række kode-trin, og samme type opgave forekommer flere gange, kan det være en stor fordel at tænke som en programmør og oprette egentlige Python-funktioner til formålet. Vi viser eksempler på dette af og til i løbet af demoerne når relevant. Hvis der ikke findes nogen indbygget Python-funktion, der kan udføre noget, du skal have gjort, så lav bare din egen!