Original article: here


CMATH


1. Uvod

CMATH je obimna biblioteka za aritmetiku kompleksnih brojeva i matematiku, sa kartezijanskim i sa polarnim koordinatama, za C/C++ i Pascal/Delphi kompajlere. CMATH je dostupan kao samostalan proizvod. Takođe je uključen i u OptiVec paket.

Sve funkcije se alternativno mogu pozivati iz klasičnog C-a i Pascal/Delphi-ja pomoću tip-specifičnih imena funkcija (poput cf_sin, cf_exp, pe_sqrt), ili iz C++ i Delphi-ja sa preklopljenim imenima funkcija i operatorima (poput sin, exp, sqrt, operator +; operatori samo u jeziku C++). Koliko god je moguće, sve funkcije imaju ista imena u Pascal/Delphi verziji, kao i u C/C++ verziji.

Nadmoćna brzina, tačnost i bezbednost se postižu kroz implementaciju u asemblerski jezik (nasuprot kompajliranom ili linijskom kodu dostupnih kompleksnih C++ biblioteka klasa). Samo za najjednostavnije zadatke se koriste alternativne linijske C++ funkcije, u C++ verziji.

Svuda gde se područje primene CMATH-a preklapa sa implementacijama kompleksnih klasa jezika Visual C++, Borland C++, i Delphi, CMATH je visoko kvalitetna zamena za potonje, koji su svi prilično neefikasni i netačni.

Nasuprot napisanih-i-kompajliranih formula iz udžbenika, kao kod većine drugih dostupnih kompleksnih biblioteka (uključujući one koje dolaze sa Visual C++ i Borland kompajlerima), implementacija CMATH-a je vođena sledećim pravilima:

  1. Bez ikakvih kompromisa, najviši prioritet se uvek daje matematički ispravnom rezultatu, uz zahtevanu tačnost za posmatrani tip podataka. Naročito za kompleksne funkcije, ovo zahteva veoma detaljnu obradu mnogo različitih situacija. Ovde različiti slučajevi moraju da se razluče pedantno i sa pažnjom. (Formule iz udžbenika ne moraju da obrađuju ove situacije zasebno, jer one teoretski pretpostavljaju beskonačnu tačnost međurezultata; stvarna implementacija, međutim, mora da radi sa ograničenom tačnošću, koju joj daju stvarni procesori.)
  2. Matematičke funkcije moraju biti “sigurne” pod svim okolnostima. One ne smeju ni iz jednog razloga da jednostavno otkažu, već moraju da izvedu pristojnu obradu greške. Ovo važi čak - a možda i naročito - za naizgled besmislene argumente, sa pojedinačnim prihvatanjem ne-brojeva INF i NAN, koji se pojavljuju samo kao posledica ozbiljnih grešaka u drugim funkcijama.
  3. Na sve moguće načine, mora se postići najveća brzina izvršavanja. (Na kraju, niste kupili svoj brzi računar bez razloga!)
  4. Programski kod mora da bude što je moguće kompaktniji. Ipak, u slučaju konflikata, većoj brzini izvršavanja se uvek daje prioritet u odnosu na manju veličinu koda.

Povratak na CMATH sadržaj   OptiVec home stranica

1.1 C/C++ Specifičnosti

Kompleksne C++ klase (classes) i C struktovi (structs) fComplex itd. su obostrano kompatibilni jedni sa drugima. Ovo može biti značajno za velike projekte sa izmešanim C i C++ modulima. Postojeći C++ kod koji koristi biblioteku kompleksnih klasa Borland C++-a, sadržanu u , može se ostaviti neizmenjen, jer su CMATH funkcije i tipovi podataka takođe obostrano kompatibilni sa onima iz . Jedini izuzetak je funkcija članica polar, koja je morala da se zameni sa magargtoc, pošto reč "polar" sada označava kompleksne klase u polarnim koordinatama.

Ovde se nalazi detaljan opis kako da koristite CMATH u vašim projektima:

  1. U C++ modulima, deklarišite
    #include <newcplx.h>
    Zatim se definiše sledećih šest kompleksnih klasa:
    class complex<float>, class complex<double>, class complex<long double>, class polar<float>, class polar<double>, i class polar<long double>.

    Tipovi podataka fComplex, dComplex, eComplex, fPolar, dPolar, i ePolar su definisani kao sinonimi za ove klase.
    Kako bi se izbeglo slovo "L" (koje je već previše korišćeno od long i unsigned long, koristi se reč extended kao sinonim za long double u Borland C++ verziji CMATH-a. U MSVC verziji, to je sinonim za double, jer MSVC ne podržava 80-bitne IEEE realne brojeve. Zbog toga su kompleksni tipovi podataka povećane (extended) preciznosti nazvani eComplex i ePolar.
  2. Ukoliko više volite da imate “klasičnu” class complex iz starijih izdanja Borland C++-a, treba da deklarišete
    #define CMATH_CLASSIC_COMPLEX
    ispred (!) uključujući <newcplx.h>.
    U ovom slučaju, biće definisana samo class complex i ona dobija sinonim dComplex. Ovde nećete imati pristup funkcijama sa kompleksnim brojevima u float i extended preciznosti, i sve funkcije u polarnim koordinatama su takođe nedostupne.
  3. Za čiste-C module, ne možete da uključite . Umesto toga, molimo da deklarišete
    #include <cmath.h>
    Ukoliko koristite samo jedan nivo preciznosti sa pokretnim zarezom, možete poželeti da uključite samo jedan od tip-specifičnih include-fajlova: <cfmath.h>, <cdmath.h>, ili <cemath.h>, respektivno.
    Čista-C implementacija CMATH-a se zasniva na sledećim definicijama kompleksnih tipova podataka:
    typedef struct { float Re, Im; } fComplex;
    typedef struct { double Re, Im; } dComplex;
    typedef struct { extended Re, Im; } eComplex;
    typedef struct { float Mag, Arg; } fPolar;
    typedef struct { double Mag, Arg; } dPolar;
    typedef struct { extended Mag, Arg; } ePolar;

    Kao što je gore opisano, tip podatka extended se koristi kao sinonim za long double (Borland C++ verzija) ili double (MSVC verzija).
  4. Sastavni delovi C++ klasa se deklarišu kao javni (nasuprot Borland C++-u !). Oni se nazivaju "Re" i "Im" u kartezijanskim klasama, i "Mag" i "Arg" u polarnim klasama. Ovo omogućava da im se pristupa kao z.Re, z.Im, p.Mag, ili p.Arg u C++ modulima, kao i u čistim-C modulima.
  5. Za vremenski-kritične primene, preporučujemo da se koristi C, pre nego C++ verzija of CMATH-a, pošto C/C++ kompajleri obrađuju struktove mnogo efikasnije nego klase. Da biste koristili C verziju sa vašim C++ modulima, molimo vas imajte u vidu sledeće stvari:
    • uključite <cmath.h> umesto <newcplx.h>
    • za inicijalizaciju, dodelite realne/imaginarne ili Mag/Arg delove direktno (npr., z.Re = 3; z.Im = 5;) ili upotrebite funkcije fcplx, dcplx, ecplx, fpolr, dpolr, epolr. Konstruktori complex(), fComplex(), polar(), fPolar(), itd., nisu dostupni.
    • Ukoliko izvodite C++ kompajliranje na modulima sa uključenim <cmath.h>, možete da birate između pozivanja CMATH funkcija putem njihovih tip-specifičnih imena (kao što su cf_sin, cf_exp), ili pomoću njihovih preklopljenih C++ imena (npr., sin, exp). U nekim prilikama, možda budete primorani da koristite tip-specifična imena kako biste razrešili dvosmislenosti.

Povratak na CMATH sadržaj   OptiVec home stranica

1.2 Pascal/Delphi specifičnosti

CMATH za Pascal/Delphi definiše šest kompleksnih tipova podataka:

type fComplex = record Re, Im: Single; end;
type dComplex = record Re, Im: Double; end;
type eComplex = record Re, Im: Extended; end;
type fPolar = record Mag, Arg: Float; end;
type dPolar = record Mag, Arg: Double; end;
type ePolar = record Mag, Arg: Extended; end;

Razlog zašto tip u jednostrukoj preciznosti dobija naziv fComplex, umesto sComplex, je što je slovo "s" već previše korišćeno od ShortInt i SmallInt, u Pascal-u. Stoga je ovo ime izvedeno od C/C++ analoga za Single, a to je float.

CMATH-Pascal tipovi podataka su obostrano kompatibilni sa onima iz C/C++ verzija.

Tip-specifična imena funkcija su ista kao u čistoj-C verziji. Sintaksa je, međutim, donekle drugačija, pošto C podržava kompleksne brojeve (definisane kao struct-ovi) kao povratne vrednosti, dok Pascal izvorno nije dozvoljavao da record-i budu vraćeni od strane funkcije (ovo je dozvoljeno samo u Delphi-ju). Zato se oni kompleksnoj funkciji prosleđuju kao var argumenti, npr.:
procedure cf_sin( var zy:fComplex; zx:fComplex );

Preklopljena imena funkcija su raspoloživa samo u Delphi-ju (ne i u verziji Turbo Pascal). Ona su ista kao u C++ verziji. Ovde se rezultati tretiraju kao prave povratne vrednosti, npr.:
function sin( zx:fComplex ): fComplex;

Povratak na CMATH sadržaj   OptiVec home stranica


2. Pregled CMATH funkcija

U sledećem tekstu, često je samo fComplex ili fPolar verzija funkcije eksplicitno pomenuta. Verzije za dComplex / dPolar, i eComplex / ePolar su uvek tačno analogne.
Sve funkcije za jezike C i Pascal/Delphi imaju prefiks koji označava tip podataka sa kojima funkcija radi:
"cf_" ili "pf_" označavaju jednostruku preciznost (argumenti i povratne vrednosti tipova podataka fComplex, fPolar, ponekad zajedno sa float),
"cd_" ili "pd_" označavaju dvostruku preciznost (argumenti i povratne vrednosti tipova podataka dComplex, dPolar, ponekad zajedno sa double), gde
"ce_" i "pe_" označavaju funkcije u povećanoj preciznosti.

U C++-u i Delphi-ju, za sve ove funkcije definisani su sinonimi. Sinonimi nemaju prefiks, pošto se informacija o tipu podatka implicitno obrađuje od strane kompajlera. Preklopljena imena funkcija su uglavnom identična onima koja se mogu naći u bibliotekama kompleksnih klasa (ako tamo postoji odgovarajuća funkcija). Imajte u vidu, ipak, da je funkcija članica polar morala da bude zamenjena sa magargtoc, pošto je ime "polar" sada rezervisano za polarne klase.

Samo za C++: Ako želite da koristite imena C funkcija u vašim C++ modulima, budite sigurni da ste uključili <cmath.h> umesto <newcplx.h>.


2.1. Inicijalizacija kompleksnih brojeva

U sledećem tekstu, označavamo kompleksne klase njihovim skraćenim imenima, fComplex, fPolar, itd. U C++-u, uvek možete da upotrebite šablon nomenklaturu, gde se umesto pisanja "complex<float>" svuda piše "fComplex", i tako za sve druge kompleksne tipove i klase.

Kompleksni brojevi se inicijalizuju zasebnim dodeljivanjem vrednosti njihovim imaginarnim i realnim delovima, npr.:
z.Re = 3.0; z.Im = 5.7;
p.Mag = 8.8; p.Arg = 3.14;

(naravno, za Pascal/Delphi, operator dodeljivanja se piše ":=").
Umesto toga, ista inicijalizacija se može postići funkcijama fcplx ili fpolr:
C/C++:
z = fcplx( 3.0, 5.7 );
p = fpolr( 4.0, 0.7 );

Pascal/Delphi:
fcplx( z, 3.0, 5.7 );
fpolr( p, 3.0, 5.7 );

Za kompleksne brojeve u dvostrukoj preciznosti, koristite dcplx i dpolr, za kompleksne brojeve u povećanoj preciznosti, koristite ecplx i epolr.


2.2. Međukonverzije tipova podataka

Međukonverzije između različitih kompleksnih tipova se izvode preko sledećih funkcija:

cftocd,  cdtocf,   cftoce,  cetocf,   cdtoce,  cetocd konverzija tačnosti naviše, ili naniže, u okviru kartezijanskih kompleksnih tipova
pftopd,  pdtopf,   pftope,  petopf,   pdtope,  petopd konverzija tačnosti naviše, ili naniže, u okviru polarnih kompleksnih tipova
cftopf,  cftopd,  cftope,
cdtopf,  cdtopd,  cdtope,
cetopf,  cetopd,  cetope
konverzija iz kartezijanskog u polarni kompleksni tip
pftocf,  pftocd,  pftoce,
pdtocf,  pdtocd,  pdtoce,
petocf,  petocd,  petoce
konverzija iz polarnog u kartezijanski kompleksni tip

OVERFLOW greške (greške prekoračenja) u pravcu konverzije na dole, vode do pojave poruke o grešci; izvršavanje programa se nastavlja sa najvećom mogućom vrednošću.

Važi samo za C++:

Za C++ module, postoji nekoliko preklopljenih konstruktora, kao alternativa gornjim funkcijama:
osnovni oblici:
   fComplex fComplex( float RePart, float ImPart=0 );
   fComplex fComplex( dComplex );
   fComplex fComplex( eComplex );
   fPolar fPolar( float MagPart, float ArgPart=0 );
   fPolar fPolar( dPolar );
   fPolar fPolar( ePolar );

međukonverzija kartezijansko <--> polarno:
   fComplex fComplex( fPolar );
   fComplex fComplex( dPolar );
   fComplex fComplex( ePolar );
   fPolar fPolar( fComplex );
   fPolar fPolar( dComplex );
   fPolar fPolar( eComplex );

Slično konstruktorima fComplex() i fPolar(), takođe i dComplex(), dPolar(), eComplex, i ePolar() postoje u preklopljenim verzijama i izvršavaju iste zadatke za klase dComplex, dPolar, eComplex, i ePolar, respektivno. Kao što je gore opisano, za C/Pascal/Delphi verzije, OVERFLOW greške u pravcu konverzije-nadole se hvataju i obrađuju preko _matherr.

Specijalni konstruktor za polarne brojeve je
fPolar pf_principal( fPolar __p );
a, samo za C++, njegov preklopljeni oblik za dva posebna realna ulazna broja je
fPolar principal( float Mag, float Arg );
Ove funkcije smanjuju ulazni Arg na opseg -p < Arg <= +p. Možete se setiti da svaki komleksni broj ima beskonačan broj predstavljanja u polarnim koordinatama, sa uglovima koji se razlikuju za celobrojni umnožak 2 p. Predstavljanje sa -p < Arg <= +p se naziva prva vrednost.
Molimo vas, obratite pažnju na to da su ovo jedine polarne funkcije koje redukuju izlaz na prvu vrednost. Sve druge prihvataju i vraćaju argumente čiji uglovi mogu pasti izvan ovog opsega.

Konverzija između kartezijanskog i polarnog formata uključuje transcendentalne funkcije, i iz tog razloga ona traži prilično vremena. Tačno je da su množenja brža u polarnim koordinatama, dok su sabiranja daleko brža u kartezijanskim. Razlika je, međutim, toliko manja od cene prebacivanja između različitih predstavljanja, da vam mi savetujemo da, generalno, ostanete u kartezijanskom formatu. Samo u sledećim slučajevima konverzija zaista ima smisla:

  1. Imate samo množenja i povezane matematičke funkcije (poput square, sqrt, ipow). Tada treba da počnete sa polarnim koordinatama.
  2. Morate da pozivate kompleksne eksponencijalne funkcije. U ovom slučaju, cf_exptop vas dovodi u polarne koordinate na vrlo prirodan način.
  3. Vi ste u polarnim koordinatama i morate da izračunate određeni logaritam. U ovom slučaju, pf_logtoc (ili slično pf_log2toc, pf_log10toc) vas “spušta” na kartezijansku predstavu.

Povratak na CMATH sadržaj   OptiVec home stranica

2.3 Osnovne kompleksne operacije

Sledeće osnovne kompleksne operacije su definisane u CMATH-u:

kartezijanska C/Pascal/Delphi funkcija polarna C/Pascal/Delphi funkcija preklopljena C++/Delphi funkcija objašnjenje
cf_conj pf_conj conj kompleksna-konjugovana forma
cf_neg pf_neg neg (ili -) negacija
cf_real pf_real real izdvajanje realnog dela
cf_imag pf_imag imag izdvajanje imaginarnog dela
cf_magargtoc N.A. magargtoc konverzija polarnih koordinata, upisanih kao zasebni realni brojevi, u kartezijanski format
N.A. pf_reimtop reimtop konverzija kartezijanskih koordinata, upisanih kao zasebni realni brojevi, u polarni format
cf_abs pf_abs abs apsolutna vrednost (magnituda pokazivača u kompleksnoj ravni; ovo je tretirano kao matematička funkcija sa rutinom za obradu grešaka)
cf_arg pf_arg arg argument (ugao pokazivača u kompleksnoj ravni)
cf_norm pf_norm norm norm (ovde definisano kao kvadrat apsolutne vrednosti)
N.A. pf_principal principal prva vrednost, sa -p < Arg <= +p

(Verzije u dvostrukoj i u povećanoj preciznosti su tačno analogne cf_ / pf_ verziji)

Povratak na CMATH sadržaj   OptiVec home stranica

2.4 Aritmetičke operacije

Važi samo za C++:

Sledeći skup operatora je raspoloživ za sve tri kartezijanske kompleksne klase:
    +   -   *   /   +=   -=   *=   /=   ==   !=
Za polarne kompleksne klase, imamo:
    *   /   *=    /=    ==    !=
Ovi operatori takođe postoje i za “mešovite” argumente, gde je jedan od argumenata kompleksan, drugi realan, i gde su argumenti brojevi sa pokretnim zarezom - različitih tačnosti.

Važi samo za Delphi:

Umesto operatora definisanih u C++-u, možete upotrebiti sledeće funkcije:
add     sub     mul     divide
One funkcionišu za dva kompleksna argumenta, ili za jedan kompleksan i jedan realan argument.

Budući da samo C++, a ne i čisti-C, niti Pascal, dozvoljava preklopljene aritmetičke operatore, sve aritmetičke operacije sa kompleksnim brojevima implementiraju se dodatno kao funkcije koje se mogu pozivati iz C/Pascal/Delphi, kao i C++ modula:

Kartezijanske Polarne
cf_add N.A. sabiranje dva kompleksna broja
cf_addRe N.A. sabiranje kompleksnog i realnog broja
cf_sub N.A. oduzimanje dva kompleksna broja (prvi operand minus drugi operand)
cf_subRe N.A. oduzimanje realnog od kompleksnog broja
cf_subrRe N.A. oduzimanje kompleksnog od realnog broja
cf_mul pf_mul množenje dva kompleksna broja
cf_mulRe pf_mulRe množenje kompleksnog i realnog broja
cf_div pf_div deljenje dva kompleksna broja (prvi operand odeljen drugim operandom)
cf_divRe pf_divRe deljenje kompleksnog broja realnim brojem
cf_divrRe pf_divrRe deljenje realnog broja kompleksnim brojem

(slično je i za verzije u duploj i povećanoj preciznosti)

Operator dodeljivanja vrednosti "=" ili ":=" je jedini operator koji je za kompleksne brojeve definisan takođe i u čistom-C i jezicima Pascal/Delphi.

Povratak na CMATH sadržaj   OptiVec home stranica

2.5 Matematičke funkcije

CMATH sadrži sve matematičke funkcije koje ćete pronaći u bibliotekama kompleksnih klasa jezika C++, zajedno sa još nekoliko dodatnih:

kartezijanske C/Pascal/Delphi funkcije polarne C/Pascal/Delphi funkcije preklopljene C++/Delphi funkcije formula objašnjenje
cf_abs pf_abs abs ry = | zx | apsolutna vrednost
cf_acos N.A. acos zy = acos( zx ) arkus kosinus funkcija
cf_asin N.A. asin zy = asin( zx ) arkus sinus funkcija
cf_atan N.A. atan zy = atan( zx ) arkus tangens funkcija
cf_cos N.A. cos zy = cos( zx ) cosinusne funkcije
cf_cosh N.A. cosh zy = cosh( zx ) hiperbolički kosinus
cf_cubic pf_cubic cubic zy = zx3 treći stepen (kub)
cf_exp cf_exptop exp zy = exp( zx ) eksponencijalna funkcija
cf_inv pf_inv inv zy = 1.0 / zx inverzna funkcija
cf_ipow pf_ipow ipow zy = zxn celobrojni stepen
cf_ln pf_lntoc ln zy = ln( zx ) prirodni logaritam
cf_log pf_logtoc log zy = ln( zx ) identično sa cf_ln,  pf_lntoc,  ln
cf_log2 pf_log2toc log2 zy = lb( zx ) binarni logaritam
cf_log10 pf_log10toc log10 zy = lg( zx ) dekadni logaritam
cf_pow N.A. pow zy = zxzexp proizvoljni stepen
cf_powReBase N.A. pow, powReBase zy = rzx realna osnova na kompleksni stepen
cf_powReExpo pf_powReExpo pow, powReExpo zy = zxr realni stepen kompleksne osnove
cf_quartic pf_quartic quartic zy = zx4 četvrti stepen
cf_sin N.A. sin zy = sin( zx ) sinus
cf_sinh N.A. sinh zy = sinh( zx ) hiperbolički sinus
cf_square pf_square square zy = zx2 kvadrat
cf_sqrt pf_sqrt sqrt zy = sqrt( zx ) kvadratni koren
cf_tan N.A. tan zy = tan( zx )tangent tangens
cf_tanh N.A. tanh zy = tanh( zx ) hiperbolički tangens

Kao što je gore navedeno, eksponencijalne i logaritamske funkcije pružaju prirodan prelaz između kartezijanskih i polarnih koordinata. Dok postoje exp i log funkcije za fComplex kao argument i povratnu vrednost, cf_exptop uzima fComplex argument i vraća fPolar. U obrnutom pravcu, pf_logtoc uzima fPolar argument i vraća fComplex.

Povratak na CMATH sadržaj   OptiVec home stranica


3. Obrada grešaka

3.1 Generalna obrada grešaka kompleksnih funkcija

Obrada grešaka kompleksnih funkcija prati pravila koja generalno važe i za funkcije i operacije sa realnim brojevima. Za sve aritmetičke operacije, dizajn algoritama eliminiše opasnost od otkaza zbog neregularnih među-rezultata. Izlaženje iz opsega, ili na drugi način neregularni konačni rezultati, međutim, dovešće do toga da se generiše hardverski interrupt, i da, kao posledica toga, program prekine rad.

Suprotno od aritmetičkih operacija, sve matematičke funkcije i sve međukonverzije tipova podataka, izvode strogo proveravanje grešaka. Sve eventualno generisane poruke o greškama koriste C/Pascal ime (pre nego preklopljeno C++/Delphi ime) otkazale funkcije.

3.1.1 C/C++ specifičnosti

Sva stanja grešaka u CMATH matematičkim funkcijama, obrađuju se preko _matherr (za fComplex i dComplex funkcije) i _matherrl (za eComplex funkcije; samo za Borland C++). Re ili Mag deo kompleksnog argumenta, koji izaziva neku grešku, pohranjuje se u e->x i Im ili Arg deo u e->y.

Povratak na CMATH sadržaj   OptiVec home stranica

3.1.2 Pascal/Delphi specifičnosti

Način kako CMATH obrađuje greške kod rada sa pokretnim zarezom, u složenim matematičkim funkcijama, definiše se pozivanjem funkcije V_setFPErrorHandling. Određen broj pre-definisanih konstanti fperrXXX je na raspolaganju za pravljenje željenog moda za obradu grešaka:

Konstanta Vrednost Značenje
fperrIgnore 0 Ignoriše sve greške kod pokretnog zareza: obrađuje ih u pozadini, ne prikazuje poruku, nastavlja izvršavanje programa
fperrNoteDOMAIN $0001 Prikazuje poruku u slučaju DOMAIN greške
fperrNoteSING $0002 Prikazuje poruku u slučaju SING greške
fperrNoteOVERFLOW $0003 Prikazuje poruku u slučaju OVERFLOW greške
fperrNoteTLOSS $0004 Prikazuje poruku u slučaju TLOSS greške
fperrAbortDOMAIN $0101 Prekida program u slučaju DOMAIN greške
fperrAbortSING $0202 Prekida program u slučaju SING greške
fperrAbortOVERFLOW $0303 Prekida program u slučaju OVERFLOW greške
fperrAbortTLOSS $0404 Prekida program u slučaju TLOSS greške
fperrDefaultHandling $0107 Isto kao fperrAbortDOMAIN ili fperrNoteSING ili fperrNoteOVERFLOW

Primer:
V_setFPErrorHandling( fperrAbortDOMAIN + fperrAbortSING + fperrAbortOVERFLOW + fperrNoteTLOSS );
U ovom primeru, izvršavanje programa će se prekinuti (uz odgovarajuću poruku) u slučaju najtežih grešaka, DOMAIN i SING. U slučaju grešaka OVERFLOW i TLOSS, biće prikazano upozorenje, ali će se izvršavanje programa nastaviti, uz podrazumevane rezultate, podešene od strane funkcija u kojima dođe do greške. Ponovljeno pojavljivanje istog tipa greške unutar jedne iste funkcije dovešće do toga da bude generisana samo jedna poruka. Naredne greške će se obrađivati u pozadini, tj. “tiho”.

Povratak na CMATH sadržaj   OptiVec home stranica

3.2 Upisivanje poruke o grešci u fajl

Funkcija V_setErrorEventFile pruža mogućnost da odlučite želite li da se vaše poruke o greškama pojavljuju na ekranu, i/ili u log fajlu. Ova funkcija kao argumente traži željeno ime vašeg fajla sa zapisom događaja, i “prekidač” nazvan ScreenAndFile, koji odlučuje da li želite poruke o greškama da ispisujete simultano u fajl i na ekranu (ScreenAndFile = TRUE (non-zero)), ili isključivo u fajl (ScreenAndFile = FALSE (0)).

Povratak na CMATH sadržaj   OptiVec home stranica


4. Sintaksno referentno uputstvo

Osim kod funkcija za konverziju tipova podataka, sintaksa je data samo za float / fComplex / fPolar. Sintaksa funkcija za dvostruku (double) i povećanu (extended) preciznost je potpuno analogna.
Ukoliko odaberete “klasični” class complex, ovo je takođe slično. Jednostavno zamenite "float" sa "double" i "fComplex" sa "complex". U klasičnom class complex-u nema raspoloživih polarnih funkcija, niti postoje operatori kastovanja i funkcije međukonverzije, ako postoji samo jedan tip.

Povratak na CMATH sadržaj   OptiVec home stranica

4.1 Čist-C, Pascal/Delphi funkcije

Za funkcije preciznosti double / dComplex / dPolar i extended / eComplex / ePolar, prefiksi su, redom, cd_, pd_, ce_, i pe_.

float cf_abs( fComplex __z );
function cf_abs( zx:fComplex ): Single;
float pf_abs( fPolar __p );
function pf_abs( px:fPolar ): Single;

fComplex cf_acos( fComplex __z );
procedure cf_acos( var zy:fComplex; zx:fComplex );

fComplex cf_add( fComplex __x, fComplex __y );
procedure cf_add( var zz:fComplex; zx, zy:fComplex );

fComplex cf_addRe( fComplex __x, float __yRe );
procedure cf_addRe( var zz:fComplex; zx:fComplex; yRe:Single );

float cf_arg( fComplex __z );
function cf_arg( zx:fComplex ): Single;

float pf_arg( fPolar __z );
function pf_arg( px:fPolar ): Single;

fComplex cf_asin( fComplex __z );
procedure cf_asin( var zy:fComplex; zx:fComplex );

fComplex cf_atan( fComplex __z );
procedure cf_atan( var zy:fComplex; zx:fComplex );

eComplex cdtoce( dComplex __zd );
procedure cdtoce( var zy:eComplex; zx:dComplex );

fComplex cdtocf( dComplex __zd );
procedure cdtocf( var zy:fComplex; zx:dComplex );

dPolar cdtopd( dComplex __zd );
procedure cdtopd( var py:dPolar; zx:eComplex );

ePolar cdtope( dComplex __zd );
procedure cdtope( var py:ePolar; zx:eComplex );

fPolar cdtopf( dComplex __zd );
procedure cdtope( var py:fPolar; zx:eComplex );

dComplex cetocd( eComplex __ze );
procedure cetocd( var zy:dComplex; zx:eComplex );

fComplex cetocf( eComplex __ze );
procedure cetocf( var zy:fComplex; zx:eComplex );

dPolar cetopd( eComplex __ze );
procedure cetopd( var py:dPolar; zx:eComplex );

ePolar cetope( eComplex __ze );
procedure cetope( var py:ePolar; zx:eComplex );

fPolar cetopf( eComplex __ze );
procedure cetopf( var py:fPolar; zx:eComplex );

dComplex cftocd( fComplex __zf );
procedure cftocd( var zy:dComplex; zx:fComplex );

eComplex cftoce( fComplex __zf );
procedure cftoce( var zy:eComplex; zx:fComplex );

dPolar cftopd( fComplex __zf );
procedure cftopd( var py:dPolar; zx:fComplex );

ePolar cftope( fComplex __zf );
procedure cftope( var py:ePolar; zx:fComplex );

fPolar cftopf( fComplex __zf );
procedure cftopf( var py:fPolar; zx:fComplex );

fComplex cf_conj( fComplex __z );
procedure cf_conj( var zy:fComplex; zx:fComplex );

fPolar pf_conj( fPolar __p );
procedure pf_conj( var py:fPolar; px:fPolar );

fComplex cf_cos( fComplex __z );
procedure cf_cos( var zy:fComplex; zx:fComplex );

fComplex cf_cosh( fComplex __z );
procedure cf_cosh( var zy:fComplex; zx:fComplex );

fComplex cf_cubic( fComplex __z );
procedure cf_cubic( var zy:fComplex; zx:fComplex );

fPolar pf_cubic( fPolar __p );
procedure pf_cubic( var py:fPolar; px:fPolar );

fComplex cf_div( fComplex __x, fComplex __y );
procedure cf_div( var zz:fComplex; zx, zy:fComplex );

fPolar pf_div( fPolar __x, fPolar __y );
procedure pf_div( var pz:fPolar; px, py:fPolar );

fComplex cf_divRe( fComplex __x, float __yRe ); /* x / yRe */
procedure cf_divRe( var zz:fComplex; zx:fComplex; yRe:Single );

fPolar pf_divRe( fPolar __x, float __yRe ); /* x / yRe */
procedure pf_divRe( var pz:fPolar; px:fPolar; yRe:Single );

fComplex cf_divrRe( fComplex __x, float __yRe ); /* yRe / x */
procedure cf_divrRe( var zz:fComplex; zx:fComplex; yRe:Single );

fPolar pf_divrRe( fPolar __x, float __yRe ); /* yRe / x */
procedure pf_divrRe( var pz:fPolar; px:fPolar; yRe:Single );

fComplex cf_exp( fComplex __z );
procedure cf_exp( var zy:fComplex; zx:fComplex );

fPolar cf_exptop( fComplex __z );
procedure cf_exptop( var py:fPolar; zx:fComplex );

fComplex fcplx( float __ReVal, float __ImVal);
procedure fcplx( var zy:fComplex; xRe, xIm:Single );

fPolar fpolr( float __MagVal, float __ArgVal);
procedure fpolr( var py:fPolar; xMag, xArg:Single );

float cf_imag( fComplex __z );
function cf_imag( zx:fComplex ): Single;

float pf_imag( fPolar __p );
function pf_imag( px:fPolar ): Single;

fComplex cf_inv( fComplex __z );
procedure cf_inv( var zy:fComplex; zx:fComplex );

fPolar pf_inv( fPolar __p );
procedure pf_inv( var py:fPolar; zx:fComplex );

fComplex cf_ipow( fComplex __z, int __exponent );
procedure cf_ipow( var zy:fComplex; zx:fComplex; exponent:Integer );

fPolar pf_ipow( fPolar __p, int __exponent );
procedure pf_ipow( var py:fPolar; px:fPolar; exponent:Integer );

fComplex cf_ln( fComplex __z );
procedure cf_ln( var zy:fComplex; zx:fComplex );

fComplex pf_lntoc( fPolar __p );
procedure pf_lntoc( var zy:fComplex; zx:fPolar );

fComplex cf_log( fComplex __z );
procedure cf_log( var zy:fComplex; zx:fComplex );

fComplex pf_logtoc( fPolar __p );
procedure pf_logtoc( var zy:fComplex; zx:fPolar );

fComplex cf_log2( fComplex __z );
procedure cf_log2( var zy:fComplex; zx:fComplex );

fComplex pf_log2toc( fPolar __p );
procedure pf_log2toc( var zy:fComplex; zx:fPolar );

fComplex cf_log10( fComplex __z );
procedure cf_log10( var zy:fComplex; zx:fComplex );

fComplex pf_log10toc( fPolar __p );
procedure pf_log10toc( var zy:fComplex; zx:fPolar );

fComplex cf_magargtoc( float __mag, float __angle );
procedure cf_magargtoc( var zy:fComplex; mag, angle:Single );

fComplex cf_mul( fComplex __x, fComplex __y );
procedure cf_mul( var zz:fComplex; zx, zy:fComplex );

fPolar pf_mul( fPolar __x, fPolar __y );
procedure pf_mul( var zz:fPolar; zx, zy:fPolar );

fComplex cf_mulRe( fComplex __x, float __yRe );
procedure cf_mulRe( var zz:fComplex; zx:fComplex; yRe:Single );

fPolar pf_mulRe( fPolar __x, float __yRe );
procedure pf_mulRe( var zz:fPolar; zx:fPolar; yRe:Single );

fComplex cf_neg( fComplex __z );
procedure cf_neg( var zy:fComplex; zx:fComplex );

fPolar pf_neg( fPolar __p );
procedure pf_neg( var py:fPolar; px:fPolar );

float cf_norm( fComplex __z );
function cf_norm( zx:fComplex ): Single;

float pf_norm( fPolar __p );
function pf_norm( px:fPolar ): Single;

dComplex pdtocd( dPolar __pd );
procedure pdtocd( var zy:dComplex; px:dPolar );

eComplex pdtoce( dPolar __pd );
procedure pdtoce( var zy:eComplex; px:dPolar );

fComplex pdtocf( dPolar __pd );
procedure pdtocf( var zy:fComplex; px:dPolar );

ePolar pdtope( dPolar __pd );
procedure pdtope( var zy:ePolar; zx:dPolar );

fPolar pdtopf( dPolar __pd );
procedure pdtopf( var zy:fPolar; zx:dPolar );

dComplex petocd( ePolar __pe );
procedure petocd( var zy:dComplex; px:ePolar );

eComplex petoce( ePolar __pe );
procedure petoce( var zy:eComplex; px:ePolar );

fComplex petocf( ePolar __pe );
procedure petocf( var zy:fComplex; px:ePolar );

dPolar petopd( ePolar __pe );
procedure petopd( var zy:dPolar; zx:ePolar );

fPolar petopf( ePolar __pe );
procedure petopf( var zy:fPolar; zx:ePolar );

dComplex pftocd( fPolar __pf );
procedure pftocd( var zy:dComplex; px:fPolar );

eComplex pftoce( fPolar __pf );
procedure pftoce( var zy:eComplex; px:fPolar );

fComplex pftocf( fPolar __pf );
procedure pftocf( var zy:fComplex; px:fPolar );

dPolar pftopd( fPolar __pf );
procedure pftopd( var zy:dPolar; zx:fPolar );

ePolar pftope( fPolar __pf );
procedure pftope( var zy:ePolar; zx:fPolar );

fComplex cf_polar( float mag, float arg ); /* same as cf_magargtoc */
procedure cf_polar( var zy:fComplex; mag, arg:Single );

fComplex cf_pow( fComplex __base, fComplex __exponent );
procedure cf_pow( var zy:fComplex; zx:fComplex; exponent:Integer );

fComplex cf_powReBase( float __base, fComplex __exponent );
procedure cf_powReBase( var zy:fComplex; base:Single; exponent:fComplex );

fComplex cf_powReExpo( fComplex __base, float __exponent );
procedure cf_powReExpo( var zy:fComplex; zx:fComplex; exponent:Single );

fPolar pf_powReExpo( fPolar __base, float __exponent );
procedure pf_powReExpo( var py:fPolar; px:fPolar; exponent:Single );

fComplex cf_quartic( fComplex __z );
procedure cf_quartic( var zy:fComplex; zx:fComplex );

fPolar pf_quartic( fPolar __p );
procedure pf_quartic( var py:fPolar; zx:fPolar );

float cf_real( fComplex __z );
function cf_real( zx:fComplex ): Single;

float pf_real( fPolar __p );
function pf_real( px:fPolar ): Single;

fComplex cf_sin( fComplex __z );
procedure cf_sin( var zy:fComplex; zx:fComplex );

fComplex cf_sinh( fComplex __z );
procedure cf_sinh( var zy:fComplex; zx:fComplex );

fComplex cf_square( fComplex __z );
procedure cf_square( var zy:fComplex; zx:fComplex );

fPolar pf_square( fPolar __p );
procedure pf_square( var py:fPolar; zx:fPolar );

fComplex cf_sqrt( fComplex __z );
procedure cf_sqrt( var zy:fComplex; zx:fComplex );

fPolar pf_sqrt( fPolar __p );
procedure pf_sqrt( var py:fPolar; px:fPolar );

fComplex cf_sub( fComplex __x, fComplex __y );
procedure cf_sub( var zz:fComplex; zx, zy:fComplex );

fComplex cf_subRe( fComplex __x, float __yRe ); /* x - yRe */
procedure cf_subRe( var zz:fComplex; zx:fComplex; yRe:Single );

fComplex cf_subrRe( fComplex __x, float __yRe ); /* yRe - x */
procedure cf_subrRe( var zz:fComplex; zx:fComplex; yRe:Single );

fComplex cf_tan( fComplex __z );
procedure cf_tan( var zy:fComplex; zx:fComplex );

fComplex cf_tanh( fComplex __z );
procedure cf_tanh( var zy:fComplex; zx:fComplex );

Povratak na CMATH sadržaj   OptiVec home stranica

4.2 Preklopljene C++/Delphi funkcije

float abs( fComplex _z );
function abs( zx:fComplex ): Single;

float abs( fPolar _p );
function abs( px:fPolar ): Single;

fComplex acos( fComplex _z );
function acos( zx:fComplex ): fComplex;

function add( zx, zy:fComplex ): fComplex;
function add( zx:fComplex; yRe:Single ): fComplex;
function add( yRe:Single; zx:fComplex ): fComplex;
function addRe( zx:fComplex; yRe:Single ): fComplex;

float arg( fComplex _z );
function arg( zx:fComplex ): Single;

float arg( fPolar _p );
function arg( px:fPolar ): Single;

fComplex asin( fComplex _z );
function asin( zx:fComplex ): fComplex;

fComplex atan( fComplex _z );
function atan( zx:fComplex ): fComplex;

fComplex conj( fComplex _z );
function conj( zx:fComplex ): fComplex;

fPolar conj( fPolar _p );
function conj( px:fPolar ): fPolar;

fComplex cos( fComplex _z );
function cos( zx:fComplex ): fComplex;

fComplex cosh( fComplex _z );
function cosh( zx:fComplex ): fComplex;

fComplex cubic( fComplex _z );
function cubic( zx:fComplex ): fComplex;

fPolar cubic( fPolar _p );
function cubic( px:fPolar ): fPolar;

function divide( zx, zy:fComplex ): fComplex;
function divide( zx:fComplex; yRe:Single ): fComplex;
function divide( yRe:Single; zx:fComplex ): fComplex;
function divide( px, py:fPolar ): fPolar;
function divide( px:fPolar; yRe:Single ): fPolar;
function divide( yRe:Single; px:fPolar ): fPolar;

function divRe( zx:fComplex; yRe:Single ): fComplex;
function divRe( px:fPolar; yRe:Single ): fPolar;
function divrRe( zx:fComplex; yRe:Single ): fComplex;
function divrRe( px:fPolar; yRe:Single ): fPolar;

fComplex exp( fComplex _z );
function exp( zx:fComplex ): fComplex;

fPolar exptop( fComplex _z );
function exptop( zx:fComplex ): fPolar;

fComplex fComplex( float Re_part, float Im_part=0 );
fComplex fComplex( dComplex cd );
fComplex fComplex( eComplex ce ); // type-casting constructors
fComplex fComplex( fPolar pf ); // interconversion from polar
fComplex fComplex( dPolar pd );
fComplex fComplex( ePolar pe );

float imag(); // to be used as zim = z.imag();
float imag( fComplex _z ); // to be used as zim = imag( z );
function imag( zx:fComplex ): Single;

float imag( fPolar _p );
function imag( px:fPolar ): Single;
fComplex inv( fComplex _z );
function inv( zx:fComplex ): fComplex;

fPolar inv( fPolar _p );
function inv( px:fPolar ): fPolar;

fComplex ipow( fComplex __base, int __expon );
function ipow( zx:fComplex; exponent:Integer ): fComplex;

fPolar ipow( fPolar __base, int __expon );
function ipow( px:fPolar; exponent:Integer ): fPolar;

fComplex ln( fComplex _z );
function ln( zx:fComplex ): fComplex;

fComplex lntoc( fPolar _p );
function lntoc( px:fPolar ): fComplex;

fComplex log( fComplex _z );
function log( zx:fComplex ): fComplex;

fComplex logtoc( fPolar _p );
function logtoc( px:fPolar ): fComplex;

fComplex log2( fComplex _z );
function log2( zx:fComplex ): fComplex;

fComplex log2toc( fPolar _p );
function log2toc( px:fPolar ): fComplex;

fComplex log10( fComplex _z );
function log10( zx:fComplex ): fComplex;

fComplex log10toc( fPolar _p );
function log10toc( px:fPolar ): fComplex;

fComplex magargtoc( float _mag, float _angle );
function magargtoc( mag, angle:Single ): fComplex;

function mul( zx, zy:fComplex ): fComplex;
function mul( zx:fComplex; yRe:Single ): fComplex;
function mul( yRe:Single; zx:fComplex ): fComplex;
function mul( px, py:fPolar ): fPolar;
function mul( px:fPolar; yRe:Single ): fPolar;
function mul( yRe:Single; px:fPolar ): fPolar;

function mulRe( zx:fComplex; yRe:Single ): fComplex;
function mulRe( px:fPolar; yRe:Single ): fPolar;

fComplex neg( fComplex _z );
function neg( zx:fComplex ): fComplex;

fPolar neg( fPolar _p );
function neg( px:fPolar ): fPolar;

float norm( fComplex _z );
function norm( zx:fComplex ): Single;

float norm( fPolar _p );
function norm( px:fPolar ): Single;

fComplex pow( fComplex __base, fComplex __expon);
fComplex pow( float __base, fComplex __expon);
fComplex pow( fComplex __base, float __expon );
function pow( zx, exponent:fComplex ): fComplex;
function pow( zx:fComplex; exponent:Single ): fComplex;
function pow( base:Single; exponent:fComplex ): fComplex;
function pow( px:fPolar; exponent:Single ): fPolar;

fComplex powReBase( float __base, fComplex __expon );
function powReBase( base:Single; exponent:fComplex ): fComplex;

fComplex powReExpo( fComplex __base, float __expon );
function powReExpo( zx:fComplex; exponent:Single ): fComplex;

fPolar powReExpo( fPolar __base, float __expon );
function powReExpo( px:fPolar; exponent:Single ): fPolar;

fPolar principal( fPolar _p );
fPolar principal( floag __mag, float __arg );
function principal( px:fPolar ): fPolar;

fComplex quartic( fComplex _z );
function quartic( zx:fComplex ): fComplex;

fPolar quartic( fPolar _p );
function quartic( px:fPolar ): fPolar;

float z.real(); // to be used as zre = z.real();
float real( fComplex _z ); // to be used as zre = real ( _z );
function real( zx:fComplex ): Single;

float real( fPolar _p );
function real( px:fPolar ): Single;

fPolar reimtop( float _re, float _im );
function reimtop( re, im:Single ): fPolar;

fComplex sin( fComplex _z );
function sin( zx:fComplex ): fComplex;

fComplex sinh( fComplex _z );
function sinh( zx:fComplex ): fComplex;

fComplex sqrt( fComplex _z );
function sqrt( zx:fComplex ): fComplex;

fPolar sqrt( fPolar _p );
function sqrt( px:fPolar ): fPolar;

fComplex square( fComplex _z );
function square( zx:fComplex ): fComplex;

fPolar square( fPolar _z );
function square( px:fPolar ): fPolar;

function sub( zx, zy:fComplex ): fComplex;
function sub( zx:fComplex; yRe:Single ): fComplex;
function sub( yRe:Single; zx:fComplex ): fComplex;
function subRe( zx:fComplex; yRe:Single ): fComplex;
function subrRe( zx:fComplex; yRe:Single ): fComplex;

fComplex tan( fComplex _z );
function tan( zx:fComplex ): fComplex;

fComplex tanh( fComplex _z );
function tanh( zx:fComplex ): fComplex;

Povratak na CMATH sadržaj   OptiVec home stranica

Autorska prava © 1998-2012 OptiCode - Dr. Martin Sander softverski razvoj

Poslednja izmena: 21. oktobar 2012.