• Status: Solved
• Priority: Medium
• Security: Public
• Views: 1524

# Inverse a Matrix

Can anybody give me a function that inverses a matrix of preferably any size but 7 by 7 will do

0
Pennywisdom
• 18
• 12
• 11
• +4
1 Solution

Commented:
Something like this perhaps?

Dim arrOriginal(1 To 10, 1 To 7) As String

Dim lngDim1 As Long
Dim lngDim2 As Long

Dim arrNew() As String

ReDim arrNew(1 To UBound(arrOriginal, 2), 1 To UBound(arrOriginal, 1))

For lngDim1 = 1 To UBound(arrOriginal, 1)
For lngDim2 = 1 To UBound(arrOriginal, 2)
arrNew(lngDim2, lngDim1) = arrOriginal(lngDim1, lngDim2)
Next
Next

0

Commented:
Basically, I'm assuming your matrix is something like this

A B C
D E F
G H I

etc..

which can be represented by a two-dimensional array. As an example I've used an array of 10 by 7 as you've suggested. To avoid confusion I dimmed it with lower and upper bounds, and a base 1.

I assume that by inverting a matrix you mean that a (N x M) matrix is converted to a (M x N) matrix and each element (x,y) from the original matrix will be placed in (y,x) of the new matrix?

If you meant anything different let me know.
0

Billing EngineerCommented:
You are not able to declare a multi-dimension matrix dynamically, only the last dimension can be resized.

If you want to inverse square matrixes (10 by 10, 7 by 7), then I can produce the code for it.
0

Commented:
Anyway... your arrOriginal can be any two-dimensional array with a base 1 for both dimensions, and the code
Dim lngDim1 As Long
Dim lngDim2 As Long

Dim arrNew() As String

ReDim arrNew(1 To UBound(arrOriginal, 2), 1 To UBound(arrOriginal, 1))

For lngDim1 = 1 To UBound(arrOriginal, 1)
For lngDim2 = 1 To UBound(arrOriginal, 2)
arrNew(lngDim2, lngDim1) = arrOriginal(lngDim1, lngDim2)
Next
Next

will invert it according to my explanation.
0

Commented:
"You are not able to declare a multi-dimension matrix dynamically"

Rubbish! See my code. I've done exactly that.
0

Author Commented:
I'm affraid that Inversing a matrix is a bit more complicated its a mathematical thing that I don't realy understand myself

Thanks anyway caraf g
0

Billing EngineerCommented:
Dim vntMatrix(1 To 10, 1 To 10) As Variant
Dim lngRow As Long
Dim lngCol As Long

Dim vntTemp As Variant

For lngRow = 1 To UBound(vntMatrix)
For lngCol = 1 To lngRow - 1
vntTemp = vntMatrix(lngRow, lngCol)
vntMatrix(lngRow, lngCol) = vntMatrix(lngCol, lngRow)
vntMatrix(lngCol, lngRow) = vntTemp
Next
Next
0

Commented:
try this:

Dim x(10, 7) As String
Dim y(10, 7) As String
Dim iVal As Long
Dim jVal As Long
Dim kVal As Long

'Set X to contain the original matrix

jVal = 0
For iVal = 10 To 0 Step -1
For kVal = 0 To 7
y(jVal, kVal) = x(iVal, kVal)
Next kVal
jVal = jVal + 1
Next iVal
For iVal = 0 To 10
For jVal = 0 To 7
x(iVal, jVal) = y(iVal, jVal)
Next jVal
Next iVal

'X Is NOW INVERTED

0

Author Commented:
To AngelIII:
My matrix as to be
Matrix(1 to 10,1 to 7) or Matrix(1 to 7,1 to 10)

Couuld you produce the code for it?
0

Commented:
"I'm affraid that Inversing a matrix is a bit more complicated its a mathematical thing that I don't realy understand myself"

You'll need to give me an explanation then of what it is. Don't worry, I understand basic maths so even if you could just copy and paste the explanation from your text book or something...

0

Author Commented:
To mcrider:

By inversing a matrix I mean that if A is a 2 by 2 matrix then

A * Inverse(A) = |1 0|
|0 1|

Example:

|4 -2|   |1   1|   |1 0|
|-3 2| * |3/2 2| = |0 1|

so |1   1|
|3/2 2|
is the inverse of
|4 -2|
|-3 2|
0

Billing EngineerCommented:
caraf_g: my apologies, but what I had in mind are arrays that have been initialized once (sorry)

Pennywisdom:
the code of caraf_g should work...
0

Commented:
OK, we're getting somewhere now. Can you just explain to us how the * operator works?

And what would be the inverse of a non-square matrix? - In your example the inverse of a 2x2 matrix is another 2x2 matrix, and the * operator between those two matrices gives you another 2x2 matrix. But if your matrix is not square (like your example of 10x7) then what? Would the inverse matrix be (7x10)? And the result of the * operator, would that give you a (7x7), a (10x10) or an altogether different result?
0

Author Commented:
If you have the matrix
|a b|
|c d|

1-Calculate the derterminant:

2-exchange the elements of the diagonal
a <--> d

3-Take the negative value of the other two
b = -b
c = -c

4-Divide each element by the determinant
of the original matrix

The book that I have explains it in this way but it does'nt explain for M x N matrix
0

Commented:
OK... deduction.

ColumnA1 * RowB1 = 4*1 -3*1 = 1
ColumnA2 * RowB1 = -2*1 + 2*1 = 0
ColumnA1 * RowB2 = 4*3/2 - 3*2 = 0
ColumnA2 * RowB2 = -2*3/2 + 2*2 = 1

So the inverse of a 10x7 matrix is a 7x10 matrix giving a result of diagonal 1s in a 10x10 matrix, am I correct?
0

Commented:
Geez. that's hard.
0

Author Commented:
Yes caraf g you are correct
0

Author Commented:
I'M Sorry caraf g but you are mistaken 10x7 matrix inversed would be a 10x7 also
0

Author Commented:
Sorry about my mistake you ARE RIGHT
0

Commented:
Actually, that is *really* hard. I've got intrigued but there doesn't seem to be anything on the web that inverts non-square matrices....

Let's phone a friend.
0

Author Commented:
Sorry about my mistake you ARE RIGHT
0

Commented:
I used e-mail a friend to e-mail ozo, hopefully we'll get a response there.
0

Commented:
i'm a little rusty on my linear algebra but can you give me a matrix and its inverse so that I can check to see if i remembered how to perform this algorithm correctly (for non square matrices)
0

Author Commented:
I was mistaken what I need is a 7x7 matrix maybe that will simplifie the question
0

Author Commented:
Edited text of question.
0

Commented:
aaaaah much easier...at least from a mathematical standpoint...now getting it into code is another matter...
0

Commented:
OK, I finally found a web page that is half decent. Never mind the MathView references...

http://www.np.ac.sg/~bms/Mat_Det/DetandMa.htm

OK, you already know how to determine the determinant of a 2x2 matrix.

To determine the determinant of a 3x3 matrix you basically split it into 3 2x2 matrices:

Let's say you have this matrix:
A B C
D E F
G H I

Take the first column, that will give you A, D and G. Then make a 2x2 matrix of the stuff that is not in the same row.

In other words, for A, you can make a 2x2 matrix (M1, with determinant DM1)
E F
H I

For D (DM2)
B C
H I

for G (DM3)
B C
E F

Right....
The determinant of the whole matrix is then calculated as
A * DM1 - D * DM2 + G * DM3

Etc.

Solution: you'll need a recursive algoritm.

And that, as you can see from the link, is only the start of it...

Alas, I live in Ireland. And tomorrow is St. Patrick's day. So this is a long weekend. I'm afraid I won't get the chance to really work out a solution for you. Hopefully this helps, and otherwise perhaps one of the other participants has enough info now to work out your solution for you.

0

Commented:
for all of you interested in trying to code this, the algorithm for finding the inverse to a square matrix is as follows (known as the Gauss - Jordan Elimination):

For PennyWisdom's example you would write the augmented matrix as :

[4 -2 1 0]
[-3 2 0 1]

and the idea is to get it into the form:
[1 0 m1 m2]
[0 1 m3 m4]

To accomplish this we must use the rows of the matrix to help us simplify it, such as, since we need a 1 in the upper left corner for starters, we see it can be done by adding row2 and row1 to yield:
[1 0 1 1]
[-3 2 0 1]
notice only the row that is being operated on is changed (i.e. row1)
Now we need to reduce row2. We see this can be done by multiplying row1 by three and adding it to row2 which yields (again only row2 is changed because it is being acted upon, even though we are multiplying row1 by 3 to get our desired values row1 is unchanged):
[1 0 1 1]
[0 2 3 4]
Lastly we need that 2 in row2 column2 to be a 1. This can be done simply by dividing through the 2nd row by 2:
[1 0 1 1]
[0 1 3/2 2]
So
[1   1]

Now tackling this with code is not something I would be looking forward to   =)
0

Commented:
Unfortunately, I believe that once you get passed the 2 x 2 form of a matrix, the simple algorithm of calculating the determinant and swapping values in the matrix and making some negative and such becomes obselete.  Only in that simplified manner can that be used.  I may be incorrect but in Numerical Methods and Linear Algebra they made sure we went through all that hell above to get our solutions. Had there been an easier way you better believe I would have used it.
0

Commented:
As for a general algorithm, the simplest layout would probably be this (noting that this isnt the best solution as far as time to execute is conecernted but it keeps it simple)

Declare your matrix, remember if it is a 4 x 4 you must declare an 8 x 8 and so on.
Declare a temporary array to store the values of a single row (this array will hold values needed to perform operations on other rows)

Start off by looking at row1, column1
Divide row1 by that element to make it a 1 and the rest of the values whatever.
Then multiply row1 by the magnitude and opposite sign of each row thereafter
This is done to make the first element in each following row a 0.

Then go to row2, column2
Divide row2 by that element to make it a 1 and the rest of the values whatever.
Then multiply row2 by the magnitude and opposite sign of every other row's column 2 element. This will make all column2 entries a 0 for the other rows.

So up to this point, for a 4 x 4 for example you would have:
[1 0 x x x x x]
[0 1 x x x x x]
[0 0 x x x x x]
[0 0 x x x x x]

Then just continue with this until you have the identity matrix created on the left hand side.  Am i making any sense or just babbling to hear myself type??  =)
0

Author Commented:
To AzraSound:

I don't understand where you're going with this.
0

Commented:
well did you understand the mathematical algorithm I discussed above?

If you have a matrix like
[2 4 8 16]
[4 12 16 32]
[8 24 32 64]
[16 40 64 128]  for example then you would need to create the matrix

[2  4  8  16  1  0  0  0]
[4 12 16  32  0  1  0  0]
[8 24 32  64  0  0  1  0]
[16 40 64 128  0  0  0  1]

the first step would be to divide the first row by 2 to make it:
[1  2  4  8  1/2  0  0  0]

Then now that you have a 1 in the first row first column, multiply it by each successive row's magnitude and opposite sign and add it to that row to get all 0's...so multiply it by -4 and add it to row2 to get:
[0  4  0  0  -2  1  0  0]
multiply it by -8 and add it to row3:
[0  8  0  0  -4  0  1  0]
and the last row by -16 and add:
[0  8  0  0  -8  0  0  1]

Now your matrix looks like this:
[1  2  4  8  1/2  0  0  0]
[0  4  0  0  -2  1  0  0]
[0  8  0  0  -4  0  1  0]
[0  8  0  0  -8  0  0  1]

Now we have all the correct values in column1. Moving on to column2 we need a 1 where the 4 is.  Divide row2 by 4 to get:
[0 1  0  0  -1/2  1/4  0  0]

Now we use this row to put zeros in all the other rows in the second column because we want the left side of our matrix to become the identity matrix.

SO if we multiply row2 by -2 and add it to row1 we get:
[1  0  4  8  3/2  -1/2  0  0]
And so on for the other rows.  After this process the second column will then be of the form
[0]
[1]
[0]
[0]
You will do the same for the third and fourth rows. First divide row3 by the element in row3,column3 to get a 1 and then use that to put 0's in column3 of all the other rows.  Likewise for row4.  After all that is done the left side of the matrix will be the identity:
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
And the right side will probably be a mess of fractional numbers.  But the right side will be the inverse matrix. And I'm spent...
0

Author Commented:
ok now that I understand what you're doing

Do you think that it is possible to code that because if I understand correctly you need to find the correct number to divide by so that it sets what I want to 0, You used a matrix that was easy to inverse :) with that logic but what if I have :

7.494285028      4.128843338      1.022252597      0      0      0      0
3.57934146      6.232796486      1.479160036      0      0      0      0
2.481922535      1.390922401      12.57026183      0      0      0      0
0.001464129      0.001464129      0.001952172      -1      0      0      0
0.001464129      0.001464129      0.001952172      0      -1      0      0
0.001464129      0.001464129      0.001952172      0      0      -1      0
0.001464129      0.001464129      0.001952172      0      0      0      -1

Now, I pasted this directly from an exel table so I don't know how it will look exactly but I think you get the idea that the numbers are less abvious

I just don't see a constant logic that I can code
0

Commented:
yes the numbers are less obvious but the logic still holds.  You first divide row1 by the element in row1,column1 to get a 1 in that position.  Once you have a 1, it doesnt really matter how complex the numbers in the other rows are because all you will do is multiply row1 by the negative value of the numbers in column1 and add them to those rows.  Likewise for the other columns, once you get that 1 in there...the rest becomes basic operations regardless of the complexity of the values.
0

Commented:
And clearly, to get a 1, you simply divide the entire row by the value of where you need a 1 to appear
0

Commented:
And clearly, to get a 1, you simply divide the entire row by the value of where you need a 1 to appear
0

Commented:
to inverse a 7 x 7 matrix will take thousands of calculations.
This will be realy hard because i`m doing a level further pure maths and only a three by three is used so this is of high degree level
0

Author Commented:
By looking at some examples of inverse matrices I found that a 3x3 can be calculated this way:
[a b c]
[d e f]
[g h j]

1-Calculate the determinant

2-Take each element and calculate the determinant of the matrix formed when you take out his colomn and row
ex :
a = determinant of
[e f]
[h j]

b = determinant of
[d d]
[g j]

e = determinant of
[a c]
[g j]

Negate the result by this standard:
[+ - +]
[- + -]
[+ - +]

3- Divide each new element by the determinant of the original matrix

So if you have the matrix
1  2  3
a[2  4  8]
b[4 12 16]
c[8 16 33]
Det = 8

a1 = Det of b2:c3
a1 = 140
a2 = - det of
b1 b3
c1 c3
a2 = -4
and so on. In the end the matrix would look like:
[140 -2 -32]
[-4   2   0]
[-32  0   8]

after dividing it would be :
[17.5 -0.5 -4]
[-0.5 0.25  0]
[-4      0  1]

And it is the inverse
know I coded this for a 7x7 :
Public Sub Inverse(Matrix() As Double)
Dim i As Integer, j As Integer, Det As Double, k As Integer, l As Integer
Dim i2 As Integer, j2 As Integer
Dim Temp(1 To 7, 1 To 7) As Double, a(1 To 6, 1 To 6) As Double

Det = Determinant7(Matrix)

For i = 1 To 7
For j = 1 To 7
Temp(i, j) = Matrix(i, j)
Next j
Next i

For k = 1 To 7
For l = 1 To 7
For i = 1 To 7
For j = 1 To 7
If i <> k And j <> l Then
If j < l Then
j2 = j
Else
j2 = j - 1
End If
If i < k Then
i2 = i
Else
i2 = i - 1
End If
a(i2, j2) = Temp(i, j)
End If
Next j
Next i
Matrix(k, l) = Determinant6(a) / Det
Next l
Next k
End Sub

Determinant6 calculates the determiant of a 6x6
Determinant7 of a 7x7
both of those function have been tested and work perfectly

Any idea why the inverse returns garbage?
0

Commented:
as i said before...those shortcut methods for finding inverses dont hold for higher order matrices from what i remember...if i have some time i will tackle the code for the Gauss - Jordan Elimination
0

Author Commented:
Well I finally did it I now have a function that Inverses a matrix thanks to the help of AzraSound and Caraf g

So what I will do is create too questions that will be called:
Points to AzraSound
and
Points to Caraf g

that will be worth 125 points each all you have to do is anser anything and I will accept your anser

Thanks alot for all your help I really apreciate it
0

Author Commented:
I will post the questions after you give me comment here because I have to delete this question to have enought points
0

Commented:
you should post the final code here and ask the help desk to lower the points for you..that way others can benefit from this discussion
0

Author Commented:
I will post the questions after you give me comment here because I have to delete this question to have enought points
0

Author Commented:
Where should I ask to lower the points
0

Commented:
click on help desk at the top and go post a question in the customer support area or whatever it is called and explain why you need to lower the points.
0

Commented:
Community Support has reduced points from 250 to 125
0

Commented:
Per your request, I have reduced the points on this question by half.

darinw
Customer Service
0

Author Commented:
Thanks alot AzraSound
0

## Featured Post

• 18
• 12
• 11
• +4
Tackle projects and never again get stuck behind a technical roadblock.