TECHNICKÁ UNIVERZITA V LIBERCI
Fakulta strojní Katedra aplikované kybernetiky
BAKALÁŘSKÁ PRÁCE
2012 Říčan Michal
TECHNICKÁ UNIVERZITA V LIBERCI FAKULTA STROJNÍ
S
tudijní obor 2301R030 VÝROBNÍ SYSTÉMY
se zaměřením na :
INŽENÝRSKOU INFORMATIKU
KNIHOVNA MATEMATICKÝCH FUNKCÍ PRO JAZYK REXX
LIBRARY OF MATHEMATICAL FUNCTIONS FOR REXX LANGUAGE
Říčan Michal
Vedoucí bakalářské práce : Ing. Michal Moučka Ph.D.
Rozsah stran : 57 Počet příloh : 3
OFICIÁLNÍ ZADÁNÍ
BAKALÁŘSKÉ
PRÁCE
P R O H L Á Š E N Í
Byl jsem seznámen s tím, že na mou bakalářskou práci se plně vztahuje zákon č. 121/2000 o právu autorském, zejména § 60 (školní dílo).
Beru na vědomí, že Technická univerzita v Liberci (TUL) nezasahuje do mých autorských práv užitím mé bakalářské práce.
Užiji-li bakalářskou práci nebo poskytnu-li licenci k jejímu využití, jsem si vědom povinnosti informovat o této skutečnosti TUL; v tomto případě má TUL právo ode mne požadovat úhradu nákladů, které vynaložila na vytvoření díla, až do její skutečné výše.
Bakalářskou práci jsem vypracoval samostatně s použitím uvedené literatury a na základě konzultací s vedoucím bakalářské práce a konzultantem.
Datum :
Podpis :
PODĚKOVÁNÍ
Rád bych zde poděkoval vedoucímu práce Ing. Michalu Moučkovi, Ph.D. za cenné rady a čas, který mi věnoval při tvorbě bakalářské práce. Dále bych rád poděkoval rodině a přátelům za podporu během studia. Nadále nesmím opomenout svoji přítelkyni Markétu Pipkovou, které bych rád poděkoval za korekturu textu.
ANOTACE
Bakalářská práce se zabývá tvorbou dynamické knihovny matematických funkcí pro programovací jazyk REXX. V průběhu práce je čtenář seznámen se základní problematikou dynamických knihoven a programovacím jazykem REXX. Většina práce je věnována praktické části, kde je popsáno, jakým způsobem a v jakém prostředí byla knihovna tvořena, jsou zde popsány jednotlivé soubory, které musí knihovna pro správnou funkci obsahovat, a způsob jakým lze knihovnu přeložit. Výsledkem je funkční knihovna matematických funkcí, která může být použita společně s jakoukoliv aplikací využívající REXX.
Klíčová slova : knihovny ( programování ), programovací jazyk REXX, dynamická knihovna, šablona knihovny, překlad knihovny.
ANOTATION
This thesis deals with the creation of a dynamic library of mathematical functions for programming language REXX. During the work the reader is familiar with the fundamentals of dynamic libraries and programming language REXX . Most of the work is devoted to the practical part, which describes how and in what environment the library was formed. All files for proper function are described and there is shown the way how to compile the library.The result is functional library of mathematical functions that can be used together with any application using REXX.
Klíčová slova : libraries ( computing ), programming language REXX, dynamic library, template of library , compile of library.
OBSAH
1 Úvod...9
2 Knihovny...10
2.1 Výhody...11
2.2 Nevýhody...11
3 Programovací jazyk REXX...12
3.1 Historie...12
3.2 Charakteristika...13
3.3 Klíčová slova...13
3.4 Cykly a podmínky...14
3.5 Proměnná STEM...15
3.6 Ukázkový program...17
3.7 Funkce a procedury...19
3.7.1 Interní funkce...19
3.7.2 Vestavěné funkce...20
3.7.3 Externí funkce...21
3.7.4 Funce RXFUNCDROP()...21
3.7.5 Funkce RXFUNCQUERY()...22
3.7.6 Funkce FUNCDEF()...22
3.7.7 Funkce RXFUNCADD()...24
3.8 RexxUtil...25
4 Vývoj knihovny – MathRexx...26
4.1 Vývojové prostředí...26
4.2 Tvorba matematických funkcí...26
4.3 Tvorba šablony pro knihovnu...30
4.4 Kompilace (překlad) DLL knihovny...34
5 Použití knihovny – MathRexx...37
5.1 Seznam funkcí...37
5.3 Deregistrace funkcí...39
5.4 Funkce a použití...40
5.4.1 RxDegToRad...40
5.4.2 RxRadToDeg...40
5.4.3 RxSin...40
5.4.4 RxCos...41
5.4.5 RxTan...41
5.4.6 RxCot...41
5.4.7 RxAsin...42
5.4.8 RxAcos...42
5.4.9 RxAtan...42
5.4.10 RxSqrt...43
5.4.11 RxExp...43
5.4.12 RxFakt...43
5.4.13 RxLn...44
5.4.14 RxLog...44
5.4.15 RxMocnina...44
5.4.16 RxNewton...45
5.4.17 RxLinReg...45
5.4.18 RxExpReg...46
5.4.19 RxDetMatrix...46
5.4.20 RxInvMatrix...47
5.4.21 RxMulMatrix...48
5.4.22 RxSma...48
5.4.23 RxSavGolCoef...49
5.4.24 RxBSortU...49
5.4.25 RxBSortD...50
6 Ukázka aplikace funkcí z knihovny...51
7 Závěr...54
Seznam použité literatury...55
Seznam příloh...57
1 Úvod
V dnešní době se již snad každý člověk, užívající počítač pravidelně, za účelem zábavy, vzdělání, práce či jiné činnosti, setkal s pojmem knihovna. Ale co si pod pojmem knihovna v informatice představit? Knihovnu v informatice můžeme z hlediska účelnosti přirovnat ke knihovně, kterou všichni dobře známe. Když si představíme, že knihy jsou funkce či procedury a my jsme aplikace. V případě, že nás někdo požádá o činnost či pomoc, o které nic nevíme, zajdeme do knihovny a danou problematiku si nastudujeme. V informatice je to podobné, aplikace plní příkazy uživatele, a když narazí na funkci, kterou neznájí, „navštíví“ knihovnu a funkci načtou (nastudují). Aplikace, stejně jako my, musí vědět, kde knihovnu hledat.
Náplní bakalářské práce bylo vytvořit knihovnu matematických funkcí pro programovací jazyk REXX, která by rozšířila funkčnost a použitelnost jazyka REXX.
Podnětem k tvorbě této knihovny byla knihovna stávající, která obsahuje pouze základní funkce, a proto složitější výpočty bylo nutné provádět v jiném jazyce či softwaru.
Knihovna bude obsahovat matematické, goniometrické funkce, aproximace a interpolace, filtry a třídící funkci. Funkce jsou naprogramovány v programovacím jazyce C a následně exportovány do DLL knihovny přes kterou budou v REXXu volatelné.
V teoretické části se nejprve seznámíme s knihovnami, jejich základním rozdělením a problematikou, poté si řekneme něco o výhodách a nevýhodách použití knihoven. Dále se seznámíme s programovacím jazykem REXX Jelikož se jedná o velice užitečný a silný nástroj, probereme si ho trochu podrobněji.
V praktické části bude rozepsána kompletní tvorba knihovny. Od tvorby matematických funkcí, kde bude postupně vysvětleno jak vytvořit různé druhy funkcí, přes šablonu která bude tvořit ''srdce'' DLL knihovny. Závěr praktické části se bude zabývat překladem knihovny, jejím voláním a použitím.
Jako poslední část práce bude uveden manuál ke knihovně. Zde budou popsány funkce, které knihovna obsahuje, k čemu jednotlivé funkce slouží, jak je volat, jaké
2 Knihovny
Jak již bylo zmíněno v úvodu, knihovna v informatice je soubor obsahující funkce a procedury, v případě objektově orientovaného programování i objekty, datové typy a zdroje, který může sdílet více počítačových programů ( aplikací ). Pro programátora představuje knihovna ulehčení práce a zpřehlednění kódu (viz obr. 1). Dle způsobu propojení s programem můžeme knihovny dělit na statické a dynamické. [1]
Staticky linkované jsou ty knihovny, u kterých, v lepším případě, dochází v závěrečné fázi překladu programu ze zdrojového do strojového kódu k připojení volaných funkcí do výsledného spustitelného souboru. K připojení se používá spojovací program (linker). V horším případě se k programu připojuje celá knihovna, bez ohledu na to, jestli budou využity všechny její části.
Staticky linkovaný soubor při spuštění nepotřebuje žádné další soubory. Z toho důvodu odpadá instalace a lze jej jednoduše překopírovat na jiný systém a bez problému spustit.
Statické knihovny nejčastěji využívají příponu .lib nebo .a záleží však na použitém operačním systému, programovacím jazyku a linkeru.
Dynamickou knihovnu lze také slinkovat s programem.Ttyto knihovny užívají nejčastěji příponu .so [1]
U dynamicky linkované knihovny (DLL), na rozdíl od statických knihoven nedochází k propojování programu s knihovnou v době překladu, uvádějí se pouze odkazy na volané funkce. Pomocí linkeru jsou zapsány do speciální tabulky symbolů, která je připojena k výslednému souboru.
Ke spuštění takto sestaveného programu je potřeba mít k dispozici příslušné dynamické knihovny, jelikož spuštěný program přistupuje k funkcím až v době, kdy na ně narazí.
Dynamická knihovna se může odkazovat i na jiné dynamické knihovny a tím vzniká řetězec závislostí, v němž musejí být všechny knihovny přítomny.
Podle použitého systému se můžeme u Windows setkat s příponou .DLL, u
2.1 Výhody
− Aplikace nemusí být napsána ve stejném jazyce jako knihovna, je však potřebné zajistit shodu konvence volání a datových parametrů.
− Disková úspora: více aplikací je schopno využívat funkce z této knihovny najednou a nemusí být na disku vícekrát.
− Paměťová úspora: data z DLL jsou do fyzické paměti nataženy jen jednou
− Rozšíření, oprava funkcí : stačí aktualizovat DLL knihovnu, nemusíme zasahovat do kódu aplikace, v případě, že neměníme názvy funkcí.[2]
2.2 Nevýhody
Ač by se mohlo zdát, že DLL knihovny jsou geniálním řešením, mají i své nevýhody, které by si člověk při práci s nimi měl uvědomit.
− Nejznámější problém v oblasti DLL knihoven se nazývá DLL hell. K tomuto problému dochází v případě instalace nové aplikace, která používá sdílenou knihovnu, avšak novější verzi, která nemusí být kompatibilní se starší, kterou užívají ostatní aplikace. Tím dochází k problému, že aplikace užívající starší verzi knihovny nemusí fungovat korektně popř. se vůbec nespustí.
− V případě, že nalinkujeme více knihoven a začneme načítat složitější funkce, může se projevit zpomalení, které je způsobeno pomalejším přístupem k funkcím a procedurám.
− U sdílených knihoven může dojít i k problému při odinstalaci aplikace. Jestliže software pro odinstalaci předpokládá, že je knihovna sdílena, tak ji neodinstaluje a knihovny se nám hromadí do doby, než naformátujeme disk popř nepoužíváme nějaký speciální software zaměřený na čistění nevyužívaných DLL knihoven.
− Další problém však může nastat i v případě, že při odinstalaci programu deinstalační program nepředpokladá, že jde o sdílenou knihovnu a smaže ji. V tomto případě aplikace, které tuto knihovnu využívají nebudou fungovat korektně nebo vůbec. Tento problém se dá řešit jedině stažením této knihovny popř. reinstalací aplikace[2]
3 Programovací jazyk REXX
3.1 Historie
Název REXX je odvozen z anglického REstructured eXtended eXecutor. Nejprve byl pojmenován jako REX. Po problémech s již patentovaným názvem REX došlo k úpravě na REXX.
Autorem jazyka je Mike Cowlishaw který jazyk tvořil v letech 1979 – 1982 v laboratořích IBM. Myšlenkou při tvorbě bylo vytvořit skriptovací jazyk pro libovolný systém (viz. dnešní Python), který by byl schopen nahradit jazyk EXEC popř. ECEX 2.
V roce 1992 se jazyk začal stávat více a více populárním a rozšiřoval se mezi veřejnost. To sebou přineslo i freeware verze interpretu jazyka REXX. Mezi neznámější v této době lze zařadit REXX/imc pro Unix jehož autorem je Ian Collier a Regina pro Windows a Linux jejímž autorem je Anders Christenses O aktualizaci Regini se až dodnes stará Mark Hessling.
V polovině 90. let se objevili dvě varianty REXXu, Classic REXX, který bude popsán níže a ObjectREXX, který umožnoval objektově orientované programování v REXXu.
Rok 1996 s sebou přinesl rozšíření jazyka s pojmenováním NetREXX. Umožnuje psaní Java Appletů v REXXu.
Standard jazyka byl vydán v roce 1996 Americkým národním standardizačním institutem (ANSI) ANSI X3.274–1996 “Information Technology – Programming Language REXX”.
OpenObjectREXX (ooREXX) byl v roce 2005 vydán jako veřejná verze přímo od IBM. V současné době se o aktualizaci tohoto projektu stará Rexx Language Association (RexxLA). [3]
3.2 Charakteristika
REXX je spíše než programovací jazyk označován jako makroeditor jazyků a testových procesorů, povelový jazyk databázových dialogových operačních systémů, systémů řízení počítačové sítě, popř jako jazyk pro tvorbu skriptů umožňujících automatizovat a integrovat aplikace.
Dle výše uvedených charakteristik se může zdát, že se jedná o univerzální programovací jazyk, za což ho také můžeme považovat. Jonh Dvorak, známý počítačový publicista, přirovnal jazyk REXX ve svém článku Get Rexx - It Pays (Computer Shopper, November 1999) k švýcarskému armádnímu noži. [4]
Jednou z velkých odlišností od většiny programovacích jazyků je, že chybí deklarace a typy. Jelikož veškeré údaje jsou brány jako znakové řetězce proměnné délky. Proměnná se ze symbolu stává až v době přiřazení, což bývá při běhu programu.
REXX zpracovává slova jako neprázdné řetězce znaků, které neobsahují mezeru.
[5]
3.3 Klíčová slova (keyword instructions)
REXX obsahuje pouze 23 instrukcí (tab.1) s minimálními interpunkčními a formátovacími požadavky. Velkou výhodou je, že jsme u většiny instrukcí schopni dle názvu odhadnout, k čemu slouží.Všechny instrukce jsou stejného datového typu a to řetězce znaků. Což zjednodušuje ladění, trasování a všechny data zpřehledňuje.
Mezi nejčastěji využívané instrukce patří SAY, které slouží k výpisu na obrazovku nebo např. instrukce PULL, která slouží k načtení dat od uživatele.[6]
Tab. 1 – 23 klíčových slov jazyka REXX
ADDRESS IF OPTIONS RETURN
ARG INTERPRET PARSE SAY
CALL ITERATE PROCEDURE SELECT
DO LEAVE PULL SIGNAL
DROP NOP PUSH TRACE
EXIT NUMERIC QUEUE
3.4 Cykly a podmínky
Cykly a podmínky nám slouží k řízení chodu programu. U většiny programů napsaných v REXXu se s nimi můžeme setkat.
Pro začátek cyklu se v klasickém REXXu využívá klíčového slova DO a zakončujeme slovem END. Zde je odlišnost s rozšířením NetREXX, kde se používají slova LOOP pro začátek a END pro ukončení smyčky. Objektově orientovaný Rexx (ooREXX) využívá jak DO/END tak LOOP/END.
Jelikož se v prostředí klasického REXXu využívá pouze DO/END, budou uvedeny příklady pouze této smyčky. [7]
DO i = 1 to 5 by 1 //
SAY i // Cyklus vypíše na obrazovku čísla od 1 do 10.
END // Inkrementace je +1
//
a = 5; b = 10 //
DO WHILE a<b //
say a // Cyklus vypisuje číslo a dokud platí že, a<b
a = a + 1 //
END //
//
a = 10; b = 5 //
DO UNTIL a=b // Cyklus vypusuje Executed dokud se a nebude say Executed // rovnat b
b = b+1 //
END //
V případě, že budeme potřebovat zajistit chod programu určitou podmínkou máme na výběr ze dvou IF/ELSE a SELECT.
a = 10; b = 9 //
IF a > b THEN // Kontrola zda je splněna podmínky že a>b SAY A je vetsi nez B //
else if a = b then // Kontrola zda se a = b SAY A se rovna B //
else // V případě, že ani jedna z předchozích SAY A je mensi nez B // nebyla splněna je vykonán tento příkaz.
name = Michal // Proměnné name přiřazen řetězec Michal
select //
when name = Michal // Když je splněno, že name = Michal say Ahoj (name)e // Je vypsáno Ahoj Michale
when name = Tom // Když bude platit že name = Tom say Ahoj (name)e // Bude vypsáno Ahoj Tome
end
3.5 Proměnná STEM
Proměnná STEM se v REXXu využívá k uložení pole čísel nebo znaků. Ta mají následující podobu.
pole.1 pole.2 pole.3 pole.n
Kde pole.1 označuje první prvek pole, pole.2 označuje druhý prvek a pole.n označuje n-tý prvek pole. Všechny STEM proměnné můžeme poznat podle názvu (pole.). Ačkoli se tato konstrukce na první pohled může zdát zvláštní, nabízí velké pohodlí v mnoha případech.
Inicializace hodnot do proměnné STEM se provádí jako inicializace normálních proměnných a lze jim přiřadit hodnoty jako jakékoliv skalární proměnné a lze s nimi i tak manipulovat.
stroj.1 = 'soustruh' stroj.2 ='frezka' stroj.3 ='vrtacka'
stroje = stroj.1 stroj.2 stroj.3
Inicializaci všech prvků proměnné STEM stejnou hodnotou provedeme zápisem, jež je ukázán na příkladu níže. V prvním případě je všem prvkům přiřazen řetězec 'porucha', druhý případ přiřadí všem prvkům hodnotu NULL.
stroj. = 'porucha' stroj. = ''
Dle konvence nulový prvek (.0) obsahuje počet aktivních prvků proměnné STEM.
Když vezmeme v potaz příklad níže, hodnota stroj.0 = 3. Občas bohužel nemusí být prvek nastaven automaticky a musí nastavit hodnotu uživatel nebo jí nastaví explicitně program.
STEM proměnné je velice užitečné používat společně s cykly ( smyčkami ), např pro výpis všech proměnných na obrazovku lze použít cyklus viz níže uvedený příklad.
stroj.0 = 3
stroj.1 = 'soustruh'
stroj.2 ='frezka'
stroj.3 ='vrtacka'
DO i = 1 TO stroj.0
SAY stroj.i END
Proměnná STEM však nemusí obsahovat pouze jednu dimenzi. Za použití syntaxe na příkladu níže může obsahovat dvě či více. [8]
stroj.1.1 = 'soustruh univerzální' stroj.1.2 ='soustruh jednoúčelový' stroj.2.1 ='frézka konzolová' stroj.2.2 ='frézka horizontální'
3.6 Ukázkový program
V této kapitole si ukážeme, jak by mohl takový program napsaný v REXXu vypadat. Na ukázku jsem zvolil jednoduchou tipovací hru, jejímž cílem je uhodnout náhodně generované číslo v rozmezí od 1 do 10.
Níže uvedený kód si rozebereme abychom lépe pochopili, k čemu slouží jednotlivé příkazy a podmínky.
1. SAY 'Uhodni cislo na ktere myslim' 2. SAY 'Vyber obtiznost'
3. SAY '1 - Lehka - 5 pokusu' 4. SAY '2 - Stredni - 3 pokusy' 5. SAY '3 - Tezka - 1 pokus' 6.
7. PULL pokus 8.
9. SELECT
10. WHEN pokus=1 THEN DO
11. SAY 'Zvolili jste lehkou obtiznost, mate 5 pokusu' 12. pokus = 5
13. END
14. WHEN pokus=2 THEN DO
15. SAY 'Zvolili jste stredni obtiznost, mate 3 pokusu' 16. pokus = 3
17. END
18. WHEN pokus=3 THEN DO
19. SAY 'Zvolili jste tezkou obtiznost, mate 1 pokusu' 20. pokus = 1
21. END 22. OTHERWISE
23. SAY 'Zvolte moznost nachazejici se v nabidce'
24. END
25.
26. vysl=RANDOM(1,10)
27. SAY 'Ktere cislo od 1 do 10 mam na mysli' 28. DO i = 1 to pokus
29. SAY 'Pokus č.'i 30. SAY 'Zadej cislo' 31. PULL c
32. IF c=vysl THEN DO 33. SAY 'Trefa, vyhral jsi' 34. LEAVE
35. END
36. SAY 'Vedle, zbyva ti ještě 'pokus-i' pokusu'
37. END
řádek č. význam
1 - 5 Příkaz SAY vypíše uživateli text zapsaný v uvozovkách.
7 Příkaz PULL slouží k načtení dat z klávesnice a uložení do proměnné pokus. Načítání ukončíme klávesou ENTER.
9 Podmínka SELECT viz kap. 3.5
10 - 13 Pokud je do proměnné pokus načteno číslo 1, vypíše na obrazovku text v SAY a nastaví proměnnou pokus na zvolený počet pokusů.
14 – 17 Viz. řádky 10 – 13
18 - 21 Viz. řádky 10 – 13
22 - 23 Příkaz OTHERWISE používáme, pokud chceme zajistit, aby v případě, že nebude zadána ani jedna z předem definovaných možností,
o tom byl uživatel informován.
24 Příkaz END, který ukončuje SELECT na řádku 9
26 Do proměnné vysl generujeme, pomocí vestavěné funkce RANDOM, náhodné číslo od 1 do 10.
27 Vypíšeme na obrazovku v jakém rozmezí se má číslo zadat.
28 Začíná zde cyklus DO který se bude opakovat tolikrát kolik bylo zvolených pokusů. Cyklus končí na řádku 36
29 Vypíše na obrazovku kolikátý pokus probíhá.
30 Vypíše na obrazovku, že je program připraven načíst uživatelovo číslo.
31 Načítá se číslo zadané uživatelem a ukládá se do proměnné c 32 Podmínka IF ověřuje, zda se rovná číslo zadané uživatelem s číslem
generovaným.
33 Jestliže je splněna podmínka c=vysl pak je uživateli vypsáno, že číslo uhodl a vyhrál
34 Jelikož uživatel číslo uhodl, pomocí příkazu LEAVE opustíme cyklus a program končí
36 Pokud podmínka splněna nebyla, uživatel je upozorněn, že zadané číslo se neshoduje a kolik mu zbývá pokusů.
37 Ukončení cyklu DO(řádek 28) a ukončení programu.
3.7 Funkce a procedury
Funkce a procedury jsou volány stejným způsobem. Jediný rozdíl mezi funkcí a procedurou je, že funkce musí vrátit data, což procedura nemusí.Funkce můžeme dále rozdělit na interní, vestavěné a externí.
Funkce jsou vyhledávány v následujícím pořadí, nejprve se hledají interní funkce poté funkce vestavěné a nakonec funkce externí. [10]
3.7.1 Interní funkce
Jsou funkce, které si tvoří programátor pro zpřehlednění programu, nacházejí se většinou na konci programu, aby při otevření bylo na první pohled vidět, co daný program vykonává.
SAY 'Druhá mocnina z čísla 2 =' nadruhou(2) SAY 'Druhá mocnina z čísla 5 =' nadruhou(5) SAY 'Druhá mocnina z čísla 9 =' nadruhou(81) EXIT
nadruhou:
PARSE ARG x RETURN x*x
Výsledek : Druhá mocnina z čísla 2 = 4 Druhá mocnina z čísla 5 = 25 Druhá mocnina z čísla 9 = 81
Na příkladu si můžeme udělat představu jak se s interní funkcí pracuje. Když se setká REXX s funkcí nadruhou() začne hledat skript se stejným názvem. Poté co narazí na skript se stejným názvem pokračuje dále z tohoto řádku, dokud nenarazí na return.Pak se vrátí na místo, kde začal hledat skript s názvem nadruhou(). A toto místo nahradí výpočet zhotoveným ve skriptu. [6]
3.7.2 Vestavěné funkce
Vestavěné funkce (tab.2)jsou hlavní silou jazyka REXX. Těchto funkcí obsahuje jazyk od 64 do 67 a záleží na I/O modelu. Funkce můžeme rozdělit podle služeb které poskytují.
Služby pro I/O a soubory, tyto funkce jsou specifické pro každý operační systém.
Systémové služby, funkce vrací hodnotu o stavu některých prvků systému, dále umožňují uchovat či obnovit informace o stavu.
Konverze dat a číselné služby, ač má REXX pouze jeden datový typ – řetězec, má silnou sadu funkcí konverzních a číselných funkcí určených k číselné prezentaci dat.
Služby pro manipulaci s řetězci
Služby pro zpracování chyb, funkce poskytují prostředky pro elegantní zpracování chyb, které mohou nastat v průběhu provádění. [10]
Tabulka 2 – Ukázka některých vestavěných funkcí Služby I/O
a soubory
Systémové služby
Konverze dat a číselné služby
Služby pro manipulaci s řetězci
Služby pro
zpracování chyb
CHARIN ADDRESS ABS CENTER CONDITION
CHAROUT BEEP RANDOM DATE ERRORTEXT
LINEIN FORMAT WORDS
LINES TRUNC TIME
CHARIN – načte až 20 znaků ze souboru CHAROUT – zapíše až 20 znaků do souboru ADRESS – vrací název aktuálního hostitele (host)
BEEP - jednosekundové pípnutí ze systémového reproduktoru ABS – vrací absolutní hodnotu ze zadaného čísla
TRUNC – vrací celé číslo ze zadaného čísla CENTER – zarovná zadaný řetězec na střed WORDS – vrací počet slov v zadaném řetězci
Po vysvětlení externích funkcí bych se rád vrátil zpět k vestavěným funkcím, konkrétně funkcím CONVERTDATA, FUNCDEF,RXFUNCADD,RXFUNCDROP, RXFUNCQUERY. Tyto funkce se označují jako API funkce (Application Programming Interface) a slouží nám k načtení, vyčištění balíčků s externími funkcemi.
[11]
3.7.3 Externí funkce
Funkce, které se nacházejí mimo hlavní program a jazykový procesor, se nazývají externí funkce. Externí funkce mohou být napsány i v jiných jazycích než je REXX.Volat můžeme i program jako funkci a předat tak více argumentů než jen jeden.
Volání externího REXX programu jako funkce je stejné jako volání interní funkce, pro externí funkci jsou ale skryté volající proměnné.
Můžeme použít interpret instrukcí ke zpracování funkcí s proměnným názvem funkce, ale to se moc nedoporučuje, jelikož to snižuje přehlednost programu. [12]
3.7.4 Funkce RXFUNCDROP
Odstraňuje název funkce ze seznamu dostupných funkcí.
result = RXFUNCDROP('REXXname')
REXXname je název funkce pod kterým jsme funkci registrovali.
Pokud je návratová hodnota rovna 0, funkci se povedlo bez problému odstranit ze seznamu, v případě, že je návratová hodnota rovna 30, funkce nebyla registrována nebo už byla odstraněna.[11]
3.7.5 Funkce RXFUNCQUERY
Dotazuje se seznamu dostupných funkcí na název funkce. V případě, že je návratová hodnota rovna 0, funkce už je registrována. Pokud se vrátí 1, je tomu naopak.
[11]
result = RXFUNCQUERY('REXXname')
REXXname je název funkce, na kterou se dotazujeme.
3.7.6 Funkce FUNCDEF()
Registruje funkci v DLL, která není designována, aby přímo podporovala REXX.
Jestliže je funkce takto jednou registrována, pak může být volána tolikrát, kolikrát bude potřeba.
result=FUNCDEF(REXXname, Definition, DLLname, FUNCTIONname, Errors, CallType)
REXXname označuje jméno funkce, kterým ho následně budeme volat ve skriptu. Může se lišit od skutečného názvu funkce. Automaticky se převádí na velká písmena.
Definition je řetězec obsahující velké množství informací oddělujících se čárkou.První je návratový typ funkce, druhý je návratový typ pro první argument předaný funkcí, následující jsou argumenty pro zbývající typy. Nutno nastudovat v dokumentaci dodané k DLL. Ukázka v tabulce č. 3.
DLLname obsahuje název knihovny, ve které se nachází námi požadovaná funkce.
Některé systémy mohou rozlišovat velká a malá písmena, proto je potřeba si na to dát pozor. Pokud vím přesně, kde se knihovna nachází, je lepší zadat přesnou cestu, jinak musí být knihovna v místě kde ji operační systém může najít.
FUNCTIONname název funkce pod kterým se funkce nachází v knihovně.Některé systémy mohou rozlišovat velká a malá písmena. V případě, že tento údaj vynecháme, bude se požadovat za FUNCTIONname položka REXXname.
CallType je metoda kterou jsou argumenty předávány do funkce API, C,
V případě, že se návratová hodnota, v našem případě result rovná 0, registrace funkce proběhla v pořádku, dále můžeme dostat hodnoty uvedené v tabulce č.4. [11]
Tabulka č.3 – definiční řetězce FUNCDEF '8','16','32' 8,16,32-bitová celá čísla
'8u','16u','32u' 8,16,32-bitová bezznaménková čísla
'8[X]','16[X]','32[X]' Ukazatel na pole 8,16,32-bitových celých čísel. X je počet prvků pole
'8u[X]','16u[X]','32u[X]' Ukazatel na pole 8,16,32-bitových bezznaménkových celých čísel. X je počet prvků pole
'char' Jeden ASCII znak
'char[X]' Ukazatel na pole ASCII znaků. X je počet znaků pole
'str[X]' Ukazatel na pole nul ukončených ASCII znaky (např.C-string style).X je minimální počet znaků v poli
'func name' Ukazatel na zpětné volání, kde jméno je název proměnné, která obsahuje definiční řetězec podprogramu
'void' Funkce vrací speciální číselnou hodnotu
Tabulka č.4 – Návratové hodnoty pro funkci FUNCDEF()
Hodnota Význam
10 Už je registrována funkce se stejným REXXname.
REXXname musí být unikátní.
40 Zadaná DLL nebyla nalezena nebo ji nelze načíst.
Doporučeno zkontrolovat velká/malá písmena a umístění knihovny.
50 Zadané FUNCTIONname nebylo v DLL nalezeno.
Doporučeno zkontrolovat velká/malá písmena.
3.7.7 Funkce RXFUNCADD
Umožňuje zavolat extérní funkci. Také lze použít k načtení knihovny DLL. Právě tuto funkci budeme používat k načtení knihovny MathRexx
result = RXFUNCADD('REXXname','DLLname','FUNCTIONname')
REXXname obsahuje název, kterým budeme v REXX programu tuto funkci volat.
Název se nemusí shodovat s reálným názvem funkce. Je doporučeno používat pouze velká písmena.
DLLname je název DLL knihovny, ve které se funkce nachází, stačí pouze název, nemusíme psát příponu .dll. Můžeme zadávat i cestu k souboru, což je sice pracnější ale odpadnou nám tím problémy s tím, že knihovnu nebude možno lokalizovat.
FUNCTIONname je skutečný název funkce, pod kterým se nachází v DLL knihovně. Stejně jako u funkce FUNDEF si musíme dát pozor na velká a malá písmena.
Ke kontrole, zda došlo ke správnému načtení funkcí, slouží návratová hodnota.
Pokud je návratová hodnota 0, načtení bylo úspěšné. Další návratové hodnoty jsou popsány v tabulce č.5.
Tabulka č.5 – Návratové hodnoty pro funkci RXFUNCADD()
Hodnota Význam
1 Knihovna/funkce nebyla nalezena
10 Už je registrována funkce se stejným REXXname.
REXXname musí být unikátní.
40 Zadaná DLL nebyla nalezena nebo ji nelze načíst.
Doporučeno zkontrolovat velká/malá písmena a umístění knihovny.
50 Zadané FUNCTIONname nebylo v DLL nalezeno.
Doporučeno zkontrolovat velká/malá písmena.
Abychom nemuseli volat každou funkci jednotlivě, většina DLL knihoven
3.8 RexxUtil
RexxUtil je dynamická knihovna pro systémy Windows, Unix a OS/2 resp eComStation, balíček obsahuje externí funkce sloužící k :
1) manipulaci s třídami widnows a objekty
2) manipulaci se soubory operačního systému a adresáři 3) zprostředkování vstupu a výstupu textu na obrazovku
Použití a funkce knihovny RexxUtill se liší pro každý operační systém, např.
pokud budeme chtít používat funkce z knihovny na systému Windows, není potřeba funkce jednotlivě registrovat nebo k registraci používat funkcy SysLoadFuncs, jelikož k registraci funkcí dojde při zapnutí ooRexx. Na rozdíl od systémů OS/2 nebo eComStation, kde je potřeba před použitím nejprve funkce registrovat. [13]
Balíček obsahuje velké množství funkcí, pro zajímavost jich pár uvedu : RxMessageBox
- zobrazí okno daného systému SysWinVer
- vrací řetězec s informací o verzi Windows ve tvaru x.xx - umožňuje pouze knihovna RexxUtill pro windows SysIni
- umožňuje omezený přístup k INI souboru proměnných - můžeme díky ní sdílet proměnné mezi více aplikacemi SysMkDir
- vytvoří zadaný adresář
4 Vývoj knihovny - MathRexx
Úkolem bakalářské práce bylo vytvořit dynamickou knihovnu matematických funkcí pro programovací jazyk REXX. V této části bude postupně shrnuto, jak bylo postupováno při tvorbě knihovny.
4.1 Vývojové prostředí
Software vytvořený pro zjednodušení práce programátora, bývá zaměřen na jeden jazyk a obsahuje editor zdrojového kódu, kompilátor popř. Interpret a ve většině případů i debbuger.
Pro práci na dynamické knihovně byly použity tři různá vývojová prostředí. Pro tvorbu a testování funkcí, které jsou napsané v C, bylo použito vývojové prostředí Code::Blocks. Pro kompilaci knihovny bylo použito prostředí Watcom a to z toho důvodu, že prostředí Code::Blocks nepodporuje knihovny *.lib, které byly použity pro některé REXX-ovské příkazy. Poslední prostředí, které bylo použito je ooRexx, ve kterém došlo k testování a dolaďování knihovny.
OpenObejctRexx je open-source projekt který řídí RexxLA (Rexx Language Association).
OoRexx je šířen pod Common Public License (CPL 1.0).
Software byl použit především jako interpretr jazyka REXX pod Windows 7.
4.2 Tvorba matematických funkcí
Matematické funkce, jak už bylo výše zmíněno, byly tvořeny v prostředí Code::Blocks, v programovacím jazyce C. Funkce byly nejprve tvořeny jako konzolové aplikace z toho důvodu, aby se ověřila jejich funkčnost.
Při tvorbě byla využívána knihovna matematických funkcí pro C – math.h.
Funkce u kterých nebylo potřeba žádných podmínek, jako jsou sinus, cosinus, tangens atd. byly tvořeny dle následující šablony viz. obr. 4.2 - 1. Využití této šablony pro funkci cosinus je zobrazeno na obr. 4.2 – 2
Obr. 4.2-1: Śablona funkce bez podmínky
Obr. 4.2 - 2 – Funkce cosinus – rx_cos
Funkce jako arcus-sinus a arcus-cosinus, kde je potřeba zadávat v mezích byly tvořeny viz. obr. 4.2 - 3.
Obr. 4.2 - 3 – Funkce arcus-sinus - rx_asin
Knihovna math.h obsahuje pouze základní matematické a goniometrické funkce, jelikož do knihovny pro REXX byly implementovány funkce, jako jsou interpolace, aproximace, základy maticového počtu, filtry a třídící funkce, bylo potřeba tyto funkce naprogramovat. Pro ilustraci je zde uveden zdrojový kód funkce pro výpočet lineární regrese (viz. obr. 4.2 - 4).
Obr. 4.2 - 4 – Funkce pro výpočet lineární regrese - rx_linreg
Postupně se zde bude vysvětleno jak dochází k výpočtu koeficientů lineární regrese.
řádek č. význam
1 Zde dochází k vytvoření funkce rx_linreg která vrací hodnotu ukazatel na datový typ double a vstupují do ní 3 proměnné (*x, *y, n)
3 Dochází k deklaraci proměnné i, která je datového typu int(celé číslo)
4 Deklaruje se proměnná pro výpočet výsledných sum(∑x,∑x*x,∑y,∑x*y) a pole o dvou prvcích a[0] a a[1] pro koeficienty regrese
5 Je deklarován ukazatel do kterého se bude vracet výsledek z funkce 7 – 10 Proměnné x, xx, xy, y jsou nastaveny na nulu.
12 Alokujeme si místo v paměti, o velikosti 2*velikost datového typu double = 16 bajtů 14 Cyklus for od i = 0 do n-1 s krokem +1 který je uzavřen až na řádku č. 21
16 Výpočet
17 Výpočet
18 Výpočet
19 Výpočet
22
Výpočet
23
Výpočet
25 Nastaví se ukazatel tak aby ukazoval na začátek pole a, tím pádem na prvek a[0]
27 Funkce zpět vrací ukazatel p_v, který ukazuje na a[0]
29 Nepoužívaná alokovaná paměť, může být dealokována.
4.3 Tvorba šablony pro knihovnu
Zdrojový kód šablony (viz. příloha 1), který bude následně tvořit ''srdce'' knihovny, je tvořen funkcemi. Na rozdíl od ostatních aplikací zde nenalezneme hlavní funkci, která je základem všech aplikací napsaných v C.
Využívá se zde kromě standartních knihoven stdlib.h a stdio.h navíc knihovny memory.h, string.h a windows.h. Jelikož se v šabloně pracuje nejen s Cčkovskými příkazy ale používají se zde i příkazy obsažené v knihovně rexx.h, připojíme i tuto knihovnu.
Dále jsou definovány řetězce jako návratové hodnoty, konkrétně tyto:
- v případě, žádné chyby je NO_UTIL_ERROR jako 0.
- pro nedostatek paměti ERROR_NOMEM vracíme číslo 2.
- pokud je problém s otevíráním souboru ERROR_FILEOPEN vrací 3.
Návratové hodnoty u funkcí jsou definovány takto:
- jestliže nastane chyba INVALID_ROUTINE vracíme hodnotu 40.
- pokud bylo sestavení kompletní VALID_ROUTINE vracíme hodnotu 0.
Protože REXX nemá žádné datové typy a všechny údaje považuje za řetězce proměnné délky, je potřeba k tomu přizpůsobit výstup z funkce. K tomuto účelu je zde využita funkce BUILDRXSTRING. Ten převádí C-čkovský řetězec na REXX-ovský.
RxFncTable slouží jako pole názvů funkcí. Tento seznam se pak následně využívá k registraci a deregistraci funkcí. Na obr. 4.3 - 1 máme část seznamu pro ilustraci.
Obr. 4.3 - 1 - RxFncTable
RxLoadFuncs, pokud tuto funkci registrujeme a následně zavoláme, má za úkol registrovat všechny funkce nacházející se v RxFncTable. Což uživateli ulehčuje práci, protože nemusí registrovat každou funkci jednotlivě. Na obr. 4.3 - 2 si lze všimnout, že je ve funkci hlídáno, aby do ní nevstupovali žádné argumenty, pomocí entries se zde zjišťuje počet prvků v RxFncTable a následně přes for cyklus dochází k registraci jednotlivých funkcí.
Obr. 4.3 - 2 - RxLoadFuncs
RxDropFuncs (obr. 4.3 - 3), slouží k deregistraci všech doposud registrovaných funkcí, deregistrují se pouze funkce uvedeny v RxFncTable. Znovu je zde ošetřeno, aby do funkce nevstupovali žádné proměnné, a k deregistraci dochází opět pomocí for cyklu.
Obr 4.3 - 3 – RxDropFuncs
Tyto funkce tvoří základ šablony pro dynamickou knihovnu, knihovna pouze s těmito funkcemi by však neměla žádný význam, pouze by byla schopna registrovat či deregistrovat sebe sama. Jelikož se jedná o knihovnu matematických funkcí je potřeba dodat do knihovny to hlavní – matematické funkce.
Tvorba matematických funkcí byla popsána výše (viz kapitola 4.2), aby bylo možno funkci napsanou v programovacím jazyce C využít i v REXXu je potřeba ji pro REXX upravit, konkrétně vstupní a výstupní hodnoty funkce. Na obr. 4.3 - 4 máme ukázku úpravy funkce do které vstupuje jedna proměnná, pro ilustraci použijeme funkci cosinus jejíž zdrojový kód je uveden v kapitole 4.2.
Obr. 4.3 - 4 – RxCos – převod funkce do REXXu
U výše uvedené funkce RxCos je zajištěno, aby do funkce vstupovala pouze jedna proměnná, která je následně funkcí atof převedena z datového typu char na datový typ double a uložena do proměnné a. V dalším kroku je výsledek funkce rx_cos(a) uložen do proměnně b, která je definována jako datový typ double. Proměnná b pak vstoupí do funkce sprintf, přes kterou je převedena zpět na datový typ char a uložena do proměnné char. V posledním kroku je zajištěno, aby návratová hodnota byla datového typu RXSTRING, k čemuž je použita funkce BUILDRXSTRING.
Pokud bude do funkce vstupovat více než jedna vstupní proměnná, musí být pro převod použita funkce, která je uvedena na obr. 4.3 - 5, v našem případě se jedná o matematickou funkci RxMocnina se dvěma vstupy a a b, která slouží pro výpočet a^b.
Na rozdíl od funkcí zmíněných výše, kde je funkce ošetřena proti bezvstupovému použití, se zde kontroluje aby do funkce vstupovali právě dvě proměnné. Tyto proměnné jsou následně pomocí funkce atof (obsažena v stdlib.h) převedeny na datový typ double a jsou dodány do funkce rx_mocnina. Hodnota vrácená z této funkce je převedena zpět na řetězec a přes funkci BUILDRXSTRING převedena na RXSTRING a poslána na výstup z funkce RxMocnina.
Obr. 4.3 – 5 - RxMocnina – Funkce se dvěma vstupy
4.4 Kompilace (překlad) DLL knihovny
Knihovna byla poskládána ve vývojovém prostředí Open Watcom IDE a následně kompilována kompilerem Watcom C/C++.
Knihovna je tvořena z několika částí:
1) Zdrojové kódy napsané v C (C sources) A) MathRexx.c (příloha č.1)
B) funkce.c (příloha č.2) 2) Hlavičkové soubory (Header-files)
A) funkce.h (příloha č.3) 3) Knihovny (Libraries)
A) rexx.lib B) rexxapi.lib
Pokud chceme takto sestavenou knihovnu kompilovat, musí být ještě překladači označeno, jaké funkce mají být exportovány. Jednou z možností, jak tyto funkce označit, je ve vývojovém prostředí Open Watcom IDE přes položku Options → Linker switches → Import, Export and Library switches, zde je možnost v okně Export names vypsat názvy funkcí, které mají být z knihovny exportovány, funkce se oddělují čárkou.
Druhou možností je napsat před funkci syntaxi pro export, pro win32 je použita syntaxe __declspec(dllexport). Tyto obě uvedené možnosti je možné realizovat ve vývojovém prostředí Open Watcom IDE, bohužel se už jedná o starší verzi softwaru, která má jisté problémy s kompatibilitou pod Windows.
Výslednou kompilaci lze provést také více způsoby, nejjednodušší je v grafickém prostředí využít Make all ( ), ), která za nás kompilaci provede. V okně IDE Log, jsou postupně vypsány příkazy které jsou ke kompilaci používány. Další způsob, který lze pro překlad knihovny využít, je přes příkazovou řádku, kde by bylo potřeba postupně vypisovat jednotlivé příkazy, které vykonává v předchozím případě možnost Make all.
Tento způsob je sice zdlouhavější, ale má tu výhodu, že zde mohou být jednodušeji nastaveny pouze přepínače, které potřebujeme.
Pokud nebudeme mít k dispozici žádné vývojové prostředí pro usnadnění práce, můžeme použít tzv. LINKFILE, který nám propojí požadované soubory. Ukázka LINKFILu na obr 4.4 – 1.
Obr 4.4 – 1 – LINKFILE pro tvorbu knihovny
Poslední možností jak přeložit knihovnu je využití definition souboru (*.def). Tato metoda byla při tvorbě matematické knihovny zvolena jako optimální, jelikož nedocházelo k chybě špatně nebo vůbec exportovaných funkcí. K překladu pomocí definition souboru bylo potřeba mít object soubory mathrexx.obj a funkce.obj, tyto soubory byly vytvořeny v prostředí Open Watcom IDE. Dále je potřeba dodat k překladu statické knihovny rexx.lib a rexxapi.lib. Poslední věcí, kterou je potřeba překladači dodat, aby překlad proběhl úspěšně, je definition soubor. Ukázka na obr. 4.4 – 2, soubor musí obsahovat položku LIBRARY, kam je zapsán název výsledné knihovny. Další položkou je DESCRIPTION, která slouží spíše k popisu (pojmenování) definition souboru. Poslední a nejdůležitější položkou, kterou definition soubor obsahuje, je položka EXPORTS, ve které jsou postupně vypsány funkce, které mají být ve výsledku exportovány. V případě, že jsou výše popsané soubory k dispozici, může být knihovna přeložena.
K přeložení bylo použito linkeru v příkazové řádce. Ve složce, kde se nacházejí soubory ke knihovně, byla otevřena příkazová řádka a přes příkaz viz. níže byla knihovna přeložena.
link mathrexx.obj funkce.obj rexx.lib rexxapi.lib /DLL /DEF:mathrexx.def
Na obr. 4.4 – 3 je ukázka definition souboru který byl použit při překladu, z důvodu velikosti obrázku se v položce EXPORTS nenacházejí všechny funkce, které byly exportovány do výsledné knihovny.
Obr. 4.4 – 3 – Ukázka definition souboru
5 Použití knihovny - MathRexx
V této části bude postupně popsáno, jaké funkce knihovna umožňuje použít, jak načíst potřebné funkce, budou zde rozepsány proměnné které je potřeba funkci dodat, aby pracovala korektně a co bude výstupem z funkce.
5.1 Seznam funkcí
V tab. 5.1 - 1 jsou uvedeny všechny funkce, kterými knihovna disponuje.
Ve sloupci název funkce je uveden název, pod kterým se tato funkce nachází v knihovně. Tento název se používá k registraci funkce.
Ve druhém sloupci popis funkce je uvedeno co tato funkce vykonává, ačkoli funkce pojmenovávány takovým způsobem, aby bylo na první pohled patrné, k čemu daná funkce slouží.
Jednotlivé funkce budou níže probrány trochu detailněji, tato část je pouze jakýsi rychlý přehled názvů funkcí.
Tabulka 5.1 - 1 – Přehled funkcí.
Název funkce Popis funkce
RxLoadFuncs Slouží k registraci všech funkcí.
RxDropFuncs Slouží k deregistraci všech funkcí.
RxDegToRad Převádí stupně na radiány.
RxRadToDeg Převádí radiány na stupně.
RxSin Výpočet goniometrické funkce sinus.
RxCos Výpočet goniometrické funkce cosinus.
RxTan Výpočet goniometrické funkce tangens RxCot Výpočet goniometrické funkce cotangens RxAsin Výpočet goniometrické funkce arcus-sinus.
RxAcos Výpočet goniometrické funkce arcus-cosinus.
RxAtan Výpočet goniometrické funkce arcus-tangens.
RxSqrt Výpočet druhé odmocniny.
RxFakt Výpočet faktoriálu.
RxLn Výpočet přirozeného logaritmu.
RxLog Výpočet logaritmu o základu 10.
RxMocnina Umocňuje číslo a^b
RxNewton Aproximace pomocí interpolačního polynomu.
RxLinReg Výpočet koeficientů lineární regrese.
RxExpReg Výpočet koeficientu exponenciální regrese.
RxDetMatrix Výpočet determinantu zadané matice.
RxInvMatrix Výpočet inverzní matice k matici zadané.
RxMulMatrix Násobení dvou matic.
RxSma Klouzavý průměr.
RxSavGolCoef Koeficienty pro Golay-Savitzkého filtr
RxBSortU Třídění čísel vzestupně
RxBSortD Třídění čísel sestupně
5.2 Registrace funkce
Pro registraci funkcí slouží funkce RXFUNCADD (viz. kap. 3.7.7). Funkce mohou být načítány jednotlivě voláním této funkce na každou funkci, která má být registrována nebo pomocí speciální funkce RxLoadFuncs, která je součástí knihovny.
První proměnná značí, pod jakým názvem má být funkce registrována.
Druhá proměnná obsahuje název knihovny, ze které mají být funkce načteny.
Třetí proměnná označuje, pod jakým názvem se funkce skrývá v knihovně. Tyto názvy funkcí jsou uvedeny v tab. 5.1 – 1.
Ukázka registrace funkce RxSin. V případě, že se návratový kód nerovná 0, což znamená, že funkce nebyla registrována, program vypíše chybu a oznámí návratový kód chyby.
rc = RXFUNCADD('RXSIN','MathRexx','RxSin') IF rc \== 0 THEN DO
SAY 'Funkce nebyla registrovana - RC ='rc EXIT
END
Registrace všech funkcí nacházejích se v knihovně se provádí stejným způsobem, musí ale být nejprve registrována funkce RxLoadFuncs a následně zavolána, čímž dojde k registraci všech ostatních funkcí.
rc = RXFUNCADD('RXLOADFUNCS','MathRexx','RxLoadFuncs') IF rc \== 0 THEN DO
SAY 'Funkce nebyla registrovana - RC ='rc EXIT
END
CALL RXLOADFUNCS( )
5.3 Deregistrace funkce
V případě, že už knihovna či registrovaná funkce nebude potřeba, může být tzv.
deregistrována. Stejně jako v předchozím případě registrace funkce, jde funkce deregistrovat jednotlivě nebo pomocí speciální funkce RXFUNCDROP .
Do funkce vstupuje pouze jedna proměnná a to název funkce, která má být deregistrována.
Na uvedeném příkladu bude ukázáno jak výše registrovanou funkci RxSin
deregistrovat.
rc = RXFUNCDROP('RXSIN') IF rc \== 0 THEN DO
SAY 'Funkce nebyla deregistrovana - RC ='rc EXIT
END
Jestliže z knihovny bude využíváno více funkcí, bylo by zdlouhavé funkce deregistrovat jednotlivě. K hromadné deregistraci slouží funkce RxDropFuncs, což je funkce která se v REXXu standardně nenachází, a je tedy nutné jí nejprve registrovat.
Když bude funkce již registrována, stačí ji pouze zavolat.
rc = RXFUNCADD('RXDROPFUNCS','MathRexx','RxDropFuncs') IF rc \== 0 THEN DO
SAY 'Funkce nebyla registrovana - RC ='rc EXIT
END
5.4 Funkce a použití
V této části bude vysvětleno jakým způsobem funkci registrovat, zavolat a jaké proměnné musí být funkci dodány pro správnou funkci.
5.4.1 RxDegToRad
Funkce slouží k převodu stupňů na radiány.
Registrace funkce:
call RxFuncAdd 'RXDEGTORAD','MathRexx','RxDegToRad' Volání funkce:
v = RXDEGTORAD( x ) Vstupující proměnná:
x – Hodnota ve stupních, kterou chceme převést na radiány
5.4.2 RxRadToDeg
Funkce slouží k převodu radiánů na stupně.
Registrace funkce:
call RxFuncAdd 'RXRADTODEG','MathRexx','RxRadToDeg' Volání funkce:
v = RXRADTODEG( x ) Vstupující proměnná:
x – hodnota v radiánech, kterou chceme převést na stupně
5.4.3 RxSin
Funkce sloužící k výpočtu funkční hodnoty goniometrické funkce sinus.
Registrace funkce - jednotlivě:
call RxFuncAdd 'RXSIN','MathRexx','RxSin' Volání funkce :
v = RXSIN( x) Vstupující proměnné :
x – hodnota, pro kterou chceme zjistit hodnotu sin(x), hodnota musí být uvedena v radiánech.
5.4.4 RxCos
Funkce sloužící k výpočtu funkční hodnoty goniometrické funkce cosinus.
Registrace funkce - jednotlivě:
call RxFuncAdd 'RXCOS','MathRexx','RxCos' Volání funkce :
v = RXCOS( x) Vstupující proměnné :
x – hodnota pro kterou chceme zjistit hodnotu cos(x), hodnota musí být uvedena v radiánech.
5.4.5 RxTan
Funkce sloužící k výpočtu funkční hodnoty goniometrické funkce tangens.
Registrace funkce - jednotlivě:
call RxFuncAdd 'RXTAN','MathRexx','RxTan' Volání funkce:
v = RXTAN( x) Vstupující proměnné:
x – hodnota, pro kterou chceme zjistit hodnotu tg(x), hodnota musí být uvedena v radiánech.
5.4.6 RxCotg
Funkce sloužící k výpočtu funkční hodnoty goniometrické funkce cotangens.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXCOT','MathRexx','RxCot Volání funkce :
v = RXCOT( x) Vstupující proměnné :
x – hodnota, pro kterou chceme zjistit hodnotu cotg(x), hodnota musí být uvedena v radiánech.
5.4.7 RxAsin
Funkce pro výpočet hodnoty arcus-sinus zadaného čísla.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXASIN','MathRexx','RxAsin' Volání funkce :
v = RXASIN( x) Vstupující proměnné :
x – hodnota pro kterou chceme zjistit hodnotu sin-1(x),hodnota musí být uvedena v radiánech.
5.4.8 RxAcos
Funkce pro výpočet hodnoty arcus-cosinus zadaného čísla.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXACOS','MathRexx','RxAcos' Volání funkce :
v = RXACOS( x) Vstupující proměnné :
x – hodnota, pro kterou chceme zjistit hodnotu cos-1(x), hodnota musí být uvedena v radiánech.
5.4.9 RxAtan
Funkce pro výpočet hodnoty arcus-tangens zadaného čísla.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXATAN','MathRexx','RxAtan' Volání funkce :
v = RXATAN( x) Vstupující proměnné :
x – hodnota, pro kterou chceme zjistit hodnotu tg-1(x), hodnota musí být uvedena v radiánech.
5.4.10 RxSqrt
Funkce pro výpočet hodnoty druhé mocniny zadaného čísla.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXSQRT','MathRexx','RxSqrt' Volání funkce :
v = RXSQRT( x) Vstupující proměnné :
x – hodnota, pro kterou chceme zjistit hodnotu
√
x5.4.11 RxExp
Funkce pro výpočet hodnoty exponencilní funkce zadaného čísla.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXEXP','MathRexx','RxExp' Volání funkce :
v = RXEXP( x) Vstupující proměnné :
x – hodnota, pro kterou chceme zjistit hodnotu ex
5.4.12 RxFakt
Funkce pro výpočet hodnoty faktoriálu zadaného čísla.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXFAKT','MathRexx','RxFakt' Volání funkce :
v = RXFAKT( x) Vstupující proměnné :
x – hodnota, pro kterou chceme zjistit hodnotu x !
5.4.13 RxLn
Funkce pro výpočet hodnoty přirozeného logaritmu zadaného čísla.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXLN','MathRexx','RxLn' Volání funkce :
v = RXLN( x) Vstupující proměnné :
x – hodnota, pro kterou chceme zjistit hodnotu ln x
5.4.14 RxLog
Funkce pro výpočet hodnoty logaritmu o základu 10 zadaného čísla.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXLOG','MathRexx','RxLog' Volání funkce :
v = RXLOG( x) Vstupující proměnné :
x – hodnota, pro kterou chceme zjistit hodnotu log( x)
5.4.15 RxMocnina
Funkce slouží k umocnění dvou čísel ab Registrace funkce - jednotlivě :
call RxFuncAdd 'RXMOCNINA','MathRexx','RxMocnina' Volání funkce :
v = RXMOCNINA( a,b) Vstupující proměnné :
a – základ mocniny (mocněnec) b – exponent (mocnitel)
5.4.16 RxNewton
Funkce slouží k aproximaci funkce pomocí interpolačního polynomu a vypočítání funkční hodnoty v požadovaném bodě.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXNEWTON','MathRexx','RxNewton' Volání funkce :
v = RXNEWTON( x.,y.,n,f) Vstupující proměnné :
x. – naměřené hodnoty x, které jsou zapsány v proměnné stem.
y. – naměřené hodnoty y, které jsou zapsány v proměnné stem.
n – počet naměřených hodnot.
f – bod, pro který chceme zjistit funkční hodnotu.
5.4.17 RxLinReg
Funkce počítá koeficienty a, b lineární regrese, která je zapsána ve tvaru : y (x )=a∗x+b
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXLINREG','MathRexx','RxLinReg' Volání funkce :
call RXLINREG x. , y. , n , v.
Vstupující proměnné :
x. – naměřené hodnoty x, které jsou zapsány v proměnné stem.
y. – naměřené hodnoty y, které jsou zapsány v proměnné stem.
n – počet naměřených hodnot.
v. - poměnná stem, ve které je uložen výsledek.
Volání výstupní hodnoty :
- v případě, že byla funkce zapsána jako na příkladu, výsledky jsou uloženy v proměnné stem.
- koeficient a = v.1 - koeficient b = v.2
5.4.18 RxExpReg
Funkce počítá koeficienty a, b exponenciální regrese, která je zapsána ve tvaru : y (t)=b∗ea∗t
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXEXPREG','MathRexx','RxExpReg' Volání funkce :
call RXEXPREG x. , y. , n , v.
Vstupující proměnné :
x. – naměřené hodnoty x, které jsou zapsány v proměnné stem.
y. – naměřené hodnoty y, které jsou zapsány v proměnné stem.
n – počet naměřených hodnot.
v. - proměnná stem ve které je uložen výsledek.
Volání výstupní hodnoty :
- v případě, že byla funkce zapsána jako na příkladu, výsledky jsou uloženy v proměnné stem v.
- koeficient a = v.1 - koeficient b = v.2
5.4.19 RxDetMatrix
Funkce slouží k výpočtu hodnoty determinantu zadané matice.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXDETMATRIX','MathRexx','RxDetMatrix' Volání funkce :
v = RxDetMatrix( x.,n) Vstupující proměnné :
x. – jednotlivé prvky matice.
Ukázka zápisu matice :
- matice je zapsána jako vektor o velikosti nxn - např matice 2x2 bude zapsána ve tvaru:
mat.1 = 1 mat.2 = 2 mat.3 = 3 mat.4 = 4
- tímto způsobem dostaneme matici 1 2 3 4
5.4.20 RxInvMatrix
Funkce slouží k výpočtu inverzní matice z matice zadané.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXINVMATRIX','MathRexx','RxInvMatrix' Volání funkce :
call RXINVMATRIX x. , n , v.
Vstupující proměnné :
x. – jednotlivé prvky matice n – počet naměřených hodnot.
v. - proměnná stem, ve které je uložena inverzní matice k x.
Zápis vstupní matice :
- matici zapíšeme jako vektor o velikosti nxn - matice 2x2 :
x.1 = 1
x.2 = 0 => 1 0
−1 2 x.3 = -1
x.4 = 2 Výstupní hodnoty :
- jsou uloženy jako vektor o velikost nxn - inverzní matice k matici x :
v.1 = 1 v.2 = 0
v.3 = 0.5 => 1 0 0.5 0.5 v.4 = 0.5
5.4.21 RxMulMatrix
Funkce, slouží k násobení dvou matic.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXMULMATRIX','MathRexx','RxMulMatrix' Volání funkce :
call RXMULMATRIX x. , y. , r1. , r2. , v.
Vstupující proměnné :
x. – jednotlivé prvky první matice.
y. - jednotlivé prvky druhé matice.
r1. – proměnná, ve které jsou uloženy rozměry první matice.
r2. – proměnná, ve které jsou uloženy rozměry druhé matice.
v. - proměnná, kde je uložen výsledek násobení matic Zápis vstupních proměnných :
- matici zapíšeme jako vektor o velikosti mxn viz. předchozí funkce.
- rozměry zapíšeme ve tvaru :
r1.1 = m r2.1 = m r1.2 = n r2.2 = n Výstupní prvky matice :
- jsou uloženy jako vektor o velikost mxn
- jednotlivé prvky lze vyvolat pomocí v.1, v.2, v.3....v.(mxn).
5.4.22 RxSma
Funkce aplikuje na změřená data filtr – klouzavý průměr.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXSMA','MathRexx','RxSma' Volání funkce :
call RXSMA x. , s , n , v.
Vstupující proměnné :
x. – naměřené hodnoty x, které jsou zapsány v proměnné stem.
s – počet prvků, po kterých se bude průměrování provádět n – počet naměřených hodnot.
v. – proměnná, ve které je uložen výsledek – v.1...v.(n-s)
5.4.23 RxSavGolCoef
Funkce počítá koeficienty pro Golay-Savitzkého filtr.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXSAVGOLCOEF','MathRexx','RxSavGolCoef' Volání funkce :
call RXSAVGOLCOEF np , nl , nr , ld , m , c.
Vstupující proměnné :
np – počet vrácených koeficientů (určuje se jako nl + nr + 1) nl – počet naměřených hodnot vlevo před hodnotou požadovanou.
nl – počet naměřených hodnot vpravo před hodnotou požadovanou.
ld – stupeň derivace, pro vyhlazování volíme 0.
m – řád polynomu.
c. - proměnná do které jsou uloženy koeficienty – c.1....c.(np).
Koeficienty uložené v c : - např. pro np = 5 :
c.1 = C0
c.2 = C-1
c.3 =C-2
c.4 = C2
c.5 = C1
5.4.24 RxBSortU
Funkce využívá bubblesort algoritmus k setřídění číselných dat vzestupně.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXBSORTU','MathRexx','RxBSortU' Volání funkce :
call RXBSORTU x. , n , v.
Vstupující proměnné :
x. – hodnoty pro setřídění.
n – počet hodnot.
v. – proměnná, ve které jsou uložena data po setřídění
5.4.25 RxBSortD
Funkce využívá bubblesort algoritmus k setřídění číselných dat sestupně.
Registrace funkce - jednotlivě :
call RxFuncAdd 'RXBSORTD','MathRexx','RxBSortD' Volání funkce :
call RXBSORTD x. , n , v.
Vstupující proměnné :
x. – hodnoty pro setřídění.
n – počet hodnot.
v. – proměnná, ve které jsou uložena data po setřídění
6 Ukázka aplikace funkcí z knihovny
Knihovnu lze využít k řešení linearních soustav. Mějme například soustavu ve tvaru : 2x1 -3x2 + x3 = 0
x1 + 2x2 – x3 = 3 => A*x = b => A-1*A*x = A-1*b => x = A-1*b 2x1 + x2 + x3 = 12
Sestavíme si matici A a vektor b.
A = 2 −3 1
1 2 −1
2 1 1
b = 0 3 12 Zdrojový kód výpočtu :
rc = RxFuncAdd('RxLoadFuncs','MathRexx','RxLoadFuncs')
call RxLoadFuncs // Voláme knihovnu a registrujeme funkce.
A.1 = 2 // Plníme matici A daty.
A.2 = -3 A.3 = 1 A.4 = 1 A.5 = 2 A.6 = -1 A.7 = 2 A.8 = 1 A.9 = 1
b.1 = 0 // Plníme daty vektor b.
b.2 = 3 b.3 = 12
r1.1 = 3 // Definujeme rozměry matice A 3x3.
r1.2 = 3
r2.1 = 3 // Definujeme rozměry vektoru b 3x1.
r2.2 = 1
call RxInvMatrix A. , 3 , inv. // Výpočet inverzní matice k A.
call RxMulMatrix inv. , b. , r1. , r2. , x. // Násobíme vektor b inverzní maticí A zleva.
do i = 1 to 3
say "x"i" = "x.i // Vypíšeme výsledek na obrazvku.
end
Vypsaný výsledek na obrazovku :
Ukázka funkce vybraných elementárních funkcí : Zdrojový kód :
rc = RxFuncAdd('RxLoadFuncs','MathRexx','RxLoadFuncs') call RxLoadFuncs
say "Sin(PI/2) = "RxSin(1.57079)
say "Cos(PI) = "RxCos(3.14159) say "Acos(0.5) = "RxAcos(0.5)
say "Odmocnina z 25 = "RxSqrt(25) say "e^2 = "RxExp(2)
say "5! = " RxFakt(5) say "ln(2) = "RxLn(2) Výstup na obrazovku :
Výpočet koeficientů lineární regrese : Data : x = [1 2 3 4 5]
y = [1.4 2.3 3.7 4.8 5]
Zdrojový kód :
rc = RxFuncAdd('RxLoadFuncs','MathRexx','RxLoadFuncs') call RxLoadFuncs
x.1 = 1 x.2 = 2 x.3 = 3 x.4 = 4 x.5 = 5 y.1 = 1.4 y.2 = 2.3 y.3 = 3.7 y.4 = 4.8 y.5 = 5
call RxLinReg x. , y. , 5 , res.
Výpis výsledku na obrazovku :
Tvorba grafu :
Z výsledků můžeme například v prostředí MATLAB vytvořit graf.
Třídění dat :
Data : x = [10 7 8 15 12 14 5 2 6 1]
rc = RxFuncAdd('RxLoadFuncs','MathRexx','RxLoadFuncs') call RxLoadFuncs
x.1 = 10 x.2 = 7 x.3 = 8 x.4 = 15 x.5 = 12 x.6 = 14 x.7 = 5 x.8 = 2 x.9 = 6 x.10 = 1
call RxBSortU x., 10 , resu.
call RxBSortD x., 10 , resd.
do i = 1 to 10 say resu.i" "resd.i