WPROWADZENIE DO MAPLE'A CZ. IV
* INSTRUKCJE WARUNKOWE
* OBLICZENIA CYKLICZNE
* JESZCZE O FUNKCJACH I PROCEDURACH
INSTRUKCJE WARUNKOWE - wybierają jedną ścieżkę obliczeniową z kilku potencjalnie
możliwych
Ogólna budowa instrukcji warunkowej if ... end if:
if wyrażenie warunkowe then
polecenia
elif wyrażenie warunkowe then
polecenia
elif wyrażenie warunkowe then
polecenia
.
.
.
else
polecenia
end if ;
(elif =else + if)
Minimalna składnia instrukcji warunkowej:
if wyrażenie warunkowe then
polecenia
end if ;
Przykład
>
x:=2; # x:=-2
:=
x
2
>
if x>0 then
x:=x-1:
end if:
>
x;
1
>
if 2>1 then
"kontynuujemy wykład"
else
"idziemy na wagary"
end if;
"kontynuujemy wykład"
Przykład
>
x:=2; # zmienić na -1
:=
x
2
>
if x>0 then y:=x->sqrt(x) else y:=x->sqrt(-x) end if;
:=
y
→
x
x
>
y(x);
2
Przykład
>
kasa:=45000;
:=
kasa
45000
>
if kasa>50000 then
print("kupię Golfa")
elif kasa>35000 then
print("kupię C3")
else print("kupię nowy kupon totolotka")
end if;
"kupię C3"
Przykład zagnieżdżenia instrukcji warunkowych ( if wewnątrz if)
>
x:=1;
:=
x
1
>
if x>0 then
print("x jest dodatnie")
else
if x=0 then
print("x jest równe zero")
else
print("x jest ujemne")
end if;
end if;
"x jest dodatnie"
To samo bez zagnieżdżenia - zamiast else if -> elif
>
if x>0 then
print("x jest dodatnie")
elif x=0 then
print("x jest równe zero")
else
print("x jest ujemne")
end if;
"x jest dodatnie"
>
x:='x':
Przypadek, gdy wartość logiczna wyrażenia logicznego
jest równa FAIL
>
testeq(exp(x)=exp(1)^(x));
true
>
testeq(sin(x)^2+cos(x)^2=2);
false
>
testeq(LambertW(x)=x);
FAIL
>
w:=true; # w:=false; w:=FAIL;
:=
w
true
>
w;
true
>
not w;
false
>
if w then
print(1)
elif not w then
print(0)
else
print(-1)
end if;
1
>
>
Operator `if ` - uproszczona forma instrukcji warunkowej if
`if `(wyrażenie warunkowe, polecenia gdy true, polecenia gdy false lub FAIL)
Przykład
>
x:=4; # x:=6
:=
x
4
>
`if`(x<5,1,0);
1
Tradycyjnie
>
if x<5 then
1
else
0
end if;
1
Poprzedni przykład
>
w:=FAIL;
:=
w
FAIL
>
`if`(w,1,0);
0
>
OBLICZENIA CYKLICZNE (obliczenia w pętli)
( for - from, for - in, while )
Ogólna postać pętli typu for - from
for nazwa from wyrażenie by wyrażenie to wyrażenie while wyrażenie warunkowe do
polecenia
end do ;
Uwaga: klauzula for określa liczbę powtórzeń zaś klauzula while określa warunek, który musi być
speniony, aby były wykonywane obliczenia cykliczne
>
restart:
>
for i from 1 by 1 to 5 while i^2>=i! do
i;
end do;
1
2
3
>
i;
4
>
4^2,4!;
,
16 24
>
i;
4
>
i:='i':
Wartości domyślne klauzul (klauzla = zastrzeżenie lub warunek)
from 1
by 1
to infinity
while true
Przykłady:
>
for i while i^2>=i! do
i
end do;
1
2
3
>
for i to 5 do end do; # dopuszczalny jest brak jakichkolwiek
poleceń
>
i;
6
>
i:='i':
>
for i from 1000 while not isprime(i) do end do;
>
i;
1009
>
nextprime(1000);
1009
>
isprime(%);
true
>
i:=1;
:=
i
1
>
do i:=i+1 end do;
>
Przykład instrukcji warunkowej w pętli (sprawdzanie kuponu Totolotka)
>
l:=[1,5,16,23,32,44]; # wynik losowania
:=
l
[
]
, ,
,
,
,
1 5 16 23 32 44
>
k:=[2,5,13,23,16,44]; # liczby skreślone na kuponie
:=
k
[
]
, ,
,
,
,
2 5 13 23 16 44
>
n:=0;
:=
n
0
>
for i to 6 do
for j to 6 do
if k[i]=l[j] then
n:=n+1;
end if;
end do;
end do:
>
n;
4
>
n:='n':
Rzuty kostką do gry
>
rzut:=rand(1..6):
>
to 10 do rzut(); end do;
4
3
4
6
5
3
6
3
2
2
Pętle typu while
Ogólna postać pętli typu while
while wyrażenie warunkowe do
polecenia
end do ;
Przykłady:
>
i:=1;
:=
i
1
>
while i^2>= i! do i:=i+1 end do;
:=
i
2
:=
i
3
:=
i
4
>
i^2, i!;
,
16 24
>
x:=30;
:=
x
30
>
while x>2 do x:=x/2 end do;
:=
x
15
:=
x
15
2
:=
x
15
4
:=
x
15
8
Pętle typu for - in
Ogólna postać pętli typu for - in
for nazwa in wyrażenie while wyrażenie warunkowe do
polecenia
end do ;
Uwaga: nazwie występującej w pętli przypisywane są kolejno elementy wyrażenia (listy, zbioru
etc.)
Przykład
>
dane:=[3,6,0,7,2];
:=
dane
[
]
, , , ,
3 6 0 7 2
>
for x in dane do
if x<=6 then
print(x);
end if;
end do;
3
6
0
2
Uwaga: zamiast i może być cokolwiek np. bzz
>
Przerywanie obliczeń w pętli
( break, next )
Przykłady
>
dane:=[3,6,0,7,2];
:=
dane
[
]
, , , ,
3 6 0 7 2
>
for x in dane do
if x=0 then break
else print(1/x);
end if;
end do;
1
3
1
6
>
dane:=[3,6,0,7,2];
:=
dane
[
]
, , , ,
3 6 0 7 2
>
for x in dane do
if x=0 then next
else print(1/x);
end if;
end do;
1
3
1
6
1
7
1
2
Komendy wykonujące obliczenia w pętli
(seq, $, add, mul,sum, product, map, zip, )
Przykłady
>
seq(t,i=1..10);
, , , , , , , , ,
t t t t t t t t t t
>
t$10;
, , , , , , , , ,
t t t t t t t t t t
>
s:=NULL;
:=
s
>
for i to 10 do s:=s,t end do:s;
, , , , , , , , ,
t t t t t t t t t t
>
add(i,i=1..10);
55
>
S:=0: for i to 10 do S:=S+i; end do: S;
55
>
mul(i,i=1..10);
3628800
>
S:=1: for i to 10 do S:=S*i; end do: S;
3628800
>
n;
n
>
sum(i,i=1..n);
Error, (in sum) summation variable previously assigned, second argument
evaluates to 11 = 1 .. n
>
i;
11
>
sum('i','i'=1..n);
− −
(
)
+
n 1
2
2
n
2
1
2
>
eval(%,n=10);
55
>
product('i','i'=1..n);
(
)
Γ +
n 1
>
eval(%,n=10);
3628800
>
10!;
3628800
>
map(x->x^3,[1,2,3,4,5]);
[
]
, ,
,
,
1 8 27 64 125
>
zip((x,y)->[x,y],[1,2,3],[10,15,20]);
[
]
,
,
[
]
,
1 10 [
]
,
2 15 [
]
,
3 20
>
restart:
JESZCZE O FUNKCJACH (unapply, piecewise)
Zamiana wyrażenia na funkcję ( unapply )
>
w:=x+sin(x)+ln(x)*cot(x);
:=
w
+
+
x
( )
sin x
( )
ln x
( )
cot x
>
f:=unapply(w,x);
:=
f
→
x
+
+
x
( )
sin x
( )
ln x
( )
cot x
>
f(1);
+
1
( )
sin 1
>
W:=sin(r*s)-x*y/z+u^v*t^2;
:=
W
−
+
(
)
sin r s
x y
z
u
v
t
2
>
F:=unapply(W,(r,t,z));
:=
F
→
(
)
, ,
r t z
−
+
(
)
sin r s
x y
z
u
v
t
2
>
F(0,0,1);
−x y
Zapis funkcji przedziałami zmiennej ( piecewise )
Ogólny zapis funkcji/wyrażenia przedziałami zmiennej:
nazwa := piecewise(warunek1, wyrażenie1, warunek2, wyrażenie2, ..., wyrażenie w pozostałym
przedziale)
>
schodki:=piecewise(x<0,0,x<1,1,x<2,2,x<3,3,3*exp(-(x-3)));
:=
schodki
0
<
x 0
1
<
x 1
2
<
x 2
3
<
x 3
3 e
(
)
− +
x 3
otherwise
>
plot(schodki,x=0..10,scaling=constrained);
>
eval(schodki,x=1.3);
2
>
fschodki:=x->piecewise(x<0,0,x<1,1,x<2,2,x<3,3,3*exp(-(x-3)));
:=
fschodki
→
x
(
)
piecewise
, ,
, ,
, ,
, ,
<
x 0 0
<
x 1 1
<
x 2 2
<
x 3 3 3 e
(
)
− +
x 3
>
fschodki(1.3);
2
>
Coś więcej o PROCEDURACH
Ogólna budowa procedury: proc ..... end proc
proc ( sekwencja parametrów formalnych )
local sekwencja zmiennych lokalnych
global sekwencja zmiennych globalnych
options opcje
description opis
polecenia
end proc;
Przykład
>
pschodki:=proc(x)
if x<0 then 0 elif x<1 then 1 elif x<2 then 2 elif x<3 then 3
else 3*exp(-(x-3))
end if
end proc;
pschodki
x
proc( )
:=
<
x 0
0
if
then
<
x 1
1
elif
then
<
x 2
2
elif
then
<
x 3
3
elif
then
∗
3
(
)
exp
− +
x 3
else
end if
end proc
>
pschodki(1.3);
2
>
Sprawdzanie typu parametrów formalnych: p::t
p - parametr formalny, t - deklaracja typu np. integer, nonnegint, list .... (?type)
Przykład
>
restart:
>
silnia:=proc(n::nonnegint)
mul(i,i=1..n):
end proc;
:=
silnia
proc(
)
end proc
::
n nonnegint
(
)
mul ,i
=
i
..
1 n
>
silnia(5);
120
>
silnia(0); # mul(f, i = m..n); If m is greater than n, mul
returns 1.
1
>
silnia(-5);
Error, invalid input: silnia expects its 1st argument, n, to be of type
nonnegint, but received -5
>
silnia(5.5);
Error, invalid input: silnia expects its 1st argument, n, to be of type
nonnegint, but received 5.5
>
0!; (5.5)!;
1
287.8852778
>
factorial(0); factorial(5.5);
1
287.8852778
>
plot(x!,x=0..6);
>
?factorial
>
?doublefactorial
>
doublefactorial(5);doublefactorial(6);
15
48
Zmienne lokalne i globalne
Zmienne lokalne mają znaczenie tylko wewnątrz procedury.
Zmienne globalne są dostępne również na zewnątrz procedury.
>
totek:=proc(l1::list,l2::list)
local i,j;
global n;
n:=0:
for i to 6 do
for j to 6 do
if l1[i]=l2[j] then
n:=n+1;
end if;
end do;
end do;
end proc;
totek
,
::
l1 list
::
l2 list
proc(
)
:=
local
;
,i j
global ;
n
;
:=
n
0 for to do
end do
i
6
for to do
end do
j
6
if
then
end if
=
[ ]
l1 i
[ ]
l2 j
:=
n
+
n 1
end proc
>
k:=[2,5,13,23,16,44];
:=
k
[
]
, ,
,
,
,
2 5 13 23 16 44
>
l:=[1,5,16,23,32,44];
:=
l
[
]
, ,
,
,
,
1 5 16 23 32 44
>
totek(l,k); # kolejność nieistotna
4
Zapamiętywanie procedur i wczytywanie procedur ( save, read )
>
save totek, "totalizator"; # lokalizacja - C:\Program
Files\Maple 9\bin.win lub miejsce pliku Maple'a
>
restart:
>
read "totalizator";
totek
,
::
l1 list
::
l2 list
proc(
)
:=
local
;
,i j
global ;
n
;
:=
n
0 for to do
end do
i
6
for to do
end do
j
6
if
then
end if
=
[ ]
l1 i
[ ]
l2 j
:=
n
+
n 1
end proc
Przyklad procedury
>
restart;
Procedura wyznaczania równań ruchu układów dyskretnych na podstawie równań Lagrange'a
>
lagrange:=proc(n,x,v,L,R)
local i,uzm_x,uzm_v,rel_v_x,Lx,Lv,Lvt,Rv:
global row:
uzm_x:=seq(x[j]=x[j](t),j=1..n);
uzm_v:=seq(v[j]=v[j](t),j=1..n);
for i to n do
Lx[i]:=subs([uzm_x,uzm_v],diff(L,x[i])):
Lv[i]:=subs([uzm_x,uzm_v],diff(L,v[i])):
Rv[i]:=subs(uzm_v,diff(R,v[i])):
end do;
for i from 1 to n do
Lvt[i]:=diff(Lv[i],t):
end do;
rel_v_x:=seq(v[j](t)=diff(x[j](t),t),j=1..n);
for i to n do
row[i]:=subs(rel_v_x,Lvt[i]+Rv[i]-Lx[i]=0):
end do;
seq(row[i],i=1..n);
end proc:
>
Schemat oscylatora harmonicznego
m
k
x
G
G
N
G
>
n:=1;
:=
n
1
>
U:=1/2*k*x[1]^2;
:=
U
1
2
k x
1
2
>
E:=1/2*m*v[1]^2;
:=
E
1
2
m v
1
2
>
L:=E-U;
:=
L
−
1
2
m v
1
2
1
2
k x
1
2
>
rr:=lagrange(n,x,v,L,R);
:=
rr
=
+
m
d
d
2
t
2
( )
x
1
t
k ( )
x
1
t
0
>
dsolve({rr,x[1](0)=x0,D(x[1])(0)=v0},{x[1](t)});
=
( )
x
1
t
+
v0 m
sin
k t
m
k
x0
cos
k t
m
>