VF_ratioVD_ratioVE_ratio
VF_ratio_dVF_ratio_eVD_ratio_e
VFx_ratioVDx_ratioVEx_ratio
VFx_ratio_dVFx_ratio_eVDx_ratio_e
VF_ratioOddEvenVD_ratioOddEvenVE_ratioOddEven
VF_ratioOddEven_dVF_ratioOddEven_eVD_ratioOddEven_e
VFx_ratioOddEvenVDx_ratioOddEvenVEx_ratioOddEven
VFx_ratioOddEven_dVFx_ratioOddEven_eVDx_ratioOddEven_e
VF_ratioEvenOddVD_ratioEvenOddVE_ratioEvenOdd
VF_ratioEvenOdd_dVF_ratioEvenOdd_eVD_ratioEvenOdd_e
VFx_ratioEvenOddVDx_ratioEvenOddVEx_ratioEvenOdd
VFx_ratioEvenOdd_dVFx_ratioEvenOdd_eVDx_ratioEvenOdd_e
   
VFu_ratioVDu_ratioVEu_ratio
VFu_ratio_dVFu_ratio_eVDu_ratio_e
VFux_ratioVDux_ratioVEux_ratio
VFux_ratio_dVFux_ratio_eVDux_ratio_e
VFu_ratioOddEvenVDu_ratioOddEvenVEu_ratioOddEven
VFu_ratioOddEven_dVFu_ratioOddEven_eVDu_ratioOddEven_e
VFux_ratioOddEvenVDux_ratioOddEvenVEux_ratioOddEven
VFux_ratioOddEven_dVFux_ratioOddEven_eVDux_ratioOddEven_e
VFu_ratioEvenOddVDu_ratioEvenOddVEu_ratioEvenOdd
VFu_ratioEvenOdd_dVFu_ratioEvenOdd_eVDu_ratioEvenOdd_e
VFux_ratioEvenOddVDux_ratioEvenOddVEux_ratioEvenOdd
VFux_ratioEvenOdd_dVFux_ratioEvenOdd_eVDux_ratioEvenOdd_e
FunktionRatio: Quotient zweier Polynome
Syntax C/C++#include <VFmath.h>
int VF_ratio( fVector Y, fVector X, ui size, fVector Coeff, unsigned degP, unsigned degQ );
int VFx_ratio( fVector Y, fVector X, ui size, fVector Coeff, unsigned degP, unsigned degQ, float A, float B );
int VFu_ratio( fVector Y, fVector X, ui size, fVector Coeff, unsigned degP, unsigned degQ );
int VFux_ratio( fVector Y, fVector X, ui size, fVector Coeff, unsigned degP, unsigned degQ, float A, float B );
C++ VecObj#include <OptiVec.h>
int vector<T>::ratio( const vector<T>& X, const vector<T>& Coeff, unsigned degP, unsigned degQ );
int vector<T>::x_ratio( const vector<T>& X, const vector<T>& Coeff, unsigned degP, unsigned degQ, const T& A, const T& B );
Pascal/Delphiuses VFmath;
function VF_ratio( Y, X:fVector; size:UIntSize; Coeff:fVector; degP, degQ:UInt ): IntBool;
function VFx_ratio( Y, X:fVector; size:UIntSize; Coeff:fVector; degP, degQ:UInt; A, B:Single ): IntBool;
function VFu_ratio( Y, X:fVector; size:UIntSize; Coeff:fVector; degP, degQ:UInt ): IntBool;
function VFux_ratio( Y, X:fVector; size:UIntSize; Coeff:fVector; degP, degQ:UInt; A, B:Single ): IntBool;
CUDA-Funktion C/C++#include <cudaVFmath.h>
int cudaVF_ratio( fVector d_Y, fVector d_X, ui size, fVector h_Coeff, unsigned degP, unsigned degQ );
int cusdVF_ratio( fVector d_Y, fVector d_X, ui size, fVector d_Coeff, unsigned degP, unsigned degQ );
int cudaVFx_ratio( fVector d_Y, fVector d_X, ui size, fVector h_Coeff, unsigned degP, unsigned degQ, float A, float B );
int cusdVFx_ratio( fVector d_Y, fVector d_X, ui size, fVector d_Coeff, unsigned degP, unsigned degQ, float *d_A, float *d_B );
int cudaVFu_ratio( fVector d_Y, fVector d_X, ui size, fVector h_Coeff, unsigned degP, unsigned degQ );
int cusdVFu_ratio( fVector d_Y, fVector d_X, ui size, fVector d_Coeff, unsigned degP, unsigned degQ );
int cudaVFux_ratio( fVector d_Y, fVector d_X, ui size, fVector h_Coeff, unsigned degP, unsigned degQ, float A, float B );
int cusdVFux_ratio( fVector d_Y, fVector d_X, ui size, fVector d_Coeff, unsigned degP, unsigned degQ, float *d_A, float *d_B );
int VFcu_ratio( fVector h_Y, fVector h_X, ui size, fVector h_Coeff, unsigned degP, unsigned degQ );
int VFxcu_ratio( fVector h_Y, fVector h_X, ui size, fVector h_Coeff, unsigned degP, unsigned degQ, float A, float B );
int VFucu_ratio( fVector h_Y, fVector h_X, ui size, fVector h_Coeff, unsigned degP, unsigned degQ );
int VFuxcu_ratio( fVector h_Y, fVector h_X, ui size, fVector h_Coeff, unsigned degP, unsigned degQ, float A, float B );
CUDA-Funktion Pascal/Delphiuses VFmath;
function cudaVF_ratio( d_Y, d_X:fVector; size:UIntSize; h_Coeff:fVector; degP, degQ:UInt ): IntBool;
function cusdVF_ratio( d_Y, d_X:fVector; size:UIntSize; d_Coeff:fVector; degP, degQ:UInt ): IntBool;
function cudaVFx_ratio( d_Y, d_X:fVector; size:UIntSize; h_Coeff:fVector; degP, degQ:UInt; A, B:Single ): IntBool;
function cusdVFx_ratio( d_Y, d_X:fVector; size:UIntSize; d_Coeff:fVector; degP, degQ:UInt; d_A, d_B:PSingle ): IntBool;
function cudaVFu_ratio( d_Y, d_X:fVector; size:UIntSize; h_Coeff:fVector; degP, degQ:UInt ): IntBool;
function cusdVFu_ratio( d_Y, d_X:fVector; size:UIntSize; d_Coeff:fVector; degP, degQ:UInt ): IntBool;
function cudaVFux_ratio( d_Y, d_X:fVector; size:UIntSize; h_Coeff:fVector; degP, degQ:UInt; A, B:Single ): IntBool;
function cusdVFux_ratio( d_Y, d_X:fVector; size:UIntSize; d_Coeff:fVector; degP, degQ:UInt; d_A, d_B:PSingle ): IntBool;
function VFcu_ratio( h_Y, h_X:fVector; size:UIntSize; h_Coeff:fVector; degP, degQ:UInt ): IntBool;
function VFxcu_ratio( h_Y, h_X:fVector; size:UIntSize; h_Coeff:fVector; degP, degQ:UInt; A, B:Single ): IntBool;
function VFucu_ratio( h_Y, h_X:fVector; size:UIntSize; h_Coeff:fVector; degP, degQ:UInt ): IntBool;
function VFuxcu_ratio( h_Y, h_X:fVector; size:UIntSize; h_Coeff:fVector; degP, degQ:UInt; A, B:Single ): IntBool;
Beschreibungeinfache Versionen VF_ratio, VD_ratio, VE_ratio:
Yi = P/Q mit
P = p0 + p1 * Xi + p2 * Xi2 + ... + pdegP * XidegP,
Q = q0 + q1 * Xi + q2 * Xi2 + ... + qdegQ * XidegQ

erweiterte Versionen VFx_ratio, VDx_ratio, VEx_ratio:
xi = (A*Xi + B),
Yi = P/Q wie oben mit xi anstelle von Xi

Ein Polynom P vom Grade degP wird durch ein Polynom Q vom Grade degQ dividiert, wobei die Koeffizienten pk und qk dem Vektor Coeff entnommen werden. Coeff muss das konstante Glied p0 als nulltes Element enthalten, den linearen Koeffizienten p1 als erstes Element usw. bis hin zum Koeffizienten pdegP als degP-tem Element und direkt anschließend das konstante Glied q0 als (degP+1)-tes, q1 als (degP+2)-tes usw. bis hin zum Koeffizienten qdegQ als (degP+degQ+1)-tes Element. Dies bedeutet, dass Coeff insgesamt (degP+degQ+2) Elemente haben muss.

"ungeschützte" Versionen (Präfix VFu_,   VFux_, etc.):
Diese Funktionen führen keinerlei Fehlerbehandlung durch und sind hierdurch bis zu 50% schneller als die Normalversionen. Durch ihren Rückgabewert zeigen sie aber das Auftreten eventueller Fehler an.

Da die einzelnen Polynome gerne zum numerischen Überlauf neigen, während ihr Quotient ein perfekt legales Endergebnis liefern kann, bietet OptiVec zusätzliche Versionen, die intern in höherer Genauigkeit rechnen: VF_ratio_d und VF_ratio_e arbeiten intern in double bzw. extended, bevor das Endergebnis zurück in einfache Genauigkeit gewandelt wird. Analog arbeitet VD_ratio_e zunächst extended-genau (dies gilt auch, wenn der Compiler eigentlich gar keine extended-Genauigkeit unterstützt!) und wandelt erst das Endergebnis wieder in double um. Diese Versionen existieren aber nur für die CPU, nicht für CUDA.

In der praktischen Anwendung findet man gelegentlich rationale Modelle für mathematische Funktionen, bei denen das Zähler-Polynom nur aus ungeraden und das Nenner-Polynom nur aus geraden Termen besteht oder umgekehrt. Beispiele hierfür sind die rationale Darstellung des Tangens (nur ungerade Terme im Zähler, nur gerade Terme im Nenner) und des Cotangens (nur gerade Terme im Zähler, nur ungerade Terme im Nenner). Hierfür dienen in OptiVec die folgenden Funktionen:

VF_ratioOddEven: Zähler nur ungerade, Nenner nur gerade Terme:
Pi = p1 * Xi + p1 * Xi3 + ... + pdegP * XidegP, wobei degP = 2n+1
Qi = q0 + q2 * Xi2 + ... + qdegQ * XidegQ, wobei degQ = 2n
Coeff enthält hier (degP+1)/2 + (degQ/2)+1 Koeffizienten.

VF_ratioEvenOdd: Zähler nur gerade, Nenner nur ungerade Terme:
Pi = p0 + p2 * Xi2 + ... + pdegP * XidegP, wobei degP = 2n
Qi = q1 * Xi + q1 * Xi3 + ... + qdegQ * XidegQ, wobei degQ = 2n+1
Coeff enthält hier (degP/2)+1 + (degQ+1)/2 Koeffizienten.

Mathematisch sind zwar Polynome und Ratios beliebig hohen Grades möglich. Praktisch sorgen aber Überlauf-, Unterlauf- und Rundungsfehler dafür, dass hohe Grade hier sinnlos sind. Dementsprechend erlauben VF_ratio, VF_ratio_d und VD_ratio nur degP+degQ ± 32. Bei Überschreitung dieser Grenze wird eine Fehlermeldung "Invalid Parameter(s)" ausgegeben und die Programmausführung beendet. Nur die VE_-Versionen sowie VF_ratio_e und VD_ratio_e erlauben höhere Grade.

FehlerbehandlungOVERFLOW- oder ZERODIVIDE-Fehler führen zu ±HUGE_VAL als Ergebnis. 0/0-Situationen werden nur in den VE_ und V?_ratio_e-Versionen aufgelöst, indem 0/0 durch den Quotienten aus der 1. Ableitung von P und der 1. Ableitung von Q ersetzt wird. In allen anderen Versionen folgt ±HUGE_VAL als Ergebnis.
RückgabewertFALSE (0), wenn fehlerfrei, andernfalls eine Bit-Kombination der aufgetretenen Fehler 0x4 (Division durch 0), 0x8 (OVERFLOW) und 0x1 (0/0).
Obwohl die "ungeschützte" Varianten (Präfix VFu_,   VFux_, etc.) keine Fehlerbehandlung durchführen, geben sie dieselben Fehler-Codes zurück wie die "geschützte" Normal-Version.
QuerverweisVF_poly,   VF_ipow,   VF_pow

VectorLib Inhaltsverzeichnis  OptiVec Home