Search
System of Equations

How to solve system of linear equations in Excel with Custom Function

March 21, 2021

While I was preparing this post, I found  this C# function based on LU matrix decomposition to solve a system of linear equations. I converted it to VBA Function and decided to share it with you. I found this method simpler and quicker than the matrix inverse method.

This function accepts two ranges as parameters  and returns the solutions on the worksheet.

Function in a standard module
Option Explicit
Option Base 1
Public Function SolveLinearEquation(LeftPart As Range, RightPart As Range) As Variant()
      
      Dim L() As Variant, U() As Variant, sum As Double, n As Integer, i As Integer, j As Integer, k As Integer, Result() As Variant
      Dim tempresult() As Variant, temp2() As Variant
      n = LeftPart.Columns.Count
      sum = 0
      ReDim L(n, n)
      ReDim U(n, n)
      ReDim tempresult(n)
      ReDim Result(n)
      
    '' LU decomposition
      For i = 1 To n
             
        
            For j = i To n
          
                  sum = 0
                  For k = 1 To i
                        sum = sum + L(i, k) * U(k, j)
               
                  Next k
               
                  U(i, j) = LeftPart(i, j) - sum
          
            Next j
            
            
            For j = i To n
          
                  If j = i Then
                  
                        L(i, i) = 1
                  Else
                        sum = 0
                        For k = 1 To i
                              sum = sum + L(j, k) * U(k, i)
               
                        Next k
               
                        L(j, i) = (1 / U(i, i)) * (LeftPart(j, i) - sum)
                  End If
             
            Next j
            
      Next i
        
       ''Solving LY =rightpart
      For i = 1 To n
        
            sum = 0
           
            For k = 1 To i
           
                  sum = sum + L(i, k) * tempresult(k)
           
            Next k
        
            tempresult(i) = RightPart(i) - sum
      Next i
      
      ''Back substitution UX=Y
      For i = n To 1 Step -1
        
            sum = 0
           
            For k = 1 To n
           
                  sum = sum + U(i, k) * Result(k)
           
            Next k
        
            Result(i) = (1 / U(i, i)) * (tempresult(i) - sum)
      Next i
        
       '' Return the solutions
      SolveLinearEquation = WorksheetFunction.Transpose(Result)
End Function

You can copy and paste the above code in a standard module in your workbook and just call the function in a cell to solve your system of linear equations. Don't forget to use Ctrl+Shift+Enter to enter your function.

How to use this function

Look at this video.

System of linear equations

I hope you will find this custom function useful and if you have any suggestions, please leave a comment or email me at info@civilconstructiontools.com.

  • Version 1.0.0
  • Download 11401
  • File Size 15 KB
  • File Count 2
  • Create Date March 21, 2021
  • Last Updated March 21, 2021
FileAction
How to solve a system of linear equations.zipDownload
System of Equations.pngDownload

If you believe my tools are helping you and would like to support me, please use the below button to donate.

Sharing is caring:

2 thoughts on “How to solve system of linear equations in Excel with Custom Function”

  1. Hi Rodrigue,
    This matrix decomposition by triangulation comes handy for ranks over 3, although it degrades computation performance as the rank increases (it turns to be O(n³)), and some other solvers as Conjugate gradient are better suited when the rank reaches some hundreds. For information purposes only, for rank 3 (and for rank 2 also), there is a direct function to solve the inverse, as explained here https://ardoris.wordpress.com/2008/07/18/general-formula-for-the-inverse-of-a-3×3-matrix/

    Kind regards mate

    1. Here is some code Conjugate gradient from my VBA arsenal:

      'CONJUGATE GRADIENT METHOD FOR SOLVING EQUATIONS
      Public Sub sConjugateGradient()
      Dim a() As Double
      Dim B() As Double
      Dim X() As Double

      '-------------------------------
      Dim arrA As Variant
      Dim arrB As Variant
      Dim row As Long
      Dim col As Long

      With Application
      .Calculation = xlCalculationManual
      .ScreenUpdating = False
      End With

      'arrA = Range(Cells(1, 1), Cells(xxx, xxx)).Value2
      'arrB = Range(Cells(1, 1), Cells(xxx, xxx)).Value2

      ReDim a(LBound(arrA, 1) To UBound(arrA, 1), LBound(arrA, 2) To UBound(arrA, 2))
      ReDim B(LBound(arrB, 1) To UBound(arrB, 1))
      For row = LBound(arrA, 1) To UBound(arrA, 1)
      For col = LBound(arrA, 2) To UBound(arrA, 2)
      a(row, col) = arrA(row, col)
      Next col
      B(row) = arrB(row, 1)
      Next row
      '-------------------------------

      X() = fConjugateGradient_Solver(a(), B())
      With Application
      .Calculation = xlCalculationAutomatic
      .ScreenUpdating = True
      End With
      Stop
      End Sub

      Public Function fConjugateGradient_Solver(ByRef a() As Double, _
      ByRef B() As Double, _
      Optional ByVal dbTolerance As Double = 0.000001, _
      Optional ByVal iter_Max As Long = 10) As Double()
      ' Fletcher-Reeves algorithm (array should be symmetric)
      Dim retValue As VbMsgBoxResult
      Dim i As Long
      Dim j As Long
      Dim n As Long
      Dim X() As Double
      Dim g() As Double
      Dim D() As Double
      Dim ad() As Double
      Dim iter As Long
      Dim dad As Double
      Dim c As Double
      Dim aL As Double
      Dim gg1 As Double
      Dim gg2 As Double
      Dim GG_Previous As Double
      Dim bt As Double

      'Dim dbTolerance As Double
      dbTolerance = 0.000001

      'Ensure matrix is square
      If (UBound(a, 1) - LBound(a, 1)) _
      (UBound(a, 2) - LBound(a, 2)) Then
      retValue = fMsgBox("Array [A] is not square", vbCritical)
      Exit Function
      End If

      ' Solutions array
      n = UBound(a, 1) - LBound(a, 1) + 1
      ReDim X(LBound(a, 1) To UBound(a, 1))

      ' Create auxiliary arrays
      ReDim g(LBound(a, 1) To UBound(a, 1))
      ReDim D(LBound(a, 1) To UBound(a, 1))
      ReDim ad(LBound(a, 1) To UBound(a, 1))
      For i = LBound(a, 1) To UBound(a, 1)
      'X(I) = 0 'Initialize array
      g(i) = -B(i)
      D(i) = B(i)
      Next i

      gg1 = 0
      For i = LBound(a, 1) To UBound(a, 1)
      gg1 = gg1 + (g(i) * g(i))
      Next i
      GG_Previous = gg1

      Do While gg1 > dbTolerance
      ' Convergence analysis
      If gg1 <= GG_Previous Then
      GG_Previous = gg1
      Else
      ' it's not converging
      'GoTo ErrConvergence
      End If

      iter = iter + 1
      dad = 0

      For i = LBound(a, 1) To UBound(a, 1)
      c = 0
      For j = LBound(a, 1) To UBound(a, 1)
      c = c + (a(i, j) * D(j))
      Next j
      ad(i) = c
      dad = dad + (c * D(i))
      Next i

      'If VBA.Abs(DAD) iter_Max Then GoTo ErrSlowConvergence ' it's not converging
      Loop

      ' Free memory
      Erase g(), D(), ad() ', A(), B()

      fConjugateGradient_Solver = X()

      ExitProc:
      Exit Function

      ErrConvergence:
      retValue = MsgBox("Conjugate gradient solver it's not converging, array seems to be bad conditioned" & vbNewLine & _
      "[" & gg1 & ">" & GG_Previous & "] on iteration [" & iter & "]", _
      vbCritical)
      GoTo ExitProc
      ErrSlowConvergence:
      retValue = MsgBox("Conjugate gradient solver it's converging slowly, array seems to be bad conditioned" & vbNewLine & _
      "Convergence = [" & gg1 & "] on iteration [" & iter & "]", _
      vbCritical)
      GoTo ExitProc
      End Function

Leave a Reply

Your email address will not be published. Required fields are marked *