VF_ratio_d | VF_ratio_e | VD_ratio_e |
VFx_ratio | VDx_ratio | VEx_ratio |
VFx_ratio_d | VFx_ratio_e | VDx_ratio_e |
VF_ratioOddEven | VD_ratioOddEven | VE_ratioOddEven |
VF_ratioOddEven_d | VF_ratioOddEven_e | VD_ratioOddEven_e |
VFx_ratioOddEven | VDx_ratioOddEven | VEx_ratioOddEven |
VFx_ratioOddEven_d | VFx_ratioOddEven_e | VDx_ratioOddEven_e |
VF_ratioEvenOdd | VD_ratioEvenOdd | VE_ratioEvenOdd |
VF_ratioEvenOdd_d | VF_ratioEvenOdd_e | VD_ratioEvenOdd_e |
VFx_ratioEvenOdd | VDx_ratioEvenOdd | VEx_ratioEvenOdd |
VFx_ratioEvenOdd_d | VFx_ratioEvenOdd_e | VDx_ratioEvenOdd_e |
VFu_ratio | VDu_ratio | VEu_ratio |
VFu_ratio_d | VFu_ratio_e | VDu_ratio_e |
VFux_ratio | VDux_ratio | VEux_ratio |
VFux_ratio_d | VFux_ratio_e | VDux_ratio_e |
VFu_ratioOddEven | VDu_ratioOddEven | VEu_ratioOddEven |
VFu_ratioOddEven_d | VFu_ratioOddEven_e | VDu_ratioOddEven_e |
VFux_ratioOddEven | VDux_ratioOddEven | VEux_ratioOddEven |
VFux_ratioOddEven_d | VFux_ratioOddEven_e | VDux_ratioOddEven_e |
VFu_ratioEvenOdd | VDu_ratioEvenOdd | VEu_ratioEvenOdd |
VFu_ratioEvenOdd_d | VFu_ratioEvenOdd_e | VDu_ratioEvenOdd_e |
VFux_ratioEvenOdd | VDux_ratioEvenOdd | VEux_ratioEvenOdd |
VFux_ratioEvenOdd_d | VFux_ratioEvenOdd_e | VDux_ratioEvenOdd_e |
|
Funktion | Ratio: 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/Delphi | uses 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/Delphi | uses 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;
|
|
Beschreibung | einfache 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.
|
|
Fehlerbehandlung | OVERFLOW- 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ückgabewert | FALSE (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. |
|
|