FC_BandAlgorithm - Allgemeine Informationen
Typ |
Funktion |
Verfügbar ab: |
V1.0.3.0 |
Versionen: |
Aktuelle Version |
Lösung des Gleichungssystems, das durch eine Bandmatrix gegeben ist.
Eine Bandmatrix ist eine Matrix, bei der nur die Hauptdiagonale und einige Nebendiagonalen von Elementen ungleich null enthalten. Gleichungssysteme mit Bandmatrizen kommen häufig in der Praxis vor (z. B. bei der Berechnung von Splines). Sie sind oft sehr groß (> 1000 Unbekannte), sodass die Speicherung der zugehörigen Matrix in einem quadratischen Array einer enormen Verschwendung von Speicherplatz gleichkommen würde (bei einer 1000x1000-Matrix für einen Spline wären von den 1000000 Matrixelementen nur 3000 von null verschieden). Stattdessen speichert man die Matrix in einem Array, das so viele Zeilen wie die Matrix hat, jedoch nur wenige Spalten, und passt den Gauß-Algorithmus entsprechend an.
Eingang |
Datentyp |
Beschreibung |
---|---|---|
i_diDim |
DINT |
Anzahl der Gleichungen des zu lösenden Systems bzw. Zeilen-/Spaltenzahl der zugehörigen Matrix. Muss >= 2 sein. |
i_diBands |
DINT |
Anzahl der Bänder des Gleichungssystems. Die Bänder sind die Nebendiagonalen, die Elemente ungleich 0 enthalten, wobei nur auf der Seite der Hauptdiagonalen gezählt wird, die mehrere solcher Diagonalen enthält. Die obige Matrix hat z. B. 2 Bänder. |
i_lrZeroLimit |
LREAL |
Numerische Null-Grenze. Matrixelemente, die betraglich kleiner als diese Zahl sind, werden als null betrachtet. Dient dazu, die Rundungsfehlerfortpflanzung zu begrenzen. Der günstigste Wert hängt von den numerischen Eigenschaften der Matrix ab. Muss > 0,0 sein. Ein gängiger Wert ist beispielsweise 1E-12. |
i_plrMatrix |
POINTER TO LREAL |
Zeiger auf den Beginn des Speicherbereichs, in dem die Matrix des linearen Gleichungssystems abgelegt ist. Dieser Bereich muss zusammenhängend sein und mindestens Speicherplatz für i_diDim * (3 * i_diBands + 1) LREALs bieten. Dieses Array bietet mehr Platz, als für die Speicherung der Matrixelemente ungleich null erforderlich wäre. Die zusätzlichen Elemente werden für die Pivotisierung benötigt. Die Belegung dieses Bereichs wird unten erläutert. |
i_plrVector |
POINTER TO LREAL |
Zeiger auf den Beginn des Speicherbereichs, in dem der Inhomogenitätsvektor („rechte Seite“) des linearen Gleichungssystems abgelegt ist. Dieser Bereich muss zusammenhängend sein und mindestens Speicherplatz für i_diDim LREALs bieten. |
i_plrSolutionVector |
POINTER TO LREAL |
Zeiger auf den Beginn des Speicherbereichs, in den der Lösungsvektor des linearen Gleichungssystems kopiert werden soll. Dieser Bereich muss zusammenhängend sein und mindestens Speicherplatz für i_diDim LREALs bieten. Die POU berechnet den Vektor SolutionVector so, dass die Gleichung Matrix * SolutionVector = Vector erfüllt ist. |
Ausgang |
Datentyp |
Beschreibung |
---|---|---|
q_etDiag |
Allgemeingültige, bibliotheksunabhängige Aussage zur Diagnose. Ein Wert ungleich ET_Diag.Ok entspricht einer Diagnosemeldung. |
|
q_etDiagExt |
POU-spezifischer, diagnosebezogener Ausgang. q_etDiag = ET_Diag.Ok -> Statusmeldung q_etDiag <> ET_Diag.Ok -> Diagnosemeldung |
oDiese POU benötigt i_diDim * (3 * i_diBands + 2) * SIZEOF(LREAL) Bytes dynamischen Speicher. Es muss daher sichergestellt sein, dass der Parameter LMCx00C\C\Konfiguration\Programm\DynIECDataSize (gesamter zur Verfügung stehender dynamischer Speicher) auf einen hinreichend großen Wert gesetzt ist.
oDie korrekte Größe der Speicherbereiche, auf die die Zeiger i_plrMatrix, i_plrVector und i_plrSolutionVector zeigen, muss sorgfältig geprüft werden, da die POU sonst einen Speicherzugriffsfehler verursacht.
i_plrMatrix: i_diDim * (3 * i_diBands + 1) LREALs
i_plrVector: i_diDim LREALs
i_plrSolutionVector: i_diDim LREALs
oFür die Belegung und das Lesen von Elementen der Matrix und der beteiligten Vektoren stehen die Funktionen FC_GetMatrixElement(), FC_GetVectorElement(), FC_SetMatrixElement() und FC_SetVectorElement() zur Verfügung. Für die Belegung der Matrix muss bei dieser POU die Spaltenzahl i_diNumCols = 3 * i_diBands + 1 gesetzt werden.
oDie Zuweisung der Matrixelemente zu den Elementen des Arrays A, das sie darstellt, ist wie folgt (zur kürzeren Notation wurde D = i_diDim, B = i_diBands gesetzt):
Zuweisung der Elemente einer Bandmatrix zu den Elementen des Arrays der Bandmatrix-POU
Veranschaulichung am Beispiel der obigen Bandmatrix:
diDim : DINT := 10;
diBands : DINT := 2;
diCols : DINT := 7;
alrA : ARRAY[0..9,0..6] OF LREAL;
alrB : ARRAY[0..9] OF LREAL := 10(2.0); (* Beispiel für "rechte Seite" *)
alrX : ARRAY[0..9] OF LREAL;
etDiag : PD_GlobalDiagnostic.ET_Diag;
etDiagExt : PD_PacDriveLib.ET_DiagExt;
Belegung der Matrix:
FOR i := 0 TO (diDim - 1) DO
FOR j := 0 TO (3 * diBands) DO
FC_SetMatrixElement(
i_plrMatrixStart:=ADR(alrA[0,0]),
i_diNumCols:=diCols,
i_diRow:=i,
i_diCol:=j,
i_lrValue:=0.0);
END_FOR
END_FOR
FOR i := 0 TO (diDim - 1) DO
FC_SetMatrixElement(
i_plrMatrixStart:=ADR(alrA[0,0]),
i_diNumCols:=diCols,
i_diRow:=i,
i_diCol:=diBands,
i_lrValue:=1.0);
END_FOR
FOR i := 1 TO (diDim - 1) DO
FC_SetMatrixElement(
i_plrMatrixStart:=ADR(alrA[0,0]),
i_diNumCols:=diCols,
i_diRow:=i,
i_diCol:=diBands-1,
i_lrValue:=0.5);
END_FOR
FOR i := 0 TO (diDim - 2) DO
FC_SetMatrixElement(
i_plrMatrixStart:=ADR(alrA[0,0]),
i_diNumCols:=diCols,
i_diRow:=i,
i_diCol:=diBands+1,
i_lrValue:=0.5);
END_FOR
FOR i := 0 TO (diDim - 3) DO
FC_SetMatrixElement(
i_plrMatrixStart:=ADR(alrA[0,0]),
i_diNumCols:=diCols,
i_diRow:=i,
i_diCol:=diBands+2,
i_lrValue:=1.0/3.0);
END_FOR
FC-Aufruf:
FC_BandAlgorithm (
i_diDim := diDim,
i_diBands := diBands,
i_lrZeroLimit := 1E-12,
i_plrMatrix := ADR(alrA[0,0]),
i_plrVector := ADR(alrB[0,0]),
i_plrSolutionVector := ADR(alrX[0,0]),
q_etDiag => etDiag,
q_etDiagExt => etDiagExt );
Nach dem Aufruf der Funktion steht die Lösung des Gleichungssystems im Array alrX zur Verfügung.
q_etDiag |
q_etDiagExt |
Enumerationswert |
Beschreibung |
---|---|---|---|
OK |
0 |
OK |
|
ControllerConditionInvalid |
75 |
Es ist zu wenig dynamischer Speicher reserviert. |
|
InputParameterInvalid |
73 |
Bands ist außerhalb des gültigen Bereichs |
|
InputParameterInvalid |
72 |
Dim ist außerhalb des gültigen Bereichs. |
|
InputParameterInvalid |
77 |
Die Matrix ist singulär. |
|
InputParameterInvalid |
69 |
Der Zeiger Matrix ist ungültig. |
|
InputParameterInvalid |
71 |
Der Zeiger SolutionVector ist ungültig. |
|
InputParameterInvalid |
70 |
Der Zeiger Vector ist ungültig. |
|
InputParameterInvalid |
74 |
ZeroLimit ist außerhalb des gültigen Bereichs. |
|
UnexpectedProgramBehavior |
1 |
Es ist ein unbeabsichtigter Fehler während der Ausführung aufgetreten. |
Enumerationsname: |
BandsRange |
Enumerationswert: |
73 |
Beschreibung: |
Bands ist außerhalb des gültigen Bereichs |
Problem |
Ursache |
Lösung |
---|---|---|
- |
Am Eingang i_diBands wurde ein ungültiger Wert übergeben. |
Es muss gelten: i_diBands > 0 |
Enumerationsname: |
DimRange |
Enumerationswert: |
72 |
Beschreibung: |
Dim ist außerhalb des gültigen Bereichs. |
Problem |
Ursache |
Lösung |
---|---|---|
- |
Am Eingang i_diDim wurde ein ungültiger Wert übergeben. |
Es muss gelten: i_diDim > 1 |
Enumerationsname: |
DynIecDataSizeTooSmall |
Enumerationswert: |
75 |
Beschreibung: |
Es ist zu wenig dynamischer Speicher reserviert. |
Problem |
Ursache |
Lösung |
---|---|---|
- |
Es steht kein oder nicht genügend dynamischer Speicher zu Verfügung. |
Erhöhen Sie den dynamischen Speicher Controller > Konfiguration > Programm > DynIECDataSize. |
Enumerationsname: |
MatrixSingular |
Enumerationswert: |
77 |
Beschreibung: |
Die Matrix ist singulär. |
Problem |
Ursache |
Lösung |
---|---|---|
- |
Die Matrix am Eingang i_plrMatrix ist singulär. |
Dem Eingang i_plrMatrix muss eine reguläre Matrix übergeben werden. |
Enumerationsname: |
Ok |
Enumerationswert: |
0 |
Beschreibung: |
OK |
Das Gleichungssystem wurde erfolgreich gelöst.
Enumerationsname: |
PointerMatrixInvalid |
Enumerationswert: |
69 |
Beschreibung: |
Der Zeiger Matrix ist ungültig. |
Problem |
Ursache |
Lösung |
---|---|---|
- |
Am Eingang i_plrXMatrix wurde ein Nullzeiger übergeben. |
Dem Eingang i_plrXMatrix muss die Addresse des Speichers übergeben werden, in dem die Matrix liegt. |
Enumerationsname: |
PointerSolutionVectorInvalid |
Enumerationswert: |
71 |
Beschreibung: |
Der Zeiger SolutionVector ist ungültig. |
Problem |
Ursache |
Lösung |
---|---|---|
- |
Am Eingang i_plrSolutionVector wurde ein Nullzeiger übergeben. |
Dem Eingang i_plrSolutionVector muss die Addresse des Speichers übergeben werden, in dem der Lösungsvektor liegt. |
Enumerationsname: |
PointerVectorInvalid |
Enumerationswert: |
70 |
Beschreibung: |
Der Zeiger Vector ist ungültig. |
Problem |
Ursache |
Lösung |
---|---|---|
- |
Am Eingang i_plrVector wurde ein Nullzeiger übergeben. |
Dem Eingang i_plrVector muss die Addresse des Speichers übergeben werden, in dem der Vektor liegt. |
Enumerationsname: |
UnexpectedFeedback |
Enumerationswert: |
1 |
Beschreibung: |
Es ist ein unbeabsichtigter Fehler während der Ausführung aufgetreten. |
Problem |
Ursache |
Lösung |
---|---|---|
- |
Es ist ein Fehler in der internen Abarbeitung aufgetreten. |
Bitte informieren Sie das Supportteam über diesen Fehler. |
Enumerationsname: |
ZeroLimitRange |
Enumerationswert: |
74 |
Beschreibung: |
ZeroLimit ist außerhalb des gültigen Bereichs. |
Problem |
Ursache |
Lösung |
---|---|---|
- |
Am Eingang i_lrZeroLimit wurde eine Zahl <= 0 angelegt. |
i_lrZeroLimit muss größer sein als 0. |