i did an exercise with LU decomposition in Matlab, my professor highlighted some problems, but i don't understand what i should correct.
This is for the lower triangular matrix:
function b = triI(A,b)
n = length(A);
for i=1:n
for j=1:i-1
b(i) = b(i) - A(i,j)*b(j);
end
if A(i,i) == 0
error(’the matrix is singular’)
end
b(i) = b(i)/A(i,i);
end
This is for the lower triangular matrix:
function b = triS(A,b)
n = length(A);
for i=n:-1:1
for j=i+1:n
b(i) = b(i) - A(i,j)*b(j);
end
if A(i,i) == 0
error(’the matrix is singular’)
end
b(i) = b(i)/A(i,i);
end
LU decomposition
function x = solveLU(A,x)
n = lenght(A);
M = tril(A,-1)+eye(n);
x = solvetril(M,x);
M = triu(A);
x = solvetriu(M,x);
How can i resolve this? He said that it isn't a correct algorithm...
Thanks in advance!
Related
Can someone help me debug this Matlab code? Like I have a matrix A, and I need to find A^k by diagonalization method. Below is my original code, but there is a problem with this part:
m = (M - R(i,1)*eye(NumRowsR));
disp(rref(m));
t = null(rref(m));
disp(t);
This part can't give me the nullspace of matrix t after reduced for some reasons (I recently did some research on the Internet and see some people said about the bug of rref and null). The problem is that it keeps showing me elementary matrix
1 0 0
0 1 0
0 0 1
for the eigenvalues. Does anyone know how to fix it? I will be very much appreciated!
Below is my original code, for a better view:
syms x NumRowsM NumColsM NumRowsR NumColsR NumRowst NumColst k numeigen
M = input('Input a square matrix M: ');
k = input('Input the power of matrix M: ');
[NumRowsM, NumColsM]=size(M);
if (NumRowsM ~= NumColsM)
disp('Not valid input. Matrix must be a square matrix!')
else
%Find eigenvalues:
R = solve(det(M - x*eye(NumRowsM)), x);
[NumRowsR, NumColsR] = size(R);
if (or(NumRowsR == 0,NumColsR == 0))
disp('No eigenvalues. The matrix is not diagonalizable')
else
numeigen = 0;
F = zeros(NumRowsR, NumRowsR);
d = zeros(NumRowsR,1);
for i = 1:NumRowsR
m = (M - R(i,1)*eye(NumRowsR));
disp(rref(m));
t = null(rref(m));
disp(t);
[NumRowst, NumColst] = size(t);
if (NumColst == 0)
if (i == NumRowsR && numeigen > NumRowsR)
disp('Matrix not diagonalizable due to invalid eigenvalue');
return
else
continue
end
else
numeigen = numeigen + 1;
if (NumColst == 1)
for j = 1:NumRowsR
[n, d(j)] = numden(sym(t(j,1)));
end
for j = 1:NumRowsR
F(j,i) = sym(t(j,1)) * lcm(sym(d));
end
else
for k = 1:NumColst
for j = 1:NumRowsR
[n, d(j)] = numden(sym(t(j,k)));
end
for j = 1:NumRowsR
F(j,k) = sym(t(j,k)) * lcm(sym(d));
end
end
end
end
end
disp(F);
D = (F\M)*F;
disp('The power k of the matrix M is: ');
T = F*(D^k)/(F);
disp(T)
end
end
How do you write MATLAB code for LU factorization when U is the unit matrix instead of L. The upper triangular matrix will have the diagonal of 1s instead of the lower triangular matrix.
You are looking for Crout's Method for LU decomposition.
The Wikipedia article has the following code
function [L, U] = LUdecompCrout(A)
[R, C] = size(A);
for i = 1:R
L(i, 1) = A(i, 1);
U(i, i) = 1;
end
for j = 2:R
U(1, j) = A(1, j) / L(1, 1);
end
for i = 2:R
for j = 2:i
L(i, j) = A(i, j) - L(i, 1:j - 1) * U(1:j - 1, j);
end
for j = i + 1:R
U(i, j) = (A(i, j) - L(i, 1:i - 1) * U(1:i - 1, j)) / L(i,i);
end
end
end
Here's one way to do this. If M is your matrix,
[P,Q] = lu(M');
L = Q'; U = P';
Alternatively, assuming that M has an LU decomposition, we could do the following:
[L,U,P,Q,D] = lu(M);
L = L*P'*D*Q';
This should yield a lower triangular L and upper triangular U where U has 1's on the diagonal whenever M has an LU decomposition.
I have this code for LU decomposition but I want to include determinant of L and U so that the output will be determinant of LU or determinant of PLU.
function [ P, L, U ] = LUdecomposition(A)
A=input('matrix A =');
m = size(A);
n = m(1);
L = eye(n);
P = eye(n);
U = A;
for i=1:m(1)
if U(i,i)==0
maximum = max(abs(U(i:end,1)));
for k=1:n
if maximum == abs(U(k,i))
temp = U(1,:);
U(1,:) = U(k,:);
U(k,:) = temp;
temp = P(:,1);
P(1,:) = P(k,:);
P(k,:) = temp;
end
end
end
if U(i,i)~=1
temp = eye(n);
temp(i,i)=U(i,i);
L = L * temp;
U(i,:) = U(i,:)/U(i,i);
end
if i~=m(1)
for j=i+1:length(U)
temp = eye(n);
temp(j,i) = U(j,i);
L = L * temp;
U(j,:) = U(j,:)-U(j,i)*U(i,:);
end
end
end
P = P';
end
L and U are triangular matrices. So their determinants are the product of the diagonal elements. In a classical LU decomposition the diagonal elements of L are 1, therefore det(L) = 1. Because of A = L*U => det(A) = det(L)*det(U) you can easily compute the determinant of LU by computing the determinant of U. Therefore det(PLU) = + or - det(LU). I'm not sure how to figure it out :/
I am trying to implement my own LU decomposition with partial pivoting. My code is below and apparently is working fine, but for some matrices it gives different results when comparing with the built-in [L, U, P] = lu(A) function in matlab
Can anyone spot where is it wrong?
function [L, U, P] = lu_decomposition_pivot(A)
n = size(A,1);
Ak = A;
L = zeros(n);
U = zeros(n);
P = eye(n);
for k = 1:n-1
for i = k+1:n
[~,r] = max(abs(Ak(:,k)));
Ak([k r],:) = Ak([r k],:);
P([k r],:) = P([r k],:);
L(i,k) = Ak(i,k) / Ak(k,k);
for j = k+1:n
U(k,j-1) = Ak(k,j-1);
Ak(i,j) = Ak(i,j) - L(i,k)*Ak(k,j);
end
end
end
L(1:n+1:end) = 1;
U(:,end) = Ak(:,end);
return
Here are the two matrices I've tested with. The first one is correct, whereas the second has some elements inverted.
A = [1 2 0; 2 4 8; 3 -1 2];
A = [0.8443 0.1707 0.3111;
0.1948 0.2277 0.9234;
0.2259 0.4357 0.4302];
UPDATE
I have checked my code and corrected some bugs, but still there's something missing with the partial pivoting. In the first column the last two rows are always inverted (compared with the result of lu() in matlab)
function [L, U, P] = lu_decomposition_pivot(A)
n = size(A,1);
Ak = A;
L = eye(n);
U = zeros(n);
P = eye(n);
for k = 1:n-1
[~,r] = max(abs(Ak(k:end,k)));
r = n-(n-k+1)+r;
Ak([k r],:) = Ak([r k],:);
P([k r],:) = P([r k],:);
for i = k+1:n
L(i,k) = Ak(i,k) / Ak(k,k);
for j = 1:n
U(k,j) = Ak(k,j);
Ak(i,j) = Ak(i,j) - L(i,k)*Ak(k,j);
end
end
end
U(:,end) = Ak(:,end);
return
I forgot that If there was a swap in matrix P I had to swap also the matrix L. So just add the next line after after swapping P and everything will work excellent.
L([k r],:) = L([r k],:);
Both functions are not correct.
Here is the correct one.
function [L, U, P] = LU_pivot(A)
[m, n] = size(A); L=eye(n); P=eye(n); U=A;
for k=1:m-1
pivot=max(abs(U(k:m,k)))
for j=k:m
if(abs(U(j,k))==pivot)
ind=j
break;
end
end
U([k,ind],k:m)=U([ind,k],k:m)
L([k,ind],1:k-1)=L([ind,k],1:k-1)
P([k,ind],:)=P([ind,k],:)
for j=k+1:m
L(j,k)=U(j,k)/U(k,k)
U(j,k:m)=U(j,k:m)-L(j,k)*U(k,k:m)
end
pause;
end
end
My answer is here:
function [L, U, P] = LU_pivot(A)
[n, n1] = size(A); L=eye(n); P=eye(n); U=A;
for j = 1:n
[pivot m] = max(abs(U(j:n, j)));
m = m+j-1;
if m ~= j
U([m,j],:) = U([j,m], :); % interchange rows m and j in U
P([m,j],:) = P([j,m], :); % interchange rows m and j in P
if j >= 2; % very_important_point
L([m,j],1:j-1) = L([j,m], 1:j-1); % interchange rows m and j in columns 1:j-1 of L
end;
end
for i = j+1:n
L(i, j) = U(i, j) / U(j, j);
U(i, :) = U(i, :) - L(i, j)*U(j, :);
end
end
I need to evaluate following expression (in pseudo-math notation):
∑ipi⋅n
where p is a matrix of three-element vectors and n is a three-element vector. I can do this with for loops as follows but I can't figure out
how to vectorize this:
p = [1 1 1; 2 2 2];
n = [3 3 3];
s = 0;
for i = 1:size(p, 1)
s = s + dot(p(i, :), n)
end
Why complicate things? How about simple matrix multiplication:
s = sum(p * n(:))
where p is assumed to be an M-by-3 matrix.
I think you can do it with bsxfun:
sum(sum(bsxfun(#times,p,n)))
----------
% Is it the same for this case?
----------
n = 200; % depending on the computer it might be
m = 1000*n; % that n needs to be chosen differently
A = randn(n,m);
x = randn(n,1);
p = zeros(m,1);
q = zeros(1,m);
tic;
for i = 1:m
p(i) = sum(x.*A(:,i));
q(i) = sum(x.*A(:,i));
end
time = toc; disp(['time = ',num2str(time)]);