Compute a matrix inverse by repeatedly solving n linear systems - matlab

I am trying to solve this problem. But I keep getting an error.
This is my First Code.
% Program 3.3
function [L, U, P] = lufact(A)
[N, N] = size(A);
X = zeros(N, 1);
Y = zeros(N, 1);
C = zeros(1, N);
R = 1:N;
for p = 1: N-1
[max1, j] = max(abs(A(p:N, p)));
C = A(p,:);
A(p,:) = A(j + p - 1,:);
A(j + p -1, :) = C;
d = R(p);
R(p) = R(j + p -1);
R(j + p - 1) = d;
if A(p,p) == 0
'A is Singular. No unique Solution'
break
end
for k = p + 1:N
mult = A(k,p)/A(p,p);
A(k,p) = mult;
A(k,p + 1:N) = A(k, p + 1:N) - mult *A(p, p + 1:N);
end
I=(1:N)'*ones(1,N,1); J=I';
L = (I>J).*A + eye(N);
U = (J>=I).*A;
P = zeros(N);
for k=1:N
P(k,R(k))=1;
end
end
X(N) = Y(N)/A(N,N);
for k = N-1: -1: 1
X(k) = (Y(k) - A(k, k+1:N)*X(k+1:N))/A(k,k);
end
And This is my 2nd Code which I'm using to solve this problem.
function B = Ques3(A)
% Computes the inverse of a matrix A
[L,U,P] = lufact(A);
N = max(size(A));
I = eye(N);
B = zeros(N);
for j = 1:N
Y = forsub(L,P*I(:,j));
B(:,j) = backsub(U,Y);
end
But I keep getting an error in MATLAB,
>> Ques3(A)
Unrecognized function or variable 'forsub'.
Error in Ques3 (line 12)
Y = forsub(L,P*I(:,j));

Related

How to display a function with double values instead of symbolic?

I want the function P to look like this:
-1 + 0.6366*(x+pi/2) + (-0.000)*(x + pi/2)*(x)
and right now it looks like this
(5734161139222659*x)/9007199254740992 + (5734161139222659*pi)/18014398509481984 - (8131029572207409*x*(x + pi/2))/324518553658426726783156020576256 - 1.
How to convert S array so that the values are not symbolic?
syms P x
f = sin(x);
f = matlabFunction(f);
X = [-pi/2, 0, pi/2];
Y = f(sym(X));
P = MetN(X,Y,x)
P = matlabFunction(P);
function [P] = MetN(X,Y,x)
n = length(X);
for i = 1:n
A(i,1) = 1;
end
for i = 2:n
for j = 2: n
if i >= j
produs = 1;
for k =1:j-1
produs = produs * (X(i) - X(k));
end
A(i,j) = produs;
end
end
end
S = SubsAsc(A, Y);
S = double(S);
disp(S);
sym produs
P = double(sym(S(1)));
for i = 2:n
produs = 1;
for j = 1:i-1
produs = produs * (x - sym(X(j)));
end
disp(produs);
P = P + double(S(i))*produs;
end
end
function [x] = SubsAsc(A,b)
n = length(b);
x(1) = (1/A(1,1))*b(1);
for k = 2:n
s = 0;
for j = 1:k-1
s = s + A(k,j)*x(j);
end
x(k) = (1/A(k,k))*(b(k)-s);
end
end
The output you currently have is because symbolic uses exact arithmetic, so it outputs it as a rational number (hence the ugly fraction).
To have it output P using decimals, use vpa(). For instance output P using decimals to 5 significant digits
>> vpa(P, 5)
ans =
0.63662*x - 2.5056e-17*x*(x + 1.5708)
This will, however, also round pi, so you can't really have the best of both worlds here.

Undefined function or variable 'x'

I am trying to evaluate two matrixes which I defined outside of the function MetNewtonSist using subs and I get the error Undefined function or variable 'x' whenever I try to run the code.
[edit] I added the code for the GaussPivTot function which determines the solution of a liniear system.
syms x y
f1 = x^2 + y^2 -4;
f2 = (x^2)/8 - y;
J = jacobian( [ f1, f2 ], [x, y]);
F = [f1; f2];
subs(J, {x,y}, {1, 1})
eps = 10^(-6);
[ x_aprox,y_aprox, N ] = MetNewtonSist( F, J, 1, 1, eps )
function [x_aprox, y_aprox, N] = MetNewtonSist(F, J, x0, y0, eps)
k = 1;
x_v(1) = x0;
y_v(1) = y0;
while true
k = k + 1;
z = GaussPivTot(subs(J, {x, y}, {x_v(k-1), y_v(k-1)}),-subs(F,{x, y}, {x_v(k-1), y_v(k-1)}));
x_v(k) = z(1) + x_v(k-1);
y_v(k) = z(1) + y_v(k-1);
if norm(z)/norm([x_v(k-1), y_v(k-1)]) < eps
return
end
end
N = k;
x_aprox = x_v(k);
y_aprox = y_v(k);
end
function [x] = GaussPivTot(A,b)
n = length(b);
A = [A,b];
index = 1:n;
for k = 1:n-1
max = 0;
for i = k:n
for j = k:n
if A(i,j) > max
max = A(i,j);
p = i;
m = j;
end
end
end
if A(p,m) == 0
disp('Sist. incomp. sau comp. nedet.')
return;
end
if p ~= k
aux_line = A(p,:);
A(p,:) = A(k, :);
A(k,:) = aux_line;
end
if m ~= k
aux_col = A(:,m);
A(:,m) = A(:,k);
A(:,k) = aux_col;
aux_index = index(m);
index(m) = index(k);
index(k) = aux_index;
end
for l = k+1:n
M(l,k) = A(l,k)/A(k,k);
aux_line = A(l,:);
A(l,:) = aux_line - M(l,k)*A(k,:);
end
end
if A(n,n) == 0
disp('Sist. incomp. sau comp. nedet.')
return;
end
y = SubsDesc(A, A(:,n+1));
for i = 1:n
x(index(i)) = y(i);
end
end
By default, eps is defined as 2.2204e-16 in MATLAB. So do not overwrite it with your variable and name it any word else.
epsilon = 1e-6;
Coming to your actual issue, pass x and y as input arguments to the MetNewtonSist function. i.e. define MetNewtonSist as:
function [x_aprox, y_aprox, N] = MetNewtonSist(F, J, x0, y0, epsilon, x, y)
%added x and y and renamed eps to epsilon
and then call it with:
[x_aprox, y_aprox, N] = MetNewtonSist(F, J, 1, 1, epsilon, x, y);

QR factorization,matlab

%% Gram—Schmidt as Triangular Orthogonalization
clear
M = [1,1,1; 1,1,0; 1,1,9]
[m,n] = size(M);
Q = M;
Rinv = eye(n);
for i = 1:n
Ri = eye(n);
Ri(i,i) = 1 / norm(Q(:,i));
for j = i+1:n
Ri(i,j) = -Q(:,i)'*Q(:,j) / norm(Q(:,i));
end
Q = Q*Ri;
Rinv = Rinv*Ri;
end
Q
R = inv(Rinv)
The question: Q*R gives M butQ is not orthagonal.
This should return the correct result:
clear();
M = [1,1,1; 1,1,0; 1,1,9];
[m,n] = size(M);
Q = zeros(m,n);
R = zeros(n,n);
for j = 1:n
v = M(:,j);
for i = 1:j-1
R(i,j) = Q(:,i).' * M(:,j);
v = v - (R(i,j) * Q(:,i));
end
R(j,j) = norm(v);
Q(:,j) = v / R(j,j);
end
Alternatively, you could give a try to the following implementation I found on Matlab File Exchange (it contains many know variants of the algorithm): https://it.mathworks.com/matlabcentral/fileexchange/55881-gram-schmidt-orthogonalization

cant find my code error in LU decomposition [duplicate]

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

MATLAB sparse matrices: Gauss Seidel and power method using a sparse matrix with CSR (Compressed Sparse Row)

this is my first time here so I hope that someone can help me.
I'm trying to implementing the Gauss-Seidel method and the power method using a matrix with the storage CSR or called Morse storage. Unfortunately I can't manage to do better then the following codes:
GS-MORSE:
function [y] = gs_morse(aa, diag, col, row, nmax, tol)
[n, n] = size(A);
y = [1, 1, 1, 1];
m = 1;
while m < nmax,
for i = 1: n,
k1 = row(i);
k2 = row(i + 1) - 1;
for k = k1: k2,
y(i) = y(i) + aa(k) * x(col(k));
y(col(k)) = y(col(k)) + aa(k) * diag(i);
end
k2 = k2 + 1;
y(i) = y(i) + aa(k) * diag(i);
end
if (norm(y - x)) < tol
disp(y);
end
m = m + 1;
for i = 1: n,
x(i) = y(i);
end
end
POWER-MORSE:
I was able only to implement the power method but I don't understand how to use the former matrix... so my code for power method is:
function [y, l] = potencia_iterada(A, v)
numiter=100;
eps=1e-10;
x = v(:);
y = x/norm(x);
l = 0;
for k = 1: numiter,
x = A * y;
y = x / norm(x);
l0 = x.' * y;
if abs(l0) < eps
return
end
l = l0;
end
Please anyone can help me for completing these codes or can explain me how can I do that? I really don't understand how to do. Thank you very much