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.Height – 1 '-- 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.
Chapter & Projects