3.3. Symboliska matematikprogram Vi skall nu övergå till att behandla de vanligaste matematikprogrammen, och börja med de symboliska. Av dessa kan både Mathematica och Maple användas på flere UNIX-datorer. HU har en campuslicens för Maple, så att detta program kan användas både på Unix-systemen och mikronätet. Av dessa program är Mathematica mer känt, antagligen på grund av det funnits längre tid. Det är utvecklat ur ett äldre program, SMP, av Stephen Wolfram, en expert på cellautomater. Den som vill veta mer om bakgrunden hänvisas till en artikel av Stephen Wolfram i Scientific American september 1984. Chalmers har en kortfattad handledning: http://www.math.chalmers.se/math/grundutb/cth/tma045/9900/handledning_mathematica.pdf Textversionen av Mathematica startas vanligen genom att skriva math. Med en X-windows emulator (t.ex. WinaXe) kan man använda den grafiska versionen mathematica på heavy. Man kan bekanta sig med programmet genom att använda det som en kalkylator: klaava% math Mathematica 2.2 for Solaris Copyright 1988-93 Wolfram Research, Inc. -- Open Look graphics initialized -- Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 1
In[1]:= 2*3+4 Out[1]= 10 (obs: input avslutas av Shift-Enter). Multiplikationstecknet i formeln ovan är dock inte nödvändigt: In[2]:= 2 3 4 Out[2]= 24 Mathematica räknar vanligen ut exakta resultat, men numeriska approximationer får man med kommandot N: In[3]:= 2/2^2 1 Out[3]=- 2 In[4]:= N[%] Out[4]= 0.5 Numeriska räkningar kan utföras med nästan vilken precision som helst. Snabbt räknar man ut t.ex. π = 4 arctan(1) med hundra decimaler: In[5]:= N[4 ArcTan[1], 100] Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 2
Out[5]= 3.1415926535897932384626433832795028841971693993751058209749445923078\ > 16406286208998628034825342117068 (Mathematica känner givetvis också till konstanten Pi). Något som är värt att minnas, när man använder Mathematica, är att programmet skiljer mellan små och stora bokstäver, så det gäller att vara noggrann. Också komplexa tal kan behandlas utan svårighet. In[6]:= (1+2I)^2 Out[6]= -3 + 4 I Även komplicerade algebraiska uttryck kan lätt utvecklas med Mathematica: In[11]:= Expand [(1 + 2x + 3y + 4x^2 + 5y^2)^3] 2 3 4 5 6 Out[11]= 1 + 6 x + 24 x + 56 x + 96 x + 96 x + 64 x + 9 y + 36 x y + 2 3 4 2 2 2 2 > 108 x y + 144 x y + 144 x y + 42 y + 114 x y + 288 x y + 3 2 4 2 3 3 2 3 4 > 240 x y + 240 x y + 117 y + 180 x y + 360 x y + 210 y + 4 2 4 5 6 > 150 x y + 300 x y + 225 y + 125 y Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 3
Mathematica känner till alla de viktigaste specialfunktionerna, såsom Bessels funktioner. Såhär räknar man ut t.ex. J 0 (5.52): In[7]:= BesselJ[0,5.52] Out[7]= -0.0000265784 Detta funktionsvärde är mycket nära 0. Nollställen kan man bestämma noggrannare med FindRoot: In[8]:= FindRoot[BesselJ[0,x], {x, 5.5}] Out[8]= {x -> 5.52008} Obestämda integraler kan man beräkna med Integrate. Som ett exempel beräknar vi integralen Z 1 + x 2 1 + x 3dx: In[7]:= Integrate[(1+x^2)/(1+x^3),x] -1 + 2 x ArcTan[--------] 2 3 Sqrt[3] Log[1 + x] Log[1 - x + x ] Log[1 + x ] Out[7]= ---------------- + ---------- - --------------- + ----------- Sqrt[3] 3 6 3 Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 4
Bestämda integraler kan man beräkna numeriskt med NIntegrate. Här är ett exempel som visar hur man kan beräkna Eulers konstant (1755) nx! Z 1 γ = lim n k ln k = e x ln xdx k=1 In[9]:= NIntegrate[-Exp[-x] Log[x], {x, 0, Infinity}] Out[9]= 0.577216 Eulers konstant har också en särskild symbol, EulerGamma In[10]:= N[EulerGamma, 10] Out[10]= 0.5772156649 Mathematica kan också användas för att lösa ekvationer. Här ser vi lösningen till x 3 7x 2 + 3ax = 0: 0 In[11]:= Solve[x^3-7 x^2 + 3 a x == 0, x] 7 - Sqrt[49-12 a] 7 + Sqrt[49-12 a] Out[11]= {{x -> 0}, {x -> -------------------}, {x -> -------------------}} 2 2 Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 5
Som vi vet, kan man inte ange lösningen till ekvationer av högre gradtal än 4 i sluten form. En femtegradsekvation, såsom x 5 + 2x + 1 = 0, kan därför inte lösas exakt: In[12]:= Solve[x^5 + 2 x + 1 == 0, x] 5 Out[12]= {ToRules[Roots[2 x + x == -1, x]]} men nog numeriskt: In[13]:= N[%] Out[13]= {{x -> -0.701874-0.879697 I}, {x -> -0.701874 + 0.879697 I}, > {x -> -0.486389}, {x -> 0.945068-0.854518 I}, > {x -> 0.945068 + 0.854518 I}} Det är också möjligt att använda kommandot FindRoot för att bestämma någon av rötterna numeriskt: In[14]:= FindRoot[2 x + x^5 == -1, {x, -0.5}] Out[14]= {x -> -0.486389} Med Mathematica kan man också behandla matriser. Här visas ett exempel på hur man kan konstruera en matris: In[1]:= A = {{27,6,0}, {6,15,1}, {0,1,54}} Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 6
Out[1]= {{27, 6, 0}, {6, 15, 1}, {0, 1, 54}} Denna matris kan man också skriva i den normala formen genom att man använder kommandot MatrixForm: In[2]:= MatrixForm[A] Out[2]//MatrixForm= 27 6 0 6 15 1 0 1 54 Ett ekvationssystem med tre obekanta x, y, z och A som koefficientmatris kan uttryckas In[6]:= A.{x,y,z} == {88,70,107} Out[6]= {27 x + 6 y, 6 x + 15 y + z, y + 54 z} == {88, 70, 107} Lösningen finner man på vanligt sätt med Solve: In[7]:= Solve[%, {x,y,z}] 49154 12707 2617 Out[7]= {{x -> -----, z -> -----, y -> ----}} 19899 6633 737 Eftersom koefficientmatrisens determinant är olika 0, Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 7
In[4]:= Det[A] Out[4]= 19899 så kan man också finna samma lösning med hjälp av matrisens invers: In[9]:= Inverse[A].{88,70,107} 49154 2617 12707 Out[9]= {-----, ----, -----} 19899 737 6633 Också differentialekvationer kan lösas med Mathematica. Här har vi lösningen till y (x) ky(x) = 1: In[15]:= DSolve[y [x] - k y[x] == 1, y[x], x] 1 C[1] Sqrt[k] x Out[15]= {{y[x] -> -(-) + ---------- + E C[2]}} k Sqrt[k] x E Mathematica kan också användas för grafisk framställning i två och tre dimensioner, förutsatt att man har tillgång till en grafisk terminal (X-Windows eller en emulator). Som ett exempel på tvådimensionell grafik skall vi visa grafen av funktionen e sin x inom intervallet [0, 4]: Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 8
In[1]:= Plot[Exp[Sin[x]],{x,0,4}] Out[1]= -Graphics- Om man använder en X-terminal, och vill sända grafiken till en fil, skriver man kommandot Display["plotout",%], där plotout är namnet på en fil. Denna fil kan inte direkt skickas till en postskriptskrivare,utan måste först konverteras med programmet psfix Man kan också framställa kurvor i parametrisk form. Lissajous figuren ( x(t) = cos 3t y(t) = sin 2t kan t.ex. ritas på följande sätt: Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 9
In[1]:= ParametricPlot[{Cos[3t],Sin[2t]},{t,0,2Pi}] Out[1]:= -Graphics- Lika lätt kan man också upprita en tredimensionell yta. Som ett exempel skall vi visa sin xy för 0 x 3 och 0 y 3: In[2]:= Plot3D[Sin[x y], {x, 0, 3}, {y, 0, 3}] Out[2]= -SurfaceGraphics- Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 10
Mathematica kan också användas för kurvanpassning. Som ett exempel skall vi se hur man kan anpassa ett polynom till några punkter i xy planet. Vi skall börja med att generera en tabell över de 20 första primtalen, som beskrivs grafiskt som en funktion av ordningsnumret (grafen visas ej): In[15]:= fp = Table[Prime[x], {x,20}] Out[15]= {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, > 67, 71} In[21]:= gp = ListPlot[fp] Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 11
Out[21]= -Graphics- Därpå anpassar vi en rät linje till de givna punkterna In[16]:= fplin = Fit[fp, {1,x}, x] Out[16]= -7.67368 + 3.77368 x och ritar in linjen i punktdiagrammet (kommandot Show används då man vill rita flera kurvor i samma diagram): In[23]:= Show[Plot[fplin, {x,0,20}], gp, Prolog -> AbsolutePointSize[5]] Out[23]= -Graphics- Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 12
Som vi ser, är anpassningen inte särskilt bra. Vi kan förbättra den genom att istället för en rät linje anpassa ett polynom av andra graden (kvadratisk anpassning): In[24]:= fpkvad = Fit[fp, {1,x, x^2}, x] 2 Out[24]= -1.92368 + 2.2055 x + 0.0746753 x Resultatet är betydligt bättre: In[25]:= Show[Plot[fpkvad, {x,0,20}], gp, Prolog -> AbsolutePointSize[5]] Out[25]= -Graphics- För att gå ut ur programmet, använder man kommandot Quit (eller Ctrl-D): In[16]:= Quit Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 13
I fysiken har man ofta data, som har ett exponentiellt förlopp (t.ex. radioaktivt sönderfall). Om man t.ex. vet, att mätpunkterna avtar exponentiellt med tiden: y = ce bt = e a+bt, b < 0, så kan man linearisera denna ekvation genom att logaritmera vartdera membrum: ln y = a + bt, och bestämma koefficienterna a och b såsom ovan. En sådan beräkning kan utföras med Mathematica på följande sätt: In[2]:= y={4.1,1.9,0.9,0.43,0.2,0.096,0.045,0.0215,0.01,0.0048,0.0023} Out[2]= {4.1, 1.9, 0.9, 0.43, 0.2, 0.096, 0.045, 0.0215, 0.01, 0.0048, 0.0023} In[6]:= Exp[Fit[Log[y],{1,x},x]] 2.14474-0.748506 x Out[6]= E Kurvan jämte mätpunktunkterna kan ritas med kommandot Show[Plot[Exp[2.14474-0.748506x],{x,0,10}],ListPlot[y],Prolog->AbsolutePointSize[5]] som ger resultatet Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 14
Maple påminner mycket om Mathematica, och startas med maple (den grafiska versionen startas med xmaple eller maple -cw). Här är en kort introduktion från Linköping: http://www.mai.liu.se/~kuhan/kurser/nmac08/maple.pdf. Kommandona i Maple skrivs efter prompten >, och måste alltid efterföljas av ett semikolon (;). Om man vill ha information om något kommando, t.ex. expand, så skriver man bara?expand (allmän hjälp ges av?). Programmet försöker i första hand alltid räkna exakt: > sin(pi/3); 1/2 1/2 3 men liksom Mathematica, kan det också beräkna en numerisk approximation: > evalf(%);.8660254040 Om man vill ha ett noggrannare resultat, kan man öka antalet siffror i svaret: > Digits := 30: > evalf( sin(pi/3) );.866025403784438646763723170755 Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 15
Ett uttryck av formen > (x+y)*(x-y)-x^2; 2 (x + y) (x - y) - x kan som synes förenklas: > expand(%); 2 - y Här är ett mer komplicerat uttryck i förenklad form: > simplify(exp(a+ln(b*exp(c)))); b exp(a + c) Såhär upplöser man ett algebraiskt uttryck i faktorer: Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 16
> x^24+x^12+1; > factor(%); 24 12 x + x + 1 6 3 6 3 12 6 (x - x + 1) (x + x + 1) (x - x + 1) Man kan också lätt lösa ekvationssystem med Maple: > solve( {2*x+3*y = 1, 5*x+7*y = 2}, {x,y} ); {y = 1, x = -1} Man kan också tillordna de angivna värdena till x och y på följande sätt: > s := solve( {2*x+3*y=1, 5*x+7*y=2}, {x,y}); s := {y = 1, x = -1} > assign(s); > x; y; -1 1 Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 17
Rötterna till en ekvation kan räknas med kommandot solve på motsvarande sätt som i Mathematica: > solve( x^3-6*x = 5, x); 1/2 1/2-1, 1/2 + 1/2 21, 1/2-1/2 21 Integraler räknar programmet lätt > int(sqrt(1-x^2),x); 2 1/2 1/2 x (1 - x ) + 1/2 arcsin(x) och likaså derivator: > diff(arcsin(a*x),x); a -------------- 2 2 1/2 (1 - a x ) Det lönar sig att definiera mera komplicerade funktioner med hjälp av en symbol: Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 18
> f:=cos(x)^3+sin(3*x)^3-(x^2-x+1)^(1/2)+5; 3 3 2 1/2 f := cos(x) + sin(3 x) - (x - x + 1) + 5 Derivatan av denna funktion kan då räknas ut på följande sätt > diff(f,x); 2 2 2 x - 1-3 cos(x) sin(x) + 9 sin(3 x) cos(3 x) - ----------------- 2 1/2 2 (x - x + 1) och dess integral finner man också lätt > integrate(f,x); 2 2 1/3 cos(x) sin(x) + 2/3 sin(x) - 1/9 sin(3 x) cos(3 x) - 2/9 cos(3 x) 2 1/2 1/2 (2 x - 1) (x - x + 1) 2 3 (x - 1/2) - ------------------------- - 3/8 arcsinh(----------------) + 5 x 4 3 Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 19
(integrate är synonymt med int) Maple känner, liksom Mathematica till de flesta speciella funktioner som används i fysiken. Den tidigare omnämnda Bessel-funktionen kan sålunda också beräknas med Maple: > BesselJ(0,5.52); -.0000265783694799362399025883902395 Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009 20