Hi,
war nicht ganz so trivial, wie ich gedacht hatte: Meine Determinantenberechnung von FreeBasic nach AutoIt zu portieren..
Also, eine Matrix ist eine Zahlenanordnung aus Zeilen und Spalten, AutoIt-Benutzern auch als Array[] bekannt, doch es gibt Unterschiede
Die Division durch eine Matrix wird als Multiplikation mit der Inversen ausgeführt, doch das nur am Rande.
Aber wie bei jeder Division gibt es ein Problem, wenn der Divisor Null ist. Bei quadratischen Matrizen, wie sie z.B. in der Ausgleichungsrechnung vorkommen, läßt sich über die Berechnung der Determinanten(quasi der Wert) einer Matrix schon vor der Operation ermitteln, ob selbige überhaupt durchführbar ist. Gelingt das bei Zweier- oder Dreier-Matrizen fast noch per Kopfrechnung, so ist aber bereits bei einer Vierer-Matrix Schluß.
Die Determinantenberechnung gestaltet sich sehr umständlich, da geschieht es leicht, dass sich Vorzeichenfehler einschleichen etc. pp.
Als es das Computer-Magazin mc noch gab, habe ich dort irgendwann(~1985) mal ein Pascal-Programm gefunden, das diese Berechnung übernimmt.
Erst habe ich es nach FreeBasic portiert und dann nach AutoIt, es funktioniert immer noch^^
Wer mit dem Begriff Determinantenberechnung etwas anfangen kann, erhält hier ein Grundgerüst, mit dem soetwas auch mit AutoIt erledigt werden kann.
Wer nix mit dieser Sache zu tun hat, der braucht das Programm auch nicht
Im GUI ist eine ganze Menge möglich, einfach mal anschauen, denn es kann nichts passieren(schließlich liefere ich den Quellcode ja mit)..
Für den Fall, das jemand grad keine Matrix zur Hand hat, deren Determinante garantiert 0 ist, biddeschööön:
Es gibt zwei eingebaute Matrizen, eine über das GUI zu finden, die andere, wenn in der Dimensionsauswahl der Eintrag max ausgewählt wird.
Hier habe ich bei der einen den von einer Tabellenkalkulation ermittelten Wert eingetragen, im anderen Fall ist das Ergebnis 3, daran ist nicht zu rütteln. Sicherlich ließe sich noch vieles am GUI rumfeilen und besser/'schöner' machen, aber so ist es auf alle Fälle ausreichend, denn es ging
ja nur darum, den Algorithmus etwas zu verpacken. Genug geredet, hier isses:
Spoiler anzeigen
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
;+------------------------------------------------------------------------------------------+
;| Header: Bestimmen der Übergabeparameter |
;| AnzeigeCheck:|Il1 sind Alt-0124,Großes i,Kleines L, Eins „”᎙šñ¸=äöüßÄÖܱ© |
Const $Author='Determinante.au3 ©2011 by ytwinky, MD'; |
;| (Tastenkombination: keine) |
;| |
;| Zweck : DeterminantenBerechnung einer quadratischen Matrix(z.B. vor einer Inversion) |
;| Quelle: mc (mehr weiß ich leider nicht mehr, sorry..) |
;+------------------------------------------------------------------------------------------+
Global $Menu, $A, $d, $XL, $i, $j, $k
Global $iDim, $MatFormat, $fw, $nk
#Region ### START Koda GUI section ### Form=D:\Sprachen\AutoIt3\Au3\kxf\det.kxf
$det=GUICreate('det', 815, 585, 191, 111)
$grpMain=GUICtrlCreateGroup('', 0, -4, 813, 587)
$lblTitel=GUICtrlCreateLabel('Determinantenberechnung', 6, 10, 469, 33)
GUICtrlSetTip(-1, $Author)
GUICtrlSetFont(-1, 18, 800, 0, 'Arial')
GUICtrlSetColor(-1, 0x000080)
$grpArt=GUICtrlCreateGroup('Eingabeart festlegen', 4, 42, 197, 53)
$rbdatei=GUICtrlCreateRadio('Datei', 10, 58, 49, 17)
$rbauto=GUICtrlCreateRadio('automatisch', 10, 76, 83, 17)
$btnSuchen=GUICtrlCreateButton('Suchen', 119, 54, 75, 25, $WS_GROUP)
GUICtrlSetFont(-1, 8, 800, 0, 'MS Sans Serif')
GUICtrlSetState(-1, $GUI_Hide)
GUICtrlCreateGroup('', -99, -99, 1, 1)
$grpEingabe=GUICtrlCreateGroup('', 201, 42, 127, 53)
GUICtrlSetState(-1, $GUI_Hide)
$rbeingebaut=GUICtrlCreateRadio('eingebaute Matrix', 205, 58, 105, 17)
GUICtrlSetState(-1, $GUI_Hide)
$rbzufall=GUICtrlCreateRadio('Zufallsmatrix', 205, 76, 97, 17)
GUICtrlSetState(-1, $GUI_Hide)
GUICtrlCreateGroup('', -99, -99, 1, 1)
$grpmaxdim=GUICtrlCreateGroup('max. Dimension festlegen', 328, 42, 139, 53)
GUICtrlSetState(-1, $GUI_Hide)
$cmbmaxdim=GUICtrlCreateCombo('max', 370, 62, 53, 25)
GUICtrlSetState(-1, $GUI_Hide)
GUICtrlSetData(-1, '2|3|4|5|6|7|8|9|10|15|20')
GUICtrlCreateGroup('', -99, -99, 1, 1)
$grpFormat=GUICtrlCreateGroup('Ausgabeformat', 624, 6, 185, 89)
$lblvk=GUICtrlCreateLabel('Vorkommastellen', 634, 26, 50, 17)
$cmbvk=GUICtrlCreateCombo('5', 724, 22, 81, 25)
GUICtrlSetData(-1, '1|2|3|5|7', 5)
$lblnk=GUICtrlCreateLabel('Nachkommastellen', 632, 49, 97, 17)
$cmbnk=GUICtrlCreateCombo('5', 724, 46, 81, 25)
GUICtrlSetData(-1, '1|2|3|4|5|6|7|8|9', 5)
GUICtrlCreateGroup('', -99, -99, 1, 1)
$efMatrix=GUICtrlCreateEdit('', 4, 98, 805, 449)
$btnBerechnen=GUICtrlCreateButton('Berechnen', 4, 553, 75, 27, $WS_GROUP)
GUICtrlSetFont(-1, 8, 800, 0, 'MS Sans Serif')
$lbldet=GUICtrlCreateLabel('Determinante=', 82, 559, 82, 17)
GUICtrlSetFont(-1, 8, 800, 0, 'MS Sans Serif')
$efdet=GUICtrlCreateInput('', 168, 557, 195, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
GUICtrlSetBkColor(-1, 0xFFFFFF )
$lblSoll=GUICtrlCreateLabel('Soll=', 368, 559, 28, 17)
GUICtrlSetFont(-1, 8, 800, 0, 'MS Sans Serif')
$efSoll=GUICtrlCreateInput('', 398, 557, 149, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
GUICtrlSetBkColor(-1, 0xFFFFFF )
$lblDiff=GUICtrlCreateLabel('Soll-Ist=', 550, 559, 46, 17)
GUICtrlSetFont(-1, 8, 800, 0, 'MS Sans Serif')
$efDiff=GUICtrlCreateInput('', 598, 557, 127, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
GUICtrlSetBkColor(-1, 0xFFFFFF )
$btnQuit=GUICtrlCreateButton('Quit', 734, 553, 75, 27, BitOR($BS_DEFPUSHBUTTON,$WS_GROUP))
GUICtrlSetFont(-1, 8, 800, 0, 'MS Sans Serif')
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE, $btnQuit
Exit
Case $btnBerechnen, $cmbvk, $cmbnk
Berechnen()
Case $rbdatei
GUICtrlSetState($btnSuchen, $Gui_Show)
GUICtrlSetState($rbzufall, $Gui_Hide)
GUICtrlSetState($rbeingebaut, $Gui_Hide)
GUICtrlSetState($grpEingabe, $Gui_Hide)
GUICtrlSetState($grpmaxdim, $Gui_Hide)
GUICtrlSetState($cmbmaxdim, $Gui_Hide)
Case $rbauto
GUICtrlSetState($btnSuchen, $Gui_Hide)
GUICtrlSetState($rbzufall, $Gui_Show)
GUICtrlSetState($rbeingebaut, $Gui_Show)
GUICtrlSetState($grpEingabe, $Gui_Show)
Case $rbzufall
GUICtrlSetState($grpmaxdim, $Gui_Show)
GUICtrlSetState($cmbmaxdim, $Gui_Show)
GUICtrlSetData($efMatrix, '')
GUICtrlSetData($efSoll, $XL)
$XL=''
Case $rbeingebaut
GUICtrlSetState($grpmaxdim, $Gui_Hide)
GUICtrlSetState($cmbmaxdim, $Gui_Hide)
$iDim=6
Dim $A[$iDim][$iDim]=[[0.659327444, 0.072983257, 0.979894657, 0.756750136, 0.25441669, 0.83763853], _
[0.559241606, 0.523137874, 0.948388093, 0.330784887, 0.849705537, 0.169404574], _
[0.933652887, 0.616332953, 0.217258497, 0.907022842, 0.082662047, 0.03529322], _
[0.826041544, 0.765330767, 0.52478838, 0.158009727, 0.024860119, 0.36255325], _
[0.846792095, 0.556488281, 0.48273207, 0.122986243, 0.059224104, 0.851249939], _
[0.33697323, 0.625423359, 0.494137015, 0.130947714, 0.248825667, 0.928200963]]
$XL=0.146436546
GUICtrlSetData($efSoll, $XL)
Berechnen()
Case $cmbmaxdim
$iDim=GUICtrlRead($cmbmaxdim)
If $iDim<2 Or $iDim*1=0 Then
$iDim=3
Dim $A[$iDim][$iDim]=[[1, 2, 3], [4, 5, 6], [7, 8, 8]]
$XL=3
Else
Dim $A[$iDim][$iDim]
For $i=0 To $iDim-1
For $j=0 To $iDim-1
$a[$i][$j]=Random()
Next
Next
$XL=''
GUICtrlSetData($efDiff, $XL)
EndIf
GUICtrlSetData($efSoll, $XL)
Berechnen()
Case $btnSuchen
$s='Die Eingabedatei MUSS eine reine Ascii-Datei sein!' &@CrLf
$s&='In ihr stehen die Elemente der Matrix zeilenweise, jeweils durch 1 Leerzeichen getrennt' &@CrLf
$s&='Dezimaltrennzeichen ist der Punkt(''.''), z.B. 12.345' &@CrLf &'Formatierungszeichen(Tausendertrennzeichen) sind nicht erlaubt..' &@CrLf
$s&='Determinantenberechnung funktioniert nur bei quadratischen Matrizen' &@CrLf
$s&='(für mathematisch weniger Bewanderte:Es müssen genausoviel Zeilen vorhanden sein, wie es Spalten gibt..)' &@CrLf
$s&='Leerzeilen sind nicht erlaubt, sie würden als 0-Zeile gewertet und bewirken eine Determinante=0' &@CrLf
$s&='Werden diese Bedingungen nicht eingehalten, errechnet das Programm Unsinn oder stürzt gar ab..' &@CrLf
$s&='Für solche Bediener-Fehler bin ich nicht verantwortlich!' &@CrLf &'Wer das Programm benutzt, macht dies auf eigenes Risiko ;-))' &@CrLf
GUICtrlSetData($efMatrix, $s)
$n=FileOpenDialog('Datei suchen', @WorkingDir, 'Alle (*.*)', 1)
If FileExists($n) Then $n=StringSplit(FileRead($n), @Lf)
$iDim=$n[0]
Dim $A[$iDim][$iDim]
$k=''
For $i=1 To $n[0]
$s=StringSplit($n[$i], ' ')
For $j=1 To $s[0]
$a[$i-1][$j-1]=$s[$j]
$k&=Stringformat('%-' &$fw &'.' &$nk &'f', $a[$i-1][$j-1])
Next
Next
Berechnen()
EndSwitch
WEnd
Func Berechnen()
Local $i, $j, $vk=2, $nk=4, $s=''
$nk=GuiCtrlRead($cmbnk)
$fw=$nk+GuiCtrlRead($cmbvk)+1
For $i=0 To UBound($A)-1
For $j=0 To UBound($A)-1
$s&=Stringformat('%-' &$fw &'.' &$nk &'f', $a[$i][$j])
If $j<>(UBound($A)-1) Then
$s&=' '
Else
$s&=@CrLf
EndIf
Next
Next
GUICtrlSetData($efMatrix, $s)
$i=Determinante($A)
If $i=0 Then $i&=' EXAKT NULL'
GUICtrlSetData($efdet, $i)
If GuiCtrlRead($efSoll)<>'' Then GUICtrlSetData($efDiff, StringFormat('%-8.5E', GuiCtrlRead($efSoll)-GuiCtrlRead($efdet)))
EndFunc
Func Determinante($A)
Local $LftMat[$iDim][$iDim], $RgtMat[$iDim][$iDim], $d=1.0
Local $i, $j, $k, $n=0
$rgtmat[$n][$n]=$d
$lftmat[$n][$n]=$A[$n][$n]
For $k=$n To $iDim-1
If $lftmat[$k][$k]=0.0 Then Return 0.0
$i=$k+1
For $j=$n To $k
If $i<$idim Then ;kleine Schummelei, die in FreeBasic nicht nötig ist..
$rgtmat[$j][$i]=($a[$j][$i]-Mpy($j-1, $j, $i, $lftmat, $rgtmat))/$lftmat[$j][$j]
$lftmat[$i][$j]=$a[$i][$j]-Mpy($j-1, $i, $j, $lftmat, $rgtmat)
$lftmat[$i][$i]=$a[$i][$i]-Mpy($k, $i, $i, $lftmat, $rgtmat)
$rgtmat[$i][$i]=$d
EndIf
Next
Next
For $i=$n To $iDim-1
$d*=$lftmat[$i][$i]
Next
$LftMat=0
$RgtMat=0;Hilfsmatrizen löschen
Return $d ;Funktionsergebnis zuweisen!!!
EndFunc
Func Mpy($i, $j, $k, $LftMat, $RgtMat) ;funktioniert nur mit Determinante() ZUSAMMEN..
Local $m, $d=0.0
For $m=0 To $i
$d+=$lftmat[$j][$m]*$rgtmat[$m][$k]
Next
Return $d
EndFunc
Wer den FreeBasic-Quellcode möchte: hier klicken
Viel Spaß beim Berechnen
Gruß
ytwinky