{"id":434,"date":"2016-03-03T13:03:40","date_gmt":"2016-03-03T13:03:40","guid":{"rendered":"http:\/\/drsfenner.org\/blog\/?p=434"},"modified":"2016-03-03T13:06:25","modified_gmt":"2016-03-03T13:06:25","slug":"givens-rotations-and-qr","status":"publish","type":"post","link":"https:\/\/drsfenner.org\/blog\/2016\/03\/givens-rotations-and-qr\/","title":{"rendered":"Givens Rotations 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>Today I want to talk about Givens rotations. Givens rotations are a generalization of the rotation matrix you might remember from high school trig class. Instead of rotating in the plane of a 2D matrix, we can rotated in any plane of a larger dimension matrix. We&#8217;ll use these rotations to selectively place zeros in a target matrix. <!--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=\"rotations\">Rotations<\/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\">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=\"kn\">import<\/span> <span class=\"nn\">matplotlib.pyplot<\/span> <span class=\"kn\">as<\/span> <span class=\"nn\">plt<\/span>\n<span class=\"o\">%<\/span><span class=\"k\">matplotlib<\/span> inline\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> <span class=\"c1\"># no excessive scientific notation<\/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>I wanted to remind myself about the simplest possible rotations we make. <code>matplotlib<\/code> didn&#8217;t make me super happy, when I went to plot &quot;pedagogical&quot; vectors like you&#8217;d find in a trig. textbook. The <code>matplotlib<\/code> interface (for <code>quiver<\/code> &#8211; i.e., a quiver of arrows\/vectors) is designed for the use case of full-on &quot;vector fields&quot; that are very useful to visualize dynamic systems. So, I wrote a small wrapper that did what I want:<\/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=\"c1\"># adding an orientation would be nice<\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">sane_quiver<\/span><span class=\"p\">(<\/span><span class=\"n\">vs<\/span><span class=\"p\">,<\/span> <span class=\"n\">ax<\/span><span class=\"o\">=<\/span><span class=\"bp\">None<\/span><span class=\"p\">,<\/span> <span class=\"n\">colors<\/span><span class=\"o\">=<\/span><span class=\"bp\">None<\/span><span class=\"p\">):<\/span>\n    <span class=\"sd\">&#39;&#39;&#39;plot (0,0) origin column vectors&#39;&#39;&#39;<\/span>\n    <span class=\"n\">vs<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">asarray<\/span><span class=\"p\">(<\/span><span class=\"n\">vs<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">assert<\/span> <span class=\"n\">vs<\/span><span class=\"o\">.<\/span><span class=\"n\">ndim<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">2<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">vs<\/span><span class=\"o\">.<\/span><span class=\"n\">shape<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">2<\/span>  <span class=\"c1\"># ensure column vectors<\/span>\n    <span class=\"n\">n<\/span> <span class=\"o\">=<\/span> <span class=\"n\">vs<\/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\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">ax<\/span><span class=\"p\">:<\/span> <span class=\"n\">ax<\/span> <span class=\"o\">=<\/span> <span class=\"n\">plt<\/span><span class=\"o\">.<\/span><span class=\"n\">gca<\/span><span class=\"p\">()<\/span>\n\n    <span class=\"n\">zs<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">zeros<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">xs<\/span> <span class=\"o\">=<\/span> <span class=\"n\">vs<\/span><span class=\"o\">.<\/span><span class=\"n\">T<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n    <span class=\"n\">ys<\/span> <span class=\"o\">=<\/span> <span class=\"n\">vs<\/span><span class=\"o\">.<\/span><span class=\"n\">T<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n    \n    <span class=\"n\">props<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><span class=\"s2\">&quot;angles&quot;<\/span><span class=\"p\">:<\/span><span class=\"s1\">&#39;xy&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;scale&#39;<\/span><span class=\"p\">:<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;scale_units&#39;<\/span><span class=\"p\">:<\/span><span class=\"s1\">&#39;xy&#39;<\/span><span class=\"p\">}<\/span>\n    <span class=\"n\">ax<\/span><span class=\"o\">.<\/span><span class=\"n\">quiver<\/span><span class=\"p\">(<\/span><span class=\"n\">zs<\/span><span class=\"p\">,<\/span> <span class=\"n\">zs<\/span><span class=\"p\">,<\/span> <span class=\"n\">xs<\/span><span class=\"p\">,<\/span> <span class=\"n\">ys<\/span><span class=\"p\">,<\/span> <span class=\"n\">color<\/span><span class=\"o\">=<\/span><span class=\"n\">colors<\/span><span class=\"p\">,<\/span> <span class=\"o\">**<\/span><span class=\"n\">props<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">ax<\/span><span class=\"o\">.<\/span><span class=\"n\">set_aspect<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;equal&#39;<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">ax<\/span><span class=\"o\">.<\/span><span class=\"n\">set_axis_off<\/span><span class=\"p\">()<\/span>\n    <span class=\"c1\"># if not square:<\/span>\n    <span class=\"c1\">#ax.set_xlim(xs.min()-1, xs.max()+1)<\/span>\n    <span class=\"c1\">#ax.set_ylim(ys.min()-1, ys.max()+1)<\/span>\n    <span class=\"c1\"># else: # square axes frame<\/span>\n    <span class=\"n\">_min<\/span><span class=\"p\">,<\/span> <span class=\"n\">_max<\/span> <span class=\"o\">=<\/span> <span class=\"n\">vs<\/span><span class=\"o\">.<\/span><span class=\"n\">min<\/span><span class=\"p\">()<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">vs<\/span><span class=\"o\">.<\/span><span class=\"n\">max<\/span><span class=\"p\">()<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span>\n    <span class=\"n\">ax<\/span><span class=\"o\">.<\/span><span class=\"n\">set_xlim<\/span><span class=\"p\">(<\/span><span class=\"n\">_min<\/span><span class=\"p\">,<\/span> <span class=\"n\">_max<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">ax<\/span><span class=\"o\">.<\/span><span class=\"n\">set_ylim<\/span><span class=\"p\">(<\/span><span class=\"n\">_min<\/span><span class=\"p\">,<\/span> <span class=\"n\">_max<\/span><span class=\"p\">)<\/span>\n        \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>Let&#8217;s make a small test vector and a simple rotation:<\/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;[3]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"n\">x<\/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=\"mf\">1.0<\/span><span class=\"p\">,<\/span> <span class=\"mf\">1.0<\/span><span class=\"p\">])<\/span>\n\n<span class=\"n\">theta<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">pi<\/span><span class=\"o\">\/<\/span><span class=\"mi\">2<\/span>\n\n<span class=\"n\">sin_th<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">sin<\/span><span class=\"p\">(<\/span><span class=\"n\">theta<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">cos_th<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">cos<\/span><span class=\"p\">(<\/span><span class=\"n\">theta<\/span><span class=\"p\">)<\/span>\n\n<span class=\"n\">givens_rot<\/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=\"n\">cos_th<\/span><span class=\"p\">,<\/span> <span class=\"n\">sin_th<\/span><span class=\"p\">],<\/span>\n                       <span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"n\">sin_th<\/span><span class=\"p\">,<\/span> <span class=\"n\">cos_th<\/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>Premultiplication by the transpose of <code>givens_rot<\/code> will rotate a vector <em>counter-clockwise<\/em> (CCW) in the <em>xy<\/em>-plane. I&#8217;m not sure when\/where\/why\/how the Givens form is the transpose form of the usual, highschool trig. textbook form (see, for example the definition of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Rotation_matrix\">&quot;high school&quot; R here<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Givens_rotation\">Givens G here<\/a>. Also, <span class=\"math inline\">\\(G\\)<\/span> agrees with the venerable Golab &amp; VanLoan (3rd, pg. 215), so you can&#8217;t really argue with it. I&#8217;m going to blame it on row- versus column-major ordering. I blame everything else on that, so why not?<\/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=\"n\">fig<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"n\">axL<\/span><span class=\"p\">,<\/span> <span class=\"n\">axR<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> <span class=\"n\">plt<\/span><span class=\"o\">.<\/span><span class=\"n\">subplots<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\n\n<span class=\"c1\">#G.T.dot(X)<\/span>\n<span class=\"n\">sane_quiver<\/span><span class=\"p\">([<\/span><span class=\"n\">x<\/span><span class=\"p\">,<\/span> <span class=\"n\">givens_rot<\/span><span class=\"o\">.<\/span><span class=\"n\">T<\/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=\"n\">axL<\/span><span class=\"p\">,<\/span> <span class=\"n\">colors<\/span><span class=\"o\">=<\/span><span class=\"p\">[<\/span><span class=\"s1\">&#39;b&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;r&#39;<\/span><span class=\"p\">])<\/span>\n<span class=\"n\">axL<\/span><span class=\"o\">.<\/span><span class=\"n\">set_title<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;Rotate blue $\\pi\/2$ CCW to red&quot;<\/span><span class=\"p\">)<\/span>\n\n<span class=\"c1\"># X.dot(G)<\/span>\n<span class=\"n\">sane_quiver<\/span><span class=\"p\">([<\/span><span class=\"n\">x<\/span><span class=\"p\">,<\/span> <span class=\"n\">x<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">givens_rot<\/span><span class=\"o\">.<\/span><span class=\"n\">T<\/span><span class=\"p\">)],<\/span> <span class=\"n\">axR<\/span><span class=\"p\">,<\/span> <span class=\"n\">colors<\/span><span class=\"o\">=<\/span><span class=\"p\">[<\/span><span class=\"s1\">&#39;b&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;r&#39;<\/span><span class=\"p\">])<\/span>\n<span class=\"n\">axR<\/span><span class=\"o\">.<\/span><span class=\"n\">set_title<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;Rotate blue $\\pi\/2$ CW to red&quot;<\/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_png output_subarea \">\n<img decoding=\"async\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAYEAAADFCAYAAACy507qAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+\/AAADOJJREFUeJzt2n\/MJHV9wPH353iQQyPSQirH6UGOtNRW00PQ1PijKjVo\nFLQitJyCtSnGSG1TagCt0YQao0k1TRtSYzztFYQ2QGtATQwFmlKkFQ6o2j+qgogcKilU7hARufv2\nj5mTfZbdfXafZ+aZ3fm8Xwlhd2Z29vvMfPfeO7sbpRQkSTlt6HoAkqTuGAFJSswISFJiRkCSEjMC\nkpSYEZCkxIyAJCVmBCQpMSMwpYj4TkS8erXrNX8i4rMRcXHX45g3zvXFs5a53GkEIuKeiHg0IvZE\nxP31H\/L0KR8700Ts+8SNiGdGxK\/Ut7dHxJ9FxD9GxO+t8LjtEXFrROyNiN0R8cWIeOlK6yPiooj4\n0tC+vhURXxxa9s2IOHPMc\/f6nAxyrjen6bmefS53fSVQgNeXUg4DtgEnAO\/rdkgL60zgkYg4Djii\nlPJx4DzgbyPi2FEPiIjzgU8AHwZ+CdgCXAKcOsX6fwNeEhFRb3sUsAScMLTsuHrbVkXEQW0\/xxo5\n15vT9Fyfm7ncyTwupXT2H\/Ad4NUD9z8GXDtw\/1eBG4H\/A74OnFov\/3tgH\/BjYA\/w3nr5hcC362Xf\nAN60wvabgKuAB4C7gPesMNaLgP8GHgR2AE8b9bcA+4GtA+s+C1w8cH\/q553hWH6o\/v9pwL0Dy28F\n3jJi+8OAvcCbx+xvpfUH18fzhPr+GcBn6vM1uOybYx4\/7pw8b9Q5n3BOLgD+C\/gJ1ZuasceW6h\/e\nXcDDwD8AVwyeF+d62rne+Fwedz6bmMdNz+XWJ\/+0LwzgOcDXgE\/U95eAb9WTfQl4VX2Af3ngsa8a\n2t\/pwLMHTtojA\/eXbQ8EcBvw58BBwLH1i+o1E8b6NeBo4HDg34cm++Dfsm\/cC2PW553yOB4P\/O7A\ncXv+wLr7gG0jHnMK8DiwYcw+J66vt7kB+JP69t8Avw\/8xdCyT69w\/gfPycRzPubxt9fn5JBJx5bq\nhX4P8Mf1utPrv2\/dI+Bcn6+53vRcbnMe19s3Opdbn\/xTvDD21P\/tB64DDqvXvQy4f2j7y4EPDk\/E\nCfu\/gyffUQ2\/E3sxcM\/Q9hcBOyaM9dyB+68Dvj3mhTH23dEsz0v1DmYHcFM9SW8HrgEuGNruQgbe\nqQ0sfwPw+TF\/z\/bh4zvL+nqbDwFX17fvpLpcPmVo2dkrnP\/BczLxnI95\/NunOKefAV4O3De07ubV\nvnCc6\/2Z603P5XqutTGPd9S3X9HkXF6ie28spdwYES+nOlBHUr1Qjga+N7Ttd4HN43YUEecAf0pV\nToBn1Psb5Rhgc0Q8dODhVJdhkz7zu29oLJsmbDvOLM\/7IuCdwNuBncB5pZS\/HtwgIjYAS6WUx4eW\nH1Y\/7m1jxvEgcGREbCil7F\/FeuoxvzsifgE4spRyV0Q8APxdvez5Y\/6ucWY+5yw\/J+OO7U31vneP\n2Pd6cq7P51yHZufyJtqZxweefxMNzuV5iEAAlFJuioidwMeB3wHuB547tO0W4H\/q22XZTiK2AJ+i\nuiS7pV52x4H9D29PdZLuLqUcP8NYB8dzTD3GUR4FBn\/5cRRPToqpn7eUcj1ARGwtpeyLiOHjAdVH\nHdeNWH4B1bu5RyLimFLK8CS5Bfgp8Cbgn0Y8fqX1B7Y5HDiX6p0IpZS9EXF\/vWz3iOdd9icO3V\/p\nnK+0j7HHNiJewVNfhFuoLrPXi3N9jI7n+oFtmprLrc3j2vdpcC53\/eugYX8FvCYiXgD8J\/BoRFwQ\nEUsR8UqqS74r6m1\/CGwdeOwzqC5N\/zciNkTEO6jqzZjtvwrsrfe\/MSIOiohfj4iTJozvvIjYHBG\/\nCLyf6guZUe4EttfjeC3wW6t93vpnZwdegNtGbPKbpZSvDj3mj4B\/Bg6JiBdRvYiXKaXsoboEviQi\n3hgRh9bH+bUR8dGV1tf7eIzqs8vzqd5tH3BzvWyld04\/YPk5GXfOxx3nYZOO7S3AExHxnnrfb6a6\n7O6Kc31IV3O93qbJudzmPIam5\/JqPkNq6j\/gboY+66T62daV9e3nAf8K\/IjqFxCnDWx3GtUl0EPA\n+fWyD1Nd+j0A\/CXVt\/N\/MGH7o6guy79fP+4rw+MZGuuFVL+YeIjqc+aNo\/4W4MR6vA9TXdp+juVf\nrM3yvDuBzfXtrwAxsO5ZPPVXAy+l+rJuH9U\/FPsOPH7M\/s+i+lXFXqoX4LVUL7Zp13+kfo5tA8vO\nqJf94Qrnf9Q5GXvOp5w\/Y48t8EKqz5ofpvoHdj1\/HeRcn\/+53thcbnMeNz2Xo96hFlBEnEv1M8Mf\ndD0WqU3O9fbM28dBms0mXxRKwrneEiOwoCJiK9VvuaVec663y4+DJCkxrwQkKTEjIEmJGQFJSswI\nSFJiRkCSEjMCkpSYEZCkxIyAJCVmBCQpMSMgSYkZAUlKzAhIUmJGQJISMwKSlJgRkKTEjIAkJWYE\nJCkxIyBJiRkBSUrMCEhSYkZAkhIzApKUmBGQpMSMgCQlZgQkKTEjIEmJGQFJSswISFJiRkCSEjMC\nkpSYEZCkxIyAJCVmBCQpMSMgSYkZAUlKzAhIUmJGQJISMwKSlJgRmEbE4UQc3PUwFkUER3Q9Bqlp\nERwSwTO7HkfTjMB0Hge+TMTpRETXg5lXEfxaBJ8HfqPrsUhNiWBDBG8FrgUe63o8TTMC0yjlUeAK\n4CrgP4h4ZbcDmi8RPCeCTwNfBw4thRu6HpO0VhFEBKcAtwOXATtK4WcdD6txUUrpegyLIWIJ+AZw\nPPAI8A5KuarbQXUvgmOBa4AX1IteWAp3dDciqRkRnAN8EjgU2AW8uBT2dzuq5nklMK1SngDeB\/wY\nWKKHl4Wr9FPgYGAPcLkBUI88BgTwE+DCPgYAvBKYTfV9wFupJsangDMo5QvdDqo7EWwCbqC6QroE\nuLcU7u52VNLaRXAmsBN4G\/D0Uri04yG1ZqnrASyUqpiXAVB9P3wlESlDMBSA7X38rFQ5DQagFK7u\nejxtMwKrVcqlWUNgANRX2QIARmBtEobAAKivMgYAjMDaJQqBAVBfZQ0AGIFmJAiBAVBfZQ4AGIHm\n9DgEBkB9lT0AYASa1cMQGAD1lQGoGIGm9SgEBkB9ZQCeZATa0IMQGAD1lQFYzgi0ZYFDYADUVwbg\nqYxAmxYwBAZAfWUARjMCbVugEBgA9ZUBGM8IrIcFCIEBUF8ZgMmMwHqZ4xAYAPWVAViZEVhPcxgC\nA6C+MgDTMQLrbY5CYADUVwZgekagC3MQAgOgvjIAszECXekwBAZAfWUAZmcEutRBCAyA+soArI4R\n6No6hsAAqK8MwOoZgXmwDiEwAOorA7A2RmBetBgCA6C+MgBrZwTmSQshMADqKwPQDCMwbxoMgQFQ\nXxmA5hiBedRACAyA+soANMsIzKs1hMAAqK8MQPOMwDxbRQgMgPrKALTDCMy7GUJgANRXBqA9RmAR\nTBECA6C+MgDtMgKLYkIIDID6ygC0zwgskhEhMADqKwOwPjZ0PQDNqJRLgXcCV94Z287GAKiHDMD6\niVJK12PQakSc\/V22XLyVu2\/bz0EGQL1xUty2dDLX3\/Uv\/PYHd5UTd3Y9nr4zAgtsV5y4dBK7KIUn\nuh6L1JiIpf3ENRsoRwMnU8qDXQ+pz4yApPkTsRG4GtiMIWiV3wlImj+lPAacDuwGrifiiI5H1FtG\nQNJ8MgTrwghIml+GoHVGQNJ8MwStMgKS5p8haI0RkLQYDEErjICkxWEIGmcEJC0WQ9AoIyBp8RiC\nxhgBSYvJEDTCCEhaXIZgzYyApMVmCNbECEhafIZg1YyApH4wBKtiBCT1hyGYmRGQ1C+GYCZGQFL\/\nGIKpGQFJ\/WQIpmIEJPWXIViREZDUb4ZgIiMgqf8MwVhGQFIOhmAkIyApD0PwFEZAUi6GYBkjICkf\nQ\/BzRkBSToYAMAKSMjMERkBScslDYAQkKXEIjIAkQdoQRCml6zFI0vyI2AhcDWwGTgY2UsrubgfV\nHiMgScOWh+AJ4PWU8sNuB9UOPw6SpGHVR0MfAbYCJwIf6HZA7TECkjTaj4Ab69vvIuK4LgfTFj8O\nkqRJIl4GfAy4l1LO6no4TTMCkrSSiABOBW6mlAe7Hk6TjIAkJeZ3ApKUmBGQpMSMgCQlZgQkKTEj\nIEmJGQFJSswISFJiRkCSEjMCkpSYEZCkxIyAJCVmBCQpMSMgSYkZAUlKzAhIUmJGQJISMwKSlJgR\nkKTEjIAkJWYEJCkxIyBJiRkBSUrMCEhSYkZAkhIzApKUmBGQpMSMgCQlZgQkKTEjIEmJGQFJSswI\nSFJiRkCSEjMCkpSYEZCkxIyAJCVmBCQpMSMgSYkZAUlKzAhIUmJGQJISMwKSlJgRkKTEjIAkJWYE\nJCkxIyBJiRkBSUrMCEhSYkZAkhIzApKUmBGQpMSMgCQlZgQkKTEjIEmJGQFJSswISFJiRkCSEjMC\nkpSYEZCkxP4flpwcb9iVk6AAAAAASUVORK5CYII=\n\"\n>\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>We can generalize <span class=\"math inline\">\\(G=\\begin{bmatrix}\\cos(\\theta) &amp; \\sin(\\theta) \\\\ -\\sin(\\theta) &amp; \\cos(\\theta)\\end{bmatrix}\\)<\/span> to still be a rotation in one plane, but make that plane be an arbitrary plane in a larger space. Here&#8217;s an example for 3D:<\/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}\\renewcommand{\\nvec}[2]{\\vec{#1}_\\mathrm{#2}}\\)<\/span><\/p>\n<p><span class=\"math display\">\\[G=\\begin{bmatrix}<br \/>\n1 &amp; 0 &amp; 0 \\\\<br \/>\n0 &amp; \\cos(\\theta) &amp; \\sin(\\theta) \\\\<br \/>\n0 &amp; -\\sin(\\theta) &amp; \\cos(\\theta)<br \/>\n\\end{bmatrix}\\]<\/span><\/p>\n<p>and at the risk of belaboring the point, for 5D: <span class=\"math display\">\\[G=\\begin{bmatrix}<br \/>\n1 &amp; 0 &amp; 0 &amp; 0 &amp; 0\\\\<br \/>\n0 &amp; \\cos(\\theta) &amp; 0 &amp; \\sin(\\theta) &amp; 0 \\\\<br \/>\n0 &amp; 0 &amp; 1 &amp; 0 &amp; 0 \\\\<br \/>\n0 &amp; -\\sin(\\theta) &amp; 0 &amp; \\cos(\\theta) &amp; 0 \\\\<br \/>\n0 &amp; 0 &amp; 0 &amp; 0 &amp; 1<br \/>\n\\end{bmatrix}\\]<\/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>In general, we take a <span class=\"math inline\">\\((m,m)\\)<\/span> identity matrix and replace four elements with these trig. functions. If we want our rotation plane to be on axes 2 and 4 (as in G_2), we replace G[2,2], G[2,4], G[4,2], and G[4,4]. Since two of these elements are on the diagonal, we replace two 1s (with the cosines). The two off-diagonal elements replace two 0s with <span class=\"math inline\">\\(\\sin\\)<\/span> and its negative. In G_2, if we called our axes (x,y,z,a,b), we would be performing a CCW rotation in the ya-plane. More usually, if we called our axes <span class=\"math inline\">\\(x_1 \\dots x_5\\)<\/span>, we would be rotating in the <span class=\"math inline\">\\(x_2 x_4\\)<\/span> plane.<\/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=\"computing-a-givens-zeroing-coefficient\">Computing a Givens Zeroing Coefficient<\/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 rotate in a plane defined by two axes and we rotate just enough to get our vector pointed directly inline with one of those axes (assume the vector share a common origin\/tail\/starting point), then we have a <span class=\"math inline\">\\(0\\)<\/span> component in <em>the other<\/em> axis. Together with the fact that we can we pick the two axes out-of-a-hat, this means that we can <em>selectively<\/em> zero out single elements of a matrix using a Givens rotation. Contrast this with Householder reflections which zero out <em>all-but-one<\/em> element of a row\/column. Put the two together, and we can start slicing and dicing matrices into different form pretty nicely.<\/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=\"c1\"># GvL pg. 216 : algo 5.1.3 * see also anderson(2000) via wikipedia for continuity concerns<\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">,<\/span><span class=\"n\">z<\/span><span class=\"p\">):<\/span>\n    <span class=\"sd\">&#39;&#39;&#39; for the values x,z compute cos th, sin th <\/span>\n<span class=\"sd\">        s.t. applying a Givens rotation G(cos th,sin th) <\/span>\n<span class=\"sd\">             on 2 rows(or cols) with values x,z will<\/span>\n<span class=\"sd\">             maps x --&gt; r and z --&gt; 0&#39;&#39;&#39;<\/span>\n    <span class=\"k\">if<\/span> <span class=\"n\">z<\/span> <span class=\"o\">==<\/span> <span class=\"mf\">0.0<\/span><span class=\"p\">:<\/span> <span class=\"c1\"># better:  abs(z) &lt; np.finfo(np.double).eps<\/span>\n        <span class=\"k\">return<\/span> <span class=\"mf\">1.0<\/span><span class=\"p\">,<\/span><span class=\"mf\">0.0<\/span>\n    <span class=\"n\">r<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">hypot<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">,<\/span><span class=\"n\">z<\/span><span class=\"p\">)<\/span> <span class=\"c1\"># C99 hypot is safe for under\/overflow<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">x<\/span><span class=\"o\">\/<\/span><span class=\"n\">r<\/span><span class=\"p\">,<\/span> <span class=\"o\">-<\/span><span class=\"n\">z<\/span><span class=\"o\">\/<\/span><span class=\"n\">r<\/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;[6]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"c1\"># from the 45deg .. pi\/4 .. y=x line, <\/span>\n<span class=\"c1\"># theta should be pi\/4, we should rotate <\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">sqrt<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span><span class=\"o\">\/<\/span><span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">sin<\/span><span class=\"p\">(<\/span><span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">pi<\/span><span class=\"o\">\/<\/span><span class=\"mi\">4<\/span><span class=\"p\">),<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">cos<\/span><span class=\"p\">(<\/span><span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">pi<\/span><span class=\"o\">\/<\/span><span class=\"mi\">4<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">,<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">)<\/span>\n\n\n<span class=\"k\">print<\/span> <span class=\"n\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/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.707106781187 0.707106781187 0.707106781187\n(0.70710678118654746, -0.70710678118654746)\n(0.70710678118654746, -0.70710678118654746)\n(0.59999999999999998, -0.80000000000000004)\n(0.80000000000000004, -0.59999999999999998)\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>Now, we can <em>apply<\/em> a Givens transformation by hand. We do it in two steps: (1) create the appropriate Givens matrix as a <span class=\"math inline\">\\((2\\ \\mathrm{x}\\ 2)\\)<\/span> array from the computed zeroing coefficients and (2) apply that on the correct rows (for a left Givens) or columns (for a right Givens). Remember, on the left, we use the tranpose.<\/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=\"c1\"># column vector<\/span>\n<span class=\"n\">x<\/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=\"mf\">1.0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span> <span class=\"mi\">4<\/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\">1<\/span><span class=\"p\">)<\/span>\n\n<span class=\"c1\"># compute coefficients<\/span>\n<span class=\"n\">c<\/span><span class=\"p\">,<\/span><span class=\"n\">s<\/span> <span class=\"o\">=<\/span> <span class=\"n\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"mi\">20<\/span><span class=\"p\">,<\/span> <span class=\"mi\">40<\/span><span class=\"p\">)<\/span>\n\n<span class=\"c1\"># apply transformation (in-place)<\/span>\n<span class=\"n\">givensT<\/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=\"n\">c<\/span><span class=\"p\">,<\/span> <span class=\"o\">-<\/span><span class=\"n\">s<\/span><span class=\"p\">],<\/span>\n                    <span class=\"p\">[<\/span><span class=\"n\">s<\/span><span class=\"p\">,<\/span>  <span class=\"n\">c<\/span><span class=\"p\">]])<\/span>\n<span class=\"n\">x<\/span><span class=\"p\">[[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">],<\/span> <span class=\"p\">:]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">givensT<\/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><span class=\"mi\">3<\/span><span class=\"p\">],:])<\/span>\n\n<span class=\"k\">print<\/span> <span class=\"n\">x<\/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.        ]\n [ 4.47213595]\n [ 3.        ]\n [ 0.        ]]\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=\"applying-a-givens-rotation\">Applying a Givens Rotation<\/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, we&#8217;ve moved straight into Python land, so we&#8217;ll be using zero-indexing now. You&#8217;ve been warned! And yes, I&#8217;m shamed. I reworked these functions (slightly) in the next post, because I didn&#8217;t like the separation of the &quot;Givens&quot; args (<code>c,s,r1,r2<\/code>) and <code>A<\/code> being lumped in the middle.<\/p>\n<p>The form of Givens rotations means that <em>we can save a lot of work<\/em> when we multiply. Most of a Givens matrix is <span class=\"math inline\">\\(0\\)<\/span> &#8211; and much of the rest is an identity vector. So, we can effectively <em>ignore<\/em> most of it. On the left, we only need to update two rows. On the right, it&#8217;s two columns. We&#8217;ll see examples below.<\/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\"># GvL, pg. 216 .... Section 5.1.9<\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">left_givensT<\/span><span class=\"p\">((<\/span><span class=\"n\">c<\/span><span class=\"p\">,<\/span><span class=\"n\">s<\/span><span class=\"p\">),<\/span> <span class=\"n\">A<\/span><span class=\"p\">,<\/span> <span class=\"n\">r1<\/span><span class=\"p\">,<\/span> <span class=\"n\">r2<\/span><span class=\"p\">):<\/span>\n    <span class=\"sd\">&#39;&#39;&#39; update A &lt;- G.T.dot(A) ... affects rows r1 and r2 &#39;&#39;&#39;<\/span>\n    <span class=\"n\">givensT<\/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=\"n\">c<\/span><span class=\"p\">,<\/span> <span class=\"o\">-<\/span><span class=\"n\">s<\/span><span class=\"p\">],<\/span>   <span class=\"c1\"># manually transposed <\/span>\n                        <span class=\"p\">[<\/span> <span class=\"n\">s<\/span><span class=\"p\">,<\/span>  <span class=\"n\">c<\/span><span class=\"p\">]])<\/span>\n    <span class=\"n\">A<\/span><span class=\"p\">[[<\/span><span class=\"n\">r1<\/span><span class=\"p\">,<\/span><span class=\"n\">r2<\/span><span class=\"p\">],:]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/span><span class=\"o\">.<\/span><span class=\"n\">dot<\/span><span class=\"p\">(<\/span><span class=\"n\">givensT<\/span><span class=\"p\">,<\/span> <span class=\"n\">A<\/span><span class=\"p\">[[<\/span><span class=\"n\">r1<\/span><span class=\"p\">,<\/span><span class=\"n\">r2<\/span><span class=\"p\">],:])<\/span>\n\n<span class=\"c1\"># A.dot(G) .... affects two cols of A<\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">right_givens<\/span><span class=\"p\">((<\/span><span class=\"n\">c<\/span><span class=\"p\">,<\/span><span class=\"n\">s<\/span><span class=\"p\">),<\/span> <span class=\"n\">A<\/span><span class=\"p\">,<\/span> <span class=\"n\">c1<\/span><span class=\"p\">,<\/span> <span class=\"n\">c2<\/span><span class=\"p\">):<\/span>\n    <span class=\"sd\">&#39;&#39;&#39; update A &lt;- A.dot(G) ... affects cols c1 and c2 &#39;&#39;&#39;<\/span>\n    <span class=\"n\">givens<\/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=\"n\">c<\/span><span class=\"p\">,<\/span> <span class=\"n\">s<\/span><span class=\"p\">],<\/span>\n                       <span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"n\">s<\/span><span class=\"p\">,<\/span> <span class=\"n\">c<\/span><span class=\"p\">]])<\/span>\n    <span class=\"n\">A<\/span><span class=\"p\">[:,[<\/span><span class=\"n\">c1<\/span><span class=\"p\">,<\/span> <span class=\"n\">c2<\/span><span class=\"p\">]]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">np<\/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\">c1<\/span><span class=\"p\">,<\/span> <span class=\"n\">c2<\/span><span class=\"p\">]],<\/span> <span class=\"n\">givens<\/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;[9]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"n\">x<\/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=\"mf\">1.0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span> <span class=\"mi\">4<\/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\">1<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">x<\/span>\n\n<span class=\"n\">c<\/span><span class=\"p\">,<\/span><span class=\"n\">s<\/span> <span class=\"o\">=<\/span> <span class=\"n\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">4<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">left_givensT<\/span><span class=\"p\">((<\/span><span class=\"n\">c<\/span><span class=\"p\">,<\/span><span class=\"n\">s<\/span><span class=\"p\">),<\/span> <span class=\"n\">x<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">x<\/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.]\n [ 2.]\n [ 3.]\n [ 4.]]\n[[ 1.        ]\n [ 4.47213595]\n [ 3.        ]\n [ 0.        ]]\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=\"c1\"># row vector<\/span>\n<span class=\"n\">x<\/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=\"mf\">1.0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span> <span class=\"mi\">4<\/span><span class=\"p\">])<\/span><span class=\"o\">.<\/span><span class=\"n\">reshape<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">4<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">x<\/span>\n\n<span class=\"c1\"># zero the 2, this time<\/span>\n<span class=\"n\">c_zero<\/span><span class=\"p\">,<\/span> <span class=\"n\">c_other<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span>\n<span class=\"n\">c<\/span><span class=\"p\">,<\/span><span class=\"n\">s<\/span> <span class=\"o\">=<\/span> <span class=\"n\">zeroing_givens_coeffs<\/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=\"n\">c_other<\/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=\"n\">c_zero<\/span><span class=\"p\">])<\/span>\n<span class=\"n\">right_givens<\/span><span class=\"p\">((<\/span><span class=\"n\">c<\/span><span class=\"p\">,<\/span><span class=\"n\">s<\/span><span class=\"p\">),<\/span> <span class=\"n\">x<\/span><span class=\"p\">,<\/span> <span class=\"n\">c_other<\/span><span class=\"p\">,<\/span> <span class=\"n\">c_zero<\/span><span class=\"p\">)<\/span>\n\n<span class=\"k\">print<\/span> <span class=\"n\">x<\/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.  4.]]\n[[ 1.          0.          3.          4.47213595]]\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;[11]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"n\">x<\/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=\"mf\">16.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\">4<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">c<\/span><span class=\"p\">,<\/span><span class=\"n\">s<\/span> <span class=\"o\">=<\/span> <span class=\"n\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"mi\">7<\/span><span class=\"p\">,<\/span><span class=\"mi\">5<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">right_givens<\/span><span class=\"p\">((<\/span><span class=\"n\">c<\/span><span class=\"p\">,<\/span><span class=\"n\">s<\/span><span class=\"p\">),<\/span> <span class=\"n\">x<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">x<\/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.          -0.92998111   2.           3.02243861]\n [  4.           0.           6.           8.60232527]\n [  8.           0.92998111  10.          14.18221193]\n [ 12.           1.85996222  14.          19.76209859]]\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 may have noticed that when I wanted to zero the <code>5<\/code> value, I had to swap the args to <code>zeroing_givens_coeff<\/code> (the zeroed <em>value<\/em> comes second) <em>and<\/em> swap the axes args to <code>right_givens<\/code> (the zeroed <em>position<\/em> comes second). Ugh. This implies that those two parameters (the order of them) are intimately coupled. And making a programmer use coupled arguments is a recipe for disaster. We&#8217;ll talk about a higher level interface in the next post. Incidentally, the two-step process is useful because we often have to apply the same transformation to more than one matrix at a time.<\/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=\"using-givens-rotations-to-perform-a-qr-decomposition\">Using Givens Rotations to Perform a QR Decomposition<\/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>Let&#8217;s take a look at how we&#8217;ll <em>use<\/em> the Givens rotations, so we can design a decent interface for them.<\/p>\n<p>We can take an arbitrary matrix <span class=\"math inline\">\\(\\vec{A}\\)<\/span> uses (zeroing) Givens rotations to zero out entries. As we do that, we get a sequence of Givens rotations <span class=\"math inline\">\\(\\vec{G_1},\\vec{G_2},\\vec{G_3},\\dots\\)<\/span>. Eventually, we have <span class=\"math inline\">\\(A=(\\prod_i \\vec{G_i}) \\vec{Z}\\)<\/span> where <span class=\"math inline\">\\(\\vec{Z}\\)<\/span> has &quot;lots&quot; of zeros in it. If we introduce those zeros in the right way, we can get <span class=\"math inline\">\\(\\vec{Z}\\)<\/span> to be upper-triangular (aka, <span class=\"math inline\">\\(\\vec{R}\\)<\/span>) and then <span class=\"math inline\">\\(\\prod_i \\vec{G_i} = Q\\)<\/span>. Presto, et voila, we have <span class=\"math inline\">\\(QR\\)<\/span>. Note that the product of several orthogonal matrices (and rotations), is itself, orthogonal (one grand rotation).<\/p>\n<p>To do this, we&#8217;ll work from left-to-right column wise. On the first column, we&#8217;ll introduce a zeros from the bottom up until we get to the top row. That top row will be modified by a zeroing Givens rotation, but it won&#8217;t be zeroed. And likewise for each additional column &#8212; except we always stop at the diagonal. Remember, as we walk across the columns, we move up the rows until we get to the diagonal, zeroing as we go. The diagonal is modified (to <span class=\"math inline\">\\(r\\)<\/span> coming out of our zeroing Givens rotation). That column, above the diagonal, is untouched by the &quot;walking up the column&quot;. When we apply our <span class=\"math inline\">\\(G_i\\)<\/span>, two rows are rotated which will affect entries above the matrix diagonal &#8212; but to the right, not to the top. The entries to the left, in those two rows, will already have been zeroed and it can be ignored.<\/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;[12]:<\/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=\"mf\">1.0<\/span><span class=\"p\">,<\/span> <span class=\"mf\">10.0<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">reshape<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">A<\/span>\n\n<span class=\"n\">col<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n<span class=\"k\">for<\/span> <span class=\"n\">row<\/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=\"mi\">1<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">)):<\/span> <span class=\"c1\"># row in [2, 1]<\/span>\n    <span class=\"c1\"># zeroing the lower row, <\/span>\n    <span class=\"c1\"># so row-1 is first arg and row is second arg<\/span>\n    <span class=\"n\">coeffs<\/span> <span class=\"o\">=<\/span> <span class=\"n\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">row<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">col<\/span><span class=\"p\">],<\/span> <span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">row<\/span><span class=\"p\">,<\/span> <span class=\"n\">col<\/span><span class=\"p\">])<\/span>\n    <span class=\"n\">left_givensT<\/span><span class=\"p\">(<\/span><span class=\"n\">coeffs<\/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\">row<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">row<\/span><span class=\"p\">)<\/span> \n    <span class=\"k\">print<\/span> <span class=\"n\">A<\/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[[  1.           2.           3.        ]\n [  8.06225775   9.42663983  10.79102191]\n [  0.          -0.3721042   -0.74420841]]\n[[  8.1240384    9.6011363   11.07823419]\n [  0.          -0.8244515   -1.648903  ]\n [  0.          -0.3721042   -0.74420841]]\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>We walk up a fixed column (here, the first column) and introduce zeros into it. As we do this, we only affect the two rows we are currently &quot;attacking&quot; (<code>row<\/code> and <code>row-1<\/code>). Since we&#8217;ll be processing the remaining columns, we don&#8217;t care that we&#8217;ve fiddled with the values. We&#8217;ll zero out the below-the-diagonal entries. But one quick question. We&#8217;re going to zero out much of the second column. When we rotate the bottom two rows, why don&#8217;t the zeros (that we introduced in the first pass) get modified as well?<\/p>\n<p>Consider the bottom-left position during the start of the second pass. When we compute <span class=\"math inline\">\\(G^TA\\)<\/span> (not Grandtheft Auto, btw), the position <span class=\"math inline\">\\((2,0)\\)<\/span> comes from <code>dot(G.T[2,:], A[:,0])<\/code> (i.e., the row-column rule of matrix multiplication). The two things being dotted are &quot;just&quot; vectors: let <code>g=G.T[2,:]<\/code> and <code>a=A[:,0]<\/code> for simplicity sake. <code>g<\/code> comes from a Givens rotation for <span class=\"math inline\">\\((1,2)\\)<\/span>, so the only entries that are non-zero are entries <code>1<\/code> and <code>2<\/code> (said another way, <code>g<\/code> is zero at position <code>1<\/code>). <code>a<\/code> currently has only one non-zero: position <code>0<\/code>. Put these two facts together and every term in the dot-product either gets a zero from <code>g<\/code> or from <code>a<\/code>. So, the whole dot-product is zero.<\/p>\n<p>As we introduce more and more zero below the diagonal, the same argument will hold for all spots to the left of our current &quot;working&quot; column and below the diagonal. Put the above code (which works for just one column) in a loop over all columns gives us:<\/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;[13]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"c1\"># GvL:  page 227 ...... algorithm 5.2.2<\/span>\n<span class=\"c1\"># updates A in-place to produce <\/span>\n<span class=\"k\">def<\/span> <span class=\"nf\">givens_qr<\/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\">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\">c<\/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=\"k\">for<\/span> <span class=\"n\">r<\/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\">c<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">m<\/span><span class=\"p\">)):<\/span>  <span class=\"c1\"># m-1, m-2, ... c+2, c+1<\/span>\n            <span class=\"c1\"># in this row and the previous row, use zeroing givens to<\/span>\n            <span class=\"c1\"># place a zero in the lower row<\/span>\n            <span class=\"n\">coeffs<\/span> <span class=\"o\">=<\/span> <span class=\"n\">zeroing_givens_coeffs<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">r<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">c<\/span><span class=\"p\">],<\/span> <span class=\"n\">A<\/span><span class=\"p\">[<\/span><span class=\"n\">r<\/span><span class=\"p\">,<\/span><span class=\"n\">c<\/span><span class=\"p\">])<\/span>\n            <span class=\"n\">left_givensT<\/span><span class=\"p\">(<\/span><span class=\"n\">coeffs<\/span><span class=\"p\">,<\/span> <span class=\"n\">A<\/span><span class=\"p\">[:,<\/span> <span class=\"n\">c<\/span><span class=\"p\">:],<\/span> <span class=\"n\">r<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">r<\/span><span class=\"p\">)<\/span> \n            <span class=\"c1\"># left_givensT(coeffs, A[r-1:r+1, c:], 0, 1)<\/span>\n            <span class=\"n\">left_givensT<\/span><span class=\"p\">(<\/span><span class=\"n\">coeffs<\/span><span class=\"p\">,<\/span> <span class=\"n\">Q<\/span><span class=\"p\">[:,<\/span> <span class=\"n\">c<\/span><span class=\"p\">:],<\/span> <span class=\"n\">r<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">r<\/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>There are more efficient ways to store and compute a product of Givens rotations. Here, we simply accumulate them in <span class=\"math inline\">\\(\\vec{Q}\\)<\/span>, which starts out as an identity matrix. See G&amp;VL (3rd), pages 217, 218, and 227, for more efficient possibilities.<\/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;[14]:<\/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=\"mf\">1.0<\/span><span class=\"p\">,<\/span> <span class=\"mf\">10.0<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">reshape<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">,<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">A<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;nla.qr&#39;s R&quot;<\/span>\n<span class=\"k\">print<\/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><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>[[ 1.  2.  3.]\n [ 4.  5.  6.]\n [ 7.  8.  9.]]\nnla.qr&apos;s R\n[[ -8.1240384   -9.6011363  -11.07823419]\n [  0.           0.90453403   1.80906807]\n [  0.           0.           0.        ]]\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;[15]:<\/div>\n<div class=\"inner_cell\">\n<div class=\"input_area\">\n<div class=\" highlight hl-ipython2\">\n<pre><span class=\"n\">givens_qr<\/span><span class=\"p\">(<\/span><span class=\"n\">A<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">print<\/span> <span class=\"s2\">&quot;my givens R&quot;<\/span>\n<span class=\"k\">print<\/span> <span class=\"n\">A<\/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>my givens R\n[[  8.1240384    9.6011363   11.07823419]\n [  0.           0.90453403   1.80906807]\n [  0.           0.           0.        ]]\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=\"conclusion\">Conclusion<\/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>Like many posts, I bit off more than I thought. This got a bit long winded and I have more to say about Givens rotations and using them to selectively zero out entried in a particular kind of matrix: an upper bidiagonal matrix that has, gasp!, a blemish. Until next time &#8230;<\/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\/GivensRotationsAndQR.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\/GivensRotationsAndQR.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>Today I want to talk about Givens rotations. Givens rotations are a generalization of the rotation matrix you might remember from high school trig class. Instead of rotating in the plane of a 2D matrix, we can rotated in any plane of a larger dimension matrix. We&#8217;ll use these rotations to selectively place zeros in [&hellip;]<\/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-434","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\/434","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=434"}],"version-history":[{"count":1,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/434\/revisions"}],"predecessor-version":[{"id":435,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/434\/revisions\/435"}],"wp:attachment":[{"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/media?parent=434"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/categories?post=434"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/tags?post=434"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}