Given a matrix X and its vector form I am after the most efficient way to build the matrices L and U which extracts the lower and upper triangle from X.
So in MATLAB code it would be something like that:
clear();numRows = 3;numCols = numRows;mX = randn(numRows, numCols);vX = mX(:);% Lower Triangle are indices 2, 3, 6
mL = [ 0, 1, 0, 0, 0, 0, 0, 0, 0 ; ... 0, 0, 1, 0, 0, 0, 0, 0, 0 ; ... 0, 0, 0, 0, 0, 1, 0, 0, 0 ];% Upper Triangle are indices 4, 7, 8
mU = [ 0, 0, 0, 1, 0, 0, 0, 0, 0 ; ... 0, 0, 0, 0, 0, 0, 1, 0, 0 ; ... 0, 0, 0, 0, 0, 0, 0, 1, 0 ];assert(isequal(mL * vX, mX(logical(tril(mX, -1)))));assert(isequal(mU * vX, mX(logical(triu(mX, 1)))));
I am after sparse represenation of mU and mL in the most efficient way.
My current implementation is given by:
function [ mLU ] = GenerateTriangleExtractorMatrix( numRows, triangleFlag, diagFlag )EXTRACT_LOWER_TRIANGLE = 1;EXTRACT_UPPER_TRIANGLE = 2;INCLUDE_DIAGONAL = 1;EXCLUDE_DIAGONAL = 2;switch(diagFlag) case(INCLUDE_DIAGONAL) numElements = 0.5 * numRows * (numRows + 1); diagIdx = 0; case(EXCLUDE_DIAGONAL) numElements = 0.5 * (numRows - 1) * numRows; diagIdx = 1;endvJ = zeros(numElements, 1);if(triangleFlag == EXTRACT_LOWER_TRIANGLE) elmntIdx = 0; for jj = 1:numRows for ii = (jj + diagIdx):numRows elmntIdx = elmntIdx + 1; vJ(elmntIdx) = ((jj - 1) * numRows) + ii; end endelseif(triangleFlag == EXTRACT_UPPER_TRIANGLE) elmntIdx = numElements + 1; for jj = numRows:-1:1 for ii = (jj - diagIdx):-1:1 elmntIdx = elmntIdx - 1; vJ(elmntIdx) = ((jj - 1) * numRows) + ii; end endendmLU = sparse(1:numElements, vJ, 1, numElements, numRows * numRows, numElements);end
Is there a more efficient way to generate vJ without extensive allocation of memory (In order to allow generating really large matrices)?
Thank You.
Best Answer