6

If I want to solve a full upper triangular system, I can call linsolve(A,b,'UT'). However this currently is not supported for sparse matrices. How can I overcome this?

Jacob
  • 34,255
  • 14
  • 110
  • 165
olamundo
  • 23,991
  • 34
  • 108
  • 149

3 Answers3

4

UT and LT systems are amongst the easiest systems to solve. Have a read on the wiki about it. Knowing this, it is easy to write your own UT or LT solver:

%# some example data
A = sparse( triu(rand(100)) );
b = rand(100,1);

%# solve UT system by back substitution    
x = zeros(size(b));
for n = size(A,1):-1:1    
    x(n) = (b(n) - A(n,n+1:end)*x(n+1:end) ) / A(n,n);    
end

The procedure is quite similar for LT systems.

Having said that, it is generally much easier and faster to use Matlab's backslash operator:

x = A\b

which also works for spares matrices, as nate already indicated.

Note that this operator also solves UT systems which have non-square A or if A has some elements equal to zero (or < eps) on the main diagonal. It solves these cases in a least-squares sense, which may or may not be desirable for you. You could check for these cases before carrying out the solve:

if size(A,1)==size(A,2) && all(abs(diag(A)) > eps)
    x = A\b;
else
    %# error, warning, whatever you want
end

Read more about the (back)slash operator by typing

>> help \

or

>> help slash

on the Matlab command prompt.

Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96
  • Of course I can implement that back substitution myself, I thought that is obvious :) the problem is that for-loops are generally avoided in matlab as they are very slow. Is the slash operation guaranteed to use back substitution for triangular matrices? – olamundo Oct 07 '12 at 12:02
  • @noam: Have a look [here](http://scicomp.stackexchange.com/questions/1001/how-does-the-matlab-backslash-operator-solve-ax-b-for-square-matrices). – Rody Oldenhuis Oct 07 '12 at 17:53
  • 1
    \ is a backslash , or left division (`mldivide`), while `/`is a slash, or right division (`mrdivide`). – angainor Oct 08 '12 at 08:45
  • You used word `slash` for \, which is `backslash`. Just to be picky ;) – angainor Oct 08 '12 at 10:15
  • @angainor: Have you typed `help backslash`? you'll get an error. Type `help slash` and you get info on all (back)slash operators :) – Rody Oldenhuis Oct 08 '12 at 10:20
  • I am referring to the line `Having said that, it is generally much easier and faster to use Matlab's slash operator: x=A\b`. This is in fact a backslash.. – angainor Oct 08 '12 at 10:21
3

Edit Since what you need is a triangular solve procedure, also called backward/forward substitution, you can use ordinary MATLAB backslash \ operator for that:

x = U\b

As mentioned in the original answer, MATLAB will recognise the fact that your matrix is triangular. To be sure of that, you can compare the performance to cs_usolve procedure found in SuiteSparse. It is a mex function implemented in C that computes sparse triangular solve for upper-triangular sparse matrix (there are similar functions there too: cs_lsolve, cs_utsolve and cs_ltsolve).

You can have a look at a performance comparison of native MATLAB and cs_l(t)solve in the context of sparse Cholesky factorization. Essentially, MATLAB performance is good. The only pitfall is if you want to solve a transposed system

x = U'\b

MATLAB does not recognize that and explicitly creates a transpose of U. In that case you should call cs_utsolve explicitly.

Original answer If your system is symmetric and you only store the upper triangular matrix part (that is how I understood full in your question), and if Cholesky decomposition is suitable for you, chol handles symmetric matrices, if your matrix is positive definite. For indefinite matrices you can use ldl. Both handle sparse storage and work on the symmetric matrix parts.

Newer matlab versions use cholmod and suitesparse for that. That is by far the best performing Cholesky factorization I know of. In matlab it is also parallelised usin parallel BALS.

The factor you obtain from the above functions is upper triangular matrix L such that

A=LL'

All you need to do now is perform forward and backward substitution, which is simple and cheap. In matlab this is automatically done in tha backslash operator

x=L'\(L\b)

the matrix can be sparse, and matlab will recognise that it is upper/lower triangular. You would also use this call together with forward substitution for factors obtained using the cholesky factorization.

angainor
  • 11,760
  • 2
  • 36
  • 56
  • 2
    I think he means `A = triu(...)` (full) vs `A = sparse(triu(...))` (sparse) – Rody Oldenhuis Oct 07 '12 at 09:00
  • @RodyOldenhuis Oh, now I read it again I think you are right. But my answer anyway includes information about triangular solves (backward/forward substitution) - in the end this is what you do after you factorize your matrix anyway :) – angainor Oct 07 '12 at 09:17
1

you can use MLDIVIDE( \ ) or MRDIVIDE( / ) operators on your sparse matrices...

bla
  • 25,846
  • 10
  • 70
  • 101