9. Sonstiges
9.1 Evaluate
Evaluate ist ein Funktionsparser, der
die Funktion eval_term() zu Verfuegung stellt. Der Funktion wird ein Funktionsstring
und eine Parameterliste übergeben, deren Formate später erläutert
werden. Die Funktion liefert als Ergebnis ein nTuple. Die gesamte
Funktion basiert auf dem Typen double.
Parameter
Die Parameterliste kann beliebig viele
Parameter enthalten. Ein Parameter hat immer einen eindeutigen Namen und
einen Wert. Mit der Funktion add_param() kann der Parameterliste ein neuer
Parameter hinzugefügt werden.
Beispiel 1:
paralist_t
parameterliste = {0,NULL};
add_param(parameterliste,"PI",3.1415);
fügt
einen Parameter mit Namen "PI", der den Wert 3.1415 hat, in die Parameterliste
"parameterliste" ein.
Der Parametername
wird beim Auswerten des Funktionsstrings durch den Parameterwert ersetzt.
Der Vorteil von Parametern ist, daß man einen vorhandnen Funktionsstring
nicht neu generieren muß, wenn sich ein variabler Wert in der Funktion
ändert. Hier kann einfach der Parameterwert verändert werden.
Dafür wird die Funktion set_param() bereit gestellt.
Beispiel 2:
set_param(parameterliste,"PI",PI);
setzt den Parameter
mit Namen "PI", den wir in Beispiel 1 erzeugt haben, auf den Wert von PI,
in der Parameterliste "parameterliste".
Enthält die angegebene Parameterliste
keinen Eintrag mit dem angegebenen Namen, so wird dieser Parameter wie
mit add_param() erzeugt.
nTuple
Die Funktion eval_term() gibt als Ergebnis
ein nTuple zurück. Ein Vektor, der aus z.B. drei Elementen besteht,
kann also ein Ergebnis sein.
Beispiel 3:
ntuple_t *result
= NULL;
add_param(parameterliste,"x",0);
add_param(parameterliste,"y",1);
add_param(parameterliste,"z",2);
result = eval_term("(x
* PI,y * PI,z * PI)",parameterliste);
result enthält
jetzt drei Werte (0,PI,PI * 2).
Man kann natürlich das Beispiel 3
auch so lösen:
Beispiel 4:
ntuple_t *resultx
= NULL;
ntuple_t *resulty
= NULL;
ntuple_t *resultz
= NULL;
resultx = eval_term("x
* PI",parameterliste);
resulty = eval_term("y
* PI",parameterliste);
resultz = eval_term("z
* PI",parameterliste);
resultx, resulty,
resultz enthalten jetzt jeweils nur einen Wert.
Matrizen können nicht als Ergebnis
von eval_term() zurück gegeben werden.
Funktionsstring
In Beispiel 3 und 4 haben wir schon
ein paar Beispiele fuer Funktionsstrings gesehen. Funktionsstrings können
Terme (Beispiel 4) oder nTuple von Termen (Beispiel 3) sein. Terme setzten
sich aus Operatoren, Zahlen, Parametern und Funktionen zusammen, welche
immer durch ein Leerzeichen getrennt werden sollten.
Beispiel 5:
result = eval_term("(sin(Winkel
* PI / 180) * Breite, cos(Winkel * Pi / 180) * Hoehe)",paralist);
result enthält
zwei Werte, die einen Punkt in R2 beschreiben, der auf einer Elipse liegt.
Operatoren
Operatoren sind infix-Funktionen, die
man aus der Mathematik kennt. Folgende Operatoren sind definiert: + , -
, * , / , ^ , %.
Die Bedeutungen sind eindeutig und werden
deshalb nicht näher erläutert. Außerdem gibt es für
die Boolsche Algebra folgende Operatoren: & , | Diese Operatoren sind
identisch mit && und || in C und heisen
binaer und und binear
oder. Zuletzt gibt es für die Boolsche Algebra noch Relationen:
= , < , > , #. Die ersten drei Relationen sind eindeutig. # steht für
ungleich.
Die Rangfolge der Operatoren:
1. ^ (Achtung: ist nicht Linksassoziativ)
2. * , / , %
3. + , -
4. = , < , > , #
5. & , |
Wer Operatoren vermißt sieht bitte,
ob er diese nicht durch Funktionen ersetzen kann.
Zahlen
Zahlen sind beliebige Zahlenstrings.
Zahlen koennen bisher nicht in der Mathematischen bzw. Exponentialschreibweise
angegeben werden.
Funktionen
Funktionen haben folgendes Aussehen:
func(<term>) oder func(<ntuple>) Es gibt viele Funktionen aus der
C-Lib. Hier eine Liste aller Funktionen:
Mathematisch:
sin(x)
cos(x)
tan(x)
asin(x)
acos(x)
atan(x)
sinh(x)
cosh(x)
tanh(x)
asinh(x)
acosh(x)
atanh(x)
logn(x)
logd(x)
ceil(x)
floor(x)
abs(x) oder fabs(x)
sqrt(x)
sqr(x)
pow(x,y)
mod(x,y)
drand() oder rand()
seedrand(x)
Boolsche Algebra:
isnan(x)
not(x)
and(x,y)
or(x,y)
xor(x,y)
Alle Funktionen sind entweder eindeutig
oder in der C-lib erklärt.
Siehe z.B. manpages oder math.h.
Partialdefinierte Funktionen
Die Syntax fuer partialdefinierte Funktionen
hat folgendes Aussehen:
{<equal>:<term>;<equal>:<term>...}
<equal> ist ein Term, dessen Ergebnis
als Wahr oder Falsch interpretiert wird. Falls <equal> Wahr ist, dann
ist das Ergebnis der partialdefinierten Funktion das Ergebnis von <term>
der direkt auf <equal> folgt. Um ein Abstürzen der Funktion eval_term()
beim Auswerten von solchen Funktionen zu vermeiden, sollte die entsprechende
Funktion über den gesamten Wertebereicht definiert sein. Außerdem
erhält man sonst, irgendwelche undefinierten Werte. Wichtig sind die
beiden geschweiften Klammern, die die Funktion einschließen. Auch
geschachtelte partialdefinierte Funktionen sollten, wenn dies auch unsinnig
ist, möglich sein.
Dortmund, 18.2.1996