image thumbnail
from Linear Algebra Package by Brian Moore
Implements many common linear algebra functions in completely self-contained MATLAB code.

myCholesky(mat,varargin)
function varargout = myCholesky(mat,varargin)
%--------------------------------------------------------------------------
% Syntax:       L = myCholesky(mat);
%               L = myCholesky(mat,'lower');
%               U = myCholesky(mat,'upper');
%               [U D] = myCholesky(mat, 'UD');
%               [L D] = myCholesky(mat, 'LD');
%
% Inputs:       mat is a symmetric, positive definite square matrix
%               
%               Note: myCholesky() forces mat symmetric by only accesing
%               its upper triangle and assuming mat(i,j) = mat(j,i)
%               
%               mode can be {'upper','lower','UD','LD'}.
%               The default is 'lower'
%
% Outputs:      When mode == 'lower', L is a lower triangular matrix s.t.
%               mat = L * L';
%
%               When mode == 'upper', U is an upper triangular matrix s.t.
%               mat = U' * U;
%
%               When mode == 'UD', U is a unit upper triangular matrix,
%               and D is a diagonal matrix s.t.
%               mat = U * D * U';
%
%               When mode == 'LD', L is a unit lower triangular matrix,
%               and D is a diagonal matrix s.t.
%               mat = L' * D * L;
%
% Description:  This function computes the Cholesky or Unit Cholesky
%               Decomposition of the input square, positive definite, and
%               (assumed) symmetric matrix. If mat is not positive
%               definite, an error message is displayed.
%
%               Note: This script can easily be modified to test if a
%               symmetric matrix is positive definite.
%
% Author:       Brian Moore
%               brimoor@umich.edu
%
% Date:         June 28, 2012
%--------------------------------------------------------------------------

CHOL_TOL = 1e-15;
UD_TOL = 1e-15;

[n m] = size(mat);

if (n ~= m)
    error('Input matrix must be square');
end

if nargin > 1
    mode = varargin{1};
else
    mode = 'lower';
end

if (strcmpi(mode,'UD') || strcmpi(mode,'LD')) 
    U = zeros(n);
    D = zeros(n);
    
    for j = n:-1:1
        for i = j:-1:1
            sum = mat(i,j);
            for k = (j+1):n
                sum = sum - U(i,k) * D(k,k) * U(j,k);
            end
            if (i == j)
                if (sum <= UD_TOL)
                    error('Input matrix is not positive definite');
                else
                    D(j,j) = sum;
                    U(j,j) = 1;
                end
            else
                U(i,j) = sum / D(j,j);
            end
        end
    end
    
    if strcmpi(mode,'LD')
        varargout{1} = U';
        varargout{2} = D;
    else
        varargout{1} = U;
        varargout{2} = D;
    end
else
    L = mat;
    d = zeros(n,1);
    
    for i = 1:n
        for j = i:n
            sum = L(i,j);
            for k = (i-1):-1:1
                sum = sum - L(i,k)*L(j,k);
            end
            if (i == j)
                if (sum <= CHOL_TOL)
                    error('Input matrix is not positive definite');
                end
                d(i) = sqrt(sum);
            else
                L(j,i) = sum / d(i);
            end
        end
    end

    for i = 1:n
        for j = 1:(i-1)
            L(j,i) = 0;
        end
        L(i,i) = d(i);
    end

    if strcmpi(mode,'upper')
        varargout{1} = L';
    else
        varargout{1} = L;
    end
end

Contact us