lineare Gleichungen lösen....da hatte ich vor Jahrzehnten mal was gebastelt, sogar mit GUI^^
Seitdem wird dieses Script immer wieder mal von mir benutzt, wer Spass hat, kann ja die GUI auf "schön" umfunktionieren.
Und btw. es wird das Gaußsche Eliminationsverfahren verwendet.
#include <GUIConstantsEx.au3>
;~ ;linearer gleichungslöser nach Gaußschem Eliminationsverfahren,
#include <array.au3>
;~ $n = 3
;~ Dim $a[$n][$n] = [[1, 1, 0],[0, 1, 1],[1, 0, 1]] ;matrix
;~ Dim $b[$n] = [100, 200, 240] ;lösungen
;~ ;$n = 4
;~ ;Dim $a[$n][$n] = [[1, 3, -2, 1],[-2, 1, -4, -5],[1, -3, 1, 0],[-3, 4, -6, 2]] ;matrix
;~ ;Dim $b[$n] = [-7, -6, 6, -21] ;lösungen
;~ $s = _solve_linear_quad($a, $b)
;~ _ArrayDisplay($s)
Global $num_unknowns = Number(InputBox("Lösung Lineare Gleichungssysteme", "Anzahl Unbekannte?", 3))
Dim $coeff[$num_unknowns][$num_unknowns] ;matrix
Dim $values[$num_unknowns + 1][$num_unknowns + 2] ;
Dim $b[$num_unknowns] ;lösungen
GUICreate("Enter Equations:", (48 * $num_unknowns) + 121, (26 * $num_unknowns) + 77)
For $n = 1 To $num_unknowns
For $r = 1 To $num_unknowns
$values[$n][$r] = GUICtrlCreateInput("", 48 * $r, 26 * $n, 25, 21)
GUICtrlCreateLabel(StringMid("abcdefghijklmnopqrstuvwxyz", $r, 1), (48 * $r) + 26, (26 * $n) + 5, 10, 17)
If $r < $num_unknowns Then
GUICtrlCreateLabel("+", (48 * $r) + 37, (26 * $n) + 5, 10, 17)
Else
GUICtrlCreateLabel("=", (48 * $r) + 37, (26 * $n) + 5, 10, 17)
EndIf
Next
$values[$n][$r] = GUICtrlCreateInput("", 48 * $r, 26 * $n, 25, 21)
Next
$solve_button = GUICtrlCreateButton("Lösen", (48 * $num_unknowns) + 38, (26 * $num_unknowns) + 36, 50, 25)
GUISetState()
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $solve_button
For $n = 0 To $num_unknowns - 1
For $r = 0 To $num_unknowns - 1
$coeff[$n][$r] = Number(GUICtrlRead($values[$n + 1][$r + 1]))
Next
$b[$n] = Number(GUICtrlRead($values[$n + 1][$num_unknowns + 1]))
Next
;~ _arraydisplay($b)
;~ _arraydisplay($coeff)
GUISetState(@SW_HIDE)
$sols = _solve_linear_quad($coeff, $b)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sols = ' & $sols & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$solutWin = GUICreate("Lösungen:", 280, (21 * UBound($sols)) + 42)
For $n = 0 To UBound($sols) - 1
GUICtrlCreateLabel(StringMid("abcdefghijklmnopqrstuvwxyz", $n + 1, 1) & " = " & Round($sols[$n], 3) & " (Max. 3 Nachkommastellen)", 30, 21 * ($n + 1), 200, 20)
Next
GUISetState(@SW_SHOW, $solutWin)
EndSwitch
WEnd
Func _solve_linear_quad($a, $b) ;matrix,lösung Gaußsches Eliminationsverfahren, löst x gleichungen mit x unbekannten
;by Andy www.autoit.de
Local $n, $t
Dim $Y[UBound($b)] ;ergebnisse
$n = UBound($a) - 1 ;anzahl der zeilen/spalten
;falls erforderlich, zeilen und spalten tauschen
If $a[0][0] = 0 Then ;wenn erster koeffizient = 0, dann kann das system nicht starten => spalten tauschen ggf zeilen tauschen
For $k = 0 To $n ;jede zeile
For $j = 0 To $n ;alle spalten in dieser Zeile testen
If $a[$k][$j] <> 0 Then
For $m = 0 To $n ;treffer, die erste spalte mit der j. tauschen
$t = $a[$m][$j] ;sichern
$a[$m][$j] = $a[$m][0] ;mit erster spalte tauschen
$a[$m][0] = $t
Next
For $j = 0 To $n ;zeilen tauschen
$t = $a[0][$j] ;sichern
$a[0][$j] = $a[$k][$j] ;mit erster spalte tauschen
$a[$k][$j] = $t
Next
$t = $b[0] ;ergebnisse auch tauschen
$b[0] = $b[$k]
$b[$k] = $t
ExitLoop 2
EndIf
Next
Next
EndIf
If $a[0][0] = 0 Then Return SetError(1, 0, 1)
;endlich rechnen :)
For $I = 0 To $n ;alle zeilen
If $a[$I][$I] <> 0 Then
;erstes element auf 1 bringen indem man gesamte zeile durch erstes Element teilt
For $k = $I To $n
$t = $a[$k][$I] ;erstes element merken
If $t <> 0 Then ;nur, wenn das erste element ungleich null ist...
For $j = $I To $n
$a[$k][$j] /= $t ;alle zeilenmitglieder durch erstes element teilen
Next
;b durch i teilen
$b[$k] /= $t ;ergebnis natürlich auch
EndIf
Next
; _ArrayDisplay($a, "oben " & $I)
;zeile i von allen weiteren zeilen subtrahieren, erstes element wird zu 0
For $k = $I + 1 To $n
If $a[$k][$I] <> 0 Then ;wenn null, dann überspringen
For $j = $I To $n
$a[$k][$j] -= $a[$I][$j] ;die i.zeile von der aktuellen zeile subtrahieren
Next
$b[$k] -= $b[$I] ;ergebnisse natürlich auch
EndIf
Next
; _ArrayDisplay($a, "unten " & $I)
Else ;null in aktueller spalte
;zeilen tauschen
; msgbox(0,$i,"null gefunden")
For $k = $I + 1 To $n
If $a[$k][$I] <> 0 Then ;zeile tauschen
For $j = $I To $n ;zeilen tauschen
$t = $a[$I][$j] ;sichern
$a[$I][$j] = $a[$k][$j] ;mit erster spalte tauschen
$a[$k][$j] = $t
Next
$t = $b[$I] ;ergebnisse auch tauschen
$b[$I] = $b[$k]
$b[$k] = $t
EndIf
;erstes element auf 1 bringen indem man gesamte zeile durch erstes Element teilt
For $k = $I To $n
$t = $a[$k][$I] ;erstes element merken
If $t <> 0 Then ;nur, wenn das erste element ungleich null ist...
For $j = $I To $n
$a[$k][$j] /= $t ;alle zeilenmitglieder durch erstes element teilen
Next
;b durch i teilen
$b[$k] /= $t ;ergebnis natürlich auch
EndIf
Next
; _ArrayDisplay($a, "oben1 " & $I)
;zeile i von allen weiteren zeilen subtrahieren, erstes element wird zu 0
For $k = $I + 1 To $n
If $a[$k][$I] <> 0 Then ;wenn null, dann überspringen
For $j = $I To $n
$a[$k][$j] -= $a[$I][$j] ;die i.zeile von der aktuellen zeile subtrahieren
Next
$b[$k] -= $b[$I] ;ergebnisse natürlich auch
EndIf
Next
;_ArrayDisplay($a, "unten1 " & $I)
Next
EndIf
Next
;alle parameter bestimmen durch rückwärtseinsetzen
$Y[$n] = $b[$n] ;letzter ist bereits bekannt
For $I = $n - 1 To 0 Step -1
For $j = $n To $I + 1 Step -1
$b[$I] -= $a[$I][$j] * $Y[$j]
Next
$Y[$I] = $b[$I]
Next
Return $Y
EndFunc ;==>_solve_linear_quad
Exit
Alles anzeigen