Solved

Inverse a Matrix

Posted on 2000-03-16
48
1,448 Views
Last Modified: 2012-08-14
Can anybody give me a function that inverses a matrix of preferably any size but 7 by 7 will do

Thanks in advance
0
Comment
Question by:Pennywisdom
  • 18
  • 12
  • 11
  • +4
48 Comments
 
LVL 10

Expert Comment

by:caraf_g
ID: 2623976
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
 
LVL 10

Expert Comment

by:caraf_g
ID: 2623993
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
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 2624001
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
 
LVL 10

Expert Comment

by:caraf_g
ID: 2624002
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
 
LVL 10

Expert Comment

by:caraf_g
ID: 2624007
"You are not able to declare a multi-dimension matrix dynamically"

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

Author Comment

by:Pennywisdom
ID: 2624010
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
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 2624017
 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
 
LVL 14

Expert Comment

by:mcrider
ID: 2624027
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


Cheers!®©
0
 

Author Comment

by:Pennywisdom
ID: 2624031
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
 
LVL 10

Expert Comment

by:caraf_g
ID: 2624063
"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 Comment

by:Pennywisdom
ID: 2624076
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
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 2624094
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
 
LVL 10

Expert Comment

by:caraf_g
ID: 2624102
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 Comment

by:Pennywisdom
ID: 2624120
If you have the matrix
|a b|
|c d|

1-Calculate the derterminant:
ad - bc

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
 
LVL 10

Expert Comment

by:caraf_g
ID: 2624151
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
 
LVL 10

Expert Comment

by:caraf_g
ID: 2624157
Geez. that's hard.
0
 

Author Comment

by:Pennywisdom
ID: 2624213
Yes caraf g you are correct
0
 

Author Comment

by:Pennywisdom
ID: 2624224
I'M Sorry caraf g but you are mistaken 10x7 matrix inversed would be a 10x7 also
0
 

Author Comment

by:Pennywisdom
ID: 2624242
Sorry about my mistake you ARE RIGHT
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2624292
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 Comment

by:Pennywisdom
ID: 2624303
Sorry about my mistake you ARE RIGHT
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2624496
I used e-mail a friend to e-mail ozo, hopefully we'll get a response there.
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2624741
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 Comment

by:Pennywisdom
ID: 2624839
I was mistaken what I need is a 7x7 matrix maybe that will simplifie the question
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:Pennywisdom
ID: 2624843
Edited text of question.
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2624864
aaaaah much easier...at least from a mathematical standpoint...now getting it into code is another matter...
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2624943
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
 
LVL 28

Expert Comment

by:AzraSound
ID: 2624956
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]
where {m1,m2,m3,m4} is your inverse.

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]
[3/2 2]  is our answer

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

Expert Comment

by:AzraSound
ID: 2624982
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
 
LVL 28

Expert Comment

by:AzraSound
ID: 2625077
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 Comment

by:Pennywisdom
ID: 2625158
To AzraSound:

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

Accepted Solution

by:
AzraSound earned 125 total points
ID: 2625244
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 Comment

by:Pennywisdom
ID: 2625480
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
 
LVL 28

Expert Comment

by:AzraSound
ID: 2625576
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
 
LVL 28

Expert Comment

by:AzraSound
ID: 2625594
And clearly, to get a 1, you simply divide the entire row by the value of where you need a 1 to appear
0
 
LVL 28

Expert Comment

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

Expert Comment

by:Marktalbot
ID: 2627386
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 Comment

by:Pennywisdom
ID: 2628767
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
 
LVL 28

Expert Comment

by:AzraSound
ID: 2629082
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 Comment

by:Pennywisdom
ID: 2629170
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 Comment

by:Pennywisdom
ID: 2629185
I will post the questions after you give me comment here because I have to delete this question to have enought points
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2629187
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 Comment

by:Pennywisdom
ID: 2629200
I will post the questions after you give me comment here because I have to delete this question to have enought points
0
 

Author Comment

by:Pennywisdom
ID: 2629219
Where should I ask to lower the points
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2629237
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
 
LVL 3

Expert Comment

by:darinw
ID: 2629352
Community Support has reduced points from 250 to 125
0
 
LVL 3

Expert Comment

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

darinw
Customer Service
0
 

Author Comment

by:Pennywisdom
ID: 2629371
Thanks alot AzraSound
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now