@@ -29,64 +29,67 @@ that describes the mechanics:
2929https://en.wikipedia.org/wiki/QR_decomposition#Using_Householder_reflections
3030"
3131
32- | identityMatrix householderVector i matrixOfMinor |
33- identityMatrix := PMSymmetricMatrix identity: colSize.
32+ | i matrixOfMinor |
3433 1 to: self numberOfColumns do: [ :col |
35- | columnVectorFromRMatrix householderMatrix v |
34+ | householderReflection householderMatrix householderVector columnVectorFromRMatrix |
3635 columnVectorFromRMatrix := r columnVectorAt: col size: colSize.
37- householderVector := columnVectorFromRMatrix householder.
38- v := (PMVector zeros: col - 1 ) , (householderVector at: 2 ).
39- householderMatrix := identityMatrix
40- -
41- ((householderVector at: 1 ) * v tensorProduct: v).
36+ householderReflection := self
37+ householderReflectionOf:
38+ columnVectorFromRMatrix
39+ atColumnNumber: col.
40+ householderVector := householderReflection at: 1 .
41+ householderMatrix := householderReflection at: 2 .
4242 q := q * householderMatrix.
4343 matrixOfMinor := r minor: col - 1 and : col - 1 .
4444 matrixOfMinor := matrixOfMinor
4545 - ((householderVector at: 2 ) tensorProduct:
4646 (householderVector at: 1 )
4747 * (householderVector at: 2 ) * matrixOfMinor).
4848 matrixOfMinor rowsWithIndexDo: [ :aRow :index |
49- aRow withIndexDo: [ :n :c |
49+ aRow withIndexDo: [ :element :column |
50+ | rowNumber columnNumber |
51+ rowNumber := col + index - 1 .
52+ columnNumber := col + column - 1 .
5053 r
51- rowAt: col + index - 1
52- columnAt: col + c - 1
53- put: ((n closeTo: 0 )
54+ rowAt: rowNumber
55+ columnAt: columnNumber
56+ put: ((element closeTo: 0 )
5457 ifTrue: [ 0 ]
55- ifFalse: [ n ]) ] ] ].
58+ ifFalse: [ element ]) ] ] ].
5659 i := 0 .
5760 [ (r rowAt: colSize) isZero ] whileTrue: [
5861 i := i + 1 .
5962 colSize := colSize - 1 ].
6063 i > 0 ifTrue: [
61- r := PMMatrix rows: (r rows copyFrom: 1 to: colSize) .
64+ r := self upperTriangularPartOf: r With: colSize.
6265 i := q numberOfColumns - i.
6366 q := PMMatrix rows:
64- (q rows collect : [ :row | row copyFrom: 1 to: i ]) ].
67+ (q rowsCollect : [ :row | row copyFrom: 1 to: i ]) ].
6568 ^ Array with: q with: r
6669]
6770
6871{ #category : #arithmetic }
6972PMQRDecomposition >> decomposeWithPivot [
7073
71- | identityMatrix householderVector i v vectorOfNormSquareds rank mx pivot matrixOfMinor |
74+ | i vectorOfNormSquareds rank positionOfMaximum pivot matrixOfMinor |
7275 vectorOfNormSquareds := matrixToDecompose columnsCollect: [
7376 :columnVector | columnVector * columnVector ].
74- mx := vectorOfNormSquareds indexOf: vectorOfNormSquareds max.
77+ positionOfMaximum := vectorOfNormSquareds indexOf: vectorOfNormSquareds max.
7578 pivot := Array new : vectorOfNormSquareds size.
7679 rank := 0 .
77- identityMatrix := PMSymmetricMatrix identity: colSize.
7880 [
79- | householderMatrix |
81+ | householderReflection householderMatrix householderVector columnVectorFromRMatrix |
8082 rank := rank + 1 .
81- pivot at: rank put: mx.
82- r swapColumn: rank withColumn: mx.
83- vectorOfNormSquareds swap: rank with: mx.
84- householderVector := (r columnVectorAt: rank size: colSize)
85- householder.
86- v := (PMVector zeros: rank - 1 ) , (householderVector at: 2 ).
87- householderMatrix := identityMatrix
88- -
89- ((householderVector at: 1 ) * v tensorProduct: v).
83+ pivot at: rank put: positionOfMaximum.
84+ r swapColumn: rank withColumn: positionOfMaximum.
85+ vectorOfNormSquareds swap: rank with: positionOfMaximum.
86+ columnVectorFromRMatrix := r columnVectorAt: rank size: colSize.
87+ householderReflection := self
88+ householderReflectionOf:
89+ columnVectorFromRMatrix
90+ atColumnNumber: rank.
91+ householderVector := householderReflection at: 1 .
92+ householderMatrix := householderReflection at: 2 .
9093 q := q * householderMatrix.
9194 matrixOfMinor := r minor: rank - 1 and : rank - 1 .
9295 matrixOfMinor := matrixOfMinor
@@ -95,9 +98,12 @@ PMQRDecomposition >> decomposeWithPivot [
9598 * (householderVector at: 2 ) * matrixOfMinor).
9699 matrixOfMinor rowsWithIndexDo: [ :aRow :index |
97100 aRow withIndexDo: [ :element :column |
101+ | rowNumber columnNumber |
102+ rowNumber := rank + index - 1 .
103+ columnNumber := rank + column - 1 .
98104 r
99- rowAt: rank + index - 1
100- columnAt: rank + column - 1
105+ rowAt: rowNumber
106+ columnAt: columnNumber
101107 put: ((element closeTo: 0 )
102108 ifTrue: [ 0 ]
103109 ifFalse: [ element ]) ] ].
@@ -109,29 +115,42 @@ PMQRDecomposition >> decomposeWithPivot [
109115 - (r rowAt: rank columnAt: ind) squared ].
110116 rank < vectorOfNormSquareds size
111117 ifTrue: [
112- mx := (vectorOfNormSquareds
118+ positionOfMaximum := (vectorOfNormSquareds
113119 copyFrom: rank + 1
114120 to: vectorOfNormSquareds size) max.
115- (mx closeTo: 0 ) ifTrue: [ mx := 0 ].
116- mx := mx > 0
121+ (positionOfMaximum closeTo: 0 ) ifTrue: [ positionOfMaximum := 0 ].
122+ positionOfMaximum := positionOfMaximum > 0
117123 ifTrue: [
118- vectorOfNormSquareds indexOf: mx startingAt: rank + 1 ]
124+ vectorOfNormSquareds indexOf: positionOfMaximum startingAt: rank + 1 ]
119125 ifFalse: [ 0 ] ]
120- ifFalse: [ mx := 0 ].
121- mx > 0 ] whileTrue.
126+ ifFalse: [ positionOfMaximum := 0 ].
127+ positionOfMaximum > 0 ] whileTrue.
122128 i := 0 .
123129 [ (r rowAt: colSize) isZero ] whileTrue: [
124130 i := i + 1 .
125131 colSize := colSize - 1 ].
126132 i > 0 ifTrue: [
127- r := PMMatrix rows: (r rows copyFrom: 1 to: colSize) .
133+ r := self upperTriangularPartOf: r With: colSize.
128134 i := q numberOfColumns - i.
129135 pivot := pivot copyFrom: 1 to: i.
130136 q := PMMatrix rows:
131- (q rows collect : [ :row | row copyFrom: 1 to: i ]) ].
137+ (q rowsCollect : [ :row | row copyFrom: 1 to: i ]) ].
132138 ^ Array with: q with: r with: pivot
133139]
134140
141+ { #category : #private }
142+ PMQRDecomposition >> householderReflectionOf: columnVector atColumnNumber: columnNumber [
143+
144+ | householderVector v identityMatrix householderMatrix |
145+ householderVector := columnVector householder.
146+ v := (PMVector zeros: columnNumber - 1 ) , (householderVector at: 2 ).
147+ identityMatrix := PMSymmetricMatrix identity: colSize.
148+ householderMatrix := identityMatrix
149+ -
150+ ((householderVector at: 1 ) * v tensorProduct: v).
151+ ^ Array with: householderVector with: householderMatrix .
152+ ]
153+
135154{ #category : #private }
136155PMQRDecomposition >> initialQMatrix [
137156
@@ -158,3 +177,9 @@ PMQRDecomposition >> of: matrix [
158177 r := self initialRMatrix.
159178 q := self initialQMatrix.
160179]
180+
181+ { #category : #private }
182+ PMQRDecomposition >> upperTriangularPartOf: matrix With: columnSize [
183+
184+ ^ PMMatrix rows: (r rows copyFrom: 1 to: columnSize)
185+ ]
0 commit comments