{"id":1221,"date":"2015-06-29T12:00:34","date_gmt":"2015-06-29T17:00:34","guid":{"rendered":"https:\/\/blogs.mathworks.com\/cleve\/?p=1221"},"modified":"2018-02-09T11:29:53","modified_gmt":"2018-02-09T16:29:53","slug":"dubrulle-creates-a-faster-tridiagonal-qr-algorithm","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/cleve\/2015\/06\/29\/dubrulle-creates-a-faster-tridiagonal-qr-algorithm\/","title":{"rendered":"Dubrulle Creates A Faster Tridiagonal QR Algorithm"},"content":{"rendered":"<div class=\"content\">\r\n\r\n<!--introduction-->Augustin (Austin) Dubrulle deserves to be better known in the numerical linear algebra community. His version of the implicit QR algorithm for computing the eigenvalues of a symmetric tridiagonal matrix that was published in a half-page paper in <i>Numerische Mathematik<\/i> in 1970 is faster than Wilkinson's version published earlier. It is still a core algorithm in MATLAB today.\r\n\r\n<!--\/introduction-->\r\n<h3>Contents<\/h3>\r\n<div>\r\n<ul>\r\n \t<li><a href=\"#c5b6ab5c-cf7a-43dd-8f73-cb3909656232\">QR vs. QL<\/a><\/li>\r\n \t<li><a href=\"#dd0f630a-cc91-43e7-a894-8bded4b451ca\">Austin Dubrulle<\/a><\/li>\r\n \t<li><a href=\"#8e491b7b-3861-492e-80c9-a6731a5c1ff1\">Dubrulle's Paper<\/a><\/li>\r\n \t<li><a href=\"#42b58372-97f2-4965-b92f-26089f65cda8\">Underflow and Overflow<\/a><\/li>\r\n \t<li><a href=\"#cad7b12a-df9d-4ed7-9512-1ef25bb9ba27\">Handbook Alters History<\/a><\/li>\r\n \t<li><a href=\"#853b3b8e-1a77-4e19-81b5-f5a6a59ee8f4\">Impact Today<\/a><\/li>\r\n \t<li><a href=\"#d95af083-b5fa-4153-bf86-f69a72bb0dfc\">eigsvdgui<\/a><\/li>\r\n<\/ul>\r\n<\/div>\r\n<h4>QR vs. QL<a name=\"c5b6ab5c-cf7a-43dd-8f73-cb3909656232\"><\/a><\/h4>\r\n\"QR\" and \"QL\" are right- and left-handed, or forward and backward, versions of the same algorithm. We are used to thinking of factoring a matrix into an orthogonal factor, Q, and an upper or right triangular factor, R. This leads to QR algorithms. But for reasons having to do with starting a loop at $1$ rather than $n-1$, the authors of the Handbook Series on Linear Algebra decided to use left triangular and QL algorithms.\r\n<h4>Austin Dubrulle<a name=\"dd0f630a-cc91-43e7-a894-8bded4b451ca\"><\/a><\/h4>\r\nAugustin (Austin) Dubrulle is the only guy that I know who improved on an algorithm of Jim Wilkinson. Austin was born in France. He began his career in the early 1960's with IBM at their <i>Institut de Calcul Scientifique<\/i> in Paris. In 1968 he transferred to an IBM center in Houston, and began work on SSP, IBM's Scientific Subroutine Package.\r\n\r\nAfter studying papers and books by Wilkinson and Parlett, Austin derived his own version of the implicit QR algorithm for computing the eigenvalues of a symmetric tridiagonal matrix. He was careful about the use of common subexpressions to save operations. This is especially important when computing eigenvectors because the transformations are applied to an accompanying full matrix.\r\n\r\nAustin told me that he wrote up his result in the style of the Linear Algebra series in <i>Numerische Mathematik<\/i> and asked IBM for permission to submit the paper for publication. He was told by company lawyers that, in view of the Justice Department antitrust suit, IBM could not give away software, and that the ALGOL included in the paper was software. Austin tried to make the case that ALGOL was primarily a means of human communication and secondarily a programming language of little practical use, but that argument did not fly.\r\n\r\nWhen Martin and Wilkinson published their implicit algorithm, Austin was encouraged to realize that his version had fewer operations in the inner loop and so would be faster. He arranged to meet Wilkinson at the 1969 University of Michigan numerical analysis summer school. Jim encouraged Austin to submit a note with just the algorithm, no provocative software, to the series.\r\n\r\nHere is a recreation of Dubrulle's half-page 1970 paper in <i>Numerische Mathematik<\/i>. This is the entire paper. You can get the original here or purchase it <a href=\"http:\/\/link.springer.com\/article\/10.1007\/BF02165514\">here<\/a>.\r\n\r\n(You can get the Martin and Wilkinson contribution here or purchase it <a href=\"http:\/\/link.springer.com\/article\/10.1007%2FBF02161360#page-1\">here<\/a>.)\r\n<h4>Dubrulle's Paper<a name=\"8e491b7b-3861-492e-80c9-a6731a5c1ff1\"><\/a><\/h4>\r\n<pre>'********************************************************************************************'<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/cleve\/dubrulle_title.jpg\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nThe following is a formulation of the <i>QL<\/i> algorithm with implicit shift which requires fewer operations than the explicit and implicit algorithms described in [1] and [2].\r\n\r\nLet $d_i^{(s)}$ $(i=1,...,n)$ and $e_i^{(s)}$ $(i=1,...,n-1)$ be the diagonal and codiagonal elements of the matrix at the $s$ -th iteration and $k_s$ the shift. Then the $(s+1)$ -st iteration can be expressed as follows.\r\n\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/cleve\/dubrulle_eqns.jpg\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\n<i>Acknowledgements<\/i>. The author wishes to thank Dr. J.H. Wilkinson for his helpful comments\r\n\r\nReferences\r\n\r\n1. Bowdler, H., Martin, R.S., Reinsch, C., Wilkinson, J.H.: The QR and QL algorithms for symmetric matrices. Numerische Mathematik 11, 293-306 (1968).\r\n\r\n2. Martin, R. S., Wilkinson, J.H.: The implicit QL algorithm. Numerische Mathematik 12, 377-383 (1968).\r\n<pre>A. Dubrulle\r\nIBM Corporation\r\nIndustry Development-Scientific Applications\r\n6900 Fannin\r\nHouston, Texas 77025, U.S.A.<\/pre>\r\n<pre>'********************************************************************************************'<\/pre>\r\n<h4>Underflow and Overflow<a name=\"42b58372-97f2-4965-b92f-26089f65cda8\"><\/a><\/h4>\r\nDubrulle's algorithm still needs a little work. The computation of the next $e_{i+1}$ as the square root of the sum of squares is dangerous. There is potential for unnecessary underflow or overflow. I discussed this in a post almost two years ago on <a href=\"https:\/\/blogs.mathworks.com\/cleve\/2012\/07\/30\/pythagorean-addition\/\">Pythagorean Addition<\/a>. I don't suggest actually using the <i>pythag<\/i> algorithm. Instead, do something like this.\r\n<pre class=\"language-matlab\"><span class=\"keyword\">if<\/span> abs(p) &gt;= abs(q)\r\n   c = q\/p;  t = sqrt(1+c^2);\r\n   e(i+1) = t*p;  s = 1\/t;  c = c*s;\r\n<span class=\"keyword\">else<\/span>\r\n   s = p\/q;  t = sqrt(1+s^2);\r\n   e(i+1) = t*q;  c = 1\/t;  s = s*c;\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre>\r\n<h4>Handbook Alters History<a name=\"cad7b12a-df9d-4ed7-9512-1ef25bb9ba27\"><\/a><\/h4>\r\nWhen the papers from <i>Numerische Mathematik<\/i> were collected to form the 1971 <i>Handbook for Automatic Computation, Volume II, Linear Algebra<\/i>, almost all of them where reprinted without change. But, despite what its footnote says, Contribution II\/4, <i>The Implicit QL Algorithm<\/i>, never appeared in the journal. The paper is the merger of Dubrulle's note and the Martin-Wilkinson contribution that it references. The ALGOL procedures, <i>imtql1<\/i> and <i>imtql2<\/i>, are new.\r\n\r\nThe authors of Contribution II\/4 are A. Dubrulle, R.S.Martin, and J.H.Wilkinson, although the three of them never worked together. Proper credit is given, but I'm afraid that an interesting little bit of history has been lost.\r\n<h4>Impact Today<a name=\"853b3b8e-1a77-4e19-81b5-f5a6a59ee8f4\"><\/a><\/h4>\r\nDubrulle's version of the implicit tridiagonal QR algorithm continues to be important today. We had it in EISPACK. Look at the source for <a href=\"http:\/\/www.netlib.org\/eispack\/imtql1.f\">IMTQL1.F<\/a>. You will see code that is very similar to Austin's note. Except there is a call to a function <tt>PYTHAG<\/tt> to compute <tt>E(I+1)<\/tt>.\r\n\r\nIn LAPACK the <i>imtql1<\/i> and <i>imtql2<\/i> functions are combined into one subroutine named <a href=\"http:\/\/www.netlib.org\/lapack\/explore-html-3.3.1\/d9\/d3f\/dsteqr_8f_source.html\">DSTEQR.F<\/a> Here again you will see code that is very similar to Austin's note. Now <tt>PYTHAG<\/tt> is named <tt>DLATRG<\/tt>.\r\n\r\nI haven't run any timing experiments myself recently, but I have been told that the method of choice for the real symmetric matrix eigenvalue problem is Cuppen's divide and conquer algorithm, as perfected and implemented in LAPACK's <a href=\"http:\/\/www.netlib.org\/lapack\/lapack-3.1.1\/html\/dstedc.f.html\">DSTEDC.F<\/a>. A large problem is recursively broken into smaller ones. When the matrices become small enough, and eigenvectors are desired, DSTEQR is called. This is Dubrulle's version of implicit QR. Then the recursion is unwound to produce the final result.\r\n<h4>eigsvdgui<a name=\"d95af083-b5fa-4153-bf86-f69a72bb0dfc\"><\/a><\/h4>\r\nI could use an appropriate graphic for this post. Here is a picture of the tridiagonal QR algorithm in action, generated by <tt>eigsvdgui<\/tt> from <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/37976-numerical-computing-with-matlab\"><i>Numerical Computing with MATLAB<\/i><\/a>.\r\n\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/cleve\/eigsvdgui.jpg\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\n<script>\/\/ <![CDATA[\r\nfunction grabCode_2ed3b840dcc64a27a9f1cf969944263b() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='2ed3b840dcc64a27a9f1cf969944263b ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 2ed3b840dcc64a27a9f1cf969944263b';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2015 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('\r\n\r\n\r\n\r\n<\/p>\r\n<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\r\n<p>\r\n\r\n\r\n\r\n\r\n\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }\r\n\/\/ ]]><\/script>\r\n<p style=\"text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;\"><a><span style=\"font-size: x-small; font-style: italic;\">Get\r\nthe MATLAB code<noscript>(requires JavaScript)<\/noscript><\/span><\/a><\/p>\r\nPublished with MATLAB\u00ae R2015a\r\n\r\n<\/div>\r\n<!--\r\n2ed3b840dcc64a27a9f1cf969944263b ##### SOURCE BEGIN #####\r\n%% Dubrulle Creates A Faster Tridiagonal QR Algorithm\r\n% Augustin (Austin) Dubrulle deserves to be better known in the numerical\r\n% linear algebra community.  His version of the implicit QR algorithm for\r\n% computing the eigenvalues of a symmetric tridiagonal matrix that was\r\n% published in a half-page paper in _Numerische Mathematik_ in 1970 is faster\r\n% than Wilkinson's version published earlier.  It is still a core algorithm\r\n% in MATLAB today.\r\n\r\n%% QR vs. QL\r\n% \"QR\" and \"QL\" are right- and left-handed, or forward and backward, versions\r\n% of the same algorithm.  We are used to thinking of factoring a matrix into\r\n% an orthogonal factor, Q, and an upper or right triangular factor, R.  This\r\n% leads to QR algorithms.  But for reasons having to do with starting\r\n% a loop at $1$ rather than $n-1$, the authors of the Handbook Series on\r\n% Linear Algebra decided to use left triangular and QL algorithms.\r\n\r\n%% Austin Dubrulle\r\n% Augustin (Austin) Dubrulle is the only guy that I know who improved on an\r\n% algorithm of Jim Wilkinson.  Austin was born in France.  He began his career\r\n% in the early 1960's with IBM at their _Institut de Calcul Scientifique_\r\n% in Paris.  In 1968 he transferred to an IBM center in Houston,\r\n% and began work on SSP, IBM's Scientific Subroutine Package.\r\n\r\n%%\r\n% After studying papers and books by Wilkinson and Parlett, Austin derived\r\n% his own version of the implicit QR algorithm for computing the eigenvalues\r\n% of a symmetric tridiagonal matrix.  He was careful about the use of common\r\n% subexpressions to save operations.\r\n% This is especially important when computing eigenvectors\r\n% because the transformations are applied to an accompanying full matrix.\r\n\r\n%%\r\n% Austin told me that he wrote up his result in the style of the Linear Algebra\r\n% series in _Numerische Mathematik_ and asked IBM for permission to submit\r\n% the paper for publication.  He was told by company lawyers that, in view of\r\n% the Justice Department antitrust suit, IBM could not give away software,\r\n% and that the ALGOL included in the paper was software.  Austin tried to\r\n% make the case that ALGOL was primarily a means of human communication and\r\n% secondarily a programming language of little practical use, but that\r\n% argument did not fly.\r\n\r\n%%\r\n% When Martin and Wilkinson published their implicit algorithm, Austin was\r\n% encouraged to realize that his version had fewer operations in the inner\r\n% loop and so would be faster.  He arranged to meet Wilkinson at the 1969\r\n% University of Michigan numerical analysis summer school.\r\n% Jim encouraged Austin to submit a note with just the algorithm, no\r\n% provocative software, to the series.\r\n\r\n%%\r\n% Here is a recreation of Dubrulle's half-page 1970 paper in _Numerische\r\n% Mathematik_.  This is the entire paper.\r\n% You can get the original\r\n% < % here> or purchase it\r\n% <http:\/\/link.springer.com\/article\/10.1007\/BF02165514 here>.\r\n%\r\n\r\n%%\r\n% (You can get the Martin and Wilkinson contribution\r\n% < % here> or purchase it\r\n% <http:\/\/link.springer.com\/article\/10.1007%2FBF02161360#page-1 here>.)\r\n\r\n%% Dubrulle's Paper\r\n%  '**********************************************************************************************'\r\n%\r\n% <<dubrulle_title.jpg>>\r\n%\r\n% The following is a formulation of the _QL_ algorithm with implicit shift\r\n% which requires fewer operations than the explicit and implicit algorithms\r\n% described in [1] and [2].\r\n\r\n%%\r\n% Let $d_i^{(s)}$ $(i=1,...,n)$ and  $e_i^{(s)}$ $(i=1,...,n-1)$ be the diagonal\r\n% and codiagonal elements of the matrix at the $s$ -th iteration and $k_s$\r\n% the shift.  Then the $(s+1)$ -st iteration can be expressed as follows.\r\n%\r\n% <<dubrulle_eqns.jpg>>\r\n%\r\n\r\n%%\r\n% _Acknowledgements_. The author wishes to thank Dr. J.H. Wilkinson for his\r\n% helpful comments\r\n\r\n%%\r\n% References\r\n\r\n%%\r\n% 1. Bowdler, H., Martin, R.S., Reinsch, C., Wilkinson, J.H.: The QR and QL\r\n% algorithms for symmetric matrices. Numerische Mathematik 11, 293-306 (1968).\r\n\r\n%%\r\n% 2. Martin, R. S., Wilkinson, J.H.: The implicit QL algorithm. Numerische\r\n% Mathematik 12, 377-383 (1968).\r\n\r\n%%\r\n%  A. Dubrulle\r\n%  IBM Corporation\r\n%  Industry Development-Scientific Applications\r\n%  6900 Fannin\r\n%  Houston, Texas 77025, U.S.A.\r\n\r\n%%\r\n%  '**********************************************************************************************'\r\n%\r\n\r\n%% Underflow and Overflow\r\n% Dubrulle's algorithm still needs a little work.  The computation of the next\r\n% $e_{i+1}$ as the square root of the sum of squares is dangerous.\r\n% There is potential for unnecessary underflow or overflow.  I discussed this\r\n% in a post almost two years ago on\r\n% <https:\/\/blogs.mathworks.com\/cleve\/2012\/07\/30\/pythagorean-addition\/ % Pythagorean Addition>.  I don't suggest actually using the _pythag_ algorithm.\r\n% Instead, do something like this.\r\n%\r\n%   if abs(p) >= abs(q)\r\n%      c = q\/p;  t = sqrt(1+c^2);\r\n%      e(i+1) = t*p;  s = 1\/t;  c = c*s;\r\n%   else\r\n%      s = p\/q;  t = sqrt(1+s^2);\r\n%      e(i+1) = t*q;  c = 1\/t;  s = s*c;\r\n%   end\r\n\r\n%% Handbook Alters History\r\n% When the papers from _Numerische Mathematik_ were collected to form the\r\n% 1971 _Handbook for Automatic Computation, Volume II, Linear Algebra_,\r\n% almost all of them where reprinted without change.  But, despite what\r\n% its footnote says, Contribution II\/4, _The Implicit QL Algorithm_,\r\n% never appeared in the journal.  The paper is the merger of Dubrulle's note\r\n% and the Martin-Wilkinson contribution that it references.  The ALGOL\r\n% procedures, _imtql1_ and _imtql2_, are new.\r\n\r\n%%\r\n% The authors of Contribution II\/4 are A. Dubrulle, R.S.Martin,\r\n% and J.H.Wilkinson, although the three of them never worked together.\r\n% Proper credit is given, but I'm afraid that an interesting little bit\r\n% of history has been lost.\r\n\r\n%% Impact Today\r\n% Dubrulle's version of the implicit tridiagonal QR algorithm continues to\r\n% be important today.  We had it in EISPACK.  Look at the source for\r\n% <http:\/\/www.netlib.org\/eispack\/imtql1.f IMTQL1.F>.\r\n% You will see code that is very similar to Austin's note.  Except there\r\n% is a call to a function |PYTHAG| to compute |E(I+1)|.\r\n\r\n%%\r\n% In LAPACK the _imtql1_ and _imtql2_ functions are combined into one\r\n% subroutine named\r\n% <http:\/\/www.netlib.org\/lapack\/explore-html-3.3.1\/d9\/d3f\/dsteqr_8f_source.html % DSTEQR.F>\r\n% Here again you will see code that is very similar to Austin's note.\r\n% Now |PYTHAG| is named |DLATRG|.\r\n\r\n%%\r\n% I haven't run any timing experiments myself recently, but I have been\r\n% told that the method of choice for the real symmetric matrix eigenvalue\r\n% problem is Cuppen's divide and conquer algorithm, as perfected and\r\n% implemented in LAPACK's\r\n% <http:\/\/www.netlib.org\/lapack\/lapack-3.1.1\/html\/dstedc.f.html % DSTEDC.F>.  A large problem is recursively broken into smaller ones.\r\n% When the matrices become small enough, and eigenvectors are desired,\r\n% DSTEQR is called.  This is Dubrulle's version of implicit QR.\r\n% Then the recursion is unwound to produce the final result.\r\n\r\n%% eigsvdgui\r\n% I could use an appropriate graphic for this post.  Here is a picture of\r\n% the tridiagonal QR algorithm in action, generated by |eigsvdgui| from\r\n% <https:\/\/www.mathworks.com\/moler.htmlncmfilelist.html % _Numerical Computing with MATLAB_>.\r\n%\r\n% <<eigsvdgui.jpg>>\r\n%\r\n\r\n##### SOURCE END ##### 2ed3b840dcc64a27a9f1cf969944263b\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/feature_image\/eigsvdgui.jpg\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><!--introduction-->Augustin (Austin) Dubrulle deserves to be better known in the numerical linear algebra community. His version of the implicit QR algorithm for computing the eigenvalues of a symmetric tridiagonal matrix that was published in a half-page paper in <i>Numerische Mathematik<\/i> in 1970 is faster than Wilkinson's version published earlier. It is still a core algorithm in MATLAB today.\r\n\r\n<!--\/introduction-->... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/cleve\/2015\/06\/29\/dubrulle-creates-a-faster-tridiagonal-qr-algorithm\/\">read more >><\/a><\/p>","protected":false},"author":78,"featured_media":1226,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[11,4,6,16,8],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/1221"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/users\/78"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/comments?post=1221"}],"version-history":[{"count":6,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/1221\/revisions"}],"predecessor-version":[{"id":2994,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/1221\/revisions\/2994"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/media\/1226"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/media?parent=1221"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/categories?post=1221"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/tags?post=1221"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}