Programování v Mathematice

Úvod

Mathematica umí počítat.

1+1

Umí řešit symbolické rovnice.

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

Notebook, frontend, kernel

Frontend zajišťje komunikaci mezi uživatelem a jádrem (kernelem), které počítá
 - kalkulačka
 - programovací jazyk (vývojové prostředí).

Notebook je to, v čem Mathematica uchovává vstup a výstup (*.nb)
 - skládá se z buněk(Cell), které mohou být do sebe vnořené
 - každá buňka má svůj styl, podle kterého se vykresluje a zpracovává (viz záložka)

Kernel je to co počítá
 - jeden kernel, víc notebooků
 - jeden frontend, víc kernelů (paralelizace)

Základní ovládací prvky

Potvrzení vstupu: Shift + Enter, nebo Enter na numerické klávesnici.

F1
Why the beep, Why the coloring

Alt - .
Quit Kernel (restart)

%

%%%+1

1+(* Toto je komentář uvnitř Mathematica kódu *)1

blokování výstupu: středník

1+1;

aplikování funkce jedné proměnné

f[x]
x //f

Výrazy

V Mathematice je všechno výraz (základní a jediná datová struktura).

Výrazy se uchovávají v infixovém tvaru:

a+b+c//FullForm
1/2 // FullForm
(x/(Sqrt[5]))+(y^2)+1/z//FullForm

a+b+c//TreeForm
(x/(Sqrt[5]))+((y^2)+1)/Exp[z]//TreeForm

Spousta dalších forem:

((∫_a^b)f[x,(E^(x+z)),z]\[DifferentialD]x)//FullForm
((∫_a^b)f[x,(E^(x+z)),z]\[DifferentialD]x)//TraditionalForm
((∫_a^b)f[x,(E^(x+z)),z]\[DifferentialD]x)//TeXForm
((∫_a^b)f[x,(E^(x+z)),z]\[DifferentialD]x)//StandardForm

Operace s výrazy

a+b+c // Head
1 //Head
x //Head

Porovnávání :  == pro hodnoty, === pro výrazy

u==v
u===v

u=1;v=1;
u==v
u===v

Simplify

Sin[x]^2+Cos[x]^2
Sin[x]^2+Cos[x]^2 //Simplify

(x+y)^2
(x+y)^2 //Simplify
(x+y)^2 //Expand
x^2+2*x*y+y^2 //Simplify

Seznamy

Seznam není nic jiného než speciální funkce List, která má neomezený počet parametrů a speciální značení pomocí { }

{Sin[x],1,(E^x)}
List[Sin[x],1,(E^x)]

Seznam nemá žádná omezení na typ dat, hloubku zanoření, atd.

{1234,Graphics[{Pink,Disk[]}],Text[franta],x+y//TreeForm}

n[k_]:={n[k-1],{}};
n[0]={};
TableForm[Table[n[i],{i,0,5}],TableDepth->1]
(* ve skutečnosti nejsou pole nic jiného, než jenom hezké zobrazení výrazu *)
Table[n[i],{i,0,5}]//TreeForm

Seznam je uspořádaná n-tice, prvky se mohou opakovat

{1,2} =={2,1}
{1,1}=={1}

Indexování:

r=List[a,b,c,d,e];
First[r]
Rest[r]
Last[r]
r[[2]]
r[[-2]]
r[[1;;3]]
r[[1;;5;;2]]

Přepisování částí seznamu:

r[[2]]=x;
r

Funguje pro libovolné výrazy:

(a+b+c)[[2]]
(f[x+y,z])[[1]]

(a+b+c)[[0]]
(a+b+c)//Head

r=a+b+c;
r[[0]]=List;
r

Operace se seznamy

Zadat seznam:

{a,b,c,d}
Range[1,10]
Table[n^2,{n,1,10}]

Operace se seznamy:

Join[{a,b,c,d},{e,d,c,b}]
Append[{a,b,c,d},x]
Prepend[{a,b,c,d},x]

Seznamy jako množiny:

Union[{a,b,c,d},{e,d,c,b}]
Intersection[{a,b,c,d},{e,d,c,b}]
Subsets[{a,b,c}]
Tuples[{a,b,c},2]

Apply, Map, Select

Apply[f,{a,b,c}]
Map[f,{a,b,c}]
Select[Range[10],PrimeQ]

Apply[f,a+b+c]
Map[f,a+b+c]

Definice

Proměnné a funkce mohou mít v názvu libovolné znaky, nikoliv podtržítko (to se používá na tzv. pattern matching). 
Zabudované funkce a konstanty bez vyjímky začínají na velké písmeno.

Pi

abc

abc=3;
abc^2

abc

Clear[abc]
abc

=    vs.   :=

= .... do symbolu vlevo se uloží výraz vpravo
:= .... do symbolu vlevo se uloží výraz vpravo aniž by se vyhodnocoval

rand1=RandomInteger[20]

rand2:=RandomInteger[20]

Table[rand1,{5}]
Table[rand2,{5}]

Transformační pravidla

{a,b,c,d}/.b->1
a+b+c+d/.b->1

a+b+c+d/.Plus->Times

Vzory (patterns)

a+(b^2)+(c^d)/.((n_)^2)->f[n]
a+(b^2)+(c^d)/.((n_)^(k_))->f[n]
a+(b^2)+(c^d)/.((n_)^(k_Integer))->f[n]

Řešením rovnic jsou také transformační pravidla !!!

reseni=Solve[(x^2)+x+2==0,x]

x/.reseni
x^2/.reseni
x^2+x+2/.reseni

Simplify[x^2+x+2/.reseni]

Programování

Definice vlastní funkce:

f1=Function[x,(x^2)]
f2=#^2&
f3=Function[{x,y,z},(x^2)+(y^2)+(z^2)]
f4=((#1)^2)+((#2)^2)+((#3)^2)&

f1[2]
f2[2]
f3[2,2,2]
f4[2,2,2]

Typické použití anonymních funkcí:

Map[#^2&,{1,2,3,4,5}]
Select[{1,2,3,4,5},Mod[#,3]==1&]

Jiný způsob definování funkcí:

g1[x_]:=x^2
g1[10]
g1[a]

g2[x_Integer]:=x^2
g2[10]
g2[a]

g3[x_]:=x^2/;PrimeQ[x]
g3[10]
g3[11]

Module - prostředí s lokálními proměnnými

fib[n_]:=Module[{a=1,b=1,i,p},
For[i=2,i<n,i++,p=b;b=a+b;a=p];
b
]
fib[5]
p

fib1[n_]:=Module[{a=1,b=1,i},
For[i=2,i<n,i++,p=b;b=a+b;a=p];
b
]
fib1[5]
p

Cykly

a=0;
Do[a=a+n,{n,1,4}]
a

a=0;n=1;
While[n<=4,a=a+n;n++]
a

a=0;
For[n=1,n<=4,n++,a=a+n]
a

If

a=1;If[a==1,1,0,nevim]
a=2;If[a==1,1,0,nevim]
Clear[a];If[a==1,1,0,nevim]

Procedurální vs. funkcionální programování vs. speciální funkce

Faktoriál: 1. procedurálně, 2. rekurzivně, 3. matematicky, 4. s využitím základních funkcí

fact1[x_]:=Module[{i,a},a=1;For[i=2,i<=x,i++,a=a*i];a]

fact2[1]:=1
fact2[x_]:=fact2[x-1]*x

fact3[x_]:=Product[i,{i,1,x}]

fact4[x_]:=Apply[Times,Range[x]]

fact1[5]
fact2[5]
fact3[5]
fact4[5]

fact1[55555]//Timing//First
fact2[55555]//Timing//First
fact3[55555]//Timing//First
fact4[55555]//Timing//First

Block[{$RecursionLimit=Infinity},fact2[55555]//Timing//First]

l1[n_]:=Module[{i,l},l={};For[i=1,i<=n,i++,l[[i]]=i^2];l]
l2[n_]:=Module[{i,l},l={};For[i=1,i<=n,i++,l=Append[l,i^2]];l]
l3[n_]:=Module[{i,l},l={};For[i=n,i≥1,i--,l=Prepend[l,i^2]];l]
l4[n_]:={}/; n==0
l4[n_]:=Append[l4[n-1],n^2]
l5[n_]:=Table[i^2,{i,1,n}]

l1[10]
l2[10]
l3[10]
l4[10]
l5[10]

l2[15000]//Timing//First
l3[15000]//Timing//First
l5[15000]//Timing//First

Eukleidův algoritmus

nsd1[a_,b_]:=nsd1[b,a]/;a<b 
nsd1[a_,0]:=a
nsd1[a_,b_]:=nsd1[b,Mod[a,b]]

nsd1[123,456]

nsd2[x_,y_] := Module[ {r,a=x,b=y} ,While[b>0,  r= Mod[a,b]; a=b; b=r]; a ]

nsd2[123,456]

a=RandomInteger[2^100000];b=RandomInteger[2^100000];$IterationLimit=Infinity;
nsd1[a,b]//Timing
nsd2[a,b]//Timing

Další užitečné funkce (které se těžko hledají)

Měření času

Timing[N[Pi,10^5];]
Timing[N[Pi,10^5];]

ClearSystemCache[]
Timing[N[Pi,10^5];]

Numerická hodnota

1/2+Pi
1/2+Pi+0.0
N[1/2+Pi]

N[Pi,100]

2.000000002-2.000000001==0.000000001

Znaky které nejsou na klávesnici   -  Escape sekvence:      EscněcoEsc      kde "něco" je zkratka znaku 
    - např. řecká písmena jsou podle prvního znaku z anglického názvu, třeba α je a 
    -𝒜 je crA    ,    ℝ  je dsR    , apod.

Grafika

Plot[Sin[x],{x,0,6 Pi}]

Manipulate[Plot[Sin[a*x],{x,0,6*Pi}],{a,-1,1}]

ListPlot[Table[{x,Sin[x]},{x,0,6 Pi,Pi/10}]]

Plot3D[Sin[x*y],{x,-3,3},{y,-2,2}]

ContourPlot[Sin[x*y], {x, -3, 3}, {y, -2, 2}]

Kombinování grafů do sebe - Show

Show[Plot[x^2,{x,0,4}],ListPlot[Table[{x,x^2},{x,0,4}],Filling->Axis]]