<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://zhengbo0503.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://zhengbo0503.github.io/" rel="alternate" type="text/html" /><updated>2026-04-06T20:31:16+00:00</updated><id>https://zhengbo0503.github.io/feed.xml</id><title type="html">Zhengbo Zhou (周正博)</title><subtitle>ZB Personal Website</subtitle><author><name>Zhengbo Zhou</name><email>zhengbo.zhou@postgrad.manchester.ac.uk</email></author><entry><title type="html">The Jacobi algorithm for eigenvalues</title><link href="https://zhengbo0503.github.io/posts/2023/12/blog-post-2/" rel="alternate" type="text/html" title="The Jacobi algorithm for eigenvalues" /><published>2023-12-08T00:00:00+00:00</published><updated>2023-12-08T00:00:00+00:00</updated><id>https://zhengbo0503.github.io/posts/2023/12/blog-post-2</id><content type="html" xml:base="https://zhengbo0503.github.io/posts/2023/12/blog-post-2/"><![CDATA[<h2 id="jacobi-algorithm">Jacobi algorithm</h2>
<p>Given a symmetric $A \in \mathbb{R}^{n\times n}$, 
the Jacobi algorithm produces a sequence of orthogonally similar 
matrices $A_{k+1} = J_{k}^{T} A_{k} J_{k}$ for $k = 1,2,\dots$,
$A_{1} = A$, and $J_{k}$ are the carefully constructed Jacobi rotations.
In fact, the Jacobi rotation is the same as the <a href="https://en.wikipedia.org/wiki/Givens_rotation">Givens rotation</a>, but we give the credit to the inventor, Carl G. J. Jacobi.</p>

<p>We now describe the $k$ th step of the Jacobi algorithm. 
We first choose a pivot $(i,j)$, 
and the task of this step is to eliminate $a_{ij}^{(k)}$
and $a_{ji}^{(k)}$. 
Let us now focused on the operations on the $(i,j)$ plane of iterates,
with 
\begin{equation}\notag
  A_{k}([i,j],[i,j]) = 
\begin{bmatrix}
  \alpha &amp; \gamma \ \gamma &amp; \beta
\end{bmatrix}.
\end{equation}
Then, the Jacobi algorithm will produce
\begin{equation}\label{eq1}
  A_{k+1}([i,j],[i,j]) = 
\begin{bmatrix}
  \widetilde{\alpha} &amp; 0 \ 0 &amp; \widetilde{\beta}
\end{bmatrix} = 
\begin{bmatrix}
  c &amp; s \ -s &amp; c 
\end{bmatrix}^T 
\begin{bmatrix}
  \alpha &amp; \gamma \ \gamma &amp; \beta
\end{bmatrix}
\begin{bmatrix}
  c &amp; s \ -s &amp; c 
\end{bmatrix},
\end{equation}
with specially chosen $c$ and $s$. 
Rutishauser in /Handbook for Automatic Computation/ provided a nice way to
compute the Jacobi rotation. He first computes a parameter $t$ by 
\begin{equation}\notag
  \displaystyle\zeta = \frac{\beta - \alpha}{2\gamma}, \quad 
t = {\rm sign}(\zeta)/(|\zeta| + \sqrt{1+\zeta^{2}}),
\end{equation}
with ${\rm sign}(0) = -1$, and then we have 
\begin{equation}\notag
  c = 1/\sqrt{1+t^{2}}, \quad s = ct. 
\end{equation}</p>

<h2 id="convergence-in-general">Convergence in general</h2>
<p>Define ${\rm off}(A) = \sqrt{\sum_{i &gt; j}^{} a_{ij}^{2}} = |A|<em>{F}^{2} -
\sum</em>{k=1}^{n}a_{kk}^{2}$.
Since the Jacobi rotation is orthogonal, we have 
$\widetilde{\alpha}^{2} + \widetilde{\beta}^{2} =<br />
\alpha^{2} + \beta^{2} + 2\gamma^{2}$.
More importantly, we have 
${\rm off}(A_{k+1})^{2} = {\rm off}(A_{k})^{2} - 2\gamma^{2}$.
Although later steps of the Jacobi algorithm can make $\gamma$ 
to become nonzero again, 
the above relation ensures the off-diagonal entries are decreasing
overall.</p>

<h2 id="pivot-strategies">Pivot strategies</h2>

<h3 id="classical-jacobi-algorithm">Classical Jacobi algorithm</h3>
<p>Jacobi in his original paper choose the largest in magnitude 
off-diagonal entries as the pivot element. 
The Jacobi algorithm with such choice is called the 
/classical Jacobi algorithm/. 
It has been proved by Jacobi that, the classical Jacobi algorithm 
converges linearly,
\begin{equation}\notag
\displaystyle 
  {\rm off}(A_{k+1}) \le \sqrt{1-1/N} {\rm off}(A),
\qquad N = \frac{n(n-1)}{2}. 
\end{equation}
We will call $N$ iterations as a sweep. 
Later, its local quadratic convergence has been proved by 
Henrici (/J. Soc. Indust. Appl. Math./ 6, 144–162, 1958), 
which said for large enough $i$, we have 
\begin{equation}\notag
  {\rm off}(A_{i+N}) \le c \cdot {\rm off}(A_{i})^{2},
\end{equation}
for some constant $c$.
This method does not attractive in practice, 
due to the searching time is more than the performing 
time ($O(n^{2})$ flops versus $O(n)$ flops)!</p>

<h3 id="cyclic-jacobi-algorithm">Cyclic Jacobi algorithm</h3>
<p>Gregory (/Math. Comp./ 7, 215-220, 1953) discussed choosing $a_{ij}$ in a row-by-row fashion, 
\begin{equation}\notag
  (i,j) = (1,2),\dots,(1,n),(2,3),\dots,(n-1,n),(1,2),\dots.
\end{equation}
This type of the Jacobi algorithm is known as the /cyclic Jacobi algorithm/. 
One requires the magnitude of the rotation angle  to be less than $\pi/4$ in order to achieve convergence. In fact, the difficulty of proving the convergence of the cyclic Jacobi algorithm is the possibility that the larger off-diagonal elements are always moving around /ahead/ of the current element.
The cyclic Jacobi algorithm is also asymptotically quadratically convergent like the classical Jacobi algorithm.</p>

<h2 id="implementation">Implementation</h2>
<p>The Jacobi algorithm for eigenvalues is not implemented in LAPACK. The only related routines in LAPACK Version 3.12.0 are <a href="https://www.netlib.org/lapack/explore-html/d9/deb/group__gesvj_ga7aec05d2a1523bbeee77ece21b12187c.html#ga7aec05d2a1523bbeee77ece21b12187c">DGESVJ</a> and <a href="https://www.netlib.org/lapack/explore-html/d8/d78/group__gejsv_gaca7ba7f1e8002c7a1d5bffa4ccbb541f.html#gaca7ba7f1e8002c7a1d5bffa4ccbb541f">DGEJSV</a> which use the /one-sided Jacobi algorithm/ to compute the singular values, see Drmač and Veselić (/SIAM J. Matrix Anal. Appl./ 29, 1322-1342, 2008).</p>

<p>** Further readings</p>
<ul>
  <li>Beresford N. Parlett, <a href="https://epubs.siam.org/doi/book/10.1137/1.9781611971163">The Symmetric Eigenvalue Problem</a>, xxiv+398, Society for Industrial and Applied Mathematics, 1998.</li>
  <li>James Demmel, <a href="https://epubs.siam.org/doi/book/10.1137/1.9781611971446">Applied Numerical Linear Algebra</a>, xi+416, Society for Industrial and Applied Mathematics, 1997</li>
</ul>]]></content><author><name>Zhengbo Zhou</name><email>zhengbo.zhou@postgrad.manchester.ac.uk</email></author><category term="Algorithm" /><category term="Spectral decomposition" /><summary type="html"><![CDATA[Jacobi algorithm Given a symmetric $A \in \mathbb{R}^{n\times n}$, the Jacobi algorithm produces a sequence of orthogonally similar matrices $A_{k+1} = J_{k}^{T} A_{k} J_{k}$ for $k = 1,2,\dots$, $A_{1} = A$, and $J_{k}$ are the carefully constructed Jacobi rotations. In fact, the Jacobi rotation is the same as the Givens rotation, but we give the credit to the inventor, Carl G. J. Jacobi.]]></summary></entry><entry><title type="html">A MATLAB function to generate random symmetric matrix</title><link href="https://zhengbo0503.github.io/posts/2023/12/blog-post-1/" rel="alternate" type="text/html" title="A MATLAB function to generate random symmetric matrix" /><published>2023-12-06T00:00:00+00:00</published><updated>2023-12-06T00:00:00+00:00</updated><id>https://zhengbo0503.github.io/posts/2023/12/blog-post-1</id><content type="html" xml:base="https://zhengbo0503.github.io/posts/2023/12/blog-post-1/"><![CDATA[<p>The MATLAB builtin function <code class="language-plaintext highlighter-rouge">gallery('randsvd',...)</code> can only generate a random matrix or a symmetric positive definite matrix. However, sometimes, we need to test our algorithms for symmetric matrices. Although you can get a symmetric matrix by <code class="language-plaintext highlighter-rouge">A = randn(n); A = A + A';</code>, it would be nice to inherit the features from <code class="language-plaintext highlighter-rouge">gallery('randsvd')</code>, such as the ability to control the distributions of the singular values. The attached code achieves such desire by</p>
<ul>
  <li>first, generate singular values,</li>
  <li>then construct a random orthogonal matrix using <code class="language-plaintext highlighter-rouge">qmult</code>, and</li>
  <li>finally multiply the orthogonal matrix at both sides of the diagonal matrix that contains these singular values.</li>
</ul>

<p>We modified the source code of <code class="language-plaintext highlighter-rouge">randsvd</code>, and using two additional functions:
<code class="language-plaintext highlighter-rouge">qmult</code> and <code class="language-plaintext highlighter-rouge">mysign</code>, which are all from Prof. Nicholas J. Higham.</p>

<ul>
  <li>Version: Thursday December 6, 2023</li>
  <li>Acknowledgement: Prof. Nicholas J. Higham</li>
</ul>

<div class="language-matlab highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">A</span> <span class="o">=</span> <span class="n">my_randsvd</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">kappa</span><span class="p">,</span> <span class="nb">mode</span><span class="p">)</span>
<span class="c1">%MY_RANDSVD Customized gallery('randsvd')</span>
<span class="c1">%  A = MY_RANDSVD(N, KAPPA, MODE) generates</span>
<span class="c1">%  a random symmetric matrix A of order N with </span>
<span class="c1">%  cond(A) = KAPPA and singular values from distribution MODE.</span>
<span class="c1">%</span>
<span class="c1">% Input :</span>
<span class="c1">%      N : Size of the matrix.</span>
<span class="c1">%</span>
<span class="c1">%  KAPPA : pre-defined 2-norm condition number for the output,</span>
<span class="c1">%          if kappa is negative, it will return a symmetric</span>
<span class="c1">%          positive definite matrix.</span>
<span class="c1">%		   Default value is 100.</span>
<span class="c1">% https://www.mathworks.com/help/matlab/ref/gallery.html </span>
<span class="c1">%  </span>
<span class="c1">%  </span>
<span class="c1">%   MODE : one of the following values:</span>
<span class="c1">%	       1: one large singular value,</span>
<span class="c1">%		   2: one small singular value,</span>
<span class="c1">%		   3: geometrically distributed singular values,</span>
<span class="c1">%		   4: arithmetically distributed singular values,</span>
<span class="c1">%		   5: random singular values with uniformly distributed</span>
<span class="c1">%		      logarithm.</span>
<span class="c1">%          Default value is 3. </span>
<span class="c1">%</span>
<span class="c1">% Reference:</span>
<span class="c1">% The MATLAB 'gallery' function.</span>
<span class="n">classname</span> <span class="o">=</span> <span class="s1">'double'</span><span class="p">;</span>

<span class="k">switch</span> <span class="nb">nargin</span>
	<span class="k">case</span> <span class="mi">1</span>
		<span class="n">kappa</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
		<span class="nb">mode</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
	<span class="k">case</span> <span class="mi">2</span>
		<span class="nb">mode</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="k">end</span>

<span class="c1">% check if we need export p.d. matrix</span>
<span class="k">if</span> <span class="nb">sign</span><span class="p">(</span><span class="n">kappa</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">pd</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="k">else</span><span class="p">,</span> <span class="n">pd</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="k">end</span>
<span class="n">kappa</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="n">kappa</span><span class="p">);</span>

<span class="k">switch</span> <span class="nb">mode</span> <span class="c1">% Set up vector of singular values</span>
	<span class="k">case</span> <span class="mi">1</span>
		<span class="n">sigma</span> <span class="o">=</span> <span class="nb">ones</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="p">/</span><span class="n">kappa</span><span class="p">;</span>
		<span class="n">sigma</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>

	<span class="k">case</span> <span class="mi">2</span>
		<span class="n">sigma</span> <span class="o">=</span> <span class="nb">ones</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span>
		<span class="n">sigma</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">=</span> <span class="mi">1</span><span class="p">/</span><span class="n">kappa</span><span class="p">;</span>

	<span class="k">case</span> <span class="mi">3</span>
		<span class="nb">factor</span> <span class="o">=</span> <span class="n">kappa</span><span class="o">^</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">/(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">));</span>
		<span class="n">sigma</span> <span class="o">=</span> <span class="nb">factor</span><span class="o">.^</span><span class="p">(</span><span class="mi">0</span><span class="p">:</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>

	<span class="k">case</span> <span class="mi">4</span>
		<span class="n">sigma</span> <span class="o">=</span> <span class="nb">ones</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="mi">0</span><span class="p">:</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">'</span><span class="p">/(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="mi">1</span><span class="p">/</span><span class="n">kappa</span><span class="p">);</span>

	<span class="k">case</span> <span class="mi">5</span>    <span class="c1">% In this case cond(A) &lt;= kappa.</span>
		<span class="n">sigma</span> <span class="o">=</span> <span class="nb">exp</span><span class="p">(</span> <span class="o">-</span><span class="nb">rand</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="nb">log</span><span class="p">(</span><span class="n">kappa</span><span class="p">)</span> <span class="p">);</span>

	<span class="k">otherwise</span>
		<span class="nb">error</span><span class="p">(</span><span class="n">message</span><span class="p">(</span><span class="s1">'MATLAB:randsvd:invalidMode'</span><span class="p">));</span>
<span class="k">end</span>

<span class="n">sigma</span> <span class="o">=</span> <span class="nb">cast</span><span class="p">(</span><span class="n">sigma</span><span class="p">,</span><span class="n">classname</span><span class="p">);</span>

<span class="k">if</span> <span class="o">~</span><span class="n">pd</span> <span class="c1">% randomly introducing signs</span>
	<span class="p">[</span><span class="n">l</span><span class="p">,</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="nb">size</span><span class="p">(</span><span class="n">sigma</span><span class="p">(</span><span class="mi">2</span><span class="p">:</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">));</span>
	<span class="n">signs</span> <span class="o">=</span> <span class="nb">sign</span><span class="p">(</span><span class="nb">rand</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">n</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">'</span><span class="p">;</span>
	<span class="n">signs</span> <span class="o">=</span> <span class="nb">reshape</span><span class="p">(</span><span class="n">signs</span><span class="p">,[</span><span class="n">l</span><span class="p">,</span><span class="n">j</span><span class="p">]);</span>
	<span class="n">sigma</span><span class="p">(</span><span class="mi">2</span><span class="p">:</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">=</span> <span class="n">sigma</span><span class="p">(</span><span class="mi">2</span><span class="p">:</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">.*</span> <span class="n">signs</span><span class="p">;</span>
<span class="k">end</span>

<span class="n">Q</span> <span class="o">=</span> <span class="n">qmult</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="n">classname</span><span class="p">);</span>
<span class="n">A</span> <span class="o">=</span> <span class="n">Q</span><span class="o">*</span><span class="nb">diag</span><span class="p">(</span><span class="n">sigma</span><span class="p">)</span><span class="o">*</span><span class="n">Q</span><span class="o">'</span><span class="p">;</span>
<span class="n">A</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span> <span class="o">+</span> <span class="n">A</span><span class="o">'</span><span class="p">)/</span><span class="mi">2</span><span class="p">;</span> <span class="c1">% ensure symmetry</span>

<span class="k">end</span>
</code></pre></div></div>

<p>Here is the code for <code class="language-plaintext highlighter-rouge">qmult</code> and <code class="language-plaintext highlighter-rouge">mysign</code>:</p>
<div class="language-matlab highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">B</span> <span class="o">=</span> <span class="n">qmult</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">method</span><span class="p">,</span><span class="n">classname</span><span class="p">)</span>
<span class="c1">%QMULT Pre-multiply matrix by random orthogonal matrix.</span>
<span class="c1">%   QMULT(A) returns Q*A where Q is a random real orthogonal matrix</span>
<span class="c1">%   from the Haar distribution of dimension the number of rows in A.</span>
<span class="c1">%   Special case: if A is a scalar then QMULT(A) is the same as QMULT(EYE(A)).</span>
<span class="c1">%   QMULT(A,METHOD) specifies how the computations are carried out.</span>
<span class="c1">%   METHOD = 0 is the default, while METHOD = 1 uses a call to QR,</span>
<span class="c1">%   which is much faster for large dimensions, even though it uses more flops.</span>

<span class="c1">%   Called by RANDCOLU, RANDCORR, RANDJORTH, RANDSVD.</span>

<span class="c1">%   Reference:</span>
<span class="c1">%   G. W. Stewart, The efficient generation of random</span>
<span class="c1">%   orthogonal matrices with an application to condition estimators,</span>
<span class="c1">%   SIAM J. Numer. Anal., 17 (1980), 403-409.</span>
<span class="c1">%</span>
<span class="c1">%   Nicholas J. Higham</span>
<span class="c1">%   Copyright 1984-2020 The MathWorks, Inc.</span>

<span class="k">if</span> <span class="nb">nargin</span> <span class="o">&lt;</span> <span class="mi">2</span> <span class="o">||</span> <span class="nb">isempty</span><span class="p">(</span><span class="n">method</span><span class="p">)</span>
	<span class="n">method</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">end</span>
<span class="c1">%  Handle scalar A.</span>
<span class="k">if</span> <span class="nb">isscalar</span><span class="p">(</span><span class="n">A</span><span class="p">)</span>
	<span class="n">n</span> <span class="o">=</span> <span class="n">A</span><span class="p">;</span>
	<span class="n">A</span> <span class="o">=</span> <span class="nb">eye</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="n">classname</span><span class="p">);</span>
<span class="k">else</span>
	<span class="n">n</span> <span class="o">=</span> <span class="nb">size</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">end</span>
<span class="k">if</span> <span class="nb">isempty</span><span class="p">(</span><span class="n">A</span><span class="p">)</span> <span class="c1">% nothing to do.</span>
	<span class="n">B</span> <span class="o">=</span> <span class="n">A</span><span class="p">;</span>
	<span class="k">return</span>
<span class="k">end</span>
<span class="k">if</span> <span class="n">method</span> <span class="o">==</span> <span class="mi">1</span>
	<span class="p">[</span><span class="n">Q</span><span class="p">,</span><span class="n">R</span><span class="p">]</span> <span class="o">=</span> <span class="nb">qr</span><span class="p">(</span><span class="nb">randn</span><span class="p">(</span><span class="n">n</span><span class="p">));</span>
	<span class="n">B</span> <span class="o">=</span> <span class="n">Q</span><span class="o">*</span><span class="nb">diag</span><span class="p">(</span><span class="nb">sign</span><span class="p">(</span><span class="nb">diag</span><span class="p">(</span><span class="n">R</span><span class="p">)))</span><span class="o">*</span><span class="n">A</span><span class="p">;</span>
	<span class="k">return</span>
<span class="k">end</span>
<span class="n">d</span> <span class="o">=</span> <span class="nb">zeros</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="n">classname</span><span class="p">);</span>
<span class="k">for</span> <span class="n">k</span> <span class="o">=</span> <span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">:</span><span class="mi">1</span>
	<span class="c1">% Generate random Householder transformation.</span>
	<span class="n">x</span> <span class="o">=</span> <span class="nb">randn</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="n">k</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span>
	<span class="n">s</span> <span class="o">=</span> <span class="nb">norm</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
	<span class="n">sgn</span> <span class="o">=</span> <span class="n">mysign</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="n">s</span> <span class="o">=</span> <span class="n">sgn</span><span class="o">*</span><span class="n">s</span><span class="p">;</span>
	<span class="n">d</span><span class="p">(</span><span class="n">k</span><span class="p">)</span> <span class="o">=</span> <span class="o">-</span><span class="n">sgn</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="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">s</span><span class="p">;</span>
	<span class="nb">beta</span> <span class="o">=</span> <span class="n">s</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="c1">% Apply the transformation to A.</span>
	<span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="o">'*</span><span class="n">A</span><span class="p">(</span><span class="n">k</span><span class="p">:</span><span class="n">n</span><span class="p">,:);</span>
	<span class="n">A</span><span class="p">(</span><span class="n">k</span><span class="p">:</span><span class="n">n</span><span class="p">,:)</span> <span class="o">=</span> <span class="n">A</span><span class="p">(</span><span class="n">k</span><span class="p">:</span><span class="n">n</span><span class="p">,:)</span> <span class="o">-</span> <span class="n">x</span><span class="o">*</span><span class="p">(</span><span class="n">y</span><span class="p">/</span><span class="nb">beta</span><span class="p">);</span>
<span class="k">end</span>
<span class="c1">% Tidy up signs.</span>
<span class="k">for</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">:</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span>
	<span class="n">A</span><span class="p">(</span><span class="n">i</span><span class="p">,:)</span> <span class="o">=</span> <span class="n">d</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="o">*</span><span class="n">A</span><span class="p">(</span><span class="n">i</span><span class="p">,:);</span>
<span class="k">end</span>
<span class="n">A</span><span class="p">(</span><span class="n">n</span><span class="p">,:)</span> <span class="o">=</span> <span class="n">A</span><span class="p">(</span><span class="n">n</span><span class="p">,:)</span><span class="o">*</span><span class="n">mysign</span><span class="p">(</span><span class="nb">randn</span><span class="p">);</span>
<span class="n">B</span> <span class="o">=</span> <span class="n">A</span><span class="p">;</span>
<span class="k">end</span>
</code></pre></div></div>

<div class="language-matlab highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">S</span> <span class="o">=</span> <span class="n">mysign</span><span class="p">(</span><span class="n">A</span><span class="p">)</span>
<span class="c1">%MYSIGN True sign function with MYSIGN(0) = 1.</span>

<span class="c1">%   Called by various matrices in elmat/private.</span>
<span class="c1">%</span>
<span class="c1">%   Nicholas J. Higham</span>
<span class="c1">%   Copyright 1984-2013 The MathWorks, Inc.</span>
<span class="n">S</span> <span class="o">=</span> <span class="nb">sign</span><span class="p">(</span><span class="n">A</span><span class="p">);</span>
<span class="n">S</span><span class="p">(</span><span class="n">S</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">end</span>
</code></pre></div></div>]]></content><author><name>Zhengbo Zhou</name><email>zhengbo.zhou@postgrad.manchester.ac.uk</email></author><category term="MATLAB" /><category term="Symmetric matrix" /><category term="Random matrix" /><summary type="html"><![CDATA[The MATLAB builtin function gallery('randsvd',...) can only generate a random matrix or a symmetric positive definite matrix. However, sometimes, we need to test our algorithms for symmetric matrices. Although you can get a symmetric matrix by A = randn(n); A = A + A';, it would be nice to inherit the features from gallery('randsvd'), such as the ability to control the distributions of the singular values. The attached code achieves such desire by first, generate singular values, then construct a random orthogonal matrix using qmult, and finally multiply the orthogonal matrix at both sides of the diagonal matrix that contains these singular values.]]></summary></entry></feed>