{ "cells": [ { "cell_type": "markdown", "id": "df1bd85d", "metadata": {}, "source": [ "# decomposeQR\n", "This tutorial shows how to decompose a matrix A in an orthogonal matrix Q and an upper\n", "triangular matrix R using QR Householder decomposition with the TDecompQRH class.\n", "The matrix same matrix as in this example is used: https://en.wikipedia.org/wiki/QR_decomposition#Example_2\n", "\n", "\n", "**Author:** \n", "This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:26 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "794e1aac", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:26:05.605693Z", "iopub.status.busy": "2026-05-19T20:26:05.605559Z", "iopub.status.idle": "2026-05-19T20:26:06.096315Z", "shell.execute_reply": "2026-05-19T20:26:06.095936Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "initial matrox A \n", "\n", "3x3 matrix is as follows\n", "\n", " | 0 | 1 | 2 |\n", "--------------------------------------------\n", " 0 | 12 -51 4 \n", " 1 | 6 167 -68 \n", " 2 | -4 24 -41 \n", "\n", "Orthogonal Q matrix \n" ] } ], "source": [ "const int n = 3;\n", "\n", "\n", "double a[] = {12, -51, 4, 6, 167, -68, -4, 24, -41};\n", "\n", "TMatrixT A(3, 3, a);\n", "\n", "std::cout << \"initial matrox A \" << std::endl;\n", "\n", "A.Print();\n", "\n", "TDecompQRH decomp(A);\n", "\n", "bool ret = decomp.Decompose();\n", "\n", "std::cout << \"Orthogonal Q matrix \" << std::endl;" ] }, { "cell_type": "markdown", "id": "fbec9db4", "metadata": {}, "source": [ "note that decomp.GetQ() returns an intenrnal matrix which is not Q defined as A = QR" ] }, { "cell_type": "code", "execution_count": 2, "id": "882d1799", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:26:06.103794Z", "iopub.status.busy": "2026-05-19T20:26:06.103664Z", "iopub.status.idle": "2026-05-19T20:26:06.311037Z", "shell.execute_reply": "2026-05-19T20:26:06.310390Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "3x3 matrix is as follows\n", "\n", " | 0 | 1 | 2 |\n", "--------------------------------------------\n", " 0 | -0.8571 0.3943 0.3314 \n", " 1 | -0.4286 -0.9029 -0.03429 \n", " 2 | 0.2857 -0.1714 0.9429 \n", "\n", "Upper Triangular R matrix \n", "\n", "3x3 matrix is as follows\n", "\n", " | 0 | 1 | 2 |\n", "--------------------------------------------\n", " 0 | -14 -21 14 \n", " 1 | 0 -175 70 \n", " 2 | 0 0 -35 \n", "\n" ] } ], "source": [ "auto Q = decomp.GetOrthogonalMatrix();\n", "Q.Print();\n", "\n", "std::cout << \"Upper Triangular R matrix \" << std::endl;\n", "auto R = decomp.GetR();\n", "\n", "R.Print();" ] }, { "cell_type": "markdown", "id": "f98b8e66", "metadata": {}, "source": [ "check that we have a correct Q-R decomposition" ] }, { "cell_type": "code", "execution_count": 3, "id": "b198dfe3", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:26:06.312583Z", "iopub.status.busy": "2026-05-19T20:26:06.312468Z", "iopub.status.idle": "2026-05-19T20:26:06.514976Z", "shell.execute_reply": "2026-05-19T20:26:06.514446Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Computed A matrix from Q * R \n", "\n", "3x3 matrix is as follows\n", "\n", " | 0 | 1 | 2 |\n", "--------------------------------------------\n", " 0 | 12 -51 4 \n", " 1 | 6 167 -68 \n", " 2 | -4 24 -41 \n", "\n" ] } ], "source": [ "TMatrixT compA = Q * R;\n", "\n", "std::cout << \"Computed A matrix from Q * R \" << std::endl;\n", "compA.Print();\n", "\n", "for (int i = 0; i < A.GetNrows(); ++i) {\n", " for (int j = 0; j < A.GetNcols(); ++j) {\n", " if (!TMath::AreEqualAbs( compA(i,j), A(i,j), 1.E-6) )\n", " Error(\"decomposeQR\",\"Reconstrate matrix is not equal to the original : %f different than %f\",compA(i,j),A(i,j));\n", " }\n", "}" ] }, { "cell_type": "markdown", "id": "e56cef12", "metadata": {}, "source": [ "chech also that Q is orthogonal (Q^T * Q = I)" ] }, { "cell_type": "code", "execution_count": 4, "id": "b616d7b1", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:26:06.516805Z", "iopub.status.busy": "2026-05-19T20:26:06.516690Z", "iopub.status.idle": "2026-05-19T20:26:06.718953Z", "shell.execute_reply": "2026-05-19T20:26:06.718246Z" } }, "outputs": [], "source": [ "auto QT = Q;\n", "QT.Transpose(Q);\n", "\n", "auto qtq = QT * Q;\n", "for (int i = 0; i < Q.GetNrows(); ++i) {\n", " for (int j = 0; j < Q.GetNcols(); ++j) {\n", " if ((i == j && !TMath::AreEqualAbs(qtq(i, i), 1., 1.E-6)) ||\n", " (i != j && !TMath::AreEqualAbs(qtq(i, j), 0., 1.E-6))) {\n", " Error(\"decomposeQR\", \"Q matrix is not orthogonal \");\n", " qtq.Print();\n", " break;\n", " }\n", " }\n", "}" ] } ], "metadata": { "kernelspec": { "display_name": "ROOT C++", "language": "c++", "name": "root" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".C", "mimetype": " text/x-c++src", "name": "c++" } }, "nbformat": 4, "nbformat_minor": 5 }