A3 Scripts

(See ShowP at the end--it shows how one can do permutation matrix operations effectively in Matlab)

P1

     function [d,c,e] = HermFactor(a,g,h)
   % a is a real column n-vector.
   % g and h are real column (n-1)-vectors.
   % Let A be the n-by-n Hermitian tridiagonal matrix with diagonal a and subdiagonal 
   % c + i*e,  where i^2 = -1. Assume that A is positive definite so that it has
   % the factorization A = L*D*L' where D is diagonal and L is unit lower bidiagonal.
   % 
   % d is a real column n-vector so D = diag(d).
   % c and e are real column (n-1)-vectors so that the subdiagonal
   % of L is  c + i*e.




% Script P1: Tests HermFactor

clc
% Generate a random example...
randn('seed',0)
n = 6;
B = triu(tril(randn(n,n) + sqrt(-1)*randn(n,n)),-1);
A = B'*B;

% Extract the diagonal and the real and imaginary part of the
% subdiagonal...
a = diag(A); g = real(diag(A,-1)); h = imag(diag(A,-1));

% Get the LDL' factorization
[d,c,e] = HermFactor(a,g,h);
L = eye(n,n) + diag( c + sqrt(-1)*e,-1)
D = diag(d)
error = A - L*D*L'

 

P2

     function u = NegVec(A)
   % A is an n-by-n symmetric matrix with at least one nonpositive eigenvalue.
   % v is a unit 2-norm vector with the property that v'*A*v <= 0.
   
 
   
% Script P2: Tests NegVec

clc
rand('seed',0)
n = 6;
% Generate a random symmetric matrix with two negative eigenvalues
D = diag([ -.1 rand(1,n-2) -.3]);
[Q,R] = qr(rand(n,n));
A = 10*Q*D*Q'
Eigenvalues = eig(A)

% Get a vector of "negative curvature" and verify...
v = NegVec(A)
alfa = v'*A*v


     function [L,D] = LDLT(A)
   % A is an n-by-n symmetric matrix
   % L is unit lower triangular, and D is diagonal
   % so A = LDL'

     [n,n] = size(A);
     D = zeros(n,n);
     L = eye(n,n);
     for k=1:n
        D(k,k) = A(k,k);
        v = A(k+1:n,k);
        L(k+1:n,k) = v/D(k,k);
        A(k+1:n,k+1:n) = A(k+1:n,k+1:n) - L(k+1:n,k)*v';
     end



P3

     function [L,mu,pVec] = SkewBunchParlett(A)
   % A is an n-by-n symmetric matrix with n = 2m.
   % mu is a column m-vector, L is unit lower triangular, and pVec is a permutation of 1:n 
   % so that if P = I(:,pVec) then PAP' = LDL' is the Skew Bunch-Parlett factorization
   % where D = diag(D1,...,Dm), with Dk = [0 mu(k); -mu(k) 0] for k=1:m.




% Script P3: Tests SkewBunchParlett

clc
randn('seed',0)
disp('A small example..')

% Generate a random skew symmetric matrix...
n = 6;
A = randn(n,n); A = A- A'

% Compute the SkewBunchParlett factorization

[L,mu,pVec] = SkewBunchParlett(A);

% Display P*A*P' - L*D*L' ...

v = zeros(n-1,1);
v(1:2:n) = mu; 
D = -diag(v,-1) + diag(v,+1)
L = L
error = A(pVec,pVec) - L*D*L'


% A bigger problem..
disp(' ')
disp('An n = 500 example...')
n = 500;
A = randn(n,n); A = A- A';
[L,mu,pVec] = SkewBunchParlett(A);
v = zeros(n-1,1); v(1:2:n) = mu; 
D = -diag(v,-1) + diag(v,+1);
Error = norm(A(pVec,pVec) - L*D*L',1)/norm(A,1)

P4

     function x = SolveSkew(L,mu,pVec,b)
   % b is a column n-vector with n = 2m. Solves Ax = b where A is a nonsingular n-by-n 
   % skew-symmetric matrix and L, mu, and pVec are output from SkewBunchParlett(A).




% Script P4: Tests SolveSkew

clc
randn('seed',0);
n = 20;
A = randn(n,n); A = A - A';
[L,mu,pVec] = SkewBunchParlett(A);
b = randn(n,1);
x = SolveSkew(L,mu,pVec,b)
 
ShowP
% Permutation matrix representation and use

  n = 5;
  I = eye(n,n);
  A = magic(5); A = A + A';
  
  clc
  disp('Representation:')
  pVec = [ 2 4 1 5 3]
  P = I(pVec,:)
  pause
  
  clc
  disp('P times a vector')
  x = 10*(1:n)'
  disp('y = P*x'); disp(' ' ); disp(P*x)
  disp('z = x(pVec)') ; disp(' ');  disp(x(pVec))
  pause
  
  clc
  disp('P'' times a vector')
  P = P
  P_transpose = P'
  x = 10*(1:n)'
  disp('y = P''*x'); disp(' ' ); disp(P'*x)
  disp('z(pVec) = x') ; disp(' ');  z(pVec) = x; disp(z)
  pause
  
  clc
  disp('P times a matix')
  A = magic(5)
  P = P
  disp('B = P*A'); disp(' '); disp(P*A)
  disp('C = A(pVec,:)'); disp(' '); disp(A(pVec,:))
  pause
  
  clc
  disp('P times a matrix times P''')
  A = magic(5); A = A+A'
  P = P
  disp('B = P*A*P'''); disp(' '); disp(P*A*P')
  disp('C = A(pVec,pVec)'); disp(' '); disp(A(pVec,pVec))
  pause

  clc
  disp('P = P2*P1')
  disp(' ')
  disp('pVec1 = [2 4 1 5 3]'); pVec1 = [2 4 1 5 3];
  disp('P1 = I(pVec1,:)'); P1 = I(pVec1,:); disp(' '); disp(P1)
  disp(' ')
  disp('pVec2 = [4 5 3 1 2]'); pVec2 = [4 5 3 1 2];
  disp('P2 = I(pVec2,:)'); P2 = I(pVec2,:); disp(' '); disp(P2)
  disp(' ')
  disp('P = P2*P1'); P = P2*P1; disp(' '); disp(P)
  disp('pVec = pVec1(pVec2)'); pVec = pVec1(pVec2); disp(' '); disp(pVec)