Introduktion till MATHEMATICA

(Avsedd att kunna läsas hemma utan tillgång till dator och utan att ha kört programmet.
Du lär dig inte alla detaljer på en gång,  men kommer att "ha ett och annat i bakhuvudet" senare.
En viss slagsida mot programmeringsaspekter möjligen,  men så är de också viktiga när det gäller Mathematica.)

Mathematica är ett mycket ambitiöst program. Det är konstruerat att klara av såväl
	1) numeriska beräkningar,
	2) symboliska beräkningar ("bokstavsräkning"),
	3) grafik (visualisering),
	4) dokumentproduktion (ordbehandling), som
	5) att utvidgas av användaren själv genom programmering
Tanken är att forskaren/ingenjören skall göra allt – beräkningar och rapportskrivning – med ett och samma program: resultatvärdena stoppas in direkt i de diagramritande rutinerna, etc. 
Denna bredd har sina nackdelar – det är inte realistiskt att vara bäst på allt och programmet blir med nödvändighet komplicerat, när det skall kunna ta hand om så många olika uppgifter.

HHs studentavtal för Mathematica, fungerar så att, när man installerat programmet på sin dator, genereras en kod som man får skicka till Wolfram Research (företaget som konstruerat Mathematica), för att få ett lösenord, med vilket man kan köra ett år framåt. Nya lösenord får man sedan så länge HH fortsätter att betala licensen.

Mathematica-material på www2.hh.se/staff/getc

Gå till  www2.hh.se/staff/getc   och därifrån vidare till "Mathematica-diverse exempel".
Första passet tar upp icke-matematiska "kringdetaljer", lämpliga att gå igenom första gången man jobbar vid datorn.
Sedan finns ytterligare Mathematicadokument med exempel på vad man kan göra med programmet.
(De skulle visst behöva redigeras och "putsas" – sådant blir man aldrig färdig med ... :-)

Allt i Mathematica är funktioner

Mathematica kan sägas bestå av en massa (flera tusen) funktioner. Ovanpå dem kan du sedan definiera dina egna.
Du skriver något av typ f(2), så slår Mathematica upp sin definition av f och räknar ut f(2) –  ett "funktionsanrop".
(OBS! Endast hakparenteser [ ] fungerar som funktionsparanteser, se nedan!)
Begreppet funktion skall då tolkas i sin allra vidaste betydelse.
Här har vi t.ex. två funktioner som omformar algebraiska uttryck:

Expand[(((a + b))^3)]

Factor[(a^3) + 3 (a^2) b + 3 a (b^2) + (b^3)]

Det fetstilta är det du skriver. Numreringen In[1]:=, etc., sköts automatiskt av programmet.

Ett funktionsvärde kan vara "sammansatt" – följande t.ex. säger att primtalsfaktoriseringen av 600 är  600 = (2^3)·3·(5^2)

FactorInteger[600]

Funktioner kan ha flera argument:

Min[1, 2, 3, 4, 5]
Max[1, 2, 3]

Ovan ser vi också att flera funktionsanrop kan matas in på en gång  – de behandlas i tur och ordning.
För att spara papper, sätter jag i fortsättningen ihop funktionsanrop i listor så här:

{(∑_(k = 1)^n) k, (∫_a^b) 
        x \[DifferentialD]x}

"Vadå funktionsanrop?", undrar du kanske, "Det här var väl en summa- och en integral?"

Jovisst, men de kan också betraktas som funktionsanrop

{Sum[k, {k, 1, n}], Integrate[x, {x, a, b}]}

Integrate är en funktion med en integrand,  en integrationsvariabel och två integrationsgränser som argument!

(I en tidigare version skrev jag så här:  "Man knappar in ett uttryck och Mathematica svarar med dess värde". Men det är inte riktigt bra.  Mathematica transformerar uttrycket enligt de regler som hon fått föreskrivna. I mera komplicerade situationer är det inte klart vad "värde" skall betyda – samma sak kan ju ofta uttryckas på olika sätt!)

"Syntaktiskt socker"

säger dataloger när ett datorprogram tillåter alternativa uttryckssätt för en och samma sak, i syfte att ansluta till  rådande traditioner och öka läsabarheten. T.ex. får vi skriva

a + b - c

även om programmet representerar detta internt på ett annat sätt (funktionen FullForm visar hur):

FullForm[a + b - c]

Ytterligare exempel på hur Mathematica tillåter att samma sak skrivs på olika sätt:

{Union[{a, b, c}, {b, c, d, e}], 
      Intersection[{a, b, c}, {b, c, d, e}]}
{{a, b, c} ⋃ {b, c, d, e}, {a, b, c} ⋂ {b, c, d, 
          e}}

Element[(Sqrt[2]), Rationals]
(Sqrt[2]) ∈ Rationals

(Symbolerna && och ||  används för logiskt "och" resp. "eller" i  t.ex. det mycket använda programmeringsspråket C.)

{And[False, True], Or[False, True]}
{False ∧ True, False ∨ True}
{False && True, False || True}

Ibland tycker man att det ser bättre ut, om man skriver funktionens namn efter argumentet (s.k. postfix notation), och det kan man göra (Together och Apart är funktioner som gör liknämnigt resp. partialbråksuppdelar):

{(1/x) + (1/(x + 1)) // Together,  ((1 + 2  x)/((x^2) + x)) // 
        Apart}

((((Sqrt[(r^2) + (a^2)]) + a) ((Sqrt[(r^2) + (b^2)]) + b))/(r^2)) - (((Sqrt[(r^2) + (a^2)]) + (Sqrt[(r^2) + (b^2)]) + a + b)/((Sqrt[(r^2) + (a^2)]) + (Sqrt[(r^2) + (b^2)]) - a - b))  //  Simplify

Numerisk räkning: exakt form

Av föregående har du redan insett (?) att det riktigt roliga med Mathematica är att det "räknar" med mer än bara tal.
Men låt oss trots allt se hur Mathematica klarar de fyra räknesätten:

{2 + 3, 2 - 3, 2*3, 2/3, (2^3)}

Aj, aj, aj – klarar hon inte  2/3 ??
Mathematicas grundinställning är att,  om alla ingående tal är heltal,  så skall uttrycket omformas endast så länge detta kan ske utan införande av decimalapproximationer. Finns ingen föreskriven exakt omformning, så ekas uttrycket enbart:

{4/6, (Sqrt[2]) + (Sqrt[9]), Log[2], 2  π}

Minst två "botemedel" finns:

Flyttal

Låt något av de ingående talen vara flyttal, d.v.s. tal med decimalpunkt (OBS! Den anglo-saxiska världen använder punkt i stället för komma i tal med decimaler. OBS! Det som "flyter" är alltså decimalpunkten.)
(Distinktionen heltal – flyttal är ofta väsentlig i datorernas värld, eftersom datorer lagrar dessa på olika sätt.)
Det räcker med enbart punkt:

{(1.0/3) + (1/5), (Sqrt[2.]) , Log[2. ],  2.0  π}

N[ ]   alternativt   // N

Tillämpa funktionen N (står för Numeric). Här två, i detta fall, likvärdiga alternativ:

{N[(Sqrt[2])], (Sqrt[2])   // N}

Den andra är ofta bekvämare att skriva/läsa, medan den första kan generaliseras – man kan begära extra många värdesiffror, se nästa sida.

Numerisk räkning:  godtycklig precision

Är flyttal inblandade räknar Mathematicas normalt  med ca 16 värdesiffror och skriver ut resultaten med 6 värdesiffror. 
Man kan dock begära fler värdesiffror:

N[(Sqrt[2]), 50]

({{"\!\(\*StyleBox[\"\\\"expr\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"//N\\\"\", \"MR\"]\)  or  \!\(\*StyleBox[\"\\\"N[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"expr\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "approximate numerical value of \!\(\*StyleBox[\"\\\"expr\\\"\", \"TI\"]\) "}, {"\!\(\*StyleBox[\"\\\"N[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"expr\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\",\\\"\", \"MR\"]\) \!\(\*StyleBox[\"\\\"n\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "numerical value of \!\(\*StyleBox[\"\\\"expr\\\"\", \"TI\"]\) calculated with \!\(\*StyleBox[\"\\\"n\\\"\", \"TI\"]\)-digit precision "}})

Av någon underlig anledning fungerar inte

N[(Sqrt[2]), 10]

som man förväntar sig, utan man behöver

NumberForm[(Sqrt[2.0]), 10]

Vid heltalsräkning övergår Mathematica automatiskt till att räkna med fler värdesiffror, om så skulle behövas:

(2^1000)

Apropå räkning med stora tal ...

kan vi berätta om historiens enda (?) konferensföredrag, där föredragshållaren inte sa ett enda ord:
Till  American Mathematical Societys möte 1903 hade F.N.Cole anmält ett föredrag med titeln "On the Factorization of Large Numbers". När hans tur var kommen, gick han fram till tavlan och, utan att säga ett ord, räknade ut för hand dels (2^67) - 1, dels produkten 193 707 721·761 838 257 287. De blev lika. Så, fortfarande utan att ha sagt ett ord, satte han sig tillbaka på sin plats under publikens bifall. 
Faktoriseringen hade tagit honom 20 års söndagsgeftermiddagar att hitta.  Idag gör vi det på en halv sekund:

FactorInteger[(2^67) - 1] // Timing

Matematiska funktioner och symboler – ett litet smakprov

({{(e^x),"\!\(\*StyleBox[\"\\\"Exp[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "OBS. \[ExponentialE] \[ADoubleDot]r inte vanligt e !" "  "}, {"\!\(\*StyleBox[\"\\\"Log[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "naturliga logaritmen" ( ln x )"  "}, {   Log [b, x], logaritm med basen b}, {"\!\(\*StyleBox[\"\\\"Sin[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\),  \!\(\*StyleBox[\"\\\"Cos[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\),  \!\(\*StyleBox[\"\\\"Tan[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "OBS. Argument i RADIANER! "}, {"\!\(\*StyleBox[\"\\\"ArcSin[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\),  \!\(\*StyleBox[\"\\\"ArcCos[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\),  \!\(\*StyleBox[\"\\\"ArcTan[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "OBS. Resultat i RADIANER! "}})

({{x + i y,"\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\) \!\(\*StyleBox[\"\\\"+\\\"\", \"MR\"]\) \!\(\*StyleBox[\"\\\"I\\\"\", \"MR\"]\) \!\(\*StyleBox[\"\\\"y\\\"\", \"TI\"]\) ", "komplext tal  (OBS. \[ImaginaryI] \[ADoubleDot]r inte vanligt i !)" 
                    " "}, {"\!\(\*StyleBox[\"\\\"Re[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"z\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "realdel, imaginärdel "}, {"\!\(\*StyleBox[\"\\\"Conjugate[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"z\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "konjugatet av ett komplext tal,"" "\(z\&_\)"  "}, {"\!\(\*StyleBox[\"\\\"Abs[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"z\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "absolutbeloppet, "\(\(|\)\(z\)\(|\)\)"   "}, {"\!\(\*StyleBox[\"\\\"Arg[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"z\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "argument, "ϕ" i "|z|(e^(i  ϕ)), -π<ϕ≤π "  "}})

({{"\!\(\*StyleBox[\"\\\"Pi\\\"\", \"MR\"]\) ", ≃3.14159 "  "}, {e,"\!\(\*StyleBox[\"\\\"E\\\"\", \"MR\"]\) ", ≃2.71828 \(\*""""(\(OBS!\)\ e\ är\ inte\ vanligt\ \(e!\))\)}, {°,"\!\(\*StyleBox[\"\\\"Degree\\\"\", \"MR\"]\) ", π/180"  "}, {i,"\!\(\*StyleBox[\"\\\"I\\\"\", \"MR\"]\) ", \("  " 
                    imaginära\ enheten\ \((\(OBS!\)\ i\ är\ inte\ vanligt\ \(i\ !\))\)\)}, {∞ ,"\!\(\*StyleBox[\"\\\"Infinity\\\"\", \"MR\"]\) ", " oändlighetssymbolen"}})

{ArcTan[1], ArcTan[1]/Degree  // N, 
      Cos[60  °], (E^(I π))}

Viktigt att observera:

({{"◼ The arguments of all \!\(\*StyleBox[\"\\\"Mathematica\\\"\", \"TI\"]\) functions are enclosed in \!\(\*StyleBox[\"\\\"square brackets\\\"\", \"TI\"]\). "}, {"◼ The names of built-in \!\(\*StyleBox[\"\\\"Mathematica\\\"\", \"TI\"]\) functions begin with \!\(\*StyleBox[\"\\\"capital letters\\\"\", \"TI\"]\). "}})

Skilj på små och stora bokstäver!

Mathematica är vad man på engelska kallar case-sensitive: 
En liten bokstav, där det skulle stått en stor, och så har man en helt annan symbol!

{cos[π], arctan[1]}

Olika typer av parenteser

OBS. att funktionsargument skall omslutas av hakparenteser:

Cos(0)

Det här är inte alls cosinus av 0,  ty cos 0 = 1. Uttrycket tolkas som produkten av variabeln Cos med talet 0, jämför

2 (5)

De vanliga parenteserna duger endast till att ange prioritet (i vilken ordning operationerna skall utföras):

{1 + 3*5, (1 + 3)*5}

För listor, till vilka bl.a. matematikens vektorer räknas, används "måsvingar":

{a, b} . {x, y}                          
{a, b, c}\[Cross]{x, y, z}

Indexering av listor, d.v.s. att komma åt ett visst element i en lista, sker med dubbla hakparenteser:

veckodagar = {måndag, tisdag, onsdag, torsdag, fredag, 
          lördag, 
          söndag};
{veckodagar[[3]], 
      (Subscript[veckodagar, [[3]]])}

Slutligen har vi, som i exemplen ovan,  (* resp. *), som inleder resp. avslutar en kommentar – insprängd text som är till för att hjälpa människor att förstå vad som händer. Mathematica hoppar över det som står innanför parenteserna.

({{"\!\(\*StyleBox[\"\\\"(\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"term\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\")\\\"\", \"MR\"]\) ", "parentheses for grouping "}, {"\!\(\*StyleBox[\"\\\"f\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "square brackets for functions "}, {"\!\(\*StyleBox[\"\\\"a\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\",\\\"\", \"MR\"]\) \!\(\*StyleBox[\"\\\"b\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\",\\\"\", \"MR\"]\) \!\(\*StyleBox[\"\\\"c\\\"\", \"TI\"]\)"" ", "curly braces for lists "}, {"\!\(\*StyleBox[\"\\\"v\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"[[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"i\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]]\\\"\", \"MR\"]\) ", "double brackets for indexing "}, {(*  comment *), for commenting}})

Funktioner  som kan ha olika antal argument

Funktionen Mod

Om klockan är 20 nu, hur mycket är den om 13 timmar? Vi adderar som vanligt först, men drar bort 24 sedan. Inom matematiken kallas detta för "räkning modulo 24"

Mod[20 + 13, 24]

Vilken vinkel bildar minutvisaren med kl.12-riktningen 1000 minuter efter kl.12 ?

Mod[1000*(360/60) °, 360  °]

Med Mod[x,360] får vi den minsta positiva resten när x divideras med 360, d.v.s. ett tal i intervallet [0,360). Vi kanske skulle hellre vilja ha den till absolutbeloppet minsta vinkeln, d.v.s. ett tal i intervallet [-180,180)? Det kan vi faktiskt få genom att skicka ett tredje argument till Mod (de flesta av Mathematicas funktioner har  mening för olika antal argument!):

Mod[1000*(360/60) °, 
      360  °, -180 °]

(Är man ointresserad av tecknet, kan man ju ta absolutbeloppet:

Abs[ 
      Mod[1000*(360/60) °, 
        360  °, -180 °] ]

Att räkna med enheter

Som bekant, är varje fysikalisk storhet produkten av ett mätetal och en enhet. Detta illustreras av följande, som fungerar på samma sätt som om vi hade x i stället för meter:

{12 meter + 5.3 meter, 200 meter / (21.34 sekund)}

meter = 0.001 km;  sekund  = 1/3600 h;  
    200 meter/(21.34 sekund)

Derivator och integraler

(För att spara utrymme vid utskriften, sätter jag ihop skrivsätt som skall jämföras med varandra i listor.)

{(∂_x) (x^n), D[(x^n), x] , (∂_n) (x^n), 
      D[(x^n), n] }

När man deriverar, skall man klargöra vad man deriverar med avseende på !

{(∂_(x, x, x)) 
          (x^n), (∂_(x,x,x)) (x^n), 
        D[(x^n), {x, 3}] }           (* I mittenskrivsättet syns inga kommatecken mellan x:en, men det finns 2 st. s.k. InvisibleComma ! *)

{(∂_(x, y)) ((x^3) 
              Log[y]) , (∂_(x,y)) ((x^3) 
              Log[y]),   D[(x^3) Log[y], x, y]}                (* OBS .  Utan parenteser kommer derivationen att verka endast på (x^3)*)

{(∂_(x, x, y)) ((x^3) 
              Log[y]) , (∂_(x,x,y)) ((x^3) 
              Log[y]),   D[(x^3) Log[y], {x, 2}, y]}

{∫(x^n) \[DifferentialD]x, 
      Integrate[(x^n), x], (∫_a^b) (x^n) \[DifferentialD]x, 
      Integrate[(x^n), {x, a, b}]}

(* OBS. d är inte vanligt d ! *)

Det är lätt att skriva ner integraler där integranden är en s.k. elementär funktion (uppbyggd av de fyra räknesätten och gymnasiekursens funktioner), men vars primitiva funktion inte är det. Bestämda integraler kan man emellertid beräkna numeriskt:

{(∫_0^1) 
              (x^x) \[DifferentialD]x,  (∫_0^1) 
                (x^x) \[DifferentialD]x   // N,  
      NIntegrate[(x^x), {x, 0, 1}]}

Tilldelning (=)

Ofta utför man beräkningar i flera steg och behöver mellanlagra resultat. I Mathematica, liksom i de flesta "vanliga" programmeringsspråk, finns möjlighet att spara resultat under eget namn. Man säger att man definierar/deklarerar egna variabler och tilldelar dem värden.

Om vi inte sagt till Mathematica vad a skall vara kan hon naturligtvis inte göra något mer än att eka uttrycket nedan:

a + 1

Men, om vi tilldelar a ett värde, så kommer Mathematica att ersätta alla efterföljande förekomster av a med detta värde:

{a = 6, a + 1, (a^2)}

Ingenting hindrar att variabler får ett symboliskt uttryck som värde:

{a = 3  x , b = 2  y, Expand[(((a + b))^2)]}

Namngivna variabler gör räkningarna begripligare!

Tänk att Dina beräkningar skall bokföras och kommer att granskas, av Dig eller någon annan, om ett år. (Vanligt även i datorbranschen: visst går utvecklingen snabbt, men man byter ändå inte ut alla produkter varje år!) Vilken av följande två (för maskinen väsentligen likvärdiga) uppställningar skulle Du vilja titta på då?

(((1 + (5.0/100)))^25)*30000

ränteSats = 5.0;
tillväxtFaktor = 
        1 + ränteSats/100;   
startKapital = 30000;
antalÅr = 25;
slutKapital = 
      tillvä(xtFaktor^antal)År*
        startKapital

(Med semikolon på slutet undertrycker man utskrift. Därför syns här endast slut resultatet.)

Namngivna variabler gör beräkningar lättare att modifiera!

Ett annat skäl att införa namn på sina storheter är att det då blir lättare att upprepa en lång och komplicerad beräkning med andra värden på vissa storheter.
Antag att kapitalberäkningarna ovan fortsätter på 500 rader till och att räntesatsen förekommer 20 av dessa. Du vill göra en ny uträkning med en räntesats på 4% i stället för 5%. Hade Du skrivit 5.0 på alla 20 raderna, skulle Du behövt leta upp dem alla och ändra i alla dem. Skriver Du däremot ränteSats=5.0 och använder ränteSats i fortsättningen, så räcker det att ändra i första raden enbart!

Fördröjd tilldelning

Om man inte skickar alla uttryck till Mathematica på en gång kan föjande inträffa:

ränteSats = 5.0; 
    tillväxtFaktor = 1 + ränteSats/100

Något senare bestämmer man sig för att ändra räntesatsen och skriver

ränteSats = 2.0

Nu har ränteSats ändrat värde, men inte tillväxtfaktorn:

{ränteSats, tillväxtFaktor}

Tilldelningen  tillväxtFaktor=1+ränteSats/100  genomgås inte på nytt!
Men om vi ersätter den vanliga tilldelningen med s.k. "fördröjd tilldelning" – kolon framför likhetstecknet – så säger vi till Mathematica att spara den informationen och gå till den varje gång tillväxtFaktor åberopas:

ränteSats = 5.0
tillväxtFaktor := 1 + ränteSats/100           
{ränteSats = 2.0, 
      tillväxtFaktor, ränteSats = 3.0, 
      tillväxtFaktor}

Symbolnamn

Ibland säger man symboler / symbolnamn i stället för variabler / variabelnamn, eftersom Mathematica tillåter att man namnger allt möjligt:  funktioner, ekvationer, figurer...

minFunktion = Cos;    minFunktion[0]

ekvation = (x^2) + p x + q == 0; Solve[ekvation, x]

Multiplikation och symbolnamn

För multiplikation behövs faktiskt inte *, utan det räcker med mellanslag:

2 3

Detta använder vi oss naturligtvis gärna av vid bokstavsräkning:

{a = 2,  b = 3, a b, ab}

OBS. emellertid att mellanslaget verkligen behövs när båda faktorerna är bokstäver: utan mellanslag har vi i stället ett tredje symbolnamn, ab, som här inte har något värde. Lär Dig se skillnaden:

π(r^2)         Här finns inget mellanslag,så detta tolkas som kvadraten på symbolenπr

π (r^2)        Mellanslaget här gör att detta tolkas som produkten av π med (r^2)

Om den första faktorn är en siffra och den andra bokstav, behövs inte ens mellanslag:

{a = 2, 7  a, a7}

Symbolnamn får, förutom bokstäver, innehålla siffror, dock inte på första plats. 
Därför kan 7a tolkas som multiplikation, medan a7 är ett annat symbolnamn.

Namnkonventioner

Mathematica skiljer på små och stora bokstäver! 
Inbyggda funktioner börjar med stor bokstav och är ofta sammansättningar där varje del börjar med stor bokstav:

FactorInteger, FindMinimum, LinearSolve

Funktionsnamnen är ofta rätt långa, men syftet är vällovligt: öka läsbarheten och minska memoreringsbördan.

När du definierar egna symboler, följ samma konvention, men låt första bokstaven vara liten, så kan du lätt skilja på de inbyggda funktionerna och dina egna! (Så långa exempel som nedan behövs kanske inte, men begripligt är det ju:

napoleonicMarchOnMoscowAndBackAgainPlot

Radera bort inaktuella definitioner

({{"\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\) \!\(\*StyleBox[\"\\\"=.\\\"\", \"MR\"]\)  or  \!\(\*StyleBox[\"\\\"Clear[\\\"\", \"MR\"]\)\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\)\!\(\*StyleBox[\"\\\"]\\\"\", \"MR\"]\) ", "remove any value assigned to \!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\) "}})

Konstiga  resultat  kan bero på att du använder ett symbolnamn, som bär ett gammalt värde!

Skillnaden mellan tilldelning (=) och likhet (==)

I Mathematica (liksom i C och VisualBasic) har = en annan betydelse än i matematiken! 
I matematiken är vänsterled och högerled är likvärdiga: det spelar  ingen roll om vi skriver en ekvation som x = 5 eller 5 = x – båda uttrycker ett och samma påstående (logisk utsaga).
Men i programmeringens tilldelningssatser skall vänsterledet vara "etiketten" av en "låda" dit man kan "stoppa in" värden.

5=x

({{"\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\) \!\(\*StyleBox[\"\\\"=\\\"\", \"MR\"]\) \!\(\*StyleBox[\"\\\"y\\\"\", \"TI\"]\) ", "assigns \!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\) to have value \!\(\*StyleBox[\"\\\"y\\\"\", \"TI\"]\) "}, {"\!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\) \!\(\*StyleBox[\"\\\"==\\\"\", \"MR\"]\) \!\(\*StyleBox[\"\\\"y\\\"\", \"TI\"]\) ", "tests whether \!\(\*StyleBox[\"\\\"x\\\"\", \"TI\"]\) and \!\(\*StyleBox[\"\\\"y\\\"\", \"TI\"]\) are equal "}})

Assignments and tests.

Logiska test ger True eller False

2 + 2 == 4

"Tillfällig" substitution  ( /. )

Med

r = 3;  arean = π (r^2);  {arean, r}

så kommer r att ha värdet 3 i fortsättningen, så länge vi inte ändrar det igen. Med

arean = π (r^2)  /.  r -> 3; {arean, r}

är r lika med 3 endast under den här beräkningen.  
Är det flera olika värden som skall sättas in, omsluter man dem i en lista:

arean = π (r^2)  /.  r -> {3, 5, 8}

volymen = (1/3) π (r^2) h   /.  {r -> t, 
          h -> 2  t}

Egna funktioner  (program)

Man kan definiera sina egna funktioner, såväl av en som flera variabler:

f[x_] := (x^2)
g[x_, y_] := (x^2) (E^(-5 y))

OBS. 	1) understrykningstecknet efter varje argument i vänsterledet
	2) kolon före likhetstecknet

Nu kan man t.ex. räkna ut

{f[2], 
      f[a + b], f'[t],  Derivative[1, 0][g][a, 
        b], Derivative[1, 1][g][a, b]}

f[x_] := (x^n)
{f'[x],   (∂_x) f[Sin[x]],  (∂_x) 
        g[Sin[x]]}

Varför understrykningstecknet?

Utan understrykningstecknet är vi "bundna" till den symbol vi valt att beteckna argumentet med:

Clear[f]
f[x] := (x^2)
{f[x], f[2], f[t]}

Med understrykningstecken åstadkommer vi att allt det som vi skriver innanför argumentparenteserna sätts in på x:s plats i definitionens högerled:

Clear[f]
f[x_] := (x^2)
{f[2], f[a], f[{x, y}], f["blaha-blaha"]}

Det här är exempel på en teknik som på engelska kallas pattern matching. Ytterligare exempel:

\(Clear[f]; \ f[bas_\^exponent_] := exponent\)
f[(a^b)]

Listor

Listor som argument till funktioner

Ofta kan man utföra samma funktionsberäkning för flera olika argument genom att lägga dem i en lista:

{Cos[{0, (π/6), (π/4), (π/3), (π/2)}], {1, 2, 3, 4, 5}^2, {1, 2, 3, 4, 5} - 1}

Generera listor med funktionen Table

Table[a, {5}]

Table[(k^2), {k, 5}]

Table[(k^2), {k, 10, 16}]

Table[(k^2), {k, 10, 16, 2}]

Table[(k^2), {k, 16, 10, -2}]

Table[(k^2), {k, 1, 2, 0.1}]

Table[Binomial[n, k], {n, 1, 6}, {k, 0, n}]

Table[Binomial[n, k], {n, 1, 6}, {k, 0, n}]  // TableForm

Funktionsgrafer och kurvor i 2 dimensioner:  Plot, ParametricPlot

Plot[5+Sin[x], {x,10,20}];

OBS! Mathematica tar sig friheten att sätta ut koordinataxlarna där hon finner lämpligt !

Flera funktioner kan plottas samtidigt genom att lägga dem i en lista:

Plot[{(E^(-x)) 
            Cos[20  x], (E^(-x)), -(E^(-x))}, {x, 0, 2}];

Man kan mycket väl generera funktionslistan "automatiskt" med hjälp av någon annan Mathematica funktion  (som t.ex. Table nedan), men får då tillämpa funktionen Evaluate på den (listan), för att beräkningarna skall ske i rätt ordning:

Plot[
        Evaluate[Table[(x^p), {p, 0.5, 2, 0.5}]], {x, 0, 1.5}];

Kurvor på parameterform

Betyder att vi skaffar oss två funktioner, x(t) och y(t), sådana att för alla t, som tillhör ett visst intervall,  gäller att (x(t), y(t)) är koordinaterna för en punkt på kurvan, och så att alla punkter på kurvan genomlöps på detta sätt när t varierar över intervallet. 
Genom att ta x(t) = cos t,   y(t) = sin(t), så får vi ... (skall Du kunna säga utan att titta i någon bild!)

ParametricPlot[{Cos[t],  Sin[t]},  {t,  0, 
          2 π}];

Hoppsan – det här ser ju inte ut som någon cirkel ?!

AspectRatio

OBS! Märk att alla figurer ovan har samma rektangulära form, oavsett hur stora intervall i x- resp. y-led vi plottar över! Det betyder att Mathematica har i regel olika stora längdenheter för x- resp. y-led!
Skulle vi haft lika stora längdenheter i första figuren t.ex., hade det sett ut så här:

Plot[5+Sin[x], {x,10,20}, AspectRatio->Automatic];

ParametricPlot[{Cos[t],  Sin[t]},  {t,  0,  2  π},  
        AspectRatio -> Automatic];

Plot3D och ParametricPlot3D

Plot3D  plottar alltid en funktion över ett rektangulärt område. 
För funktioner vars nivåkurvor är ellipser, som t.ex. f(x, y) = (x^2) + 4  (y^2), ger detta rätt så svårtolkade bilder:

Plot3D[(x^2) + 4  (y^2), {x, -2, 2}, {y, -1, 1}];

Bättre blir det, om vi i stället plottar över området som begränsas av en ellips, t.ex. (x^2) + 4  (y^2) ≤ 
        4⟺((((x/2)))^2) + (y^2) ≤ 1
Varje punkt (x, y) innanför ellipsen svarar mot en punkt ((x/2), y) innanför enhetscirkeln, så det finns r och θ, 0 ≤ r ≤ 1,  
      0 ≤ θ < 2  π, med
	(x/2) =  r cos θ	y = r sin θ
Varje punkt (x, y, z) tillhörande grafen av f då (x^2) + 4  (y^2) ≤ 4  kan då fås på formen (obs. att (x^2) + 
          4  (y^2) = 4  (r^2) (cos^2) θ + 
            4  (r^2) (sin^2) θ = 4  (r^2))
	(2  r cos θ, r sin θ,  
        4  (r^2)) för något entydigt bestämt par (r, θ) med 0 ≤ r ≤ 1,  
      0 ≤ θ < 2  π
Därför kan vi generera ytan på följande sätt:

ParametricPlot3D[{2  r Cos[θ], r Sin[θ], 
          4  (r^2)}, {r, 0, 1}, {θ, 0, 2  π}];

Standard Packages

Så kallas "paket", som innehåller mera avancerade funktioner med snävare tillämpningsområden, som kan förmodas användas mera sällan. De finns med i standardversionen av programmet, men för att spara minnesutrymme, laddas de inte in, när man startar det, utan man får ladda in dem själv vid behov.

Att ladda in ett paket

Om man tittar noggrannare i manualen, så ser man att det finns ett tiotal paket – Algebra, Calculus, DiscreteMath, etc. – som i sin tur består av flera mindre paket: t.ex. Algebra innehåller AlgebraicInequalities, InequalitySolve,  etc.
För att ladda in t.ex. InequalitySolve skriver man

<< Algebra`InequalitySolve`

Paketen kan liknas vid katalogerna i vilka man ordnar sina datorfiler och grav accent-tecknet motsvarar närmast snedstrecket \  (backslash) i Windows.
Obs. att grav accent-tecknet ` skall finnas med på slutet också!
OBS. att grav accent-tecknet inte syns på skärmen förrän man tryckt ytterligare någon tangent. Är nästa tangent en bokstav, så kan tecknet hamna ovanför bokstaven: Ì. För att undvika detta, tryck mellanslag!

Glöm inte att ladda in paketet först!

Om man laddar in paketet efter att ha gjort ett (obesvarat) anrop av en funktion från paketet, så kan man inte utnyttja funktionen från paketet i alla fall (be mig inte förklara anledningen). Botemedlet är

Remove[funktionsnamnet]

Exempel: Kombinatorik

Mathematica har en inbyggd funktion som gör en lista av alla permutationer av en given mängd:

Permutations[{a, b, c}]

I paketet DiscreteMath`Combinatorica` finns en funktion som gör listan så att successiva permutationer i listan inte skiljer sig på mer än en s.k. transposition, d.v.s. varje permutation fås ur föregående genom att låta ett par av element (men inte fler!) byta plats :

<<DiscreteMath`Combinatorica`
MinimumChangePermutations[{a,b,c}]

Ekvationer: exakt med Solve

Polynomekvationer

Solve[(x^2) - 5 x + 6 == 0, x]

Att resultatet ges i form av "replacement rules", är till för att man lätt skall kunna stoppa in rötterna i andra uttryck:

(x^3) + 1  /.  Solve[(x^2) - 5 x + 6 == 0, x]

Vill man lagra, säg, den andra roten, i variabeln x, så kan man skriva det till synes omständliga

x = (x  /. Solve[(x^2) - 5 x + 6 == 0, x])[[2]]

I 1500 år trodde man i västerlandet att det inte fanns någon ny matematik att komma på efter allt det som de gamla grekerna hade gjort. (Vissa går nog omkring med en liknande missuppfattning idag...) Gissa om man kände en viss stolthet, när man på 1500-talet fick fram helt nya resultat – formler för lösningarna av tredje- och fjärdegradsekvationer:

Solve[(x^3) + a (x^2) + b x + c == 0, x]

Du ser nu emellertid också, varför man i alla konkreta fall föredrar att räkna ut rötterna numeriskt:

NSolve[(x^3) + 5  (x^2) - x + 7 == 0, x]

Transcendenta ekvationer

Endast vissa går att lösa:

{Solve[(Sqrt[5 - x]) == x - 3], Solve[Cos[x] == x]}

Ekvationssystem: Lägg ekvationerna i en lista!

Ex. Linjärt ekvationssystem:  (För system givna på matrisform finns funktonen LinearSolve.)

Solve[{a x + b y == e, c x + d y == f}, {x, y}]

(Kan notera att systemets determinant dyker upp i nämnaren.)

Ex. Olinjärt ekvationssystem (från kartesiska till polära koordinater i planet):

Solve[{x == r Cos[θ], 
          y == r Sin[θ]}, {r, θ}]  // 
      Simplify

Ekvationer: numeriskt med NSolve och FindRoot

Polynomekvationer (och ekvationssystem):  NSolve

För numerisk lösning av polynomekvationer (och ekvationssystem) har man NSolve:

NSolve[{(x^2) + (y^2) == 1, (((x - 1))^2) + (y^2) == 1}, {x, 
        y}]

Solve[{(x^2) + (y^2) == 1, (((x - 1))^2) + (y^2) == 1}, {x, 
        y}]

Transcendenta ekvationer: FindRoot

Transcendenta ekvationer = ekvationer där andra funktioner än polynom är inblandade, t.ex. 	tan x = x

När det gäller polynomekvationer, så kan man direkt säga hur många rötter det finns (algebrans fundamentalsats!), men så är det inte längre med ekvationer som ovanstående. Vad ett datorprogram kan göra i sådana fall är att försöka leta sig fram till en rot. Sedan stannar det och det är upp till användaren att avgöra om denna är den enda eller om det finns fler! Därför är följande strategi lämplig:

Försök att, med hjälp av analys med papper och penna samt plottning, få en uppfattning om hur många rötter som finns och var ungefär de ligger.
Ge rotapproximationerna (som startvärden) till ett datorrutin som kan förfina dem. 
I Mathematica är denna rutin funktionen FindRoot.

Plot[{Tan[x], x}, {x, 0, 10}];

Figuren ovan antyder (och det går att bevisa – hur?) att ekvationen har exakt en lösning i vart och ett av intervallen
	((π/2) + k π, 3  (π/2) + k π),  
      k = 0, 1, 2, 3,  ... 
Om det finns någon rot i intervallet (0, π/2), är det svårt att säga ur denna figur enbart, men låt oss försöka med ett startvärde i detta intervall också. Vi anropar FindRoot med startvärden 1, 4 resp. 7:

{FindRoot[Tan[x] == x, {x, 1}],  
      FindRoot[Tan[x] == x, {x, 4}], 
      FindRoot[Tan[x] == x, {x, 7}]}

Det tredje värdet, t.ex., som FindRoot spottar ut, 7.72525, verkar stämma bra överens med den "inzoomade" grafen av tan x - x. (Varför plotta differensen?)

Plot[{Tan[x] - x}, {x, 7.725, 7.726}];

Vad säger Du om det första värdet, 0.0104761 ?

Differentialekvationer: exakt med DSolve

Det som matematiker (något slarvigt) skriver
	y' + 
          a y = k   ⟺   y = 
          C (e^(-x)) + (k/a), C  godtycklig konstant

kan i Mathematica se ut på två, aningen olika, sätt:

DSolve[y'[x] + a y[x] == k, y[x], x]                (* variant 1 med y[x] som obekant *)

DSolve[y'[x] + a y[x] == k, y, x]                        (* variant 2 med y som obekant *)

Man får alltså ange: 1) ekvation, 2) obekant funktion, 3) oberoende variabel med avseende på vilken man deriverar.
(Det går inte att utelämna argumenten i ekvationen!)
Med variant 1 är man "bunden" till symbolkombinationen y[x] :

y[x]   /.  
      DSolve[y'[x] + a y[x] == k, y[x], 
        x]
y[t]  /.  
      DSolve[y'[x] + a y[x] == k, y[x], 
        x] 
y[0] /. DSolve[y'[x] + a y[x] == k, 
        y[x], x]

Fördelen med variant 2 är att y blir en funktion  (#1 och & visar att vi har en s.k. pure function)

y'[t]  /.  
      DSolve[y'[x] + a y[x] == k, y, x]

Begynnelse- och randvärden grupperas tillsammans med ekvationen i en lista:

DSolve[  {y'[x] + a y[x] == k, y[0] == 0}, y[x], 
        x]  //Simplify

(Notera att den godtyckliga konstanten C nu har fått ett bestämt värde.)

Differentialekvationer: numeriskt med NDSolve

(Differentialekvationen nedan kan vi visserligen lösa exakt, men när man skall utforska nya funktioner är det ju lämpligt att testa på problem, som man vet svaret på!)

OBS. Endast problem med en enda lösning kan Du förvänta dig att kunna lösa numeriskt! Alltså: differentialekvationer får kompletteras med tillräckligt många begynnelsevillkor för att alla godtyckliga konstanter skall bli bestämda.

Mathematicas NDSolve tar fram någon slags tabell med approximativa funktionsvärden, som programmet kallar InterpolatingFunction:

NDSolve[{y'[x] == y[x], y[0] == 1}, 
      y, {x, 0, 2}]

Vi kan beräkna ett enstaka funktionsvärde på följande sätt:

y[1]  /. 
      NDSolve[{y'[x] == y[x], y[0] == 1}, 
        y, {x, 0, 2}]

Vi kan rita lösningen graf: (OBS att Evaluate är nödvändig här!)

lösning = 
        NDSolve[{y'[x] == y[x], y[0] == 1}, 
          y, {x, 0, 2}];
Plot[ 
        Evaluate[ y[x]  /.  lösning], {x, 0, 
          2}];

Ett större exempel  (på s.k. matematisk modellering) :
Befolkningstillväxt : exponentiella och logistiska modellen

Vi har data för USA:s befolkning åren 1800-1860. Vi försöker anpassa en kurva till dessa värden (s.k. regression) för att sedan extrapolera denna till år 2000 och jämföra med nuvarande faktiska befolkningstal.

Extrapolation och interpolation

Om man, som vi nedan, har data för åren 1800, 1810, 1820, 1830, 1840, 1850, 1860, och anpassar en "jämn och fin", kontinuerlig kurva till dem och sedan använder kurvans värde för att säga vad befolkningen varit något år däremellan – 1827 eller 1845, etc. – så kallas detta att interpolera fram värden.

Skulle man däremot "förlänga" kurvan och använda dess värden för år utanför intervallet 1800-1860, så heter det att man extrapolerar. OBS. Att extrapolera skall man vara väldigt försiktig med! Resultaten kan bli högst olika beroende på ens antaganden (som vi skall se nedan) och, jämfört med interpolation, är det mycket lättare att de slår fel!

Data

Vi grupperar data i talpar av formen {årtal, befolkningsantal i miljoner} och bildar en lista av dessa:

befolkning = {{1800, 5.3}, {1810, 7.2}, {1820, 9.6}, {1830, 
            12.9}, {1840, 17.1}, {1850, 23.2}, {1860, 31.4}};

Talpar kan tolkas som koord. för punkter i ett plan. Förbind punkterna med räta linjestycken så fås en kurva:

Show[
        GraphicsArray[{ListPlot[befolkning,  PlotStyle -> PointSize[0.02]], 
            ListPlot[befolkning,  PlotJoined -> True]}]];

Exponentiella modellen

En enkel modell för befolkningstillväxt är (Malthus lag):	Ökningen är proportionell mot det befintliga antalet  
Enligt den skulle befolkningen öka exponentiellt:

DSolve[{y'[x] == a y[x]}, y[x], x]

Låt oss därför försöka anpassa en exponentialkurva 		y = C· (e^(a x)), C, a konstanter
till befolkningsdata, d.v.s. vi vill ha fram konstanter C, a så att exponentialkurvan ansluter "så bra som möjligt" till våra punkter (x = 1800,  y = 5.3), (x = 1810,  y = 7.2), etc.

Du har nog anpassat räta linjer i liknande problem – det låter sig oftast göras tillfredsställande med blotta ögat.
Men exponentialkurvor? Logaritmera ekvationen!  y = C· (e^(a x)) ⟺ ln y = ln C + a x
D.v.s. om vi plottar logaritmerna av y-värdena i stället för y-värdena själva, så skall punkterna ansluta till en rät linje

Vi definierar en funktion som, givet ett talpar, logaritmerar parets andra komponent:

logY[{x_, y_}] := {x, Log[y]}

Med Mathematicas funktion Map kan man applicera en funktion på vart och ett av elementen i en lista:

(logBefolkning = Map[logY, befolkning])  // TableForm

Vi kontrollerar om data efter logaritmeringen verkligen ser ut att ligga på en rät linje:

ListPlot[logBefolkning,  PlotJoined -> True];

Ja, då är det fritt fram att försöka bestämma konstanterna C och a.

Anpassning av linjärkombinationer av funktioner med Fit

Om (Subscript[u, 1]), (Subscript[u, 2]),  ... , (Subscript[u, n]) är vektorer, medan (Subscript[λ, 1]), (Subscript[λ, 2]),  ... , (Subscript[λ, n]) är tal, så kallar man ett uttryck av formen
	(Subscript[λ, 1]) (Subscript[u, 1]) + (Subscript[λ, 2]) 
              (Subscript[u, 2]) +  ...  + (Subscript[λ, n]) (Subscript[u, n])    en linjärkombination av vektorerna (Subscript[u, 1]), (Subscript[u, 2]), ... (Subscript[u, n])
Likaså om (Subscript[u, 1]), (Subscript[u, 2]),  ... , (Subscript[u, n]) är funktioner. T.ex. detta att den allmänna lösningen till diff.ekvationen
	y'' (t) + 9  y(t) = 0 är (Subscript[C, 1]) cos 3  t + (Subscript[C, 2]) sin 3  t
brukar uttryckas  så att lösningen är en linjärkombination av funktionerna cos 3  t och sin 3  t
Ett polynom av grad 5 (t.ex.) kan betraktas som en linjärkombination av funktionerna 1, x, (x^2), (x^3), (x^4), (x^5).
Speciellt kan en rät linje betraktas som en linjärkombination av funktionerna 1, x

Anpassning av en linjärkombination av givna funktioner (d.v.s. bestämma talen (Subscript[λ, 1]), (Subscript[λ, 2]),  ... , (Subscript[λ, n]) när (Subscript[u, 1]), (Subscript[u, 2]),  ... , (Subscript[u, n]) är givna) görs bäst i Mathematica med funktionen Fit:

linjensEkv = Fit[logBefolkning, {1, x}, x]

Vi plottar nu data och regressionskurva tillsammans (de två kurvorna kommer också separat på skärmen, men jag har klippt bort dem)  Till synes inget fel på överensstämmelsen:

Show[ Plot[Exp[linjensEkv], {x, 1800, 1860}],  
        ListPlot[befolkning,  PlotStyle -> PointSize[0.02]]];

Extrapolation till år 2000

Från Encyclopaedia Britannica, 1998 tar jag fram befolkningstal för 1998 samt prognoser för år 2000 och 2010:

befolkningNu = {{1998, 270}, {2000, 275}, {2010, 298}}

och plottar dessa tillsammans med regressionskurvan:

Show[ Plot[Exp[linjensEkv], {x, 1800, 2010}],  
        ListPlot[befolkningNu,  PlotStyle -> PointSize[0.02]]];

Alldeles åt helvete – exponentialkurvan pekar på 2.5 miljarder!

Logistiska modellen

I den exponentiella modellen antog vi att den relativa ökningstakten är densamma hela tiden: y'/y = a
Rimligare vore kanske räkna med att denna minskar allteftersom befolkningen ökar, p.g.a. att man konkurrerar om begränsade resurser. Enklast vore att anta att minskningen beror linjärt på befolkningsmängden: y'/y = a(1 - y/m)
Konstanten m spelar då rollen av "övre tak" – den maximala befolkningsmängd som är möjlig.

Denna s.k. logistiska ekvation är separabel och kan lösas exakt

DSolve[y'[x] == a y[x] (1 - y[x]/m), y[x], x]

fast för at få just de lösningar vi är intresserade utav – de som uppfyller 0 < y(x) < m – så måste vi tillåta även komplexa konstanter C[1] i formeln ovan, så att (e^C)[1] skulle kunna vara negativt!

Vi försöker följaktligen anpassa en kurva av typen (Förkorta täljare och nämnare med (e^(a x)), så att exponentialfaktorn återfinns endast på ett ställe i stället för två.)

y = (m/(1 + c (E^(-a x)))) ,      m, a, 
    c    konstanter

Uttrycket har inte formen av en linjärkombination av givna funktioner, så Fit kan inte användas. Men i ett tilläggspaket finns NonlinearFit som försöker numeriskt anpassa även sådana olinjära modeller.

För att exponentialfaktorn inte skall bli extremt liten (i förhållande till ettan i nämnaren) väljer jag att låta x = 0 svara mot år 1800:

<< Statistics`NonlinearFit`
kurvansEkv = 
      NonlinearFit[befolkning, 
        y = (m/(1 + c (E^(-a (x - 1800))))), {x}, {m, a, c}]

Icke-linjära uttryck (linjärkombinationer som (Subscript[C, 1]) (e^(-x)) + (Subscript[C, 2]) 
          (e^(-2 x)) + (Subscript[C, 3]) (x^2) är visserligen inte linjära i x, men väl i parametrarna (Subscript[C, 1]), (Subscript[C, 2]), (Subscript[C, 3])) är i allmänhet mycket svårare att behandla matematiskt, så det är lätt för en dator att "gå vilse" i jakten på ett minimum. Här anser sig Mathematica inte riktigt färdig med minimeringen, men vi tar resultaten som de är.

Nu plottar vi alltihop tillsammans:

p1 = 
        ListPlot[befolkning,  
          PlotStyle -> PointSize[0.02]];
p2 = 
        ListPlot[befolkningNu,  
          PlotStyle -> PointSize[0.02]];
p3 = Plot[kurvansEkv, {x, 1800, 2000}];
Show[ p1, p2, p3];

För bra för att vara sant!
(Sanningen är den att den numeriska optimeringen med NonlinearFit råkade ge ett, för vår modell, mycket gynnsamt värde. Vi skulle tagit varningarna på allvar – teoretiskt sett ekvivalenta omformuleringar av NonlinearFit-anropet ger faktiskt helt andra resultat. Men exemplets "anda" tycker jag att vi kan ta del utav!)

Minsta kvadratmetoden

Vi frågade oss aldrig vad "kurvan skall ansluta så bra som möjligt till data" skulle betyda!  
Det måste formuleras matematiskt – hur annars skulle ett datorporgram kunna räkna på det?
Vad "så bra som möjligt" skall betyda ur tillämpningarnas synpunkt, kan diskuteras. 
Den metod som är enklast beräkningsmässigt (och som därför används i de allra flesta fall när man inte har särskilda krav) är minsta kvadratmetoden: man bestämmer konstanterna så att summan av kvadraterna på avvikelserna i y-led blir så liten som möjligt. För den exponentiella modellen betyder det att följande summa skall minimeras
(Alltså: (Subscript[x, k]):na och (Subscript[y, k]):na är givna, medan C och a varierar och vi frågar oss vilket val av C och a ger min.)

(∑_(k = 1)^n)(((C (E^(a (Subscript[x, k]))) - (Subscript[y, k])))^2)