diff toolbox/bandred.m @ 2:c124219d7bfa draft

Re-add the 1995 toolbox after noticing the statement in the ~higham/mctoolbox/ webpage.
author Antonio Pino Robles <data.script93@gmail.com>
date Thu, 07 May 2015 18:36:24 +0200
parents 8f23314345f4
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolbox/bandred.m	Thu May 07 18:36:24 2015 +0200
@@ -0,0 +1,55 @@
+function A = bandred(A, kl, ku)
+%BANDRED  Band reduction by two-sided unitary transformations.
+%         B = BANDRED(A, KL, KU) is a matrix unitarily equivalent to A
+%         with lower bandwidth KL and upper bandwidth KU
+%         (i.e. B(i,j) = 0 if i > j+KL or j > i+KU).
+%         The reduction is performed using Householder transformations.
+%         If KU is omitted it defaults to KL.
+
+%         Called by RANDSVD.
+%         This is a `standard' reduction.  Cf. reduction to bidiagonal form
+%         prior to computing the SVD.  This code is a little wasteful in that
+%         it computes certain elements which are immediately set to zero!
+%
+%         Reference:
+%         G.H. Golub and C.F. Van Loan, Matrix Computations, second edition,
+%         Johns Hopkins University Press, Baltimore, Maryland, 1989.
+%         Section 5.4.3.
+
+if nargin == 2, ku = kl; end
+
+if kl == 0 & ku == 0
+   error('You''ve asked for a diagonal matrix.  In that case use the SVD!')
+end
+
+% Check for special case where order of left/right transformations matters.
+% Easiest approach is to work on the transpose, flipping back at the end.
+flip = 0;
+if ku == 0
+   A = A';
+   temp = kl; kl = ku; ku = temp; flip = 1;
+end
+
+[m, n] = size(A);
+
+for j=1 : min( min(m,n), max(m-kl-1,n-ku-1) )
+
+    if j+kl+1 <= m
+       [v, beta] = house(A(j+kl:m,j));
+       temp = A(j+kl:m,j:n);
+       A(j+kl:m,j:n) = temp - beta*v*(v'*temp);
+       A(j+kl+1:m,j) = zeros(m-j-kl,1);
+    end
+
+    if j+ku+1 <= n
+       [v, beta] = house(A(j,j+ku:n)');
+       temp = A(j:m,j+ku:n);
+       A(j:m,j+ku:n) = temp - beta*(temp*v)*v';
+       A(j,j+ku+1:n) = zeros(1,n-j-ku);
+    end
+
+end
+
+if flip
+   A = A';
+end