function z = twist(d,l1,l2,mu)
% z = twist(d,l1,l2,mu)
%
% Given the Cholesky factorization of a Hermitian positive definite
% pentadiagonal matrix and a computed eigenvalue,
% compute the corresponding eigenvector using the twisted factorization. 
% inputs
%     d -- diagonal of Cholesky factor
% l1,l2 -- first and second subdiagonals of Cholesky factor 
%    mu -- computed eigenvalue
% output
%     z -- eigenvector corresponding to mu
%  dependency
%   cqds.m
%
% Nov. 2005

n = length(d);

% constant
tiny = 1.0e-12;    % tolerance for small gamma
% variable declaration
z = zeros(n,1);	   % eigenvector
%
% find quotient-differences with shift mu
[dl,ll1,ll2,du,u1,u2] = cqds(d,l1,l2,mu);
% 
% for j=1,..,n, compute the twisted factorization
%        L*L' - mu*I = Nj*Dj*Nj'
% where L = diag(d) + diag(l1,-1) + diag(l2,-2),
% Dj = diag([dl(1:j-2);x;gamma;du(j+1:n)]), and
% Nj = eye(n) + diag([ll1(1:j-2);yj;zeros(n-j,1)],-1) ...
%             + diag([ll2(1:j-2);zeros(n-j,1)],-2) ...
%             + diag([zeros(j-1,1);u1(j:n-1)],+1) ...
%             + diag([zeros(j-2,1);u2(j-1:n-2)],+2),
% and find the index of the min(abs(gamma)) and the corresponding yj. 
% j=1
gmin = abs(du(1));		   % abs(gamma(1))
indx = 1;                          % index of minimum abs(gamma)
% j=2
x = dl(1) - real(conj(u2(1))*u2(1))*du(3);
y = (ll1(1)*dl(1) - u1(2)*conj(u2(1))*du(3))/x;
gamma = du(2) - x*real(conj(y)*y);  % gamma(2)
agamma = abs(gamma);
if gmin > agamma 
    gmin = agamma;
    indx = 2;
end
for j=3:n-1
    x = dl(j-1) - real(u2(j-1)*conj(u2(j-1)))*du(j+1);
    yj = (ll1(j-1)*dl(j-1) - u1(j)*conj(u2(j-1))*du(j+1))/x;
    gamma = du(j) - real(conj(ll2(j-2))*ll2(j-2))*dl(j-2) ...
            - real(conj(yj)*yj)*x;   % gamma(j)
    agamma = abs(gamma);
    if gmin > agamma 
        gmin = agamma;
        indx = j;
        y = yj;
        if gmin < tiny              % found a small gamma
            break;
        end
    end
end
% j=n
gamma = dl(n);                      % gamma(n)
agamma = abs(gamma);
if gmin > agamma
    gmin = agamma;
    indx = n;
    y = ll1(n-1);
end
%
% the eigenvector z corresponding to mu is the solution for
%                     N_{indx}'*z = e_{indx}.
z(indx) = 1;
if indx > 1
    z(indx-1) = -conj(y);
end
if indx < n
    z(indx+1) = -conj(u1(indx));
    if indx > 1
        z(indx+1) = conj(u2(indx-1)*y) + z(indx+1);
    end
end
for j = indx-2:-1:1
    z(j) = -conj(ll1(j))*z(j+1) - conj(ll2(j))*z(j+2);
end
for j = indx+2:n
    z(j) = -conj(u2(j-2))*z(j-2) - conj(u1(j-1))*z(j-1);
end
z = z/norm(z);       % normalize
