void QRSolver<T>::QRMethod(MathMatrix<T>& A, MathMatrix<T>& Q, UpTriangleMathMatrix<T>& R, int numIter) { for (int i = 0; i < numIter; ++i) { QRDecomposition(A, Q, R); A = ((i % 2 == 0) ? Q * R : R * Q); } }
int main() { // run a simpe test glm::mat3 A; // GLM stores matrices in column-major order so this initialization is the transpose of what we want A = glm::mat3( -0.558253, -0.0461681, -0.505735, -0.411397 , 0.0365854 , 0.199707, 0.285389 , -0.313789 , 0.200189); A = glm::transpose(A); std::cout << "original matrix" << std::endl; printMat3(A); /// 2. Symmetric Eigenanlysis // normal equations matrix glm::mat3 S = glm::transpose(A) * A; // std::cout << "normal equations matrix" << std::endl; // printMat3(S); glm::quat qV; jacobiEigenanalysis(S,qV); std::cout << "final S (diagonalized) " << std::endl; printMat3(S); std::cout << "cumulative rotation quaternion" << std::endl; printQuat(qV); glm::mat3 V = glm::toMat3(qV); // normalize qV, convert it to matrix //std::cout << "final rot matrix V" << std::endl; //printMat3(V); glm::mat3 B = A * V; // right-multiply A with V => left multiply for column major std::cout << "B=AV" << std::endl; //printMat3(B); ///// 3. Sorting the singular values (find V) sortSingularValues(B,V); //std::cout << "sorted B=AV" << std::endl; //printMat3(B); std::cout << "sorted V" << std::endl; printMat3(V); // // if columns 2-3 swapped, also update quaternion representation (i dont think we need to though since we're not tracking quats) ///// 4. QR factorization using Givens rotations (find U,S from B=AV) glm::mat3 U; glm::mat3 Sigma; QRDecomposition(B,U,Sigma); std::cout << "U" << std::endl; printMat3(U); std::cout << "Sigma" << std::endl; printMat3(Sigma); glm::mat3 USV = U * Sigma * glm::transpose(V); std::cout << "product USV'"<< std::endl; printMat3(USV); return 0; }
MathVector<T> QRSolver<T>::operator()(const IMathMatrix<T>& A, const MathVector<T>& b) const { UpTriangleMathMatrix<double> R(A.rows(), A.cols()); MathMatrix<T> Q(A.rows(), A.cols()); MathMatrix<T> input(A); QRDecomposition(input, Q, R); // Rx = Q^T*b MathMatrix<T> Qtranspose = Q.transpose(); MathVector<T> constants = Qtranspose * b; MathMatrix<T> augmented = GaussianEliminationSolver<T>::augmentedMatrix (R, constants); return GaussianEliminationSolver<T>::backSubstitution(augmented); }