9 template <
typename ScalarType>
void QRGivensDecomposition(vnl_matrix <ScalarType> &aMatrix, vnl_vector <ScalarType> &bVector)
11 unsigned int m = aMatrix.rows();
12 unsigned int n = aMatrix.cols();
17 bool applyQToB = (bVector.size() == m);
19 for (
unsigned int j = 0;j < n;++j)
21 for (
unsigned int i = m - 1;i >= j + 1;--i)
23 double bValue = aMatrix.get(i,j);
24 double aValue = aMatrix.get(j,j);
25 if (std::abs(bValue) <= std::numeric_limits <double>::epsilon())
29 double cosValue, sinValue;
30 double r = std::hypot(aValue,bValue);
31 cosValue = aValue / r;
32 sinValue = - bValue / r;
34 for (
unsigned int k = j;k < n;++k)
36 double ajkValue = aMatrix.get(j,k);
37 double aikValue = aMatrix.get(i,k);
38 double ajValue = cosValue * ajkValue - sinValue * aikValue;
39 double aiValue = sinValue * ajkValue + cosValue * aikValue;
41 aMatrix.put(j,k,ajValue);
42 aMatrix.put(i,k,aiValue);
47 double bjValue = cosValue * bVector[j] - sinValue * bVector[i];
48 double biValue = sinValue * bVector[j] + cosValue * bVector[i];
57 template <
typename ScalarType>
void QRPivotDecomposition(vnl_matrix <ScalarType> &aMatrix, std::vector <unsigned int> &pivotVector,
58 std::vector <ScalarType> &houseBetaValues,
unsigned int &rank)
60 unsigned int m = aMatrix.rows();
61 unsigned int n = aMatrix.cols();
66 pivotVector.resize(n);
67 houseBetaValues.resize(n);
69 for (
unsigned int i = 0;i < n;++i)
72 houseBetaValues[i] = 0.0;
75 std::vector <double> cVector(n,0.0);
76 for (
unsigned int i = 0;i < n;++i)
78 for (
unsigned int j = 0;j < m;++j)
80 double tmpVal = aMatrix.get(j,i);
81 cVector[i] += tmpVal * tmpVal;
86 double tau = cVector[0];
88 for (
unsigned int i = 1;i < n;++i)
97 std::vector <double> housedVector;
98 std::vector <double> housedTransposeA(n);
99 double epsilon = std::numeric_limits<double>::epsilon();
104 unsigned int r = rank - 1;
105 unsigned int tmpIndex = pivotVector[k];
106 pivotVector[k] = pivotVector[r];
107 pivotVector[r] = tmpIndex;
108 double tmp = cVector[k];
109 cVector[k] = cVector[r];
114 for (
unsigned int i = 0;i < m;++i)
117 aMatrix.put(i,k,aMatrix.get(i,r));
118 aMatrix.put(i,r,tmp);
122 housedVector.resize(m - r);
123 for (
unsigned int i = r;i < m;++i)
124 housedVector[i - r] = aMatrix.get(i,r);
128 double diagonalValueTest = 0.0;
129 for (
unsigned int l = r;l < m;++l)
131 double workMatrixHouseValue = 0.0;
132 unsigned int lIndex = l - r;
134 workMatrixHouseValue = - houseBetaValues[r] * housedVector[0] * housedVector[lIndex];
136 workMatrixHouseValue = 1.0 - houseBetaValues[r] * housedVector[0] * housedVector[0];
138 diagonalValueTest += workMatrixHouseValue * aMatrix.get(l,r);
143 if (std::abs(diagonalValueTest) < epsilon)
147 houseBetaValues[r] = 0.0;
148 tmpIndex = pivotVector[k];
149 pivotVector[k] = pivotVector[r];
150 pivotVector[r] = tmpIndex;
152 cVector[k] = cVector[r];
157 for (
unsigned int i = 0;i < m;++i)
159 tmp = aMatrix.get(i,k);
160 aMatrix.put(i,k,aMatrix.get(i,r));
161 aMatrix.put(i,r,tmp);
173 double basePower = std::floor(std::log(std::abs(diagonalValueTest)) / std::log(2.0));
174 epsilon *= 20.0 * (m + n) * std::pow(2.0,basePower);
177 for (
unsigned int i = 0;i < n - r;++i)
179 housedTransposeA[i] = 0.0;
180 for (
unsigned int j = 0;j < m - r;++j)
181 housedTransposeA[i] += housedVector[j] * aMatrix.get(j + r, i + r);
184 for (
unsigned int i = r;i < m;++i)
186 for (
unsigned int j = r;j < n;++j)
188 double tmpValue = aMatrix.get(i,j) - houseBetaValues[r] * housedVector[i - r] * housedTransposeA[j - r];
189 aMatrix.put(i,j,tmpValue);
193 for (
unsigned int i = rank;i < m;++i)
194 aMatrix.put(i,r,housedVector[i - r]);
196 for (
unsigned int i = rank;i < n;++i)
198 double tmpVal = aMatrix.get(r,i);
199 cVector[i] -= tmpVal * tmpVal;
209 for (
unsigned int i = rank + 1;i < n;++i)
211 if (tau < cVector[i])
222 std::vector <ScalarType> &houseBetaValues,
unsigned int rank)
224 unsigned int m = qrMatrix.rows();
225 unsigned int n = qrMatrix.cols();
230 for (
unsigned int j = 0;j < rank;++j)
233 double vtB = bVector[j];
234 for (
unsigned int i = j + 1;i < m;++i)
235 vtB += qrMatrix.get(i,j) * bVector[i];
238 bVector[j] -= houseBetaValues[j] * vtB;
240 for (
unsigned int i = j + 1;i < m;++i)
241 bVector[i] -= houseBetaValues[j] * qrMatrix.get(i,j) * vtB;
246 vnl_matrix <ScalarType> &qMatrix,
unsigned int rank)
248 unsigned int m = qrMatrix.rows();
249 unsigned int n = qrMatrix.cols();
254 qMatrix.set_size(m,m);
255 qMatrix.set_identity();
257 for (
int j = rank - 1;j >= 0;--j)
259 unsigned int vecSize = m - j;
260 vnl_vector <double> vtQ(vecSize);
263 for (
unsigned int i = 0;i < vecSize;++i)
265 vtQ[i] = qMatrix(j,i + j);
266 for (
unsigned int k = j + 1;k < m;++k)
267 vtQ[i] += qrMatrix.get(k,j) * qMatrix.get(k,i + j);
270 for (
unsigned int i = 0;i < vecSize;++i)
272 double constantValue = houseBetaValues[j];
274 constantValue *= qrMatrix.get(i + j,j);
276 for (
unsigned int k = 0;k < vecSize;++k)
278 double tmpVal = qMatrix.get(i + j,k + j) - constantValue * vtQ[k];
279 qMatrix.put(i + j,k + j,tmpVal);
void QRPivotDecomposition(vnl_matrix< ScalarType > &aMatrix, std::vector< unsigned int > &pivotVector, std::vector< ScalarType > &houseBetaValues, unsigned int &rank)
void GetQtBFromQRPivotDecomposition(vnl_matrix< ScalarType > &qrMatrix, vnl_vector< ScalarType > &bVector, std::vector< ScalarType > &houseBetaValues, unsigned int rank)
void QRGivensDecomposition(vnl_matrix< ScalarType > &aMatrix, vnl_vector< ScalarType > &bVector)
void GetQMatrixQRPivotDecomposition(vnl_matrix< ScalarType > &qrMatrix, std::vector< ScalarType > &houseBetaValues, vnl_matrix< ScalarType > &qMatrix, unsigned int rank)
void ComputeHouseholderVector(const VectorType &inputVector, VectorType &outputVector, double &beta, unsigned int dimension)