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.
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.
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.
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 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 sind beliebige Zahlenstrings. Zahlen koennen bisher nicht in der Mathematischen bzw. Exponentialschreibweise angegeben werden.
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)
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.
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