Reduced row echelon form of binary matrix in MatLab - matlab

Hello everybody I try to find Reduced row echelon form for binary matrix in matlab. Does mathlab contain any functions to do that?
Standart rref computes it only for real numbers.
Thanks

[m,n]=size(a);
b=a;
c=0;
for k=1:min(m,n)
c=c+1;
i=find(b(:,k));
i(i strictly less c)=[ ];
if (~isempty(i))
imax=min(i);
b([c imax],:)=b([imax c],:);
ck=b(c,:);
p=find(b(:,k));
p(p==c)=[];
if ~isempty(p)
v=b(p,:)+repmat(ck,length(p),1);
b(p,:)=mod(v,2);
end;
else
c=c-1;
end;
end;

Related

Matlab 'Function Unset/Unused'

I am new to Matlab, so there is a lot I do not understand; I have three questions, as followed:
The biggest issue I have revolves around function B= upper_triang(A) where it states that it is 'a function unused'. Reading through the Matlab tooltip, and I am guessing that it has to do with a value that has not been defined? ANd B of course being unset, but I thought I defined B as a function, so why is it unset? I am assuming that B is U, but in the math part that is ahh, so I am not sure what it would be.
To give context to my code I sent the part of the homework code I have a question on.
%%%This is for part a for problem 1.
A=zeros(8,8);%%%For the size column and row size of matrix A.
for j=1:8
for k=1:8
if j==k
A(j,k)=-2;
end
if abs(j-k)==1
A(j,k)=1;
end
end
end
[L,U]=lu(A); %%%Proving L and U.
L*U; %%%Proving that L*U=A, thus it is correct.
%%%This is for part b for problem 1
function B= upper_triang(A)
%%%Input A--> Matrix for m*n for the size
%%%Output B--> Is the upper triangular matrix of the same size
[m,n]=size(A);
for k=1:m-1
for i=k+1:m
u=A(i,k)/A(k,k);
for j=(k):n
A(i,j)=A(i,j)-u*A(k,j);
end
end
end
B-A;
end
Function being unused
The problem here is that you've only created a function, but you've never used it. Everything after the function B = upper_triang(A) just tells Matlab what to do in case that function is ever called, but your never do.
I'm guessing that, after your LU decomposition but before the declaration of your function, you should add a line
B = upper_triang(A);
Output unset
There is a second problem which is that, while you declared that B should be the output of your function upper_triang(), it it not "created" anywhere in the function itself.
There should be a line somewhere with
B = something;
Now, my linear algebra is quite rusty but I think that what you're trying to do should rather be:
%%%This is for part b for problem 1
function B= upper_triang(A)
%%%Input A--> Matrix for m*n for the size
%%%Output B--> Is the upper triangular matrix of the same size
[m,n]=size(A);
B = A; % copy the input matrix in B, and work with it from now on
for k=1:m-1
for i=k+1:m
u=B(i,k)/B(k,k);
for j=(k):n
B(i,j)=B(i,j)-u*B(k,j);
end
end
end
B = B - A; % not really sure about this
end

How to write a MATLAB code for this kind of Heaviside step function?

To solve one dimensional advection equation denoted by
u_t+u_x = 0, u=u(x,t), and i.c. u(x,0)= 1+H(x+1)+H(x-1)
using Lax Wanderoff method,
I need to write a Heaviside step function H(x) and it needs to be zero when x <= 0, 1 when x>0 . The problem is I also need to use that function writing H(x-t+1), H(x-t-1) as I will compare what I find by the exact solution:
u(x,t) =1 + H(x-t+1) -H(x-t-1)
Here, the "x" and "t" are vectors such that;
x=-5:0.05:5
t=0:0.05:1
I wrote the Heaviside step function as the following; however, I need it without the for loop.
L=length(x)
function H_X= heavisidefunc(x,L)
H_X=zeros(1,L);
for i= 1:L
if x(i)<= 0
H_X(i)=0;
else
H_X(i)=1;
end
end
end
I get "Dimensions must agree." error if I write
H_X3 = heavisidefunc(x-t+1,L);
H_X4 = heavisidefunc(x-t-1,L);
The Heavyside function is really easy to program in Matlab
Heavyside=#(x) x>= 0;
The easiest way to get rid of the dimensions must agree error is to transpose one of the vectors. This will cause Matlab to construct a matrix of length(x1) by length(x2)
Heavyside(x-t'+1);
I came up with a solution. My new Heaviside function is;
function H_X= heavisidefunc(x)
if x<= 0
H_X=0;
else
H_X=1;
end
end
The problem I had was because I was storing the output as a vector and it just complicated things.
Now,writing H(x-t+1), H(x-t-1) is easier. Just put "heavisidefunc(x(i)-t(j)-1)" and loop from 1 to the length of x and l in two loops. Thanks to everyone!

vectorization of matlab for-loop

I am looking for proper vectorization of following matlab function to eliminate for-loop and gain speed by multithreading.
size(A) = N-by-N, where 30 <= N <= 60
1e4 <= numIter <= 1e6
function val=permApproxStochSquare(A,numIter)
%// A ... input square non-negative matrix
%// numIter ... number of interations
N=size(A,1);
alpha=zeros(numIter,1);
for curIter=1:numIter
U=randn(N,N);
B=U.*sqrt(A);
alpha(curIter)=det(B)^2;
end
val=mean(alpha);
end
To summarize the discussion in the comment to two versions of the code which slightly improve the performance:
Using multiple ideas from the comments, the code needs roughly 1/3 less time:
N=size(A,1);
%precompute sqrt(A)
sA=sqrt(A);
alpha=zeros(numIter,1);
parfor curIter=1:numIter
%vectorizing rand did not improve the performance because it increased communitcation when combined with parfor
U=randn(N,N);
B=U.*sA;
alpha(curIter)=det(B);
end
%moved calculation out of the loop to vectorize
val=mean(alpha.^2);
Another approach, vectorize as far as possible using a for loop only did small improvemens to the perfrmance:
N=size(A,1);
%precompute sqrt(A)
sA=sqrt(A);
alpha=zeros(numIter,1);
%using a for, a vectorized rand outside the loop is faster.
U=randn(N,N,numIter);
B=bsxfun(#times,U,sA);
for curIter=1:numIter
alpha(curIter)=det(B(:,:,curIter));
end
val=mean(alpha.^2);

Replace values in a submatrix in Julia

Is there an efficient way of coding other than what I did below while converting matlab code to Julia? Especially when the parent_matrix is of the size 2000X2000 and inner_matrix is of size 800X1?
Matlab:
parent_matrix(inner_matrix(:),inner_matrix(:)) = replace_matrix;
Julia:
ind_inner_vec=reshape(inner_matrix,size(inner_matrix)[1].*size(inner_matrix)[2],1)
z=1
for x in ind_inner_vec
for y in ind_inner_vec
parent_matrix[y,x]=replace_matrix[z]
z=z+1
end
end
If I understand correctly
parent_matrix[vec(inner_matrix),vec(inner_matrix)] = replace_matrix
will do what you want. Note that the vec is only needed because you said inner_matrix is a column matrix - if it was actually a vector, it wouldn't be needed.

Gauss-Seidel method doesn't work for large sparse arrays?

Once again I have a problem with the Gauss-Seidel Method in Matlab. Here it is:
function [x] = ex1_3(A,b)
format long
sizeA=size(A,1);
x=zeros(sizeA,1);
%Just a check for the conditions of the Gauss-Seidel Method (if it has dominant diagonal)
for i=1:sizeA
sum=0;
for j=1:sizeA
if i~=j
sum=sum+abs(A(i,j));
end
end
if abs(A(i,i))<sum
fprintf('\nGauss-Seidel''s conditions not met!\n');
return
end
end
%Actual Gauss-Seidel Method
max_temp=10^(-6); %Pass first iteration
while max_temp>(0.5*10^(-6))
xprevious=x;
for i=1:sizeA
x(i,1)=b(i,1);
for j=1:sizeA
if i~=j
x(i,1)=x(i,1)-A(i,j)*x(j,1);
end
end
x(i,1)=x(i,1)/A(i,i);
end
x
%Calculating infinite norm of vector x-xprevious
temp=x-xprevious;
max_temp=temp(1,1);
for i=2:sizeA
if abs(temp(i,1))>max_temp
max_temp=abs(temp(i,1));
end
end
end
It actually works fine for a 100x100 matrix or smaller. However, my tutor wants it to work for 100000x100000 matrices. At first it was difficult to even create the matrix itself, but I managed to do it with a little help from here:
Matlab Help Center
Now, I call the ex1_3 function with A as a parameter, but it goes really slow. Actually it never ends. How can I make it work?
Here's my code for creating the specific matrix my tutor wanted:
The important part is just that it meets these conditions:
A(i; i) = 3, A(i - 1; i) = A(i; i + 1) = -1 n=100000
b=ones(100000,1);
b(1,1)=2;
b(100000,1)=2;
i=zeros(299998,1); %Matrix with the lines that we want to put nonzero elements
j=zeros(299998,1); %Matrix with the columns that we want to put nonzero elements
s=zeros(299998,1); %Matrix with the nonzero elements.
number=1;
previousNumberJ=0;
numberJ=0;
for k=1:299998 %Our index in i and j matrices
if mod((k-1),3)==0
s(k,1)=3;
else
s(k,1)=-1;
end
if k==1 || k==2
i(k,1)=1;
j(k,1)=k;
elseif k==299997 || k==299998
i(k,1)=100000;
j(k,1)=(k-200000)+2;
else
if mod(k,3)==0
number=number+1;
numberJ=previousNumberJ+1;
previousNumberJ=numberJ;
end
i(k,1)=number;
j(k,1)=numberJ;
numberJ=numberJ+1;
end
end
A=sparse(i,j,s); %Creating the sparse array
x=ex1_3(A,b);
the for loop works very slowly in Matlab, perhaps you may want to try the matrix form of the iteration:
function x=gseidel(A,b)
max_temp=10^(-6); %Pass first iteration
x=b;
Q=tril(A);
r=b-A*x;
for i=1:100
dx=Q\r;
x=x+1*dx;
r=b-A*x;
% convergence check
if all(abs(r)<max_temp) && all(abs(dx)<max_temp), return; end
end
For your A and b, it only takes 16 steps to converge.
tril extracts the lower triangular part of A, you can also obtain this Q when you build up the matrix. Since Q is already the triangular matrix, you can solve the equation Q*dx=r very easily if you are not allowed to use \ function.