How to multiple matrix column in next columns and set in a new matrix? - matlab

I want to make second matrix from the first matrix in MATLAB. Please see the following image:
AB = A and B
AC = A and C
BC = B and C
====>>>
code:
transactions={{'A','C'};{'A','B'};{'A','B','C'}};
items = unique([transactions{:}]); % A,B,C
for i = 1:size(transactions,1)
T(i,ismember(items,transactions{i,:})) = 1; %convert transactions to matrix
end
.
.
T1 = zeros(size(transactions,1), nchoosek(length(items),2));
for k=1:5
for i=1: length(items)
for j=i+1 : length(items)
z = bitand(T(k,i),T(k,j)))
% set z in matrix T1 %
end
end
end
How to set the new values and How to concate label in the result matrix?

Simply use Matlab's & operator (see documentation). Because Matlab is an interpreted language, it will automatically convert the 0's and 1's to a logical matrix.
For example:
X = [1 0 1; 1 0 0; 1 1 1; 1 0 0; 1 1 0];
Y(:,1) = X(:,1) & X(:,2);
Y(:,2) = X(:,1) & X(:,3);
Y(:,3) = X(:,2) & X(:,3);
Matrix Y will be of type logical and be the desired output:
>> Y
Y =
0 1 0
0 0 0
1 1 1
0 0 0
1 0 0
Alternatively, you can use a struct for readability:
>> X.A = [1 1 1 1 1];
>> X.B = [0 0 1 0 1];
>> X.C = [1 0 1 0 0];
>> Y.AB = X.A & X.B;
>> Y.AC = X.A & X.C;
>> Y.BC = X.B & X.C;
>> Y
Y =
AB: [0 0 1 0 1]
AC: [1 0 1 0 0]
BC: [0 0 1 0 0]
If you want to automate the process, you could do the following:
X.A = [1 1 1 1 1]';
X.B = [0 0 1 0 1]';
X.C = [1 0 1 0 0]';
names = fieldnames(X);
N = length(names);
combos = nchoosek(1:N,2);
for i=1:N
Y.(char([names(combos(i,1)) names(combos(i,2))])) = ...
X.(char(names(combos(i,1)))) & X.(char(names(combos(i,2))));
end
struct2table(Y)
Which gives the following:
ans =
AB AC BC
_____ _____ _____
false true false
false false false
true true true
false false false
true false false

Related

Undefined function or variable for 3dos mechanism

I tried to make a 3dof(3 degrees of freedom mechanism) in matlab but i get this error and i don't know why.
this is for a school project and i need to simulate a human finger.
the code is running normal but after i enter the values for the angles it says that A,B,C are
undefined and i don't know why
a1 = input('valuarea lui q1(grade):');
a2 = input('valuarea lui q2(grade):');
a3 = input('valuarea lui q3(grade):');
L1=35;
L2=45;
L3=30;
z = [-10 10];
plot(z,10);
grid ON;
O=[0;0;0;1];
m= linspace(pi/2,pi/2+a1*pi/180,100);
n = linspace(-pi/2,a2*pi/180,100);
k=linspace(-pi/2,a3*pi/180,100);
for a=1:100
[A1,B1,C1] = Transform(m(a),n(a),k(a),L1,L2,L3);
x = [O(1) A(1) B(1) C(1)];
y = [O(2) A(2) B(2) C(2)];
Cx(i)= C1(1);
Cy(i) = C1(2);
i=i+1;
Plot = plot(x,y,'r',...1
'LineWidth',1);
title('Sumularea unui deget');
plot(Cx,Cy,'--g',...
'LineWidth',1);
pause(0.075);
delete(Plot);
end
plot(x,y,'r',...
'LineWidth',3);
function [A,B,C ] = Transform( m,n,p,l1,l2,l3 )
P = [0;0;0;1];
T1 = [cos(m) -sin(m) 0 0;sin(m) cos(m) 0 0;0 0 1 0; 0 0 0 1];
T2 = [cos(n) -sin(n) 0 11;sin(n) cos(n) 0 0;0 0 1 0; 0 0 0 1];
T3 = [cos(p) -sin(p) 0 12;sin(p) cos(p) 0 0;0 0 1 0; 0 0 0 1];
T4 = [1 0 0 13;0 1 0 0; 0 0 1 0; 0 0 0 1];
A = T1*T2*P;
B = T1*T2*T3*P;
C = T1*T2*T3*T3*P;
end
In your main function, this is the first use of the variables:
x = [O(1) A(1) B(1) C(1)];
They are never written previously. Instead A1 is written, which is a different variable. I guess you mixed the two up.

Fastest way of generating a logical matrix by given row indices of true values?

What is the most efficient way of generating
>> A
A =
0 1 1
1 1 0
1 0 1
0 0 0
with
>> B = [2 3; 1 2; 1 3]
B =
2 3
1 2
1 3
in MATLAB?
E.g., B(1, :), which is [2 3], means that A(2, 1) and A(3, 1) are true.
My attempt still requires one for loop, iterating through B's row. Is there a loop-free or more efficient way of doing this?
This is one way of many, though sub2ind is the dedicated function for that:
%// given row indices
B = [2 3; 1 2; 1 3]
%// size of row index matrix
[n,m] = size(B)
%// size of output matrix
[N,M] = deal( max(B(:)), n)
%// preallocation of output matrix
A = zeros(N,M)
%// get col indices to given row indices
cols = bsxfun(#times, ones(n,m),(1:n).')
%// set values
A( sub2ind([N,M],B,cols) ) = 1
A =
0 1 1
1 1 0
1 0 1
If you want a logical matrix, change the following to lines
A = false(N,M)
A( sub2ind([N,M],B,cols) ) = true
Alternative solution
%// given row indices
B = [2 3; 1 2; 1 3];
%// number if rows
r = 4; %// e.g. = max(B(:))
%// number if cols
c = 3; %// size(B,1)
%// preallocation of output matrix
A = zeros(r,c);
%// set values
A( bsxfun(#plus, B.', 0:r:(r*(c-1))) ) = 1;
Here's a way, using the sparse function:
A = full(sparse(cumsum(ones(size(B))), B, 1));
This gives
A =
0 1 1
1 1 0
1 0 1
If you need a predefined number of rows in the output, say r (in your example r = 4):
A = full(sparse(cumsum(ones(size(B))), B, 1, 4, size(B,1)));
which gives
A =
0 1 1
1 1 0
1 0 1
0 0 0
You can equivalently use the accumarrray function:
A = accumarray([repmat((1:size(B,1)).',size(B,2),1), B(:)], 1);
gives
A =
0 1 1
1 1 0
1 0 1
Or with a predefined number of rows, r = 4,
A = accumarray([repmat((1:size(B,1)).',size(B,2),1), B(:)], 1, [r size(B,1)]);
gives
A =
0 1 1
1 1 0
1 0 1
0 0 0

How to make a parity check matrix from non-systematic to systematic in Matlab? thanks

I am trying to make a parity check matrix from non-systematic to systematic. Hence, I am attaching my code below. Somewhat it is correct, but there are some problems. It would be really great if someone could help me in this.
Subject: Information theory and coding. I am working on LDPC coding and decoding. Please check the code below
MATLAB CODE:
H = [1 0 1 1 0; 0 0 1 0 1; 1 0 0 1 0; 1 0 1 1 1]
[m,n] = size(H);
k = n-m;
for i = k+1:n
%H(:,i)
ind = find(H(:,i),1,'last');
% exchanging (ind)th row and (i-k)th row
if ind < i-k
continue;
end
if ind ~= i-k
temp = H(ind,:);
H(ind,:) = H(i-k,:);
H(i-k,:) = temp;
end
I = find(H(:,i));
% Guassian elimination
for j = 1:length(I)
if I(j) ~= i-k
H(I(j),:) = mod(H(I(j),:)+H(i-k,:),2);
end
end
end
Hsys = H
For e.g.
This is my H matrix:
H =
1 0 1 1 0
0 0 1 0 1
1 0 0 1 0
1 0 1 1 1
I want to have an identity matrix inside the matrix. The dimension on H matrix here is (mxn) which is (4x5).
Generally we use Gaussian elimination method to make the Identity matrix.hence, we make operations between rows. This is how we make it systematic.
I should have matrix as this in the result:
Hsys =
0 1 0 0 0
0 0 1 0 0
1 0 0 1 0
0 0 0 0 1
I should have an identity matrix of dimension m.
Here is how I'd do it (using Gauss-Jordan elimination):
% Not your matrix since it does not have any ones in the second column.
H=[1 1 0 1 1 0 0 1 0 0;
0 1 1 0 1 1 1 0 0 0;
0 0 0 1 0 0 0 1 1 1;
1 1 0 0 0 1 1 0 1 0;
0 0 1 0 0 1 0 1 0 1];
rows = size(H, 1);
cols = size(H, 2);
r = 1;
for c = cols - rows + 1:cols
if H(r,c) == 0
% Swap needed
for r2 = r + 1:rows
if H(r2,c) ~= 0
tmp = H(r, :);
H(r, :) = H(r2, :);
H(r2, :) = tmp;
end
end
end
% Ups...
if H(r,c) == 0
error('H is singular');
end
% Forward substitute
for r2 = r + 1:rows
if H(r2, c) == 1
H(r2, :) = xor(H(r2, :), H(r, :));
end
end
% Back Substitution
for r2 = 1:r - 1
if H(r2, c) == 1
H(r2, :) = xor(H(r2, :), H(r, :));
end
end
% Next row
r = r + 1;
end

Conditionally replace neighbouring cells

Lets say I have a matrix A:
A =
0 1 0 0
0 0 0 0
0 0 0 1
0 0 0 0
And I want to create a new matrix B of the same dimension where all ones and accompanying neighbours are replaced by the following matrix:
X =
1 1 1
1 2 1
1 1 1
The 2 in matrix X should be placed 'on top' of the 1 values as to get:
B =
1 2 1 0
1 1 2 1
0 0 1 2
0 0 1 1
Values should be added up where elements overlap and matrix X should be 'cut off' in places where it extends the dimensions of matrix A/B The idea is to eventually replace X by a 2d gaussian distribution and matrix A will be large containing many more ones. So it's essential that the code is efficient and fast. This is the code i came up with:
A = [0 1 0 0;0 0 0 0;0 0 0 1;0 0 0 0]
X = [1 1 1;1 2 1;1 1 1]
B = zeros(4,4);
t=1;
indA = find(A==1);
indX = find(X==2);
all = find(X>0);
[iall jall] = ind2sub(size(X),all);
[ia ja] = ind2sub(size(A),indA)
[ix jx] = ind2sub(size(X),indX)
iv = ia-ix
jv = ja-jx
for t=1:numel(iv),
ib = iall+iv(t);
jb = jall+jv(t);
ibjb = [ib(:), jb(:)]
c1 = (ibjb(:,1)>4)|(ibjb(:,1)<1); c2 = (ibjb(:,2)>4)|(ibjb(:,1)<1);
ibjb((c1|c2),:)=[]
isel = ibjb(:,1)-iv(t)
jsel = ibjb(:,2)-jv(t)
B(ibjb(:,1), ibjb(:,2)) = B(ibjb(:,1), ibjb(:,2))+ X(isel, jsel)
t=t+1;
end
Is there a more efficient/faster way (minimizing the loops) to code this function?
What you want is a (2D) convolution. So use conv2:
B = conv2(A, X, 'same');

How can I generate the following matrix in MATLAB?

I want to generate a matrix that is "stairsteppy" from a vector.
Example input vector: [8 12 17]
Example output matrix:
[1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1]
Is there an easier (or built-in) way to do this than the following?:
function M = stairstep(v)
M = zeros(length(v),max(v));
v2 = [0 v];
for i = 1:length(v)
M(i,(v2(i)+1):v2(i+1)) = 1;
end
You can do this via indexing.
A = eye(3);
B = A(:,[zeros(1,8)+1, zeros(1,4)+2, zeros(1,5)+3])
Here's a solution without explicit loops:
function M = stairstep(v)
L = length(v); % M will be
V = max(v); % an L x V matrix
M = zeros(L, V);
% create indices to set to one
idx = zeros(1, V);
idx(v + 1) = 1;
idx = cumsum(idx) + 1;
idx = sub2ind(size(M), idx(1:V), 1:V);
% update the output matrix
M(idx) = 1;
EDIT: fixed bug :p
There's no built-in function I know of to do this, but here's one vectorized solution:
v = [8 12 17];
N = numel(v);
M = zeros(N,max(v));
M([0 v(1:N-1)]*N+(1:N)) = 1;
M(v(1:N-1)*N+(1:N-1)) = -1;
M = cumsum(M,2);
EDIT: I like the idea that Jonas had to use BLKDIAG. I couldn't help playing with the idea a bit until I shortened it further (using MAT2CELL instead of ARRAYFUN):
C = mat2cell(ones(1,max(v)),1,diff([0 v]));
M = blkdiag(C{:});
A very short version of a vectorized solution
function out = stairstep(v)
% create lists of ones
oneCell = arrayfun(#(x)ones(1,x),diff([0,v]),'UniformOutput',false);
% create output
out = blkdiag(oneCell{:});
You can use ones to define the places where you have 1's:
http://www.mathworks.com/help/techdoc/ref/ones.html