NULLSPACE - RREF Command in Matlab bugs - matlab

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

Related

central difference A matrix

Hi im trying to code the following coefiicient matrix A in a for loop in Matlab. N is the total number of elements. And i and j are obtained from k. Could someone help me please code the A matrix correctly for any N value. The A and b are shown
for k = 1:N
A(k,k) = 4; % the diagonal element, corresponding to Tij, is always 4
% In the following, we look at the four neighbours of (i,j) that are
% involved in the 5-point formula
i = mod(k-1,nx)+1;
j = (k-i)/nx+1; %get (i,j) from k
%boundary condtion
if i == 1
b(k,1) = Tl;
elseif i == nx
b(k,1) = Tr;
elseif j == 1
b(k,1) = Tb;
elseif j == ny
b(k,1) = Tt;
end
%A matrix construction
if i>1 && j>1
if i == j
A(j-1,i) = -1;
A(j,i+1) =- 1;
A(j,i-1) = -1;
A(j+1,i) = -1;
end
end
end

How to display column vector x in Cramer's rule in MATLAB?

I am trying to code the Cramer's Rule on MATLAB for a square matrix. I understand the Rule perfectly and also believe the logic behind my code is alright. However, could you please check where I might be going wrong that my result is not being displayed correctly? Any help would be appreciated! Thanks :)
function x = cramer(A, b)
r = size(A, 1);
c = size(A, 2);
n = size(b, 1);
if r ~= c
disp('Oops! Please enter a square matrix');
end
if r == c == n
D = det(A);
if D == 0
disp('Oops! Either, there are a family of soultions or no unique solution')
end
if D ~= 0
result = zeros(n, 1);
for (i = 1:n)
A_x = A;
A_x(:, i) = b;
Dx = det(A_x);
result(i,1) = Dx/D;
end
x = result;
end
end
end
You have an error in your if r == c == n check.
The expression r == c == n can be expanded as (r == c) == n
So it compares the value of logical(r == c) with n.
As an example:
>> 2 == 2 == 1
ans =
logical
1
Rewrite your check as r == c && c == n or isequal(r,c,n) and you should be good.
EDIT: You can simplify your logic quite some, say for example by:
function x = cramers(A, b)
if diff(size(A)) && size(A,1) == n
D = det(A);
if D == 0
disp('Oops! Either, there are a family of solutions or no unique solution')
return
else
result = zeros(n, 1);
for i = 1:n
A_x = A;
A_x(:, i) = b;
Dx = det(A_x);
result(i,1) = Dx/D;
end
x = result;
end
else
disp('Dimension error')
return
end
end

Time Complexity Analysis Of A Recursion

The following code is calculating the determinant using recursion.
For the "for" loop with have O(n) then we call the function again with n-1 elements so we have to multiply each time we call the function?
something like O(n)O(n-1)...*O(1)?
function y = detm(A)
n = length(A);
y = 0;
if n == 1
y = A(1,1);
elseif n == 2
y = A(1,1).*A(2,2)-A(1,2).*A(2,1);
elseif n > 2
for i = 1:n
temp = A(2:end,:);
temp(:,i) = [];
if mod(i,2) == 0
y = y - A(1,i)*detm(temp);
else
y = y + A(1,i)*detm(temp);
end
end
end
end

Jacobi method to solve linear systems in MATLAB

How would you code this in MATLAB?
This is what I've tried, but it doesn't work quite right.
function x = my_jacobi(A,b, tot_it)
%Inputs:
%A: Matrix
%b: Vector
%tot_it: Number of iterations
%Output:
%:x The solution after tot_it iterations
n = length(A);
x = zeros(n,1);
for k = 1:tot_it
for j = 1:n
for i = 1:n
if (j ~= i)
x(i) = -((A(i,j)/A(i,i)) * x(j) + (b(i)/A(i,i)));
else
continue;
end
end
end
end
end
j is an iterator of a sum over each i, so you need to change their order. Also the formula has a sum and in your code you're not adding anything so that's another thing to consider. The last thing I see that you're omitting is that you should save the previous state of xbecause the right side of the formula needs it. You should try something like this:
function x = my_jacobi(A,b, tot_it)
%Inputs:
%A: Matrix
%b: Vector
%tot_it: Number of iterations
%Output:
%:x The solution after tot_it iterations
n = length(A);
x = zeros(n,1);
s = 0; %Auxiliar var to store the sum.
xold = x
for k = 1:tot_it
for i = 1:n
for j = 1:n
if (j ~= i)
s = s + (A(i,j)/A(i,i)) * xold(j);
else
continue;
end
end
x(i) = -s + b(i)/A(i,i);
s = 0;
end
xold = x;
end
end

Poisson PDE solver on a disked shaped domain with finite difference method using matlab

For my studies I had to write a PDE solver for the Poisson equation on a disc shaped domain using the finite difference method.
I already passed the Lab exercise. There is one issue in my code I couldn't fix. Function fun1 with the boundary value problem gun2 is somehow oscillating at the boundary. When I use fun2 everything seems fine...
Both functions use at the boundary gun2. What is the problem?
function z = fun1(x,y)
r = sqrt(x.^2+y.^2);
z = zeros(size(x));
if( r < 0.25)
z = -10^8*exp(1./(r.^2-1/16));
end
end
function z = fun2(x,y)
z = 100*sin(2*pi*x).*sin(2*pi*y);
end
function z = gun2(x,y)
z = x.^2+y.^2;
end
function [u,A] = poisson2(funame,guname,M)
if nargin < 3
M = 50;
end
%Mesh Grid Generation
h = 2/(M + 1);
x = -1:h:1;
y = -1:h:1;
[X,Y] = meshgrid(x,y);
CI = ((X.^2 +Y.^2) < 1);
%Boundary Elements
Sum= zeros(size(CI));
%Sum over the neighbours
for i = -1:1
Sum = Sum + circshift(CI,[i,0]) + circshift(CI,[0,i]) ;
end
%if sum of neighbours larger 3 -> inner note!
CI = (Sum > 3);
%else boundary
CB = (Sum < 3 & Sum ~= 0);
Sum= zeros(size(CI));
%Sum over the boundary neighbour nodes....
for i = -1:1
Sum = Sum + circshift(CB,[i,0]) + circshift(CB,[0,i]);
end
%If the sum is equal 2 -> Diagonal boundary
CB = CB + (Sum == 2 & CB == 0 & CI == 0);
%Converting X Y to polar coordinates
Phi = atan(Y./X);
%Converting Phi R back to cartesian coordinates, only at the boundarys
for j = 1:M+2
for i = 1:M+2
if (CB(i,j)~=0)
if j > (M+2)/2
sig = 1;
else
sig = -1;
end
X(i,j) = sig*1*cos(Phi(i,j));
Y(i,j) = sig*1*sin(Phi(i,j));
end
end
end
%Numberize the internal notes u1,u2,......,un
CI = CI.*reshape(cumsum(CI(:)),size(CI));
%Number of internal notes
Ni = nnz(CI);
f = zeros(Ni,1);
k = 1;
A = spalloc(Ni,Ni,5*Ni);
%Create matix A!
for j=2:M+1
for i =2:M+1
if(CI(i,j) ~= 0)
hN = h;hS = h; hW = h; hE = h;
f(k) = fun(X(i,j),Y(i,j));
if(CB(i+1,j) ~= 0)
hN = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j),Y(i+1,j))*2/(hN^2+hN*h);
A(k,CI(i-1,j)) = -2/(h^2+h*hN);
else
if(CB(i-1,j) ~= 0) %in negative y is a boundry
hS = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j),Y(i-1,j))*2/(hS^2+h*hS);
A(k,CI(i+1,j)) = -2/(h^2+h*hS);
else
A(k,CI(i-1,j)) = -1/h^2;
A(k,CI(i+1,j)) = -1/h^2;
end
end
if(CB(i,j+1) ~= 0)
hE = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j+1),Y(i,j))*2/(hE^2+hE*h);
A(k,CI(i,j-1)) = -2/(h^2+h*hE);
else
if(CB(i,j-1) ~= 0)
hW = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j-1),Y(i,j))*2/(hW^2+h*hW);
A(k,CI(i,j+1)) = -2/(h^2+h*hW);
else
A(k,CI(i,j-1)) = -1/h^2;
A(k,CI(i,j+1)) = -1/h^2;
end
end
A(k,k) = (2/(hE*hW)+2/(hN*hS));
k = k + 1;
end
end
end
%Solve linear system
u = A\f;
U = zeros(M+2,M+2);
p = 1;
%re-arange u
for j = 1:M+2
for i = 1:M+2
if ( CI(i,j) ~= 0)
U(i,j) = u(p);
p = p+1;
else
if ( CB(i,j) ~= 0)
U(i,j) = gun(X(i,j),Y(i,j));
else
U(i,j) = NaN;
end
end
end
end
surf(X,Y,U);
end
I'm keeping this answer short for now, but may extend when the question contains more info.
My first guess is that what you are seeing is just numerical errors. Looking at the scales of the two graphs, the peaks in the first graph are relatively small compared to the signal in the second graph. Maybe there is a similar issue in the second that is just not visible because the signal is much bigger. You could try to increase the number of nodes and observe what happens with the result.
You should always expect to see numerical errors in such simulations. It's only a matter of trying to get their magnitude as small as possible (or as small as needed).