Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Inverse of a 3x3 Matrix (Excel Minverse Equivalent)

0.00/5 (No votes)
23 Sep 2018 1  
.NET Equivalent to MInverse in Excel

Introduction

This function will accept one 3x3 matrix as datatable, validate it and give back the inverse as another datatable. I had intentionally used datatable for easy databinding with gridview controls, this is a continuation of Matrix multiplication in my previous tip.

Background

In my new engineering project, I came across the requirement of implementing a lot of matrix arithmetic that was previously done using Excel.

Using the Code

For demonstration purposes, I had created a simple form with a gridview to input 3x3 matrix (please check the image attached).

Then add a Button to the form and on the button click event, send the data of gridview to Calculate Inverse as datatable:

Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
       Dim dt1mat As DataTable = CType((grdMatrix1.DataSource), DataTable)
       grdMatrix3.DataSource = MatrixInverse3x3(dt1mat)
   End Sub

Please find the Inverse function below. Please go through the comments for better understanding.

''' <summary>
   ''' Inverses a Matrix of 3X3 using determinand method and Gaussian elimination
   ''' </summary>
   ''' https://en.wikipedia.org/wiki/Gaussian_elimination#Finding_the_inverse_of_a_matrix
   ''' <param name="dt">Matrix to be inversed</param>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Function MatrixInverse3x3(dt As DataTable) As DataTable
 
       Dim dtmyinverse As DataTable = New DataTable
       Dim imyasci As Integer = 65
       For index As Integer = 0 To 2
           dtmyinverse.Columns.Add(Chr(imyasci))
           imyasci += 1
       Next
 
       For index As Integer = 0 To 2
           dtmyinverse.Rows.Add()
       Next
       Dim a As Decimal = Decimal.Parse(dt.Rows(0)(0).ToString())
       Dim b As Decimal = Decimal.Parse(dt.Rows(0)(1).ToString())
       Dim c As Decimal = Decimal.Parse(dt.Rows(0)(2).ToString())
       Dim d As Decimal = Decimal.Parse(dt.Rows(1)(0).ToString())
       Dim e As Decimal = Decimal.Parse(dt.Rows(1)(1).ToString())
       Dim f As Decimal = Decimal.Parse(dt.Rows(1)(2).ToString())
       Dim g As Decimal = Decimal.Parse(dt.Rows(2)(0).ToString())
       Dim h As Decimal = Decimal.Parse(dt.Rows(2)(1).ToString())
       Dim i As Decimal = Decimal.Parse(dt.Rows(2)(2).ToString()) 
 
       'invdet = 1/Sum(v[0]*cross(v[1],v[2])); 
       '         and temp = transpose(mat3(cross(v[1],v[2]),cross(v[2],v[0]),cross(v[0],v[1])))
       ''calculate minor deteminand1
       Dim min1 As Decimal = a * ((e * i) - (f * h))
       ''calculate minor deteminand2
       Dim min2 As Decimal = b * ((d * i) - (f * g))
       ''calculate minor deteminand3
       Dim min3 As Decimal = c * ((d * h) - (e * g))
       ''det=+(minor1) -(minor2)+(minor3)-(minor4)......
       Dim det As Decimal = min1 - min2 + min3
 
 
       'Rule is inverse = 1/det * minor of the TRANSPOSE matrix.  *
       'Note (y,x) becomes (x,y) INTENTIONALLY here!
       det = 1 / det
 
       '        // computes the inverse of a matrix m
       'double det = m(0, 0) * (m(1, 1) * m(2, 2) - m(2, 1) * m(1, 2)) -
       '             m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) +
       '             m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0));
 
       dtmyinverse.Rows(0)(0) = (dt.Rows(1)(1) * dt.Rows(2)(2) - dt.Rows(2)(1) * dt.Rows(1)(2)) * det
       dtmyinverse.Rows(0)(1) = (dt.Rows(0)(2) * dt.Rows(2)(1) - dt.Rows(0)(1) * dt.Rows(2)(2)) * det
       dtmyinverse.Rows(0)(2) = (dt.Rows(0)(1) * dt.Rows(1)(2) - dt.Rows(0)(2) * dt.Rows(1)(1)) * det
       dtmyinverse.Rows(1)(0) = (dt.Rows(1)(2) * dt.Rows(2)(0) - dt.Rows(1)(0) * dt.Rows(2)(2)) * det
       dtmyinverse.Rows(1)(1) = (dt.Rows(0)(0) * dt.Rows(2)(2) - dt.Rows(0)(2) * dt.Rows(2)(0)) * det
       dtmyinverse.Rows(1)(2) = (dt.Rows(1)(0) * dt.Rows(0)(2) - dt.Rows(0)(0) * dt.Rows(1)(2)) * det
       dtmyinverse.Rows(2)(0) = (dt.Rows(1)(0) * dt.Rows(2)(1) - dt.Rows(2)(0) * dt.Rows(1)(1)) * det
       dtmyinverse.Rows(2)(1) = (dt.Rows(2)(0) * dt.Rows(0)(1) - dt.Rows(0)(0) * dt.Rows(2)(1)) * det
       dtmyinverse.Rows(2)(2) = (dt.Rows(0)(0) * dt.Rows(1)(1) - dt.Rows(1)(0) * dt.Rows(0)(1)) * det
       'dtmyinverse.Rows(0)(0) = (m(1, 1) * m(2, 2) - m(2, 1) * m(1, 2)) * det
       'dtmyinverse.Rows(0)(1) = (m(0, 2) * m(2, 1) - m(0, 1) * m(2, 2)) * det
       'dtmyinverse.Rows(0)(2) = (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * det
       'dtmyinverse.Rows(1)(0) = (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2)) * det
       'dtmyinverse.Rows(1)(1) = (m(0, 0) * m(2, 2) - m(0, 2) * m(2, 0)) * det
       'dtmyinverse.Rows(1)(2) = (m(1, 0) * m(0, 2) - m(0, 0) * m(1, 2)) * det
       'dtmyinverse.Rows(2)(0) = (m(1, 0) * m(2, 1) - m(2, 0) * m(1, 1)) * det
       'dtmyinverse.Rows(2)(1) = (m(2, 0) * m(0, 1) - m(0, 0) * m(2, 1)) * det
       'dtmyinverse.Rows(2)(2) = (m(0, 0) * m(1, 1) - m(1, 0) * m(0, 1)) * det
 
       Return dtmyinverse
   End Function

Points of Interest

It will be interesting to do the same for non 3x3 matrix also and I am currently trying to do the same and will upload once completed.

History

  • 23rd September, 2018: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here