{"id":432,"date":"2016-02-23T14:49:12","date_gmt":"2016-02-23T14:49:12","guid":{"rendered":"http:\/\/drsfenner.org\/blog\/?p=432"},"modified":"2016-02-23T14:50:27","modified_gmt":"2016-02-23T14:50:27","slug":"householder-reflections-and-qr","status":"publish","type":"post","link":"https:\/\/drsfenner.org\/blog\/2016\/02\/householder-reflections-and-qr\/","title":{"rendered":"Householder Reflections and QR"},"content":{"rendered":"<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>My next two or three posts are going to deal with the QR and SVD techniques. QR can be done in several different ways. I&#8217;m going to work through two methods of computing QR that will shed some light on our SVD implementation. So, these two topics dovetail nicely. Onward!<!--more--><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<h3 id=\"qr-via-householder-matrices\">QR via Householder Matrices<\/h3>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>For our first method, <code>HouseholderQR<\/code>, we are going to use Householder vectors and matrices. We talked about these a bit when we <a href=\"\">generated random symmetric positive definite matrices<\/a> to test our Cholesky implementation. They&#8217;re baaaaaaaack.<\/p>\n<p>Here&#8217;s a quick reminder. Householder matrices look like <span class=\"math inline\">\\(H = I &#8211; 2vv^T\\)<\/span> for <span class=\"math inline\">\\(v\\)<\/span> an <span class=\"math inline\">\\(n\\)<\/span>-element column-vector. <span class=\"math inline\">\\(H\\)<\/span> is shaped <span class=\"math inline\">\\(n \\times n\\)<\/span>. <span class=\"math inline\">\\(H\\)<\/span> is orthogonal (also, unitary &#8211; not Unitarian &#8211; but we aren&#8217;t discussing either). We only made use of the <em>orthogonality<\/em> of Householder matrices, but they have other nice properties too. Today, the property that is most important to us is that Householders can be used to transform a nonzero vector into a vector with mostly zeros (all but one entry will be zero), and likewise, for rows\/columns of a matrix. Since <span class=\"math inline\">\\(QR\\)<\/span> produces an upper-triangular <span class=\"math inline\">\\(R\\)<\/span>, we want lots of zeros. I&#8217;m going to attack this problem algebraically; if you&#8217;d like to see a geometric take on constructing the Householder form, check out <a href=\"http:\/\/johnkerl.org\/doc\/hh.pdf\">pages 11- 12 here<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<h3 id=\"im-your-zero\">I&#8217;m Your Zero<\/h3>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Here&#8217;s how zeros get introduced. If we have a column vector <span class=\"math inline\">\\(\\vec{x}{\\in}\\mathbb{R}^n\\)<\/span>, we would like to find <span class=\"math inline\">\\(\\vec{Hx}=\\vec{y}\\ {\\in}\\ \\mathbb{R}^n\\)<\/span> with the properties that <span class=\"math inline\">\\(y_1\\)<\/span> is some fixed scalar value (we&#8217;ll call it <span class=\"math inline\">\\(\\alpha\\)<\/span>) and the other values are 0. I&#8217;ll use <span class=\"math inline\">\\(\\vec{0_n}\\)<\/span> for a vector of <span class=\"math inline\">\\(n\\)<\/span> zeros, and <span class=\"math inline\">\\(\\vec{e}_{i,n}\\)<\/span> for the <span class=\"math inline\">\\(i\\)<\/span>-th standard basis vector in <span class=\"math inline\">\\(\\mathbb{R}^n\\)<\/span>. I apologize for using 1-based indexing in the math and 0-based indexing in the code. Mea culpa.<\/p>\n<p><span class=\"math inline\">\\(\\renewcommand{\\vec}[1]{\\mathbf{#1}}\\renewcommand{\\norm}[1]{\\|\\vec{#1}\\|}\\renewcommand{\\abs}[1]{\\left\\lvert#1\\right\\lvert}\\)<\/span><\/p>\n<p><span class=\"math display\">\\[<br \/>\ny_i= \\begin{cases}<br \/>\n    \\alpha &amp; i = 1 \\\\<br \/>\n    0 &amp; i \\neq 1<br \/>\n    \\end{cases}<br \/>\n    \\hspace{.5 in} \\text{and} \\hspace{.5 in}<br \/>\n    \\vec{y} = \\left[\\begin{array}{c}{\\alpha \\\\ \\mathbf{0_{n-1}}}\\end{array}\\right] = \\vec{e}_{1,n} \\alpha<br \/>\n\\]<\/span><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p><span class=\"math inline\">\\(\\vec{H}\\)<\/span> is a hint that we&#8217;re going to use a Householder matrix to map from <span class=\"math inline\">\\(\\vec{x}\\rightarrow\\vec{y}\\)<\/span>. So, take <span class=\"math inline\">\\(H\\)<\/span> as a Householder matrix. <span class=\"math inline\">\\(H\\)<\/span> is orthogonal which means <span class=\"math inline\">\\(\\vec{H}\\)<\/span> preserves vector length (we&#8217;re using the 2-norm): <span class=\"math inline\">\\(\\norm{\\vec{Hx}}=\\norm{\\vec{x}}\\)<\/span>. Together with the fact that most of <span class=\"math inline\">\\(\\vec{y}\\)<\/span> is zero which gives us <span class=\"math inline\">\\(\\norm{\\vec{y}}=\\abs{y_1}\\)<\/span>, we get <span class=\"math inline\">\\(\\norm{\\vec{x}} = \\abs{y_1} = \\abs{\\alpha}\\)<\/span>. If we take the postive root, we now know that <span class=\"math inline\">\\(\\alpha\\)<\/span> is equal to the length of <span class=\"math inline\">\\(\\vec{x}\\)<\/span>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Let&#8217;s turn our attention to <span class=\"math inline\">\\(\\vec{Hx}\\)<\/span> and apply the expanded Householder form:<\/p>\n<p><span class=\"math display\">\\[\\begin{align}<br \/>\n\\vec{Hx} &amp;= \\left(\\vec{I} &#8211; \\frac{2\\vec{vv^T}}{\\vec{v^Tv}}\\right)\\vec{x}  \\\\<br \/>\n         &amp;= \\vec{x} &#8211; \\frac{2\\vec{vv^Tx}}{\\vec{v^Tv}} &amp; \\vec{v^Tx},\\vec{vv^T} \\text{are scalars} \\\\<br \/>\n                &amp;= \\vec{x} &#8211; C\\vec{v} = \\vec{y} = \\left[\\begin{array}{c}{\\alpha \\\\ \\mathbf{0_{n-1}}}\\end{array}\\right] &amp; C = 2\\frac{\\vec{v^Tx}}{\\vec{v^Tv}}<br \/>\n\\end{align}<br \/>\n\\]<\/span><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Now, the value of <span class=\"math inline\">\\(C\\)<\/span> is a function of both <span class=\"math inline\">\\(\\vec{v}\\)<\/span> and <span class=\"math inline\">\\(\\vec{x}\\)<\/span>. But, all we need is <em>one satisfactory<\/em> <span class=\"math inline\">\\(\\vec{v}\\)<\/span>. And, if we can pick the form of <span class=\"math inline\">\\(\\vec{v}\\)<\/span> nicely, we won&#8217;t have to do much work to create it from <span class=\"math inline\">\\(\\vec{x}\\)<\/span>. Simplicity and simple thoughts lead to numbers like one and zero. Zero seems right out, but what about <span class=\"math inline\">\\(C=1\\)<\/span>? Let&#8217;s add a constraint that <span class=\"math inline\">\\(C=1\\)<\/span> and see if we end up with a consistent result. So:<\/p>\n<p><span class=\"math display\">\\[<br \/>\n\\begin{align}<br \/>\n\\vec{y} = \\vec{x}-\\vec{v} = \\left[\\begin{array}{c}{\\alpha \\\\ \\mathbf{0_{n-1}}}\\end{array}\\right]<br \/>\n\\qquad \\implies \\qquad<br \/>\ny_i = x_i &#8211; v_i = \\begin{cases}<br \/>\n\\alpha = \\norm{x} &amp; i = 1\\\\<br \/>\n0 &amp; i \\neq 1<br \/>\n\\end{cases}<br \/>\n\\end{align}<br \/>\n\\]<\/span><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>So, the elements of our (hopefull) <span class=\"math inline\">\\(\\vec{v}\\)<\/span> are given by: <span class=\"math inline\">\\(v_1 = x_1 &#8211; \\alpha = x_1 &#8211; \\norm{x}\\)<\/span> and <span class=\"math inline\">\\(v_{i \\dots n} = x_{i \\dots n}\\)<\/span>. Now, since we pulled <span class=\"math inline\">\\(C\\)<\/span> out of a hat, we need to confirm that the values of <span class=\"math inline\">\\(\\vec{v}\\)<\/span> and <span class=\"math inline\">\\(\\vec{x}\\)<\/span> yield our <span class=\"math inline\">\\(C=1\\)<\/span>. To simplify things, let&#8217;s note that the dot-product of <span class=\"math inline\">\\(\\vec{x}\\)<\/span> with itself, over all but its first element, is <span class=\"math inline\">\\(d_{2{\\dots}n}=\\sum_{i=2}^n x_i^2 = \\norm{x}^2 &#8211; x_1^2\\)<\/span>.<\/p>\n<p>Now we have, <span class=\"math display\">\\[\\begin{align}<br \/>\n\\vec{v^Tv} &amp;= v_1^2 + d_{2{\\dots}n} \\\\<br \/>\n           &amp;= (x_1 &#8211; \\norm{x})^2 + \\norm{x}^2 &#8211; x_1^2 \\\\<br \/>\n           &amp;= x_1^2 &#8211; 2x_1\\norm{x} + \\norm{x}^2 + \\norm{x}^2 &#8211; x_1^2 \\\\<br \/>\n           &amp;= 2\\norm{x}^2 &#8211; 2x_1\\norm{x} \\\\<br \/>\n           &amp; =2(\\norm{x}^2 &#8211; x_1\\norm{x})<br \/>\n\\end{align}\\]<\/span><\/p>\n<p>and<\/p>\n<p><span class=\"math display\">\\[\\begin{align}<br \/>\n\\vec{v^Tx} &amp;= v_1x_1 + d_{2{\\dots}n}  \\\\<br \/>\n           &amp;= (x_1 &#8211; \\norm{x})x_1 + (\\norm{x}^2 &#8211; x_1^2) \\\\<br \/>\n           &amp;= x_1^2 &#8211; x_1\\norm{x} + \\norm{x}^2 &#8211; x_1^2 \\\\<br \/>\n           &amp;= \\norm{x}^2 &#8211; x_1\\norm{x}<br \/>\n\\end{align}\\]<\/span><\/p>\n<p>So, <span class=\"math inline\">\\(\\frac{2\\vec{v^Tx}}{\\vec{v^Tv}} = \\frac{2 (\\norm{x}^2 &#8211; x_1\\norm{x})}{2(\\norm{x}^2 &#8211; x_1\\norm{x})}=1\\)<\/span> which means our vectors magically &#8211; well, I&#8217;m sure there is a nice linear algebra based proof about why that works &#8211; are consistent with <span class=\"math inline\">\\(C=1\\)<\/span>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<h3 id=\"codin\">Codin&#8217;<\/h3>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>The punchline of this is that we can make <span class=\"math inline\">\\(\\vec{v}\\)<\/span> very easily from <span class=\"math inline\">\\(\\vec{x}\\)<\/span>: copy it and replace the first element with <span class=\"math inline\">\\(\\norm{x}\\)<\/span>. And presto, we have a Householder matrix that will annihilate (zero) the other elements of <span class=\"math inline\">\\(\\vec{x}\\)<\/span>. I&#8217;m getting code-hungry. Too many math-carbs. We need just a few last points to tie the mathematics to the code.<\/p>\n<p>If we normalize <span class=\"math inline\">\\(\\vec{v}\\)<\/span> so that <span class=\"math inline\">\\(v_1=1\\)<\/span> then we can store our <span class=\"math inline\">\\(\\vec{v}\\)<\/span> in <span class=\"math inline\">\\(n-1\\)<\/span> slots by knowing the <span class=\"math inline\">\\(1\\)<\/span> is there implicitly. This will be very handy for reusing memory, if we are willing to overwrite an input matrix. As we produce an upper triangular <span class=\"math inline\">\\(R\\)<\/span>, we can store the <span class=\"math inline\">\\(Q\\)<\/span> (which is a sequence of <span class=\"math inline\">\\(\\vec{H}\\)<\/span>s coming from a sequence of <span class=\"math inline\">\\(\\vec{v}\\)<\/span>s) in the lower triangular portion of the input matrix. In our code, we will use a normalized <span class=\"math inline\">\\(\\vec{v}\\)<\/span>: <span class=\"math inline\">\\(\\vec{v}_{code} = \\vec{v}\/v_1\\)<\/span>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>We also have a strange <span class=\"math inline\">\\(\\beta\\)<\/span> running through our code. It comes from G&amp;VL and it shows up all over the place in LAPACK. So, let&#8217;s explain where it comes from. <span class=\"math inline\">\\(\\renewcommand{\\nvec}[2]{\\vec{#1}_\\mathrm{#2}}\\)<\/span><\/p>\n<p>Using the normalized <span class=\"math inline\">\\(\\nvec{v}{code}\\)<\/span>:<\/p>\n<p><span class=\"math display\">\\[\\nvec{H}{code}=\\left(\\vec{I} &#8211; \\frac{2\\nvec{v}{code}\\nvec{v}{code}^T}{\\nvec{v}{code}^T\\nvec{v}{code}}\\right)=\\left(\\vec{I}-\\beta\\nvec{v}{code}\\nvec{v}{code}^T\\right)\\]<\/span><\/p>\n<p>What is <span class=\"math inline\">\\(\\beta\\)<\/span>? Well,<\/p>\n<p><span class=\"math display\">\\[\\beta=\\frac{2}{\\nvec{v}{code}^T\\nvec{v}{code}}<br \/>\n=\\frac{2}{\\frac{v_1^2}{v_1^2} + \\frac{1}{v_1^2}\\left( d_{2{\\dots}n}\\right)}<br \/>\n=\\frac{2v_1^2}{v_1^2 + d_{2{\\dots}n}}\\]<\/span><\/p>\n<p>To reconstruct our <span class=\"math inline\">\\(\\vec{H}\\)<\/span> properly, we will need both <span class=\"math inline\">\\(\\beta\\)<\/span> and <span class=\"math inline\">\\(\\nvec{v}{code}\\)<\/span> . Last note (really!), it turns out that <span class=\"math inline\">\\(v_1 = x_1 &#8211; \\norm{x}\\)<\/span> can get us into numerical trouble if the <span class=\"math inline\">\\(\\vec{x}\\)<\/span> is very close to a multiple of the identity vector &#8212; that is, almost all of <span class=\"math inline\">\\(\\vec{v}\\)<\/span> is in <span class=\"math inline\">\\(x_1\\)<\/span>. If that is the case, <span class=\"math inline\">\\(x_1 &#8211; \\norm{x}\\)<\/span> will be very close to zero and we may encounter numerical errors. A formula by Parlett resolves this.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<h3 id=\"householder-vectors\">Householder Vectors<\/h3>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[1]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"kn\">from<\/span> <span class=\"nn\">math<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">sqrt<\/span>\n<span class=\"kn\">import<\/span> <span class=\"nn\">numpy<\/span> <span class=\"kn\">as<\/span> <span class=\"nn\">np<\/span>\n<span class=\"kn\">import<\/span> <span class=\"nn\">numpy.linalg<\/span> <span class=\"kn\">as<\/span> <span class=\"nn\">nla<\/span>\n<span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">set_printoptions<\/span><span class=\"p\">(<\/span><span class=\"n\">suppress<\/span><span class=\"o\">=<\/span><span class=\"bp\">True<\/span><span class=\"p\">)<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[2]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"c1\"># G&amp;vL 3rd pg. 210<\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">make_house_vec<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">):<\/span>\n    <span class=\"n\">n<\/span> <span class=\"o\">=<\/span> <span class=\"n\">x<\/span><span class=\"o\">.<\/span><span class=\"n\">shape<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n    <span class=\"n\">dot_1on<\/span> <span class=\"o\">=<\/span> <span class=\"n\">x<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">:]<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">:])<\/span>\n\n    <span class=\"c1\"># v is our return vector; we hack on v[0]<\/span>\n    <span class=\"n\">v<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">copy<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"mf\">1.0<\/span>\n    \n    <span class=\"k\">if<\/span> <span class=\"n\">dot_1on<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">finfo<\/span><span class=\"p\">(<\/span><span class=\"nb\">float<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">eps<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">beta<\/span> <span class=\"o\">=<\/span> <span class=\"mf\">0.0<\/span>\n    <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n        <span class=\"c1\"># apply Parlett&#39;s formula (G&amp;vL page 210) for safe v_0 = x_0 - norm(X) <\/span>\n        <span class=\"n\">norm_x<\/span><span class=\"o\">=<\/span> <span class=\"n\">sqrt<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span><span class=\"o\">**<\/span><span class=\"mi\">2<\/span> <span class=\"o\">+<\/span> <span class=\"n\">dot_1on<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">x<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">x<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"o\">-<\/span> <span class=\"n\">norm_x<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"o\">-<\/span><span class=\"n\">dot_1on<\/span> <span class=\"o\">\/<\/span> <span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"o\">+<\/span> <span class=\"n\">norm_x<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">beta<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">2<\/span> <span class=\"o\">*<\/span> <span class=\"n\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span><span class=\"o\">**<\/span><span class=\"mi\">2<\/span> <span class=\"o\">\/<\/span> <span class=\"p\">(<\/span><span class=\"n\">dot_1on<\/span> <span class=\"o\">+<\/span> <span class=\"n\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span><span class=\"o\">**<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">v<\/span> <span class=\"o\">=<\/span> <span class=\"n\">v<\/span> <span class=\"o\">\/<\/span> <span class=\"n\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">v<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[3]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"n\">A<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">array<\/span><span class=\"p\">([[<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">],<\/span>\n              <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">],<\/span>\n              <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">]],<\/span> <span class=\"n\">dtype<\/span><span class=\"o\">=<\/span><span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">float64<\/span><span class=\"p\">)<\/span>\n\n\n<span class=\"n\">v<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta<\/span> <span class=\"o\">=<\/span> <span class=\"n\">make_house_vec<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">[:,<\/span><span class=\"mi\">0<\/span><span class=\"p\">])<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">beta<\/span><span class=\"p\">,<\/span> <span class=\"n\">v<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"output_wrapper\">\n<div class=\"output\">\n<div class=\"output_area\">\n<div class=\"prompt\"><\/div>\n<div class=\"output_subarea output_stream output_stdout output_text\">\n<pre>0.0571909584179 [ 1.         -4.12132034 -4.12132034]\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>If you remember, the whole point of this exercise was to introduce zeros into <span class=\"math inline\">\\(x\\)<\/span> (and eventually, into a column of <span class=\"math inline\">\\(\\vec{A}\\)<\/span>). Because we&#8217;ve done some massaging to the form of <span class=\"math inline\">\\(v\\)<\/span> and since <span class=\"math inline\">\\(v\\)<\/span> and <span class=\"math inline\">\\(\\beta\\)<\/span> are used together to define our <span class=\"math inline\">\\(H\\)<\/span> (that actually does the transformation to a multiple of a basis vector (<span class=\"math inline\">\\(e_{1,n}\\)<\/span>), we need to extract out the full <span class=\"math inline\">\\(\\vec{H}\\)<\/span> to apply it to <span class=\"math inline\">\\(v\\)<\/span>. We do that by using the definition of <span class=\"math inline\">\\(H\\)<\/span> from above. Here we do it for a single Householder vector:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[4]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"k\">def<\/span> <span class=\"nf\">fullH_1d<\/span><span class=\"p\">(<\/span><span class=\"n\">v<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta<\/span><span class=\"p\">):<\/span>\n    <span class=\"n\">n<\/span> <span class=\"o\">=<\/span> <span class=\"n\">v<\/span><span class=\"o\">.<\/span><span class=\"n\">shape<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">eye<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">)<\/span> <span class=\"o\">-<\/span> <span class=\"n\">beta<\/span> <span class=\"o\">*<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">outer<\/span><span class=\"p\">(<\/span><span class=\"n\">v<\/span><span class=\"p\">,<\/span><span class=\"n\">v<\/span><span class=\"p\">)<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>And we apply <span class=\"math inline\">\\(H\\)<\/span> to <span class=\"math inline\">\\(A\\)<\/span> to get <span class=\"math inline\">\\(HA\\)<\/span>:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[5]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"n\">H<\/span> <span class=\"o\">=<\/span> <span class=\"n\">fullH_1d<\/span><span class=\"p\">(<\/span><span class=\"n\">v<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">H<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"output_wrapper\">\n<div class=\"output\">\n<div class=\"output_area\">\n<div class=\"prompt output_prompt\">Out[5]:<\/div>\n<div class=\"output_text output_subarea output_execute_result\">\n<pre>array([[ 4.24264069,  2.12132034,  2.12132034],\n       [ 0.        , -0.62132034, -3.62132034],\n       [ 0.        , -3.62132034, -0.62132034]])<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<h3 id=\"on-to-qr\">On to <span class=\"math inline\">\\(QR\\)<\/span><\/h3>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>If we do that a few times in a row (well, actually across the columns), we&#8217;re going end up with zeros below the diagonal &#8212; which is exactly the <span class=\"math inline\">\\(R\\)<\/span> (upper triangular) matrix we&#8217;re seeking for <span class=\"math inline\">\\(QR\\)<\/span>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[6]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"c1\"># householder QR .. G&amp;VL 3rd pg 224<\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">house_qr<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">):<\/span>\n    <span class=\"sd\">&#39;&#39;&#39; <\/span>\n<span class=\"sd\">        update A in place with QR ... R is upper triangular (at and above diagonal)<\/span>\n<span class=\"sd\">        below the diagonal, A holds the &quot;essential&quot; parts of the Householder vectors.<\/span>\n<span class=\"sd\">        the essential part gets shorter because they are only applied to the remaining<\/span>\n<span class=\"sd\">        bottom right square of A<\/span>\n<span class=\"sd\">    &#39;&#39;&#39;<\/span>\n    <span class=\"n\">m<\/span><span class=\"p\">,<\/span><span class=\"n\">n<\/span> <span class=\"o\">=<\/span> <span class=\"n\">A<\/span><span class=\"o\">.<\/span><span class=\"n\">shape<\/span>\n    <span class=\"n\">betas<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">empty<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">j<\/span> <span class=\"ow\">in<\/span> <span class=\"nb\">range<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">):<\/span>\n        <span class=\"n\">v<\/span><span class=\"p\">,<\/span> <span class=\"n\">betas<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">make_house_vec<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"p\">:,<\/span> <span class=\"n\">j<\/span><span class=\"p\">])<\/span>\n        <span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"p\">:,<\/span><span class=\"n\">j<\/span><span class=\"p\">:]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">eye<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"o\">-<\/span><span class=\"n\">j<\/span><span class=\"p\">)<\/span> <span class=\"o\">-<\/span> <span class=\"n\">betas<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"p\">]<\/span> <span class=\"o\">*<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">outer<\/span><span class=\"p\">(<\/span><span class=\"n\">v<\/span><span class=\"p\">,<\/span><span class=\"n\">v<\/span><span class=\"p\">))<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"p\">:,<\/span><span class=\"n\">j<\/span><span class=\"p\">:])<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">j<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">m<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">:,<\/span><span class=\"n\">j<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">:<\/span><span class=\"n\">m<\/span><span class=\"o\">-<\/span><span class=\"n\">j<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">betas<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[7]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"n\">A<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">array<\/span><span class=\"p\">([[<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">],<\/span>\n              <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">],<\/span>\n              <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">]],<\/span> <span class=\"n\">dtype<\/span><span class=\"o\">=<\/span><span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">float64<\/span><span class=\"p\">)<\/span>\n\n<span class=\"n\">betas<\/span> <span class=\"o\">=<\/span> <span class=\"n\">house_qr<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">betas<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">A<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">triu<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"output_wrapper\">\n<div class=\"output\">\n<div class=\"output_area\">\n<div class=\"prompt\"><\/div>\n<div class=\"output_subarea output_stream output_stdout output_text\">\n<pre>[ 0.05719096  1.16910198  0.        ]\n[[ 4.24264069  2.12132034  2.12132034]\n [-4.12132034  3.67423461  1.22474487]\n [-4.12132034  0.843039    3.46410162]]\n[[ 4.24264069  2.12132034  2.12132034]\n [ 0.          3.67423461  1.22474487]\n [ 0.          0.          3.46410162]]\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>If we want to see the explicit <span class=\"math inline\">\\(Q\\)<\/span> matrix, we need to apply each of the <span class=\"math inline\">\\(v_i \\rightarrow H_i\\)<\/span> transformations and get <span class=\"math inline\">\\(\\prod_i H_i = Q\\)<\/span>. In practice, you may never need to do this (see G&amp;VL, 3rd, 211-215). Becasue of their nice structure, you can almost always apply them in their packed\/compressed (read &quot;factored&quot;) form efficiently.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[8]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"c1\"># for explicit Q see G&amp;VL 3rd pg. 213 ... algo 5.1.5<\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">fullQ_house<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">,<\/span> <span class=\"n\">betas<\/span><span class=\"p\">):<\/span>\n    <span class=\"sd\">&#39;&#39;&#39;<\/span>\n<span class=\"sd\">        take the &quot;packed&quot; Householder vectors stored in A&#39;s lower triangle,<\/span>\n<span class=\"sd\">                          along with the respective \\beta s<\/span>\n<span class=\"sd\">        and expand to a full Q matrix <\/span>\n<span class=\"sd\">        (note, R still lives in A&#39;s upper triangle)<\/span>\n<span class=\"sd\">    &#39;&#39;&#39;<\/span>\n    <span class=\"n\">m<\/span><span class=\"p\">,<\/span><span class=\"n\">n<\/span> <span class=\"o\">=<\/span> <span class=\"n\">A<\/span><span class=\"o\">.<\/span><span class=\"n\">shape<\/span>\n    <span class=\"n\">Q<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">eye<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">j<\/span> <span class=\"ow\">in<\/span> <span class=\"nb\">reversed<\/span><span class=\"p\">(<\/span><span class=\"nb\">xrange<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">)):<\/span>\n        <span class=\"c1\"># NOTE:  G&amp;VL store the householder vector with a normalized v[0] == 1<\/span>\n        <span class=\"c1\">#        so it can be packed into the overwritten input matrix A<\/span>\n        <span class=\"c1\">#        we extract the &quot;essential&quot; part plus one spot and rewrite that spot with an<\/span>\n        <span class=\"c1\">#        explicit 1<\/span>\n        <span class=\"n\">v<\/span> <span class=\"o\">=<\/span> <span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"p\">:,<\/span><span class=\"n\">j<\/span><span class=\"p\">]<\/span><span class=\"o\">.<\/span><span class=\"n\">copy<\/span><span class=\"p\">()<\/span>\n        <span class=\"n\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"mf\">1.0<\/span>\n        <span class=\"n\">Q<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"p\">:,<\/span><span class=\"n\">j<\/span><span class=\"p\">:]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">eye<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"o\">-<\/span><span class=\"n\">j<\/span><span class=\"p\">)<\/span> <span class=\"o\">-<\/span> <span class=\"n\">betas<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"p\">]<\/span> <span class=\"o\">*<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">outer<\/span><span class=\"p\">(<\/span><span class=\"n\">v<\/span><span class=\"p\">,<\/span><span class=\"n\">v<\/span><span class=\"p\">))<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">Q<\/span><span class=\"p\">[<\/span><span class=\"n\">j<\/span><span class=\"p\">:,<\/span><span class=\"n\">j<\/span><span class=\"p\">:])<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">Q<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[9]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"n\">A<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">array<\/span><span class=\"p\">([[<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">],<\/span>\n              <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">],<\/span>\n              <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">]],<\/span> <span class=\"n\">dtype<\/span><span class=\"o\">=<\/span><span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">float64<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">betas<\/span> <span class=\"o\">=<\/span> <span class=\"n\">house_qr<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">Q<\/span> <span class=\"o\">=<\/span> <span class=\"n\">fullQ_house<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">,<\/span> <span class=\"n\">betas<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">Q<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">triu<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">Q<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">triu<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">))<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"output_wrapper\">\n<div class=\"output\">\n<div class=\"output_area\">\n<div class=\"prompt\"><\/div>\n<div class=\"output_subarea output_stream output_stdout output_text\">\n<pre>[[ 0.94280904 -0.27216553 -0.19245009]\n [ 0.23570226  0.95257934 -0.19245009]\n [ 0.23570226  0.13608276  0.96225045]]\n[[ 4.24264069  2.12132034  2.12132034]\n [ 0.          3.67423461  1.22474487]\n [ 0.          0.          3.46410162]]\n[[ 4.  1.  1.]\n [ 1.  4.  1.]\n [ 1.  1.  4.]]\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing code_cell rendered\">\n<div class=\"input\">\n<div class=\"prompt input_prompt\">In&nbsp;[10]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"n\">_A<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">array<\/span><span class=\"p\">([[<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">],<\/span>\n               <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">],<\/span>\n               <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">]],<\/span> <span class=\"n\">dtype<\/span><span class=\"o\">=<\/span><span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">float64<\/span><span class=\"p\">)<\/span>\n\n<span class=\"n\">nqr<\/span> <span class=\"o\">=<\/span> <span class=\"n\">nla<\/span><span class=\"o\">.<\/span><span class=\"n\">qr<\/span><span class=\"p\">(<\/span><span class=\"n\">_A<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">nqr<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">nqr<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">nqr<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">nqr<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">])<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"output_wrapper\">\n<div class=\"output\">\n<div class=\"output_area\">\n<div class=\"prompt\"><\/div>\n<div class=\"output_subarea output_stream output_stdout output_text\">\n<pre>[[-0.94280904  0.27216553 -0.19245009]\n [-0.23570226 -0.95257934 -0.19245009]\n [-0.23570226 -0.13608276  0.96225045]]\n[[-4.24264069 -2.12132034 -2.12132034]\n [ 0.         -3.67423461 -1.22474487]\n [ 0.          0.          3.46410162]]\n[[ 4.  1.  1.]\n [ 1.  4.  1.]\n [ 1.  1.  4.]]\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>You&#8217;ll notice that these are the same, up to some differences in signs. Negating <span class=\"math inline\">\\(Q\\)<\/span> and <span class=\"math inline\">\\(R\\)<\/span>, certainly yields a new, valid <span class=\"math inline\">\\(QR\\)<\/span> decomposition. It also turns out that we can <em>arbitrarily<\/em> flip the signs of (one or more of) the elements on the diagonal of <span class=\"math inline\">\\(R\\)<\/span> (see Atkinson, Intro. to Numerical Analysis, pg. 614). If we do that, we need a different sign on a corresponding element of <span class=\"math inline\">\\(Q\\)<\/span> to maintain the sign of the entry in the dot-product between the two. Details, schmetails.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<h3>\nAdditional Resources<br \/>\n<\/h3>\n<p>\nYou can grab a <a href=\"http:\/\/drsfenner.org\/public\/notebooks\/HouseholderReflectionsAndQR.ipynb\">copy of this notebook<\/a>.\n<\/p>\n<p>\nEven better, you can <a href=\"http:\/\/nbviewer.ipython.org\/url\/drsfenner.org\/public\/notebooks\/HouseholderReflectionsAndQR.ipynb\">view it using nbviewer<\/a>.\n<\/p>\n<h3>\nLicense<br \/>\n<\/h3>\n<p>\nUnless otherwise noted, the contents of this notebook are under the following license. The code in the notebook should be considered part of the text (i.e., licensed and treated as as follows).\n<\/p>\n<p><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-nc-sa\/4.0\/\"><img decoding=\"async\" alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https:\/\/i.creativecommons.org\/l\/by-nc-sa\/4.0\/88x31.png\" \/><\/a><br \/><span xmlns:dct=\"http:\/\/purl.org\/dc\/terms\/\" property=\"dct:title\">DrsFenner.org Blog And Notebooks<\/span> by <a xmlns:cc=\"http:\/\/creativecommons.org\/ns#\" href=\"drsfenner.org\" property=\"cc:attributionName\" rel=\"cc:attributionURL\">Mark and Barbara Fenner<\/a> is licensed under a <a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-nc-sa\/4.0\/\">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License<\/a>.<br \/>Permissions beyond the scope of this license may be available at <a xmlns:cc=\"http:\/\/creativecommons.org\/ns#\" href=\"drsfenner.org\/blog\/about-and-contacts\" rel=\"cc:morePermissions\">drsfenner.org\/blog\/about-and-contacts<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>My next two or three posts are going to deal with the QR and SVD techniques. QR can be done in several different ways. I&#8217;m going to work through two methods of computing QR that will shed some light on our SVD implementation. So, these two topics dovetail nicely. Onward!<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,7],"tags":[],"class_list":["post-432","post","type-post","status-publish","format-standard","hentry","category-mrdr","category-sci-math-stat-python"],"_links":{"self":[{"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/432","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/comments?post=432"}],"version-history":[{"count":1,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/432\/revisions"}],"predecessor-version":[{"id":433,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/432\/revisions\/433"}],"wp:attachment":[{"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/media?parent=432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/categories?post=432"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/tags?post=432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}