czardas Posted March 10, 2015 Share Posted March 10, 2015 (edited) Nice toy UEZ! Change the first grid value to 28 and it returns 1.#INF / 1 which is exactly what I was just talking about. Edited March 10, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
UEZ Posted March 10, 2015 Share Posted March 10, 2015 (edited) Thanks czardas, currently it is limited for integer range only. I wanted to show the calculation of the invers matrix. The fraction problem isn't solved for sure. Edited March 10, 2015 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
nullschritt Posted March 10, 2015 Author Share Posted March 10, 2015 I wouldn't give up on it altogether. Sometimes taking a step back gives you more perspective. In all honesty I'm reasonably happy with the UDF, but not quite as happy as I originally wanted to be. Regarding division by zero. You can do it as much as you like using _Fraction() so long as you do not try and access the non-existent array afterwards. That's where the interpreter throws an error. The same applies with numbers: after division by zero infinity is returned (or rather a representation of infinity) and AutoIt does not throw an error. Of course it's wrong to divide by zero in both cases and I have no intentions of overriding the current behaviour. All the checks you need are already provided. So all I have to do then is make it return the invalid fraction instead of an error, the Here a fast hack for a 2x2 matrix: expandcollapse popup;a fast hack version by UEZ #include <Array.au3> #include <EditConstants.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> Global $hGUI = GUICreate("2x2 Matrix Invers", 500, 306, -1, -1) Global $iLabel = GUICtrlCreateLabel("2x2 Matrix Invers", 40, 20, 400, 40, $SS_CENTER) GUICtrlSetFont(-1, 20, 400, 0, "Arial", 5) Global $hLabel2 = GUICtrlCreateLabel("Matrix A", 80, 90, 100, 28, $SS_CENTER) GUICtrlSetFont(-1, 20, 400, 0, "Times New Roman", 5) Global $iInput_A = GUICtrlCreateInput("4.25", 80, 130, 40, 30) Global $iInput_B = GUICtrlCreateInput("7/2", 130, 130, 40, 30) Global $iInput_C = GUICtrlCreateInput("3", 80, 165, 40, 30) Global $iInput_D = GUICtrlCreateInput("2", 130, 165, 40, 30) Global $hLabel3 = GUICtrlCreateLabel("Matrix A'", 280, 90, 100, 28, $SS_CENTER) GUICtrlSetFont(-1, 20, 400, 0, "Times New Roman", 5) Global $iInput_Ai = GUICtrlCreateInput("", 280, 130, 60, 30, $ES_READONLY) Global $iInput_Bi = GUICtrlCreateInput("", 350, 130, 60, 30, $ES_READONLY) Global $iInput_Ci = GUICtrlCreateInput("", 280, 165, 60, 30, $ES_READONLY) Global $iInput_Di = GUICtrlCreateInput("", 350, 165, 60, 30, $ES_READONLY) Global $iButton = GUICtrlCreateButton("Calculate", 280, 230, 90, 60) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete() Exit Case $iButton Calc_InversMatrix() EndSwitch WEnd Func Calc_InversMatrix() Local $aMatrix[2][2] = [[Execute(GUICtrlRead($iInput_A)), Execute(GUICtrlRead($iInput_b))],[Execute(GUICtrlRead($iInput_C)), Execute(GUICtrlRead($iInput_D))]] If Not $aMatrix[1][0] And Not $aMatrix[1][1] Then Return SetError(1, 0, 0) ; -> determinant is zero, therefore inverse matrix doesn't exist Local $fDetA = 1 / ($aMatrix[0][0] * $aMatrix[1][1] - $aMatrix[1][0] * $aMatrix[0][1]) GUICtrlSetData($iInput_Ai, Float2Frac(Number($fDetA * $aMatrix[1][1]))) GUICtrlSetData($iInput_Bi, Float2Frac(Number($fDetA * -$aMatrix[0][1]))) GUICtrlSetData($iInput_Ci, Float2Frac(Number($fDetA * -$aMatrix[1][0]))) GUICtrlSetData($iInput_Di, Float2Frac(Number($fDetA * $aMatrix[0][0]))) EndFunc Func Float2Frac($fFloat) ;coded by UEZ If Not IsNumber($fFloat) Then Return SetError(1, 0, 0) Local Const $iDec = StringLen(StringRegExpReplace($fFloat, "\d+\.(\d*)", "\1")) Local Const $iZaehler = $fFloat * 10^$iDec Local Const $iNenner = 10^$iDec Local Const $iGGT = ggT($iZaehler, $iNenner) ConsoleWrite($fFloat & " -> " & $iZaehler / $iGGT & " / " & $iNenner / $iGGT & @CRLF) Return $iZaehler / $iGGT & " / " & $iNenner / $iGGT EndFunc Func ggT($a, $b) ;coded by UEZ 2012 If Not IsInt($a) Then Return SetError(1, 0, 0) If Not IsInt($b) Then Return SetError(2, 0, 0) If $a = $b Then Return Abs($a) If Not $a And $b Then Return Abs($a) If $a And Not $b Then Return Abs($b) If ($a And $b = 1) Or ($a = 1 And $b) Then Return 1 Local $iMod Do $iMod = Mod($a, $b) If Not $iMod Then ExitLoop $a = $b $b = $iMod Until False Return $b EndFunc That looks fantastically streamlined but I don't understand a bit of it. What would I need to change to make it work with 8x8 arrays? Link to comment Share on other sites More sharing options...
czardas Posted March 11, 2015 Share Posted March 11, 2015 (edited) So all I have to do then is make it return the invalid fraction instead of an error, the You may get further forward, but I imagine the calculations producing infinity are not needed. The code appears to loop through an array, find an empty string, convert it to a number, divide by this number and then you want to override the error which occurs - at least I think that is what's happening. This is not a good approach. The whole thing needs rewriting from the very beginning. Edited March 11, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
UEZ Posted March 11, 2015 Share Posted March 11, 2015 That looks fantastically streamlined but I don't understand a bit of it. What would I need to change to make it work with 8x8 arrays?First, you need to understand the math behind. Have a look here (Cramer's rule): http://en.wikipedia.org/wiki/Cramer%27s_rule or at Wiki: http://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
jchd Posted March 11, 2015 Share Posted March 11, 2015 I believe it would first be very useful to precisely describe the goal and the algorithm you want to implement, demonstrate its correctness, then only work out a toy example with solid grounds (i.e. BigNum even if it's slow as hell). From this point you'd know if it's worth going further and creating an interface layer to a suitable library. BTW, isn't >Eigen good for you? This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
nullschritt Posted March 11, 2015 Author Share Posted March 11, 2015 You may get further forward, but I imagine the calculations producing infinity are not needed. The code appears to loop through an array, find an empty string, convert it to a number, divide by this number and then you want to override the error which occurs - at least I think that is what's happening. This is not a good approach. The whole thing needs rewriting from the very beginning. You're right, like I said, the values will NEVER be calculated, they are mere placeholders for re-arranging data. It will never actually try to divide the placeholders. Link to comment Share on other sites More sharing options...
nullschritt Posted March 11, 2015 Author Share Posted March 11, 2015 (edited) First, you need to understand the math behind. Have a look here (Cramer's rule): http://en.wikipedia.org/wiki/Cramer%27s_rule or at Wiki: http://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution I'll take a look at this and see what I can make of it. Thanks. Edit: Have been looking over this and I'm having some trouble understanding. I'm very bad at learning from reading, but from looking at your code to extend to it to work with a bigger array I would just have to do the following, right? Local $fDetA = 1 / ($aMatrix[0][0] * $aMatrix[1][1] * $aMatrix[0][2] * $aMatrix[1][2] - $aMatrix[1][0] * $aMatrix[0][1]$aMatrix[0][2] * $aMatrix[0][2]) ;etc etc for each element. Is this right? Edited March 11, 2015 by nullschritt Link to comment Share on other sites More sharing options...
nullschritt Posted March 11, 2015 Author Share Posted March 11, 2015 (edited) I believe it would first be very useful to precisely describe the goal and the algorithm you want to implement, demonstrate its correctness, then only work out a toy example with solid grounds (i.e. BigNum even if it's slow as hell). From this point you'd know if it's worth going further and creating an interface layer to a suitable library. BTW, isn't >Eigen good for you? Never saw that library before, I'll look into seeing if it returns more accurate results. Edit: When I tested all the example scripts on my computer they all stopped responding and had to be killed D: Edited March 11, 2015 by nullschritt Link to comment Share on other sites More sharing options...
UEZ Posted March 11, 2015 Share Posted March 11, 2015 I'll take a look at this and see what I can make of it. Thanks. Edit: Have been looking over this and I'm having some trouble understanding. I'm very bad at learning from reading, but from looking at your code to extend to it to work with a bigger array I would just have to do the following, right? Local $fDetA = 1 / ($aMatrix[0][0] * $aMatrix[1][1] * $aMatrix[0][2] * $aMatrix[1][2] - $aMatrix[1][0] * $aMatrix[0][1]$aMatrix[0][2] * $aMatrix[0][2]) ;etc etc for each element. Is this right? Just checkout the example for a 3x3 matrix: Inversion of 3×3 matrices[edit] A computationally efficient 3x3 matrix inversion is given by (where the scalar A is not to be confused with the matrix A). If the determinant is non-zero, the matrix is invertible, with the elements of the intermediary matrix on the right side above given by The determinant of A can be computed by applying the rule of Sarrus as follows: As you can see it isn't that simple what you did to get the determinant of the matrix. Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
nullschritt Posted March 11, 2015 Author Share Posted March 11, 2015 Gosh I haven't learned about the process behind matrix inversion since highschool, this is really hurting my brain, but maybe if I stare at it long enough I'll get it. Now I'm feeling stupid. Maybe I should have paid more attention in class. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now