20.6.1 Task-Project 2

Project 2 is based on the following task: calculating the adjoints of a (square) matrix via Laplace's evolution theorem.

This solution idea was developed: When calculating the adjoints of a matrix - as transpose of the co-factor matrix - a large number of sub-determinants (minors) must be calculated, which generally have nothing to do with each other. The task is broken down into n subtasks for calculating sub-determinants.

This proposal for implementation arose from the solution idea:

Public Function Main() As Variant
'-- Calculate array of sub-determinants...
    Return aFloatArray
End

The following specifications apply:

The source texts for the task class and the main programme are given in full. The above solution idea is implemented in them. First, the content of the task class is presented - stored in the file TaskMinors.class:

' Gambas class file
 
'-- This class calculates the minors of the specified matrix when the specified row has been deleted.
'-- The function value is an appropriately sized float array of the individual determinants.
 
Inherits Task
 
Property Tag As Variant
 
Private $hMatrix As Matrix
Private $vTag As Variant
Private $iRow As Integer
 
Public Sub _new({Matrix} As Matrix, Row As Integer)
  $hMatrix = {Matrix}
  $iRow = Row
End ' _new(..)
 
Public Function Main() As Variant
  Dim hMinor As New Matrix($hMatrix.Width - 1, $hMatrix.Width - 1)
  Dim iRemCol, iSrcRow, iSrcCol, iDstRow, iDstCol As Integer
  Dim aFloatArray As New Float[]
 
  For iRemCol = 0 To hMinor.Width
  '-- Untermatrix aufbauen
    iDstRow = 0
    For iSrcRow = 0 To hMinor.Height
        If iSrcRow = $iRow Then Continue
        iDstCol = 0
        For iSrcCol = 0 To hMinor.Width
            If iSrcCol = iRemCol Then Continue
            hMinor[iDstRow, iDstCol] = $hMatrix[iSrcRow, iSrcCol]
            Inc iDstCol
        Next
        Inc iDstRow
    Next
 
    aFloatArray.Add(hMinor.Det())
 
  Next
 
  Return aFloatArray '-- The function value is of the data type float array
 
End
 
Private Function Tag_Read() As Variant
  Return $vTag
End
 
Private Sub Tag_Write(Value As Variant)
  $vTag = Value
End

File MMain.module:

' Gambas module file
 
' -- Dimension of a random square matrix (d > 1)
Const Dimension As Integer = 15 '-- Maximum 30
 
Private $hMatrix As Matrix
Private $hAdjugate As Matrix
Private $iTasks As Integer
 
Public Sub Main()
  Dim iRow, iCol As Integer
  Dim hDet As TaskMinors
  Dim hOther As Matrix
 
'-- Create matrix of the given dimension with random elements
  $hMatrix = RandomMatrix()
  Print "Matrix:";; $hMatrix.ToString()
 
  $hAdjugate = New Matrix($hMatrix.Width, $hMatrix.Height)
  $iTasks = 0
 
  For iRow = 0 To $hMatrix.Height1 '-- k task are created
    For iCol = 0 To $hMatrix.Width - 1
    '-- Calculate all minors when deleting row iRow
      hDet = New TaskMinors($hMatrix, iRow) As "TaskMinors"
      hDet.Tag = iRow
      Inc $iTasks '-- Counts the started tasks
    Next
  '-- The tasks are started after their instantiation at the next call of the event loop. So that
  '-- not to start them all at once, let each individual task start via WAIT.
    Wait
  Next
 
'-- Wait for the calculation of the adjoints (-->> Minor_Kill())
  While $iTasks '-- As long as calculations are still being made ...
    Wait 0.001  '-- ...wait 0.001 seconds
  Wend
 
  Print "Adjunkte adj(A):";; $hAdjugate.ToString() '-- Display adjuncts
 
End
 
Public Sub TaskMinors_Kill()
  Dim iRow, iCol As Integer
  Dim aDet As Float[] = Last.Value
 
  iRow = Last.Tag
  For iCol = 0 To aDet.Max
  '-- The adjoints is the transpose of the co-factor matrix.
      $hAdjugate[iCol, iRow] = IIf(Even(iRow + iCol), 1, -1) * aDet[iCol]
  Next
  Dec $iTasks '-- Decrease the number of tasks by 1
 
End
 
Public Function RandomMatrix() As Matrix
  Dim hMatrix As New Matrix(Dimension, Dimension, False)
  Dim iRow, iCol As Integer
 
  For iRow = 0 To hMatrix.Height - 2
    hMatrix[iRow, 0] = Rnd(0, hMatrix.Height + 1)
    For iCol = 1 To hMatrix.Width - 1
      hMatrix[iRow, iCol] = IIf(iRow = iCol, iRow + 1, hMatrix.Height)
    Next
  Next
 
  For iCol = 0 To hMatrix.Width - 1
    hMatrix[hMatrix.Height - 1, iCol] = Rnd(0, hMatrix.Width + 1)
  Next
 
  Return hMatrix '-- Provide matrix with random elements
 
End

This was output to the IDE console for a calculation with dimension 3:

Matrix:

[[0.13973 | 3 | 3] ; [0.60071 | 2 | 3] ; [2.73226 | 0.28943 | 2.89609]]

Adjunkte adj(A):

[[4.92387 | -7.81996 | 3] ; [6.45708 | -7.79211 | 1.38293] ; [-5.29066 | 8.15636 | -1.52266]]

Note that with matrices of higher dimension (>10) rounding errors already have a very strong effect on the result. The identity adj(A) = det(A)∙A^(-1) provides a more precise calculation of the adjoints.

Download