Funkcje i Procedury. Określanie Funkcji. Rozwiązanie skomplikowanych zagadnień czasami jest niemożliwe bez zastosowania własnej funkcji i procedur. Chcemy stworzyć dobre aplikacje? Trzeba umieć stworzyć kompaktowe i elastyczne procedury. f [ x _]: = Wyrazenie Określa funkcję.? f Daje informację o funkcji. Clear [ f ] Anuluje wcześniej określoną funkcję. Podkreślenie po x, po lewej stronie definicji, jest koniecznym i oznacza, że x_ jest formalnym argumentem. Jeśli funkcja była określona, wtedy ponowne określenie ignoruje poprzednie. Wyrażenie - to jest dowolne wyrażenie, które można zapisać w Mathematica i w wyrażeniu x występuje bez podkreślenia. Procedurę określa się następująco proc [ x _, y _,...]: = ( Wyrazenie1 ; Wyrazenie2;... Wyrazenien ) Tu proc jest nazwą procedury, a x_,y_,.. są formalnymi parametrami. Prawą stroną procedury może być dowolny ciąg wyrażeń zapisanych w okrągłych nawiasach i oddzielony między sobą średnikiem. Jeśli za ostatnim wyrażeniem nie ma średnika, wtedy wartością naszej procedury będzie wartość tego wyrażenia, w przeciwnym razie wartość procedury nie będzie określona. W Mathematica wszystkie nazwy standardowych procedur i funkcji zaczynają się dużą literą. Aby nazwa naszej procedury nie pokrywała się z nazwą standardowej, lepiej będzie, żeby pierwsza literka w nazwie naszej funkcji była mała. Bardzie szerokie możliwości daje procedura określona jako Module: nazwa@x_, y_,...d := Module@8a, b,...<, < Ciało procedury >D Tu Module jest słowem kluczowym; nazwa to dowolna nazwa, która zaczyna się małą literą; x_,y_,...formalne parametry a {a,b,...} to zmienne lokalne, ich znaczeń nie widać poza granicą procedury. Przy określaniu funkcji typu Module, aby uniknąć błędów, zaleca się od początku zapisać pusty moduł, jak poniżej: nazwa[x_,y_,..]:=module[{}, ] a potem uzupełnić ją. Ciało procedury zapisuje się między przecinkiem i prawym kwadratowym nawiasem. Funkcję warunkową określa się następująco: f [ x _]: = Wyrazenie/;warunek; 24
Wszystkie reguły po wyrażeniu zaczyna się od znaków /;. Efekt takiego określenia widać na poniższym przykładzie. In[38]:= g@x_d := x^2 + 2x 4ê;x 2; g@x_d := 2x+ 8ê;2< x 4; g@x_d := x^2+ 12 x 32 ê;x> 4; a wykres tej funkcji wygląda następująco: In[43]:= Plot@g@xD, 8x, 2, 8<D 4 2-2 2 4 6 8-2 -4 Out[43]= Graphics Funkcję tą mogliśmy deklarować inaczej: g@x_d := If@x 2, x^2 + 2x 4, If@2 < x 4, 2x+ 8, x^2+ 12 x 32DD Jest oczywiste, że te dwie funkcje są identyczne, czyli w Mathematica zawsze istnieje kilka sposobów rozwiązywania problemów. W Mathematica można pisać funkcje z nieokreślonymi ilościami formalnych parametrów. W takich przypadkach, formalny parametr zapisuje się dwoma lub trzema podkreśleniami. x_ (jedno podkreślenie) wskazuje na to, że w tym miejscu może wystąpić jedno wyrażenia. x (Dwa podkreślenia) wskazuje na to, że w tym miejscu może wystąpić jedno lub więcej wyrażeń. x (trzy podkreślenia) wskazuje na to, że w tym miejscu może wystąpić zero lub więcej wyrażeń. Trzeba być bardzo ostrożnym przy zapisywaniu funkcji z nieokreślonymi ilościami formalnych parametrów. W poniższych przykładach pokazujemy, jak działa funkcja z nieokreślonymi parametrami w różnych przypadkach, czyli jak wynik zależy od postaci samej funkcji. 25
In[1]:= f@x_, y D := x 2 + y In[2]:= f@ad Out[2]= a 2 In[3]:= f@a, bd Out[3]= a 2 + b In[4]:= f@a, b, cd Out[4]= a 2 + b+ c się. Tu określona jest prosta funkcja. po lewej stronie której y ma potrójne podkreślenie. Tu zamiast y domyślnie bierze się zero. Parametry, jeśli ich ilość jest większa niż dwa, sumują In[5]:= f@x_, y D := x 2 + 2y In[6]:= f@ad Out[6]= 2+ a 2 Tu zamiast y domyślnie bierze się jeden. In[7]:= f@ a, bd Out[7]= In[8]:= a 2 + 2b f@ a, b, cd Out[8]= a 2 + 2bc występują Parametry, jeśli ich liczba jest większa niż dwa, jako iloczyn. In[9]:= f@x_, y D := x 2 + y 3 In[10]:= f@ad Całkiem inny otrzymujemy wynik, gdy funkcja zmienia postać. Out[10]= 3 + a 2 In[11]:= f@a, bd Out[11]= a 2 + b 3 In[12]:= f@a, b, cd Out[12]= a 2 + b c3 Tu każdy następny parametr pojawia się w potędze. Domyślne parametry i opcje. Czasami trzeba określić funkcje w której pewne argumenty są domyślne i można je omijać. Szablon x _ : v oznacza, ze argument w tym miejscu można opuścić i za jego wartość przyjmuje się znaczenie ν, jak to pokazano na przykładzie: 26
In[1]:= f@x_, n_: 3D := x^n + 1 In[2]:= f@ad Out[2]= 1+ a 3 In[3]:= f@a, 5D Out[3]= 1+ a 5 Również za pomocą opcji można określić domyślne argumenty, różnica jest w tym, że opcja nadaje nazwę argumentowi. Formalny parametr, który powinien być określony jako opcja, pisze się z potrójnym podkreśleniem. f[x_, opts ]:=<Ciało procedury> Aby zastąpić domyślną wartość argumentu bieżącym parametrem opts, w ciele procedury trzeba napisać: Opcja/.{opts}/Options[f] A domyślna wartość argumentu określa się stosując instrukcję Options. Options[f]={opcja wart} gdzie f to jest nazwą procedury, opcja nazwą domyślnego argumentu, który można pomijać a wart to domyślna wartość argumentu. Działanie tej instrukcji zobaczymy w następujących przykładach: a) Gdy instrukcja Options określa opcję poza ciałem procedury: Załóżmy, że chcemy określić funkcje g [ x] = x m + 1 i chcemy, by tam gdzie potęga jest ominięta domyślną wartością potęgi było 3. In[1]:= Options@gD = 8m 3< Out[1]= 8m 3< In[2]:= g@x_, opt D := Hx^m ê. 8opt<ê. Options@gDL + 1 In[4]:= g@xd Out[4]= 1+ x 3 In[5]:= g@x, m > 8D Out[5]= 1+ x 8 b) Gdy instrukcja Options jest określana wewnątrz procedury: Załóżmy chcemy określić funkcje SumaPotęgy@x, yd = xn + y m niech wtedy domyślnymi wartościami będą n=2, m=2. i gdy potęgi są ominięte, 27
In[6]:= SumaPotęgi@x_, y_, opt D := HOptions@SumaPotęgiD = 8n 2, m 2<; Hx^n ê. 8opt< ê. Options@SumaPotęgiDL + Hy^m ê.8opt<ê. Options@SumaPotęgiDLL In[7]:= SumaPotęgi@x, yd Out[7]= x 2 + y 2 In[8]:= SumaPotęgi@x, y, m 7, n 10D Out[8]= x 10 + y 7 Funkcje prymitywne można określić trzema sposobami: Function[x, ciało] funkcja prymitywna ma jeden argument x, który można zastąpić dowolnym wyrażeniem. Function[{x 1, x 2, }, ciało] Ciało& funkcja prymitywna ma wiele argumentów. funkcja prymitywna, w której argumenty są zdefiniowane jako # lub #1, #2 itp. #1 to będzie pierwszy parametr, #2- drugi itp. Na przykład, jeżeli chcemy określić funkcje s=sin(x) 3 +1, jako funkcję prymitywną piszmy In[1]:= s = Function@x, Sin@xD^3 + 1D Out[1]= Function@x, Sin@xD 3 + 1D a następnie x zamieniamy na ArcSin(a), otrzymujemy In[2]:= s@arcsin@add Out[2]= 1+ a 3 Jeżeli chcemy obliczyć sumę kwadratów pierwszych n naturalnych liczb, lepiej będzie skorzystać z funkcji prymitywnej następującej postaci In[4]:= f = H#2 2 + #1L &; a następnie wystarczy napisać In[5]:= n = 7; FoldList@f, 0, Range@nDD Out[5]= 80, 1, 5, 14, 30, 55, 91, 140 < 28