Shifted Kronecker Product Systems
Matlab Codes
| KPShiftSolve | Shifted KP Problem Solve |
| HessLU | LU factorization of upper Hessenburg matrix |
| LBiDiSol | Solves Lx=b when L lower bi-diagonal |
| UTriSol | Solves Ux=b when U upper triangular |
| QuasiSolve | Solves (T-lambda*I)x=b when T upper quasi-triangular |
| KPvecprod | Computes M*x when M is a kronecker product of matrices |
function x = KPShiftSolve(A,n,b,lambda,alpha)
% Solves the shifted system
% (alpha x Ap x ... x A2 x A1 - lambda*eye(N,N)) x = b
%
% INPUTS:
% n : px1 vector of positive integers
% A : px1 cell array, where A{k} is an n(k)-by-n(k) upper
% quasi-tringular matrix, k=1:p
% b : Nx1 column vector, where N = n(1)*...*n(p).
% lambda : scalar
% alpha : 1-by-1 or 2-by-2 matrix [optional argument]
% If nargin == 4 then alpha is set to 1
%
% OUTPUTS:
% x : Nx1 vector which solves the above shifted system
p = length(n);
if nargin==4
alpha = 1;
end
if length(alpha)==1
A{p} = alpha*A{p};
if p==1
% if Hessenburg sys - call Hess solver
if all(diag(A{1},-1))
[v,U]=HessLU(A{1}-lambda*eye(n(1)));
y=LBiDiSol(v,b);
x=UTriSol(U,y);
else %not Hess - use quasi-triangular solver
x = QuasiSolve(A{1},b,lambda);
end
else
N = prod(n);
x = zeros(N,1);
mp = N/n(p);
i = n(p);
while (i>=1)
if (i>1) & (abs(A{p}(i,i-1)) > 0 )
%2-by-2 bump
alpha = A{p}(i-1:i,i-1:i);
idx = 1+(i-2)*mp:i*mp;
x(idx) = KPShiftSolve(A,n(1:p-1),b(idx),lambda,alpha);
z1 = KPvecprod(A,n(1:p-1),x(1+(i-2)*mp:(i-1)*mp));
z2 = KPvecprod(A,n(1:p-1),x(1+(i-1)*mp:i*mp));
for j=1:i-2
jdx = 1+(j-1)*mp:j*mp;
b(jdx) = b(jdx) - A{p}(j,i-1)*z1 - A{p}(j,i)*z2;
end
i = i-2;
else
%1-by-1 bump
alpha = A{p}(i,i);
idx = 1+(i-1)*mp:i*mp;
x(idx) = KPShiftSolve(A,n(1:p-1),b(idx),lambda,alpha);
z = KPvecprod(A,n(1:p-1),x(idx));
for j=1:i-1
jdx = 1+(j-1)*mp:j*mp;
b(jdx) = b(jdx) - A{p}(j,i)*z;
end
i = i-1;
end
end
end
else
% alpha is a 2-by-2 matrix with complex conjugate eigenvalues
[Q,T] = schur(alpha);
[Q,T] = rsf2csf(Q,T);
% c = (Q kron I)'b
m = length(b)/2;
c = reshape(reshape(b,m,2)*conj(Q),2*m,1);
% Solve (T kron A{p} kron ... kron A{1} - lambda I)z = c
A{p+1} = T; n(p+1) = 2;
z = KPShiftSolve(A,n,c,lambda);
% x = (Q kron I)z
x = reshape(reshape(z,m,2)*Q.',2*m,1);
if norm(imag(x))<=100*eps
x = real(x);
end
end
HessLU
function [v,U] = HessLU(A) % [v,U] = HessLU(A) % % Computes LU factorization of upper Hessenburg, where U % is upper triangular and L is lower unit triangular % % Inputs: % A : nxn upper Hessenburg matrix % % Outputs: % U : nxn upper triangular % v : nx1 column vector with the property that % L = I + diag(v(2:n),-1) [n,n] = size(A); v = zeros(n,1); for k=1:n-1 v(k+1) = A(k+1,k)/A(k,k); A(k+1,k:n) = A(k+1,k:n) - v(k+1)*A(k,k:n); end U = triu(A);
function x = LBiDiSol(l,b) % Solves Lx=b for x when L lower bi-diagonal % % Inputs: % l : nx1 column vector representing a lower bi-diagonal % matrix L, L = I + diag(l(2:n),-1) % b : nx1 column vector % % Outputs: % x : nx1 column vector, solution to Lx=b n = length(b); x = zeros(n,1); x(1) = b(1); for i=2:n x(i) = b(i) - l(i)*x(i-1); end
function x = UTriSol(U,b) % Solves Ux=b for x when U upper triangular % % Inputs: % U : nxn upper triangular % b : nx1 column vector % % Outputs: % x : nx1 column vector, solution to Ux=b n = length(b); x = zeros(n,1); for j=n:-1:2 x(j) = b(j)/U(j,j); b(1:j-1) = b(1:j-1) - x(j)*U(1:j-1,j); end x(1) = b(1)/U(1,1);
function x = QuasiSolve(T,b,lambda)
% Solves (T - lambda*I)x=b for x
%
% Inputs:
% lambda : scalar
% T : nxn upper quasi-triangular, (T - lambda*I nonsingular)
% b : nx1 column vector
%
% note: if nargin == 2 then lambda is set to zero
%
% Outputs:
% x : nx1 column vector, solution to (T - lambda*I)x=b
n = length(b);
x = zeros(n,1);
if nargin==2
lambda = 0;
end
k = n;
while (k>=1)
if k>1 & (abs(T(k,k-1)) > 0)
% 2-by-2
x(k-1:k) = (T(k-1:k,k-1:k) - lambda*eye(2,2))b(k-1:k);
b(1:k-2) = b(1:k-2) - T(1:k-2,k-1:k)*x(k-1:k);
k = k-2;
else
%1-by-1
x(k) = b(k)/(T(k,k)-lambda);
b(1:k-1) = b(1:k-1) - T(1:k-1,k)*x(k);
k = k-1;
end
end
KPvecprod
function y = KPvecprod(A,n,x)
% Computes y = (A{p} kron ... kron A{1})*x
% in 2N*(n(1) + ... + n(p)) flops
%
% Inputs:
% n : px1 vector of positive integers
% A : px1 cell array, each A{i} is n(i)-by-n(i)
%
% Outputs:
% x : Nx1 column vector, N=prod(n)
p = length(n);
N = prod(n);
m = N./n;
for i=1:p
x = (A{i}*reshape(x,n(i),m(i))).';
end
y = reshape(x,N,1);