# Problem Storing Arrays Inside Arrays

## Recommended Posts

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 by czardas

##### Share on other sites

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 by UEZ

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

##### Share on other sites

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:

```;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()
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?

##### Share on other sites

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 by czardas

##### Share on other sites

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

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

##### Share on other sites

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.
RegExp tutorial: enough to get started
PCRE 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)

##### Share on other sites

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.

##### Share on other sites

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 by nullschritt

##### Share on other sites

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 by nullschritt

##### Share on other sites

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

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.

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

##### Share on other sites

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.

## Create an account

Register a new account

• ### Recently Browsing   0 members

×

• Wiki

• Back

• #### Beta

• Git
• FAQ
• Our Picks
×
• Create New...