{"id":445,"date":"2016-03-15T14:02:54","date_gmt":"2016-03-15T14:02:54","guid":{"rendered":"http:\/\/drsfenner.org\/blog\/?p=445"},"modified":"2016-03-15T14:03:59","modified_gmt":"2016-03-15T14:03:59","slug":"householder-bidiagonalization","status":"publish","type":"post","link":"http:\/\/drsfenner.org\/blog\/2016\/03\/householder-bidiagonalization\/","title":{"rendered":"Householder Bidiagonalization"},"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>We&#8217;re going to make use of <a href=\"http:\/\/drsfenner.org\/blog\/2016\/02\/householder-reflections-and-qr\/\">Householder reflections<\/a> to turn a generic matrix into a <a href=\"http:\/\/drsfenner.org\/blog\/2016\/03\/givens-rotations-and-the-case-of-the-blemished-bidiagonal-matrix\/\">bidiagonal matrix<\/a>. I&#8217;ve laid a lot of foundation for these topics in the posts I just linked. Check them out! 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=\"reducing-a-generic-matrix-to-a-bidiagonal-matrix-using-householder-reflections\">Reducing a Generic Matrix to a Bidiagonal Matrix Using Householder Reflections<\/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>Why would we want to do this? Well, it&#8217;s a long chain of logic (and this is abbreviated) but with an input matrix <span class=\"math inline\">\\(A\\)<\/span> that we eventually want to compute the SVD of <span class=\"math inline\">\\(A=U_S D V^T_S\\)<\/span>. BTW, I&#8217;m using <span class=\"math inline\">\\(D\\)<\/span> instead of the usual <span class=\"math inline\">\\(\\Sigma\\)<\/span> because I don&#8217;t want folks thinking it is a variance\/covariance matrix and it <em>is<\/em> diagonal, in any case.<\/p>\n<ol style=\"list-style-type: decimal\">\n<li>If we have <span class=\"math inline\">\\(U^T_B A V_B = B\\)<\/span> with <span class=\"math inline\">\\(B\\)<\/span> upper-bidiagonal and <span class=\"math inline\">\\(U_B,V_B\\)<\/span> orthogonal, then <span class=\"math inline\">\\(V^T_B(A^T A)V_B=B^T B=T\\)<\/span> with <span class=\"math inline\">\\(T\\)<\/span> tridiagonal and symmetric. Amazingly (serendipity?), the <span class=\"math inline\">\\(U^T\\)<\/span> disappers since: <span class=\"math inline\">\\((XYZ)^T=X^T Y^T Z^T\\)<\/span> and <span class=\"math inline\">\\(U\\)<\/span> is orthogonal (<span class=\"math inline\">\\(U U^T = I\\)<\/span>).<\/li>\n<li>The singular values of <span class=\"math inline\">\\(A\\)<\/span> are the positive square roots of the non-zero eigenvalues of <span class=\"math inline\">\\(A^TA\\)<\/span>. Take a look at the inner term of the second equation in point 1.<\/li>\n<li><span class=\"math inline\">\\(A^TA\\)<\/span> is similar &#8212; which means they have the same eigenvalues &#8212; to <span class=\"math inline\">\\(B^TB\\)<\/span> and <span class=\"math inline\">\\(T\\)<\/span>.<\/li>\n<li>A symmetric tridiagonal matrix gives rise to a particularly nice characteristic equation which allows &quot;easy&quot; determination of eigenvalues (they end up forming a <em>Sturm sequence<\/em> which has nice properties).<\/li>\n<\/ol>\n<p>I don&#8217;t want to leave a misleading impression. We won&#8217;t end up explicitly using <span class=\"math inline\">\\(B^TB\\)<\/span>. The reasons are the same reasons we avoid that form in solving least squares using the direct normal equations: it has bad numerical properties and can be large. However, we do need the bidiagonal form <span class=\"math inline\">\\(B\\)<\/span>. Here&#8217;s <code>make_house_vec<\/code> from the <a href=\"http:\/\/drsfenner.org\/blog\/2016\/02\/householder-reflections-and-qr\/\">post on using Householder reflections to perform QR<\/a><\/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;[1]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><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\n<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\">np<\/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 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=\"longwinded-and-explicit\">Longwinded and Explicit<\/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>Using Householder vectors, we&#8217;re going to introduce &quot;lots&quot; of zeros into colums of our target matrix. This is very similar to the <a href=\"link\">Householder QR process<\/a>. However, instead of simply zeroing out <em>below<\/em> the diagonal one column at a time, we&#8217;re <em>also<\/em> going to zero out above the superdiagonal. We&#8217;re also going to work down the column and across the row. So, for position <span class=\"math inline\">\\((p,p)\\)<\/span> on the diagonal of a <span class=\"math inline\">\\((m,n)\\)<\/span> matrix, we&#8217;ll zero out elements in that column (using zero based indexing):<\/p>\n<p><span class=\"math display\">\\[(p+1,p),\\ (p+2,p),\\ \\ldots\\ ,\\ (m-1,p)\\]<\/span><\/p>\n<p><em>and<\/em> we&#8217;ll zero out elements in that row:<\/p>\n<p><span class=\"math display\">\\[(p,p+2),\\ (p,p+3),\\ \\ldots\\ ,\\ (p, n-1)\\]<\/span><\/p>\n<p>We start across the row at <span class=\"math inline\">\\(p+2\\)<\/span> because we need to skip the superdiagonal element. To keep the implementation a bit more direct, we&#8217;re going to hold off on one optimization. Instead of &quot;packing&quot; the reflection matrices back into <code>A<\/code>, we&#8217;re going to compute them explicitly. You don&#8217;t need to do this in practice, but hold that thought.<\/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;[2]:<\/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\">full_house<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">,<\/span> <span class=\"n\">col<\/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=\"sd\">&#39;&#39;&#39; for size n, apply a Householder vector v in the lower right corner of <\/span>\n<span class=\"sd\">        I_n to get a full-sized matrix with a smaller Householder matrix component&#39;&#39;&#39;<\/span>\n    <span class=\"n\">full<\/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=\"n\">full<\/span><span class=\"p\">[<\/span><span class=\"n\">col<\/span><span class=\"p\">:,<\/span> <span class=\"n\">col<\/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    <span class=\"k\">return<\/span> <span class=\"n\">full<\/span>\n\n<span class=\"c1\"># G&amp;VL Algo. 5.4.2 with explicit reflections<\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">house_bidiag_explicit_UV<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">):<\/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=\"k\">assert<\/span> <span class=\"n\">m<\/span> <span class=\"o\">&gt;=<\/span> <span class=\"n\">n<\/span>\n    <span class=\"n\">U<\/span><span class=\"p\">,<\/span><span class=\"n\">Vt<\/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\">m<\/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=\"p\">)<\/span>\n    \n    <span class=\"k\">for<\/span> <span class=\"n\">col<\/span> <span class=\"ow\">in<\/span> <span class=\"nb\">xrange<\/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\">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=\"n\">col<\/span><span class=\"p\">:,<\/span><span class=\"n\">col<\/span><span class=\"p\">])<\/span>\n        <span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">col<\/span><span class=\"p\">:,<\/span><span class=\"n\">col<\/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\">col<\/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><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\">col<\/span><span class=\"p\">:,<\/span><span class=\"n\">col<\/span><span class=\"p\">:])<\/span>\n        <span class=\"n\">Q<\/span> <span class=\"o\">=<\/span> <span class=\"n\">full_house<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">,<\/span> <span class=\"n\">col<\/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\">U<\/span> <span class=\"o\">=<\/span> <span class=\"n\">U<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">Q<\/span><span class=\"p\">)<\/span>\n        \n        <span class=\"k\">if<\/span> <span class=\"n\">col<\/span> <span class=\"o\">&lt;=<\/span> <span class=\"n\">n<\/span><span class=\"o\">-<\/span><span class=\"mi\">2<\/span><span class=\"p\">:<\/span>\n            <span class=\"c1\"># transpose here, reflection for zeros above diagonal in A<\/span>\n            <span class=\"c1\"># col+1 keeps us off the super diagonal<\/span>\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=\"n\">col<\/span><span class=\"p\">,<\/span><span class=\"n\">col<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">:]<\/span><span class=\"o\">.<\/span><span class=\"n\">T<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">col<\/span><span class=\"p\">:,<\/span><span class=\"n\">col<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">:]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">col<\/span><span class=\"p\">:,<\/span> <span class=\"n\">col<\/span><span class=\"o\">+<\/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\">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=\"p\">(<\/span><span class=\"n\">col<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/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            <span class=\"n\">P<\/span> <span class=\"o\">=<\/span> <span class=\"n\">full_house<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">,<\/span> <span class=\"n\">col<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/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\">Vt<\/span> <span class=\"o\">=<\/span> <span class=\"n\">P<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">Vt<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">U<\/span><span class=\"p\">,<\/span> <span class=\"n\">A<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/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\">arange<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mf\">13.0<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">reshape<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">A_test<\/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\">A<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">A<\/span>\n\n<span class=\"n\">U<\/span><span class=\"p\">,<\/span> <span class=\"n\">B<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/span> <span class=\"o\">=<\/span> <span class=\"n\">house_bidiag_explicit_UV<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;B:<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">B<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;U:<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">U<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;Vt:<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/span>\n\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;should equal input:&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">allclose<\/span><span class=\"p\">(<\/span><span class=\"n\">U<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">B<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">Vt<\/span><span class=\"p\">),<\/span> <span class=\"n\">A_test<\/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>[[  1.   2.   3.]\n [  4.   5.   6.]\n [  7.   8.   9.]\n [ 10.  11.  12.]]\nB:\n[[ 12.88409873  21.87643283   0.        ]\n [  0.           2.24623524  -0.61328133]\n [ -0.           0.           0.        ]\n [ -0.           0.           0.        ]]\nU:\n[[ 0.07761505  0.83305216 -0.54737648  0.01946767]\n [ 0.31046021  0.45123659  0.74434565  0.38203344]\n [ 0.54330537  0.06942101  0.15343813 -0.8224699 ]\n [ 0.77615053 -0.31239456 -0.35040731  0.42096879]]\nVt:\n[[ 1.          0.          0.        ]\n [ 0.          0.66700225  0.7450557 ]\n [ 0.          0.7450557  -0.66700225]]\nshould equal input: True\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<h3 id=\"refactored-and-explicit\">Refactored and Explicit<\/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>Reading (let alone coding) the <code>row<\/code>, <code>col<\/code>, <code>+1<\/code>, <code>n-col<\/code> values in that version is painful. It might be worthwhile, for performance purposes, to have so many long-winded indexing operations. Those operations are fast (-er than python level function calls), but lack human-readable semantics &#8212; I apologize to our numerical wizard siblings who speak in binary. So, here&#8217;s another look at it, with some functions to apply the Householder vectors to both the input matrix and the rotations that we are carrying along for the ride.<\/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\">apply_house_left<\/span><span class=\"p\">(<\/span><span class=\"n\">submatrix<\/span><span class=\"p\">,<\/span> <span class=\"n\">hvec<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta<\/span><span class=\"p\">,<\/span> <span class=\"n\">rotation<\/span><span class=\"p\">,<\/span> <span class=\"n\">fullrows<\/span><span class=\"p\">):<\/span>\n    <span class=\"n\">m<\/span><span class=\"p\">,<\/span><span class=\"n\">n<\/span> <span class=\"o\">=<\/span> <span class=\"n\">submatrix<\/span><span class=\"o\">.<\/span><span class=\"n\">shape<\/span>\n    \n    <span class=\"c1\"># A needs a reduced H (just the bottom-right); <\/span>\n    <span class=\"c1\"># rotation needs a full H<\/span>\n    <span class=\"n\">fullH<\/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\">fullrows<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">partH<\/span> <span class=\"o\">=<\/span> <span class=\"n\">fullH<\/span><span class=\"p\">[<\/span><span class=\"n\">fullrows<\/span><span class=\"o\">-<\/span><span class=\"n\">m<\/span><span class=\"p\">:,<\/span> <span class=\"n\">fullrows<\/span><span class=\"o\">-<\/span><span class=\"n\">m<\/span><span class=\"p\">:]<\/span>\n    <span class=\"n\">partH<\/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\">hvec<\/span><span class=\"p\">,<\/span><span class=\"n\">hvec<\/span><span class=\"p\">)<\/span>\n    \n    <span class=\"c1\"># mutate instead of (new) object assignment<\/span>\n    <span class=\"n\">submatrix<\/span><span class=\"p\">[:]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">partH<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">submatrix<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">rotation<\/span><span class=\"p\">[:]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">rotation<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">fullH<\/span><span class=\"p\">)<\/span>\n\n\n<span class=\"k\">def<\/span> <span class=\"nf\">apply_house_right<\/span><span class=\"p\">(<\/span><span class=\"n\">submatrix<\/span><span class=\"p\">,<\/span> <span class=\"n\">hvec<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta<\/span><span class=\"p\">,<\/span> <span class=\"n\">rotation<\/span><span class=\"p\">,<\/span> <span class=\"n\">fullcols<\/span><span class=\"p\">):<\/span>\n    <span class=\"n\">m<\/span><span class=\"p\">,<\/span><span class=\"n\">n<\/span> <span class=\"o\">=<\/span> <span class=\"n\">submatrix<\/span><span class=\"o\">.<\/span><span class=\"n\">shape<\/span>\n\n    <span class=\"c1\"># A needs a reduced H (just the bottom-right); <\/span>\n    <span class=\"c1\"># rotation needs a full H<\/span>\n    <span class=\"n\">fullH<\/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\">fullcols<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">partH<\/span> <span class=\"o\">=<\/span> <span class=\"n\">fullH<\/span><span class=\"p\">[<\/span><span class=\"n\">fullcols<\/span><span class=\"o\">-<\/span><span class=\"n\">n<\/span><span class=\"p\">:,<\/span> <span class=\"n\">fullcols<\/span><span class=\"o\">-<\/span><span class=\"n\">n<\/span><span class=\"p\">:]<\/span> <span class=\"c1\"># fillable = fullcols - m  <\/span>\n    <span class=\"n\">partH<\/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\">hvec<\/span><span class=\"p\">,<\/span><span class=\"n\">hvec<\/span><span class=\"p\">)<\/span>\n    \n    <span class=\"c1\"># mutate instead of (new) object assignment<\/span>\n    <span class=\"n\">submatrix<\/span><span class=\"p\">[:]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">submatrix<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">partH<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">rotation<\/span><span class=\"p\">[:]<\/span>  <span class=\"o\">=<\/span> <span class=\"n\">fullH<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">rotation<\/span><span class=\"p\">)<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">hbd_simple<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">):<\/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\">U<\/span><span class=\"p\">,<\/span><span class=\"n\">Vt<\/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\">m<\/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=\"p\">)<\/span>\n    \n    <span class=\"k\">for<\/span> <span class=\"n\">col<\/span> <span class=\"ow\">in<\/span> <span class=\"nb\">xrange<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">):<\/span>\n        <span class=\"c1\"># zero down the column<\/span>\n        <span class=\"n\">u<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta_u<\/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\">col<\/span><span class=\"p\">:,<\/span><span class=\"n\">col<\/span><span class=\"p\">])<\/span>\n        <span class=\"n\">apply_house_left<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">col<\/span><span class=\"p\">:,<\/span> <span class=\"n\">col<\/span><span class=\"p\">:],<\/span> <span class=\"n\">u<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta_u<\/span><span class=\"p\">,<\/span> <span class=\"n\">U<\/span><span class=\"p\">,<\/span> <span class=\"n\">m<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">col<\/span> <span class=\"o\">&lt;=<\/span> <span class=\"n\">n<\/span><span class=\"o\">-<\/span><span class=\"mi\">2<\/span><span class=\"p\">:<\/span>\n            <span class=\"c1\"># zero across the row<\/span>\n            <span class=\"n\">v<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta_v<\/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\">col<\/span><span class=\"p\">,<\/span><span class=\"n\">col<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">:]<\/span><span class=\"o\">.<\/span><span class=\"n\">T<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">apply_house_right<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">col<\/span><span class=\"p\">:,<\/span> <span class=\"n\">col<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">:],<\/span> <span class=\"n\">v<\/span><span class=\"p\">,<\/span> <span class=\"n\">beta_v<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/span><span class=\"p\">,<\/span> <span class=\"n\">n<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">U<\/span><span class=\"p\">,<\/span> <span class=\"n\">A<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/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;[5]:<\/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\">arange<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mf\">13.0<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">reshape<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">A_test<\/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\">A<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">A<\/span>\n\n<span class=\"n\">U<\/span><span class=\"p\">,<\/span> <span class=\"n\">B<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/span> <span class=\"o\">=<\/span> <span class=\"n\">hbd_simple<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;B:<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">B<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;U:<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">U<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;Vt:<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/span>\n\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;should equal input:&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">allclose<\/span><span class=\"p\">(<\/span><span class=\"n\">U<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">B<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">Vt<\/span><span class=\"p\">),<\/span> <span class=\"n\">A_test<\/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>[[  1.   2.   3.]\n [  4.   5.   6.]\n [  7.   8.   9.]\n [ 10.  11.  12.]]\nB:\n[[ 12.88409873  21.87643283   0.        ]\n [  0.           2.24623524  -0.61328133]\n [ -0.           0.           0.        ]\n [ -0.           0.           0.        ]]\nU:\n[[ 0.07761505  0.83305216 -0.54737648  0.01946767]\n [ 0.31046021  0.45123659  0.74434565  0.38203344]\n [ 0.54330537  0.06942101  0.15343813 -0.8224699 ]\n [ 0.77615053 -0.31239456 -0.35040731  0.42096879]]\nVt:\n[[ 1.          0.          0.        ]\n [ 0.          0.66700225  0.7450557 ]\n [ 0.          0.7450557  -0.66700225]]\nshould equal input: True\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<h3 id=\"some-optimization\">Some Optimization<\/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>Now that we have the basic process down, let&#8217;s see if we can save some resources. Our major insight is going to be that our input matrix <code>A<\/code>, which ends up with lots of zeros, has lots of room to hold other information. And, to store our rotations, we really only need to store the <em>essential<\/em> part of the Householder vectors. We can do that in the zeroed out areas above and below the diagonal and superdiagonal band. Here&#8217;s what it looks like visually:<\/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 display\">\\[<br \/>\n\\begin{bmatrix}<br \/>\nB  &amp;   &amp; \\huge{0} \\\\<br \/>\n   &amp; B &amp;          \\\\<br \/>\n\\huge{0} &amp;  &amp; B   \\\\<br \/>\n &amp; \\huge{0} &amp;<br \/>\n\\end{bmatrix}<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>And here, we lay out the use of the zero spots for our <span class=\"math inline\">\\(\\vec{v_r}\\)<\/span> (row vectors) and <span class=\"math inline\">\\(\\downarrow u_c\\)<\/span>&#8216;s (column vectors). Yes, I think the column vector\/down arrow is very cute. The value after the colon is the length of the vector.<\/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 display\">\\[<br \/>\n\\begin{bmatrix}<br \/>\nd_1 &amp; s_1 &amp; \\vec{v_1}:n-2 &amp; &amp; \\\\<br \/>\n\\downarrow u_1:{m-1} &amp; d_2 &amp; s_2 &amp; \\vec{v_2}:n-3 &amp; \\\\<br \/>\n &amp; \\downarrow u_2:{m-2} &amp; d_2 &amp; s_3 &amp; \\vec{v_3}:n-4 \\\\<br \/>\n &amp; &amp; &amp; \\dots &amp; &amp; &amp; \\\\<br \/>\n &amp; &amp; \\downarrow u_{n-3}:m-(n-3) &amp; d_{n-2} &amp; s_{n-2} &amp; \\vec{v_{n-2}}:1 \\\\<br \/>\n &amp; &amp; &amp; \\downarrow u_{n-2}:m-(n-2)=2  &amp; d_{n-1} &amp; s_{n-1} \\\\<br \/>\n &amp; &amp; &amp; &amp; \\downarrow u_{n-1}:m-(n-1)=1 &amp; d_{n}<br \/>\n\\end{bmatrix}<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>When we store the information like that, we need a way to extract it. It&#8217;s not too bad. If you followed the explict U\/V code above, it&#8217;s very similar. We&#8217;re simply extracting the <span class=\"math inline\">\\(U\\)<\/span> and <span class=\"math inline\">\\(V^T\\)<\/span> back out from the original Householder vectors. There&#8217;s one detail with the storage method: we don&#8217;t explicitly store the <span class=\"math inline\">\\(1\\)<\/span> value at the head of the Householder vector.<\/p>\n<p>We usually don&#8217;t have to explicitly construct <span class=\"math inline\">\\(U\\)<\/span> or <span class=\"math inline\">\\(V^T\\)<\/span> to apply them. That is, we can compute the product of <span class=\"math inline\">\\(U\\)<\/span> or <span class=\"math inline\">\\(V\\)<\/span> with other matrices efficiently from the packed form. But, we&#8217;ll make them explicit here so we can debug our code and check out output.<\/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=\"extraction\">Extraction<\/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;[6]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"c1\"># Based on G&amp;VL 3rd. pg. 213 ... 5.1.5<\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">extractU<\/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=\"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\">m<\/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> <span class=\"c1\"># ignore anything beyond n<\/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\">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\">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\n<span class=\"k\">def<\/span> <span class=\"nf\">extractVt<\/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=\"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=\"c1\"># stupidly confusing to code b\/c j (our index into the Q<\/span>\n    <span class=\"c1\">#                                   we are building)<\/span>\n    <span class=\"c1\"># is &quot;off by one&quot;<\/span>\n    <span class=\"c1\"># from the values we are extracting in Q<\/span>\n    <span class=\"c1\"># this has two practical results:<\/span>\n    <span class=\"c1\">#   1.  the last row\/col in Q is ignored (it&#39;s an identity row\/col)<\/span>\n    <span class=\"c1\">#   2.  to convert from input (A) land to Q land we have to <\/span>\n    <span class=\"c1\">#       subtract 1 from the input land stuff (it&#39;s all shifted)<\/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=\"n\">v<\/span> <span class=\"o\">=<\/span> <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=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/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=\"o\">-<\/span><span class=\"mi\">1<\/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 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>These two pieces of code are very similar. We can generalize them to a single extract that will pull out either the upper (<span class=\"math inline\">\\(V^T\\)<\/span>) or lower (<span class=\"math inline\">\\(U\\)<\/span>) parts.<\/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;[7]:<\/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\">extract_house_reflection<\/span><span class=\"p\">(<\/span><span class=\"n\">_A<\/span><span class=\"p\">,<\/span> <span class=\"n\">betas<\/span><span class=\"p\">,<\/span> <span class=\"n\">side<\/span><span class=\"o\">=<\/span><span class=\"s2\">&quot;lower&quot;<\/span><span class=\"p\">):<\/span>\n    <span class=\"n\">A<\/span><span class=\"p\">,<\/span> <span class=\"n\">shift<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"n\">_A<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"k\">if<\/span> <span class=\"n\">side<\/span> <span class=\"o\">==<\/span> <span class=\"s2\">&quot;lower&quot;<\/span> <span class=\"k\">else<\/span> <span class=\"p\">(<\/span><span class=\"n\">_A<\/span><span class=\"o\">.<\/span><span class=\"n\">T<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/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\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\">m<\/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=\"nb\">min<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">,<\/span><span class=\"n\">n<\/span><span class=\"p\">))):<\/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=\"o\">-<\/span><span class=\"n\">shift<\/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\">miniQ<\/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\">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=\"o\">-<\/span><span class=\"n\">shift<\/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>\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\">miniQ<\/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 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 since we will want to extract all the pieces of the packed result, we can wrap that up in one nice call:<\/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=\"k\">def<\/span> <span class=\"nf\">extract_upper_bidiag<\/span><span class=\"p\">(<\/span><span class=\"n\">M<\/span><span class=\"p\">):<\/span>\n    <span class=\"sd\">&#39;&#39;&#39;from M, pull out the diagonal and superdiagonal <\/span>\n<span class=\"sd\">       like np.triu or np.tril would  ... assume rows &gt;= cols<\/span>\n<span class=\"sd\">       (works for non-square M)&#39;&#39;&#39;<\/span>\n    <span class=\"n\">B<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">zeros_like<\/span><span class=\"p\">(<\/span><span class=\"n\">M<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">shape<\/span> <span class=\"o\">=<\/span> <span class=\"n\">B<\/span><span class=\"o\">.<\/span><span class=\"n\">shape<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n    <span class=\"n\">step<\/span> <span class=\"o\">=<\/span> <span class=\"n\">shape<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span> <span class=\"c1\"># # cols + 1<\/span>\n    <span class=\"n\">end<\/span>  <span class=\"o\">=<\/span> <span class=\"n\">shape<\/span><span class=\"o\">**<\/span><span class=\"mi\">2<\/span>  <span class=\"c1\"># top square (shape,shape)<\/span>\n    \n    <span class=\"n\">B<\/span><span class=\"o\">.<\/span><span class=\"n\">flat<\/span><span class=\"p\">[<\/span> <span class=\"p\">:<\/span><span class=\"n\">end<\/span><span class=\"p\">:<\/span><span class=\"n\">step<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">diag<\/span><span class=\"p\">(<\/span><span class=\"n\">M<\/span><span class=\"p\">)<\/span>     <span class=\"c1\"># diag<\/span>\n    <span class=\"n\">B<\/span><span class=\"o\">.<\/span><span class=\"n\">flat<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">:<\/span><span class=\"n\">end<\/span><span class=\"p\">:<\/span><span class=\"n\">step<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">diag<\/span><span class=\"p\">(<\/span><span class=\"n\">M<\/span><span class=\"p\">,<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>  <span class=\"c1\"># super diag<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">B<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">extract_packed_house_bidiag<\/span><span class=\"p\">(<\/span><span class=\"n\">H<\/span><span class=\"p\">):<\/span>\n    <span class=\"n\">U<\/span>  <span class=\"o\">=<\/span> <span class=\"n\">extract_house_reflection<\/span><span class=\"p\">(<\/span><span class=\"n\">H<\/span><span class=\"p\">,<\/span> <span class=\"n\">betas_U<\/span><span class=\"p\">,<\/span> <span class=\"n\">side<\/span><span class=\"o\">=<\/span><span class=\"s2\">&quot;lower&quot;<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">Vt<\/span> <span class=\"o\">=<\/span> <span class=\"n\">extract_house_reflection<\/span><span class=\"p\">(<\/span><span class=\"n\">H<\/span><span class=\"p\">,<\/span> <span class=\"n\">betas_V<\/span><span class=\"p\">,<\/span> <span class=\"n\">side<\/span><span class=\"o\">=<\/span><span class=\"s2\">&quot;upper&quot;<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">B<\/span>  <span class=\"o\">=<\/span> <span class=\"n\">extract_upper_bidiag<\/span><span class=\"p\">(<\/span><span class=\"n\">H<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">U<\/span><span class=\"p\">,<\/span> <span class=\"n\">B<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/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<h3 id=\"implicit-storage\">Implicit Storage<\/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>And now we turn back to G&amp;VL (3rd) Algorithm 5.4.2 with implicit reflections and reusing <code>A<\/code>&#8216;s storage for <code>u<\/code> and <code>v<\/code>.<\/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;[9]:<\/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\">house_bidiag<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">):<\/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=\"k\">assert<\/span> <span class=\"n\">m<\/span> <span class=\"o\">&gt;=<\/span> <span class=\"n\">n<\/span>\n    <span class=\"n\">U<\/span><span class=\"p\">,<\/span><span class=\"n\">V<\/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\">m<\/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=\"p\">)<\/span>\n    \n    <span class=\"n\">betas_U<\/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=\"n\">betas_V<\/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=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">j<\/span> <span class=\"ow\">in<\/span> <span class=\"nb\">xrange<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">):<\/span>\n        <span class=\"n\">u<\/span><span class=\"p\">,<\/span><span class=\"n\">betas_U<\/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\">miniHouse<\/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\">m<\/span><span class=\"o\">-<\/span><span class=\"n\">j<\/span><span class=\"p\">)<\/span> <span class=\"o\">-<\/span> <span class=\"n\">betas_U<\/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\">u<\/span><span class=\"p\">,<\/span><span class=\"n\">u<\/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\">miniHouse<\/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=\"c1\"># A&#39;s rows go 0 to m<\/span>\n        <span class=\"c1\">#  A[j,j] and A[j,j+1] are part of the bidiagonal result<\/span>\n        <span class=\"c1\">#  A[j+1:,j]  (remainder of this COLUMN) stores u<\/span>\n        <span class=\"c1\">#  A[j+1:] means indices j+1, j+2, .... m-1 is m-j positions<\/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\">u<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">:]<\/span> <span class=\"c1\"># [1:m-j+1]<\/span>\n\n        <span class=\"k\">if<\/span> <span class=\"n\">j<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">n<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">v<\/span><span class=\"p\">,<\/span><span class=\"n\">betas_V<\/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=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">:]<\/span><span class=\"o\">.<\/span><span class=\"n\">T<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">miniHouse<\/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=\"o\">-<\/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=\"o\">-<\/span> <span class=\"n\">betas_V<\/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>\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=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">:]<\/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=\"o\">+<\/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\">miniHouse<\/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=\"o\">+<\/span><span class=\"mi\">2<\/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=\"c1\"># [1:n-j]<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">betas_U<\/span><span class=\"p\">,<\/span> <span class=\"n\">betas_V<\/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;[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\">arange<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mf\">13.0<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">reshape<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">A_test<\/span> <span class=\"o\">=<\/span> <span class=\"n\">A<\/span><span class=\"o\">.<\/span><span class=\"n\">copy<\/span><span class=\"p\">()<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">A<\/span>\n\n<span class=\"n\">betas_U<\/span><span class=\"p\">,<\/span> <span class=\"n\">betas_V<\/span> <span class=\"o\">=<\/span> <span class=\"n\">house_bidiag<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">U<\/span><span class=\"p\">,<\/span> <span class=\"n\">B<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/span> <span class=\"o\">=<\/span> <span class=\"n\">extract_packed_house_bidiag<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot; U:<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">U<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;Vt:<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">Vt<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot; B:<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">B<\/span>\n\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;should equal A:&quot;<\/span><span class=\"p\">,<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">allclose<\/span><span class=\"p\">(<\/span> <span class=\"n\">U<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">B<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">Vt<\/span><span class=\"p\">),<\/span> <span class=\"n\">A_test<\/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>[[  1.   2.   3.]\n [  4.   5.   6.]\n [  7.   8.   9.]\n [ 10.  11.  12.]]\n U:\n[[ 0.07761505  0.83305216 -0.54737648  0.01946767]\n [ 0.31046021  0.45123659  0.74434565  0.38203344]\n [ 0.54330537  0.06942101  0.15343813 -0.8224699 ]\n [ 0.77615053 -0.31239456 -0.35040731  0.42096879]]\nVt:\n[[ 1.          0.          0.        ]\n [ 0.          0.66700225  0.7450557 ]\n [ 0.          0.7450557  -0.66700225]]\n B:\n[[ 12.88409873  21.87643283   0.        ]\n [  0.           2.24623524  -0.61328133]\n [  0.           0.           0.        ]\n [  0.           0.           0.        ]]\nshould equal A: True\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<h3>\nAdditional Resources<br \/>\n<\/h3>\n<p>\nYou can grab a <a href=\"http:\/\/drsfenner.org\/public\/notebooks\/HouseBidiagonalization.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\/HouseBidiagonalization.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>We&#8217;re going to make use of Householder reflections to turn a generic matrix into a bidiagonal matrix. I&#8217;ve laid a lot of foundation for these topics in the posts I just linked. Check them out! 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-445","post","type-post","status-publish","format-standard","hentry","category-mrdr","category-sci-math-stat-python"],"_links":{"self":[{"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/445","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/comments?post=445"}],"version-history":[{"count":1,"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/445\/revisions"}],"predecessor-version":[{"id":446,"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/445\/revisions\/446"}],"wp:attachment":[{"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/media?parent=445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/categories?post=445"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/tags?post=445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}