Tato stranka je prepisem meho referatu na seminari o Linuxu - a rozhodne nedokaze (a ani nehodla) pokryt vsechny zakouti MuPADu. Jelikoz tento referat mel pouze ambice informovat (a ziskat zapocet), rozhodne nechce suplovat manual k MuPADu. Na teto kratke strance se pouze lehce dotknu nekterych casti MuPADu, zejmena jeho programovaciho jazyku a nekterych bezne pouzivanych funkci, velmi kratce se tez zmini o znazornovani funkci. Zcela mimo dosah tohoto referatu zustava napriklad pretezovani operatoru, spousta funkci, debbuger, ale i knihovny.
Jelikoz jsem v sobe nikdy nenasel dostatek sily vydrzet u jedineho komplexnejsiho matematickeho programu a proniknout do nej, nemohu bohuzel poskytnout zadne srovnani s podobnymi programy a stezi se zamerim na ty oblasti, ktere pravdepodobne zkusenejsiho uzivatele budou zajimat nejvice. Doufam vsak, ze alespon techto par radek pomuze tem, pro ktere jsou matematicke programy spanelskou vesnici tak, jako byly donedavna pro mne.
MuHlavni WWW stranka MuPADu se nachazi na universite v Paderborn , kde je MuPAD vyvijen. MuPADu si muzete tez nahrat z ftp archivu sunsite ci jakehokoliv jineho sunsite.unc.edu mirroru.
Posledni versi je verse 1.2.2, pripravuje se verse 1.3 v soucasne dobe ve fazi betestovani). V soucasne dobe je MuPAD pro Linux, ruzne Unixy, OS/2 a snad jiz i pro M$ Windows (pro uzivatele, kteri pouzivaji Wine:)
S instalaci MuPADu nebudou mit zadne problemy uzivatele (rootove), kteri maji nainstalovany Slackware - MuPAD 1.2.2 je ve versi pro Linux je pripraven k nainstalovani scriptem pkgtool. MuPAD se nainstaluje do adresaru /usr/local/MuPAD, ktery obsahuje jak versi MuPADu pro konzoli, tak i pro X windows. Celkove se do tohoto adresare nainstaluje cca 10 MB souboru. Po ukonceni instalace staci spustit script
usr/local/MuPAD/share/bin/setup
ktery nastavi promenne a linky potrebne ke spusteni MuPADu. Prikazem mupad spustite MuPAD pro konzoli, prikazem xmupad pak MuPAD Xovsky.
MuPAD muze byt pouzivat jak interaktivne, tak neinteraktivne. Z programatorskeho hlediska je hlavni jadro MuPADu napsano v jazyce C, ostatni (knihovny) je napsano v programovacim jazyce MuPAD.
Pravdepodobne ze zacatku Vasim nejpouzivanejsim prikazem bude prikaz pro vyvolani napovedy. Napriklad help k prikazu diff pro derivace vyvolate takto
?diff
Kdyz jsme se jiz zminili o derivovani, bylo by vhodne predvest, jak se derivace pouziji v praxi. Funkci diff, neboli derivaci, muzeme pouzit nasledujicim pusobem
diff( sin(x)*cos(x), x );
cos(x)^2-sin(x)^2
Dale neni tez tezke vypocist integral - k tomuto slouzi funkce int
int( cos(x)^2-sin(x)^2, x );
sin(2 x)
--------
2
A kazdy doufam vidi, ze jsme obdrzeli spravny vysledek, od ktereho jsme vysli. Pro reseni rovnic slouzi funkce solve
solve( x^2-3*x+2,x );
[1,2]
Dale ma MuPAD spoustu preddefinovanych konstant - kuprikladu cislo PI.
PI;
PI
Hmm... takto se tez chova MuPAD - vysledkem PI je PI. Pokud byste
chteli jeho ciselnou hodnotu, musite si o to rici.
float(PI);
3.151692653
Chcete vyssi presnost? Pro MuPAD to neni zadny problem
DIGITS:=40 : float(PI);
3.141592653589793238462643383279502884197
MuPAD muze byt pouzivan jak interaktivnim rezimu, tak tez v rezimu neinteraktivnim. Prikazy se oddeluji bud strednikem ci dvojteckou. Strednik pouzijete v pripade, ze chcete znat vysledek vyrazu (prikazu), dvojtecku, pokud vysledek vypsat nechcete. Vsechny prikazy mimo dvou vyjimek(?,!) se musi byt ukonceny strednikem ci dvouteckou.
Backslash na konci radku znamena pokracovani prikazu na radku dalsim (nevyhodnoti se ihned), ale vyhodnoceni az po ukonceni radku nasledujiciho.
K specialnim znakum lze tez radit znaky ! a ?. Jejich ekvivalenty jsou funkce help() a system(). Help slouzi k vyvolani napovedy, system pro spusteni prikazu systemu - napriklad
? system
system("ls -la");
nebo
! ls -la
K pouziti historie v MuPADu slozi prikaz last(i), respektive pro zkraceni znak "%". last(i) vyvola "i-ty" posledni vysledek
2*PI*5;
10 PI
float(%);
3.141592653e1
Pro MuPAD je vyraz stromem, jeho vyhodnoceni je potom transformace jednoho stromu v strom jiny. Nejdrive jsou operatory setrideny, potom se provede vyhodnoceni potomku uzlu a nakonec se vyhodnoti uzel sam. Pokud neni mozno vyraz vyhodnotit, je nezmenen - napriklad, pokud neni definovana funkce f:
f(1+2+3, sin(PI));
f(6, 0);
Dalsi vyraznou odchylkou oproti klasickym programovacim jazykum je hloubka vyhodnocovani prikazu. Nejprve uvedu priklad (":=" je operator prirazeni):
a:=b: b:=c: c:=4:
a;
4
Pro ty z Vas, ktery tento vysledek udivil, vysvetleni: vysledek je zpusoben hloubkou vyhodnocovani vyrazu. a neobsahuje hodnotu ulozenou v b, ale odkaz na b. Hloubku vyhodnocovani vyrazu ovlivnuje promenna LEVEL, ktera je nastavena na hodnotu 100, ve procedurach pak na hodnotu 1. K docasne zmene hloubky vyhodnocovani prikazu lze tez pouzit funkci level( vyraz [, hloubka] ).
level( a, 2 );
c
LEVE:=1: a;
b
Vyhodnoceni vyrazu muzeme zamezit pouzitim funkce hold.
hold(1+1);
1+1
V MuPADu muzete pouzivat nasledujici typy dat - ovsem, nemusite se samozrejme omezovat pouze na preddefinovane, pokud si dokazete difinovat vlastni.
Datove typy nemusi byt nikdy, az na nekolik vyjimek, explicitne specifikovany.
Vsechno jsou domeny, nebo lepe receno, v MuPADu vse ma svou domain. A toto neplati pouze o zakladnich datovych typech jako prirozena cisla, racionalni cisla, cisla realna a komplexni, ale tez o boolean, poli nebo mnozine. I klicova slova jazyka MuPAD nebo vyrazy jsou domain! Domain jsou jednak typy zakladni, jednak typy definovane uzivatelem.
Pro zakladni praci s domain slouzi funkce domtype( ), ktera vraci domain sveho argumentu.
domtype(1);
DOM_INT
domtype(1.0);
DOM_FLOAT
domtype(1+1);
DOM_INT
domtype(hold(1+1));
DOM_EXPR
V MuPADu jsou ctyri domain pro cisla - DOM_INT, DOM_RAT, DOM_FLOAT a DOM_COMPLEX. Jejich presnost(velikost) neni nijak omezena, je vsak ovlivnovana promennou DIGITS.
V DOM_COMPLEX je definovana komplexni jednotka I
sqrt(-1);
I
Funkce op( cislo, index ) slouzi k ziskani jednotlivych casti komplexnich nebo racionalnich (DOM_RAT) cisel.
op(1+2*I,2);
2
Identifikatory maji tez svou domain, je to domain DOM_INDENT. Identifikatory jsou "case sensitive" a maji neomezenou delku.
DOM_STRING je domain retezcu. Retezce jsou maximalne dlouhe 2^32-1 znaku a jsou uzavreny mezi zavorky. Pro retezce jsou definovany funkce strlen, strmatch, text2list a text2expr.
eval( text2expr("1+1") );
2
Znak backslash (zpetne lomitko, "\") uvozuje specialni znaky:
\\ backslash
\n novy radek
\t tabulator
\? libovolny znak
\* zadny ci nekolik libovolnych znaku
Posledni dva slouzi pro porovnavani retezcu funkci strmatch, ostatni jako formatovaci znaky ve funkci print
print(Unquoted,"Nazdar svete!\n");
NIL, ktery je definovan v DOM_NIL, slouzi ke zruseni odkazu. V MuPAD je implementovana garbage collection, tedy jakykoliv vyraz, na ktery jiz neni zadny odkaz, je zrusen. Prirazenim NIL rusime explicitne.
FAIL v DOM_FAIL vraci MuPAD v pripade, ze vyraz nemuze byt vypocten.
op(a+b+c,4);
FAIL
V domain DOM_BOOL jsou definovany TRUE a FALSE, pro ktere jsou zde bezne logicke operatory and, or, not. Tez if pouziva DOM_BOOL.
TRUE or FALSE;
TRUE
bool( 1 > 2 );
FALSE
DOM_LIST je prvnim z nekolika slozitejsich domain MuPADu. List obsahuje seznam libovolnych vyrazu. Pomoci operatoru [ ] se odkazujeme na jednotlive polozky tohoto listu kdo by si vsak myslel, ze DOM_LIST je pouze jinym nazvem pro pole, mylil by se. Proc, pochopite z nasledujiciho prikladu.
x:=1,2,3: x;
1,2,3
x[2];
2
x[2]:=2,4: x;
1,2,4,3
Doslo k vlozeni listu do listu x - neni vsak pravda, ze by 2. prvek listu x obsahoval list 2,4 - druhy prvek obsahuje 2, treti 4, ctvrty 3. Prvky lze tez z listu vyradit prirazenim polozky NIL (z DOM_NILL).
x[2]:=NIL;
NIL
x;
1,4,3
K spojeni dvou listu (nebo retezcu z DOM_STRING) slouzi operator tecka, nebo funkce append.
y:=10,11,12: x.y
1,4,3,10,11,12
Domain DOM_SET predstavuje implementaci mnozin. Mnozina muze obsahovat jakekoliv prvky (tedy i DOM_EXPR,...), ovsem kazdy prvek je v mnozine obsazen pouze jednou. Mnoziny se uzaviraji do slozenych zavorek.
Pro mnoziny jsou preddeefinovany standardni funkce jako union, minus, intesects a contains
m:={1, PI, a+b, 10.4, 1};
{a+b, 10.4, 1, PI};
contains( m, a+b );
TRUE
m intersect { PI, 10.4, 70^2 };
{1, PI}
Pro toho, kdo umi programovat v PERLu, nebude pochopit DOM_TABLE zadnym problemem, protoze DOM_TABLE bychom mohli prirovnat k PERLoskym hash tabulkam. Tato domain je velmi podobna poli, avsak jako odkaz muzeme pouzit jakykoliv vyraz - at uz DOM_INT nebo DOM_EXP. Tabulky muzeme inicialisovat dvojim zbusobem - bud primo priradit k urcitemu indexu hodnotu, anebo primo seznamem jejich indexu a hodnot.
T[a]:=b:
S:= table( x+y = "Nazdar", 1.0 = b ):
Na rozdil od DOM_LIST nebo DOM_ARRAY se v tabulkach vyrazy nevyhodnocuji. Abych toto lepe vysvetlil, uvedu priklad
x:= 5: y:= 11:
S[16];
S[16]
S;
table (
x+y="Nazdar",
1.0=b
)
Funkce contains ma v DOM_TABLE podobny vyznam jako v mnozinach
contains( S, x + y );
TRUE
Pole je specialni typ DOM_TABLE a jako jediny z typu (ci domain) musi byt explicitne definovan, a to funkci array. Pro odkazy do pole jsou musi byt pouzita prirozena cisla - tedy nikoliv cisla zaporna.
A:= array(1..3, 1..3);
Nebo i s inicialisaci:
magic:= array(1..3, 1..3, [[8, 1, 6], [3, 5, 7], [4, 8, 2]] );
Pozor - DOM_ARRAY se nechova jako DOM_LIST - neni tedy mozno vkladan ani rusit (menit rozmer) pole.
magic[1,2]:=NIL:
magic;
+- -+
| 8 , ?[1,2] , 6 |
| |
| 3 , 5 , 7 |
| |
| 4 , 8 , 2 |
+- -+
Tato domain je urcena k efektivni praci s polynomy, kterou by DOM_EXPR neumoznovala. Na polynom muzeme prevest vyraz pomoci funkce poly( vyraz, seznam (list) promennych), polynom lze kdykoliv prevest zpet na vyraz funkci expr(). Jelikoz jsou exponenty jako integer (programove, nikoliv DOM_INT), maximalni velikost sumy mocnin jedne casti polynomu je 2^32-1 (vsichni jiste s tak velkymi mocninami pocitate dene).
Polynomy lze mezi sebou navzajem scitat, nasobit, museji vsak mit stejny seznam promennych.
p:= poly(x^2-2*y+12, [x,y]);
p * poly(x^2-1, [x,y] );
(vysledek se mi nechce opisovat - vyzkousejte si sami)
Do teto domain patri temer vsechno ostatni - patri sem vyrazy, smycky, procedury
Operatory:
$1..5;
1,2,3,4,5
1/i$i=1..3;
1, 1/2, 1/3
"Nazdar" . " svete!";
"Nazdar svete!"
Pokud je vsak prvnim parametrem teto funkce identifikator, vysledkem bude identifikator novy:
a."bc":= 1; je totez, co abc:=1;
a.i$i=1..3 a1, a2, a3
Pozor!
a:=b: c:=d: bd:=3;
a.c
bd
(f @ g @ h) () je totez, co f( g( h() ))
(f+g)( ) znamena totez, jako f( )+g( )
(f^2)( ) ma stejny vyznam, jako ( f( ) )^2
T[1]:= T[1];
T[1];
Error: recursive definition
index_val(T,1);
T[1]
if vyraz
then
elif vyraz
then
else
end_if
case vyraz
of vyraz do
of vyraz do
otherwise
end_case
Poznamka: Pokud neni explicitne preruseno vykonavani prikazem break (jako
v jazyce C), bude se pokracovat nasledujicim blokem. Pokud vyhovuje vice
podminek, budou provedeny vsechny (vyhovujici).
for identifikator from vyraz to vyraz step cislo
do
end_for
for identifikator from vyraz downto vyraz step cislo
do
end_for
for identifikator in vyraz
do
end_for
while vyraz
do
end_while
repeat
until vyraz
end_repeat
break, next - maji stejny vyznam jako break a continue v klasickych jazycich.
DOM_PROC je domain procedur. Kazda procedura ma tyto atributy:
Definice funkce ma nasledujici syntaxi
proc identifikator local ....; option .....; name ....; begin end_proc
Polozka name, neboli jmeno procedury neni povinna:
f:= proc (m, n) . . .
Za navratovou hodnotu je je povazovan posledni vysledek pri vykonavani procedury, nebo parametr funkce return, ktera slouzi k okamzitemu ukonceni procedury.
Jak jsem se jiz zminil v predchozich radich, promenna LEVEL ovlivnujici hloubku vyhodnocovani vyrazu, je nastavena na 1 (misto beznych 100). Proc, vyplyne z nasledujiciho prikladu
f:= proc(x)
begin
sqrt( x );
end;
Pokud bychom dale napsali f( x^2 ); a LEVEL by byl roven 100, doslo by k rekurzivnimu vyhodnocovani vyrazu.
V MuPAD jsou vsechny parametry volane hodnotou. Pokud v definici procedury primo nespecifikujeme parametry, muzeme se na ne odkazovat pomoci args(cislo), args(0) vraci pocet argumentu.
f:=proc()
begin
args(0);
end_proc;
f(a+b,1,PI);
3
f((1,2,3,4),5);
5
Pozor, posledni vysledek je skutecne 5, nikoliv 2. Na nasledujicich radcich se muzete podivat, jak by vypadala procedura sumy
suma:= proc()
local i, S;
begin
if args(0) = 0
then return( procname());
end_if;
S:=0;
for i from 1 to args(0) do
S:= S + args(i);
end_for;
end_proc;
suma();
suma();
Tento vysledek je zapricinen nulovym poctem argumentu, ktery osetrila podminka na zacatku procedury. Dalsi priklad jiz spocita korektni vysledek
suma(1,2);
3
Lokalni promenne maji samozrejme pouze lokalni platnost - presto pozor, mohou
se vyskytnout nektere osemetne situace:
a:=1;
b:=7;
f:= proc()
local a;
begin
a:= PI;
b:= a;
end;
f();
b;
1
Promenne MuPADu, jako napriklad promenne DIGITS, LEVEL nebo promenna PRINT (ovlivnuje mnozstvi tisknuti informaci o probehu funkce), mohou byt tez lokalni.
hold - MuPAD nebude vyhodnocovat parametry procedury
remember - tento option (radeji nechavam toto slovo neprelozene, aby se nepletlo s parametrem) umoznuje zrychlit nektere slozitejsi vypocty - pro proceduru je zalozena tabulka (DOM_TABLE), ktera nese zaznamy o jiz probehlych vypoctech, takze pro nektere parametry uz neni treba vypocet opet opakovat. K tabulce jiz spocitanych hodnot je mozno pristupovat tez primo
fibonacci(0):=1;
fibonacci(1):=1;
fibonacci:= proc(a)
option remember;
begin
fibonacci(a-1)+fibonacci(a-2);
end_proc;
Procedura (nebo funkce?, mam v tom zmatek - ale nebojte se, drive nebo pozdeji si to urcite ujasnim) op() ma velmi mnoho pouziti. Jiste si pamatujete, jak nekde ze zacatku tohoto dokumentu jsem psal o jejim pouziti pro komplexni cisla. Zkusme pouzit funkci op na nasi proceduru fibonacci:
op(fibonacci);
table(
(a, NIL, remember, fibonacci(a-1)+fibonacci(a-2), 0=1, fibonacci)
1=1
)
Jedna se o jednotlive atributy procedur - prvni jsou formalni parametry - v nasem pripade a. Druhe jsou lokalni promenne - v nasem pripade funkce zadne nema. Treti jsou option procedury, ctvrte jeji samotne telo. Za nim je remember table, neboli tabulka jiz vypoctenych hodnot, posledni je jmeno procedury. Lze tez nechat si vypsat napriklad pouze jmeno nebo remember tabule.
op(fibonacci, 6);
fibonacci
Funkce jsou velmi podobne proceduram, lisi se vsak od nich zejmena tim, ze nemaji zadne lokalni promenne a parametry. Na parametry se odkazuje pomoci args(). K vytvoreni pure function slouzi funkce fun() a func().
Zde uvadim seznam nejpouzivanejsich funkci pro praci s objekty - vsechny tyto funkce lze vzdy _predefinovat_.
type(a+b);
"_plus"
SIMPLE::testtype:= proc(a)
begin
case domtype(a)
of DOM_INT do
of DOM_FLOAT do
of DOM_RAT do TRUE; break;
otherwise FALSE;
end_case;
end_proc;
test_type(1, DOM_INT);
TRUE
test_type(1, SIMPLE );
TRUE
Toto stacilo, abychom si nadefinovali novou domain SIMPLE a jeji funkci.
nops(1+2+3+4);
1
nops(hold(1+2+3+4));
4
nops(a+b);
2
nops(a*b+c+d*e);
3
op(a+b+c);
a,b,c
op(a+b^c);
c
a, b
op(fibonacci, 5);
table(
0=1,
1=1,
2=2,
3=3,
4=5,
5=8
)
op(g(a,b,c));
a,b,c
op(g(a, b, c), 0);
g
subsob( a+b, 2=f(a));
a+f(a)
subsob( c + f(y), [1,2]= 5 );
c + f(5)
subsex( a*b*c + d*e, a*c=x );
d*e+b*x
Newton:= proc( f, start, n )
local x, y, i, df, DIGITS;
begin
DIGITS:=15;
df:= diff( f(y), y );
x[0]:= float(start)
print(x[0]);
for i from 0 to (n-1) do
x[i+1] := subs((y*df-f(y))/(df-1), y=x[i]);
print(x[i+1);
end_for
end_proc;
ff := proc(x) begin x^2-1 end_proc;
Newton(ff, 1.0, 10);
int( sin(x)/x, x=0..infinity)
PI
__
2
Pokud MuPAD nedokaze integral vypocitat, je zde jeste moznost vypocitat jej numericky
int( sin(cos(x)), x=0..1);
int( sin(cos(x)), x=0..1)
float(%);
0.738642998
limit( sin(x)/x, x=0, Right);
1
factor(3*x^4+5*x^3-3*x-1);
2
[1, - x + 3 x - 1, 1, x + 1, 2]
tan := funcattr(tan, "diff", proc(x, var) begin
diff(op(x, 1), var)*(1+tan(op(x,1))^2)
end_proc):
diff(tan(2*x),x);
2*tan(2*x)^2 + 2
Na tomto miste by se jiste sluselo rozepsat se o tom, jake MuPAD kresli krasne
grafy, jak je lze kreslit at jiz primo pouzitim konstrukci jazyka MuPADu ci
pomoci grafickych menu, jak lze specifikovat temer cokoliv - od intervalu, na
kterych se funkce kresli, az po natoceni a osviceni funkci v R3. Pravda vsak
take je, ze se zkousenim technto moznosti MuPADu jsem moc stesti nemel -
ac velmi stabilni, MuPAD mi pri pokouseni techto moznosti nekolikrat osklive
hapal a jednou se mu podarilo okynka totalne zamrznout. Snad priste...