{
"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
}