@@ -29,64 +29,67 @@ that describes the mechanics:
29
29
https://en.wikipedia.org/wiki/QR_decomposition#Using_Householder_reflections
30
30
"
31
31
32
- | identityMatrix householderVector i matrixOfMinor |
33
- identityMatrix := PMSymmetricMatrix identity: colSize.
32
+ | i matrixOfMinor |
34
33
1 to: self numberOfColumns do: [ :col |
35
- | columnVectorFromRMatrix householderMatrix v |
34
+ | householderReflection householderMatrix householderVector columnVectorFromRMatrix |
36
35
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 .
42
42
q := q * householderMatrix.
43
43
matrixOfMinor := r minor: col - 1 and : col - 1 .
44
44
matrixOfMinor := matrixOfMinor
45
45
- ((householderVector at: 2 ) tensorProduct:
46
46
(householderVector at: 1 )
47
47
* (householderVector at: 2 ) * matrixOfMinor).
48
48
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 .
50
53
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 )
54
57
ifTrue: [ 0 ]
55
- ifFalse: [ n ]) ] ] ].
58
+ ifFalse: [ element ]) ] ] ].
56
59
i := 0 .
57
60
[ (r rowAt: colSize) isZero ] whileTrue: [
58
61
i := i + 1 .
59
62
colSize := colSize - 1 ].
60
63
i > 0 ifTrue: [
61
- r := PMMatrix rows: (r rows copyFrom: 1 to: colSize) .
64
+ r := self upperTriangularPartOf: r With: colSize.
62
65
i := q numberOfColumns - i.
63
66
q := PMMatrix rows:
64
- (q rows collect : [ :row | row copyFrom: 1 to: i ]) ].
67
+ (q rowsCollect : [ :row | row copyFrom: 1 to: i ]) ].
65
68
^ Array with: q with: r
66
69
]
67
70
68
71
{ #category : #arithmetic }
69
72
PMQRDecomposition >> decomposeWithPivot [
70
73
71
- | identityMatrix householderVector i v vectorOfNormSquareds rank mx pivot matrixOfMinor |
74
+ | i vectorOfNormSquareds rank positionOfMaximum pivot matrixOfMinor |
72
75
vectorOfNormSquareds := matrixToDecompose columnsCollect: [
73
76
:columnVector | columnVector * columnVector ].
74
- mx := vectorOfNormSquareds indexOf: vectorOfNormSquareds max.
77
+ positionOfMaximum := vectorOfNormSquareds indexOf: vectorOfNormSquareds max.
75
78
pivot := Array new : vectorOfNormSquareds size.
76
79
rank := 0 .
77
- identityMatrix := PMSymmetricMatrix identity: colSize.
78
80
[
79
- | householderMatrix |
81
+ | householderReflection householderMatrix householderVector columnVectorFromRMatrix |
80
82
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 .
90
93
q := q * householderMatrix.
91
94
matrixOfMinor := r minor: rank - 1 and : rank - 1 .
92
95
matrixOfMinor := matrixOfMinor
@@ -95,9 +98,12 @@ PMQRDecomposition >> decomposeWithPivot [
95
98
* (householderVector at: 2 ) * matrixOfMinor).
96
99
matrixOfMinor rowsWithIndexDo: [ :aRow :index |
97
100
aRow withIndexDo: [ :element :column |
101
+ | rowNumber columnNumber |
102
+ rowNumber := rank + index - 1 .
103
+ columnNumber := rank + column - 1 .
98
104
r
99
- rowAt: rank + index - 1
100
- columnAt: rank + column - 1
105
+ rowAt: rowNumber
106
+ columnAt: columnNumber
101
107
put: ((element closeTo: 0 )
102
108
ifTrue: [ 0 ]
103
109
ifFalse: [ element ]) ] ].
@@ -109,29 +115,42 @@ PMQRDecomposition >> decomposeWithPivot [
109
115
- (r rowAt: rank columnAt: ind) squared ].
110
116
rank < vectorOfNormSquareds size
111
117
ifTrue: [
112
- mx := (vectorOfNormSquareds
118
+ positionOfMaximum := (vectorOfNormSquareds
113
119
copyFrom: rank + 1
114
120
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
117
123
ifTrue: [
118
- vectorOfNormSquareds indexOf: mx startingAt: rank + 1 ]
124
+ vectorOfNormSquareds indexOf: positionOfMaximum startingAt: rank + 1 ]
119
125
ifFalse: [ 0 ] ]
120
- ifFalse: [ mx := 0 ].
121
- mx > 0 ] whileTrue.
126
+ ifFalse: [ positionOfMaximum := 0 ].
127
+ positionOfMaximum > 0 ] whileTrue.
122
128
i := 0 .
123
129
[ (r rowAt: colSize) isZero ] whileTrue: [
124
130
i := i + 1 .
125
131
colSize := colSize - 1 ].
126
132
i > 0 ifTrue: [
127
- r := PMMatrix rows: (r rows copyFrom: 1 to: colSize) .
133
+ r := self upperTriangularPartOf: r With: colSize.
128
134
i := q numberOfColumns - i.
129
135
pivot := pivot copyFrom: 1 to: i.
130
136
q := PMMatrix rows:
131
- (q rows collect : [ :row | row copyFrom: 1 to: i ]) ].
137
+ (q rowsCollect : [ :row | row copyFrom: 1 to: i ]) ].
132
138
^ Array with: q with: r with: pivot
133
139
]
134
140
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
+
135
154
{ #category : #private }
136
155
PMQRDecomposition >> initialQMatrix [
137
156
@@ -158,3 +177,9 @@ PMQRDecomposition >> of: matrix [
158
177
r := self initialRMatrix.
159
178
q := self initialQMatrix.
160
179
]
180
+
181
+ { #category : #private }
182
+ PMQRDecomposition >> upperTriangularPartOf: matrix With: columnSize [
183
+
184
+ ^ PMMatrix rows: (r rows copyFrom: 1 to: columnSize)
185
+ ]
0 commit comments