- On the Browser Create the DoubleArray Class as a subclass of ByteArray
ArrayedCollection variableSubclass: #GaussJordan
instanceVariableNames: 'nRows nColumns contents'
classVariableNames: ''
poolDictionaries: ''
category: 'Gauss Jordan'
- We start of by writing the class side method.
new: totalRows by: totalColumns
| instance |
instance := self new: totalRows * totalColumns.
instance setTotalRows: totalRows setTotalColumns: totalColumns.
^ instance
- In the instance side, a method is created to initialize the rows and columns of the matrix.
setTotalRows: totalRows setTotalColumns: totalColumns
nRows := totalRows.
nColumns := totalColumns.
contents := self
- A couple of methods are created to retrieve the nRows and nColumns.
getRows
^ nRows
getColumns
^ nColumns
- This following method loads the coefficients and solution bVector into an augmented matrix.
loadAugmentedMatrix: coefficients and: bVector
"start index from 1 for easier implementation"
0
to: nRows - 1
do: [:i | 1
to: nColumns
do: [:j | j >= nColumns
ifTrue: [self
at: i * nColumns + j
put: (bVector at: i + 1)]
ifFalse: [self
at: i * nColumns + j
put: (coefficients at: i * nRows + j)]]]
- A method to retrieve the xVector along with a check on singular matrix.
xVector
| answer singular |
answer := Array new: nRows.
1
to: nRows
do: [:i | answer
at: i
put: (self at: i * (nRows + 1))].
"singular matrix check"
0
to: nRows - 1
do: [:i |
singular := true.
1
to: nColumns - 1
do: [:j | (self at: i * nColumns + j)
~= 0
ifTrue: [singular := false]].
singular
ifTrue: [^ 'This is a Singular Matrix !!']].
^ answer
- Next, the main coordinator for the Gauss Jordan Elmination method is created.
Gauss: doubleArrayTransform size: matrixRow by: matrixColumn
"Perform a Gaussian Elimination operation on a square matrix with the
result vector"
"doubleArrayTransform is only used in primitive."
| pivotRowIndex m1 |
<primitive: 'primitiveGaussMatrix' module: 'GaussFlexiPlugin'>
self halt.
m1 := doubleArrayTransform asGaussJordan: matrixRow by: matrixColumn.
1
to: nRows
do: [:i |
pivotRowIndex := m1 findPivotInColumn: i.
pivotRowIndex > i
ifTrue: [m1 swapRow: i withRow: pivotRowIndex].
m1 divideRow: i byColumn: i.
1
to: nRows
do: [:j | j = i
ifFalse: [m1 reduceRow: j byRow: i]]].
^ m1
- We proceed by adding the modules to complete the Gauss Jordan Class, firstly, a method to find the pivot row for each column.
findPivotInColumn: column
"Find the row which contains the matimum value in a column and make
it a pivot row"
| pivot temp max |
max := (self at: column - 1 * nColumns + column) abs.
pivot := column.
1
to: nRows
do: [:i | (temp := (self at: i - 1 * nColumns + column) abs) > max
ifTrue: [max := temp.
pivot := i]].
^ pivot
- Swap the pivot row.
swapRow: firstRow withRow: anotherRow
| a b |
a := firstRow - 1 * nColumns + 1.
b := anotherRow - 1 * nColumns + 1.
nColumns
timesRepeat: [self swap: a with: b.
a := a + 1.
b := b + 1]
- Divide row against the pivot row.
divideRow: rowIndex byColumn: pivotColumn
"Pivot row by dividing own self with the pivot element of a column"
| temp a |
a := rowIndex - 1 * nColumns.
temp := self at: a + pivotColumn.
1
to: nColumns
do: [:i | temp = 0
ifFalse: [self at: a + i put: (self at: a + i)
/ temp]]
- Finally, reducing the pivot element in the other rows to zero.
reduceRow: firstRowIndex byRow: pivotRowIndex
"Subtracting firstRow with the pivot row."
| a b temp |
a := firstRowIndex - 1 * nColumns.
b := pivotRowIndex - 1 * nColumns.
temp := self at: a + pivotRowIndex.
1
to: nColumns
do: [:i | self at: a + i put: (self at: a + i)
- (temp
* (self at: b + i))]
- This method converts the Gauss Jordan matrix into DoubleArray.
asDoubleArray
| n answer |
n := self size.
answer := DoubleArray new: n.
1
to: n
do: [:i | answer at: i put: (self at: i) asFloat].
^ answer