99 ' colSize' ,
1010 ' r' ,
1111 ' q' ,
12- ' comparisonPrecision '
12+ ' pivot '
1313 ],
1414 #category : ' Math-Matrix' ,
1515 #package : ' Math-Matrix'
@@ -22,18 +22,6 @@ PMQRDecomposition class >> of: matrix [
2222 ^ self new of: matrix
2323]
2424
25- { #category : ' constants' }
26- PMQRDecomposition >> comparisonPrecision [
27-
28- ^ comparisonPrecision ifNil: [ self defaultComparisonPrecision ]
29- ]
30-
31- { #category : ' accessing' }
32- PMQRDecomposition >> comparisonPrecision: anObject [
33-
34- comparisonPrecision := anObject
35- ]
36-
3725{ #category : ' arithmetic' }
3826PMQRDecomposition >> decompose [
3927 "
@@ -74,79 +62,58 @@ https://en.wikipedia.org/wiki/QR_decomposition#Using_Householder_reflections
7462{ #category : ' arithmetic' }
7563PMQRDecomposition >> decomposeWithPivot [
7664
77- | i vectorOfNormSquareds rank positionOfMaximum pivot matrixOfMinor |
78- vectorOfNormSquareds := matrixToDecompose columnsCollect: [
79- :columnVector | columnVector * columnVector ].
65+ | i vectorOfNormSquareds rank positionOfMaximum matrixOfMinor |
66+ vectorOfNormSquareds := matrixToDecompose columnsCollect: [ :columnVector | columnVector * columnVector ].
8067 positionOfMaximum := vectorOfNormSquareds indexOf: vectorOfNormSquareds max.
81- pivot := Array new : vectorOfNormSquareds size.
68+ pivot := ( 1 to : vectorOfNormSquareds size) asArray .
8269 rank := 0 .
83- [
84- | householderReflection householderMatrix householderVector columnVectorFromRMatrix |
85- rank := rank + 1 .
86- pivot at: rank put: positionOfMaximum.
87- r swapColumn: rank withColumn: positionOfMaximum.
88- vectorOfNormSquareds swap: rank with: positionOfMaximum.
89- columnVectorFromRMatrix := r columnVectorAt: rank size: colSize.
90- householderReflection := self
91- householderReflectionOf:
92- columnVectorFromRMatrix
93- atColumnNumber: rank.
94- householderVector := householderReflection at: 1 .
95- householderMatrix := householderReflection at: 2 .
96- q := q * householderMatrix.
97- matrixOfMinor := r minor: rank - 1 and : rank - 1 .
98- matrixOfMinor := matrixOfMinor
99- - ((householderVector at: 2 ) tensorProduct:
100- (householderVector at: 1 )
101- * (householderVector at: 2 ) * matrixOfMinor).
102- matrixOfMinor rowsWithIndexDo: [ :aRow :index |
103- aRow withIndexDo: [ :element :column |
104- | rowNumber columnNumber |
105- rowNumber := rank + index - 1 .
106- columnNumber := rank + column - 1 .
107- r
108- rowAt: rowNumber
109- columnAt: columnNumber
110- put: ((element closeTo: 0 )
111- ifTrue: [ 0 ]
112- ifFalse: [ element ]) ] ].
113- rank + 1 to: vectorOfNormSquareds size do: [ :ind |
114- vectorOfNormSquareds
115- at: ind
116- put:
117- (vectorOfNormSquareds at: ind)
118- - (r rowAt: rank columnAt: ind) squared ].
119- rank < vectorOfNormSquareds size
120- ifTrue: [
121- positionOfMaximum := (vectorOfNormSquareds
122- copyFrom: rank + 1
123- to: vectorOfNormSquareds size) max.
124- (positionOfMaximum closeTo: 0 precision: self comparisonPrecision) ifTrue: [ positionOfMaximum := 0 ].
125- positionOfMaximum := positionOfMaximum > 0
126- ifTrue: [
127- vectorOfNormSquareds indexOf: positionOfMaximum startingAt: rank + 1 ]
128- ifFalse: [ 0 ] ]
129- ifFalse: [ positionOfMaximum := 0 ].
130- positionOfMaximum > 0 ] whileTrue.
70+ [
71+ | temp householderReflection householderMatrix householderVector columnVectorFromRMatrix |
72+ rank := rank + 1 .
73+ temp := pivot at: rank.
74+ pivot at: rank put: (pivot at: positionOfMaximum).
75+ pivot at: positionOfMaximum put: temp.
76+
77+ r swapColumn: rank withColumn: positionOfMaximum.
78+ vectorOfNormSquareds swap: rank with: positionOfMaximum.
79+ columnVectorFromRMatrix := r columnVectorAt: rank size: colSize.
80+ householderReflection := self householderReflectionOf: columnVectorFromRMatrix atColumnNumber: rank.
81+ householderVector := householderReflection first.
82+ householderMatrix := householderReflection second.
83+ q := q * householderMatrix.
84+ matrixOfMinor := r minor: rank - 1 and : rank - 1 .
85+ matrixOfMinor := matrixOfMinor
86+ - (householderVector second tensorProduct: householderVector first * householderVector second * matrixOfMinor).
87+ matrixOfMinor rowsWithIndexDo: [ :aRow :index |
88+ aRow withIndexDo: [ :element :column |
89+ | rowNumber columnNumber |
90+ rowNumber := rank + index - 1 .
91+ columnNumber := rank + column - 1 .
92+ r rowAt: rowNumber columnAt: columnNumber put: ((element closeTo: 0 )
93+ ifTrue: [ 0 ]
94+ ifFalse: [ element ]) ] ].
95+ rank + 1 to: vectorOfNormSquareds size do: [ :ind |
96+ vectorOfNormSquareds at: ind put: (vectorOfNormSquareds at: ind) - (r rowAt: rank columnAt: ind) squared ].
97+ rank < vectorOfNormSquareds size
98+ ifTrue: [
99+ positionOfMaximum := (vectorOfNormSquareds copyFrom: rank + 1 to: vectorOfNormSquareds size) max.
100+ (positionOfMaximum closeTo: 0 ) ifTrue: [ positionOfMaximum := 0 ].
101+ positionOfMaximum := positionOfMaximum > 0
102+ ifTrue: [ vectorOfNormSquareds indexOf: positionOfMaximum startingAt: rank + 1 ]
103+ ifFalse: [ 0 ] ]
104+ ifFalse: [ positionOfMaximum := 0 ].
105+ positionOfMaximum > 0 ] whileTrue.
131106 i := 0 .
132- [ (r rowAt: colSize) isZero ] whileTrue: [
133- i := i + 1 .
134- colSize := colSize - 1 ].
135- i > 0 ifTrue: [
136- r := self upperTriangularPartOf: r With: colSize.
137- i := q numberOfColumns - i.
138- pivot := pivot copyFrom: 1 to: i.
139- q := PMMatrix rows:
140- (q rowsCollect: [ :row | row copyFrom: 1 to: i ]) ].
107+ [ (r rowAt: colSize) isZero ] whileTrue: [
108+ i := i + 1 .
109+ colSize := colSize - 1 ].
110+ i > 0 ifTrue: [
111+ r := self upperTriangularPartOf: r With: colSize.
112+ i := q numberOfColumns - i.
113+ q := PMMatrix rows: (q rowsCollect: [ :row | row copyFrom: 1 to: i ]) ].
141114 ^ Array with: q with: r with: pivot
142115]
143116
144- { #category : ' constants' }
145- PMQRDecomposition >> defaultComparisonPrecision [
146-
147- ^ 0.0001
148- ]
149-
150117{ #category : ' private' }
151118PMQRDecomposition >> householderReflectionOf: columnVector atColumnNumber: columnNumber [
152119
0 commit comments