Octave compare two arrays - arrays

Given two column vectors,I need to compare each element of the vector a with the first element of vector b in the first iteration and return a logical array. Then the second element of vector b with each element of vector a and return a logical array so forth. The number of logical arrays is equal to the number of elements in vector b.
a=1:10;
b=[5 6 7];
for j=1:length(b),
for i=1:10,
c=b(j)==a(i);
end;
end;
ex:
after the first iteration of inner loop need to return [0 0 0 0 1 0 0 0 0 0]

try this:
a = 1:10
b = [5 6 7]
output = zeros(3,10);
for i = 1:length(b)
output(i,:) = (a == b(:,i)) % b(:, i) meas using index get the value
end
output =
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0

Related

How to copy and paste a small matrix into a bigger matrix without for-loop

For example, we have a small matrix
B = [5 2,
3 4]
and the bigger one
A = [1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1]
Now I want paste B into A so that A looks like
A = [1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 5 2
0 0 0 3 4]
That means the values of A of the bottom right has been replaced. I would like to do this without using a for-loop. How is that possible?
PS:
A is always an eye(n) matrix (n is a constant).
B is a square matrix and has a variable size but is always less or equal to A
Find the relevant row and column subscripts of A and put B there.
A(end-size(B,1)+1:end, end-size(B,2)+1:end)=B
It works even if B is not a square matrix.

Vectorisation of code for insertion of n x n matrices in a 3D array along the diagonal of a large matrix

As in my earlier question I am trying to insert small square matrices along the diagonal of a large matrix. However, these matrices are now contained in a 3D array, and have different values. As before, overlapping values are to be added, and the small matrices are only inserted where they can fit fully inside the large matrix. The step dimension will always be equal to 1.
I have achieved an answer through the use of for-loops, but am attempting to vectorise this code for efficiency. How would I do this? The current, unvectorised code is shown below.
function M = TestDiagonal2()
N = 10;
n = 2;
maxRand = 3;
deepMiniM = randi(maxRand,n,n,N+1-n);
M = zeros(N);
for i = 1:N+1-n
M(i:i+n-1,i:i+n-1) = M(i:i+n-1,i:i+n-1) + deepMiniM(:,:,i);
end
end
The desired result is an NxN matrix with n+1 diagonals populated:
3 1 0 0 0 0 0 0 0 0
4 5 3 0 0 0 0 0 0 0
0 3 3 3 0 0 0 0 0 0
0 0 1 6 3 0 0 0 0 0
0 0 0 4 4 4 0 0 0 0
0 0 0 0 2 3 2 0 0 0
0 0 0 0 0 2 6 2 0 0
0 0 0 0 0 0 4 2 2 0
0 0 0 0 0 0 0 3 3 1
0 0 0 0 0 0 0 0 3 3
This makes use of implicit expansion, as well as sparse to add values at coincident indices, and (:) indexing to linearize a matrix in the usual column-major order.
ind1 = repmat((1:n).', n, 1) + (0:N-n); % column indices for the sum
ind2 = repelem((1:n).', n) + (0:N-n); % row indices for the sum
M = full(sparse(ind1(:), ind2(:), deepMiniM(:), N, N)); % sum over those indices

Concatenate binary strings obtained from decimal to binary conversion

I want to place the binary equivalent number for each element side - by side i.e, the final matrix Concatenated_A would be of size m by nbits*n where [m,n] = size(A);
A = [5, 5, 4, 10, 4;
10, 10, 10, 10, 5;
];
I did an attempt but the result is wrong. I need help in correctly implementing the concatenation. Thank you
[m,n] = size(A);
numbits = 4;
for m = 1:M
Abin = dec2bin(A(m,:),numbits);
for j = 1:size(Abin,1)
Concatenated_A(m,:) = Abin(j,:);
end
end
For first row in A(1,:) = 5, 5, 4, 10, 4 ; its decimal conversion of each element would give a matrix as below.
0 1 0 1
0 1 0 1
0 1 0 0
1 0 1 0
0 1 0 0
Then, how can I do something like this :
Concatenated_A(1,:) = [0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 0 1 0 0]
The above operation is repeated for every row in A.
You can transpose the result of dec2bin so that the binary representation goes down the columns and then reshape this into the desired shape so that each row is on it's own row. After reshaping, we take the transpose again so that the rows go across the rows again. Also we need to be sure to transpose A before we start so that we encode along the rows.
out = reshape(dec2bin(A.', numbits).', [], size(A, 1)).'
% 01010101010010100100
% 10101010101010100101
Or if you want a logical matrix instead you can compare your character array to the character '1'
out = reshape(dec2bin(A.', numbits).', [], size(A, 1)).' == '1'
% 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 0 1 0 0
% 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1

How to change elements of a matrix with reference to a vector of column indices without using for-loop?

I have a matrix
a =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
and b vector
b =
1 2 3 4 5 5
I want to replace value of each row in a matrix with reference value of b matrix value and finally generate a matrix as follows without using for loop.
a_new =
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
0 0 0 0 1
if first element of b, b(1) = 1 so change take first row of a vector and make first element as 1 because b(1) = 1.
How can I implement this without using for loop?
Sure. You only need to build a linear index from b and use it to fill the values in a:
a = zeros(6,5); % original matrix
b = [1 2 3 4 5 5]; % row or column vector with column indices into a
ind = (1:size(a,1)) + (b(:).'-1)*size(a,1); % build linear index
a(ind) = 1; % fill value at those positions
Same as Luis Mendo's answer, but using the dedicated function sub2ind:
a( sub2ind(size(a),(1:numel(b)).',b(:)) ) = 1
Also via the subscript to indices conversion way,
a = zeros(6,5);
b = [1 2 3 4 5 5];
idx = sub2ind(size(a), [1:6], b); % 1:6 just to create the row index per b entry
a(idx) = 1
any of these methods works in Octave:
bsxfun(#eq, [1:5 5]',(1:5))
[1:5 5].' == (1:5)

Convert integer to logical array in MATLAB

I want to convert an integer i to a logical vector with an i-th non-zero element. That can de done with 1:10 == 2, which returns
0 1 0 0 0 0 0 0 0 0
Now, I want to vectorize this process for each row. Writing repmat(1:10, 2, 1) == [2 5]' I expect to get
0 1 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
But instead, this error occurs:
Error using ==
Matrix dimensions must agree.
Can I vectorize this process, or is a for loop the only option?
You can use bsxfun:
>> bsxfun(#eq, 1:10, [2 5].')
ans =
0 1 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
Note the transpose .' on the second vector; it's important.
Another way is to use eye and create a logical matrix that is n x n long, then use the indices to index into the rows of this matrix:
n = 10;
ind = [2 5];
E = eye(n,n) == 1;
out = E(ind, :);
We get:
>> out
out =
0 1 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
Just another possibility using indexing:
n = 10;
ind = [2 5];
x=zeros(numel(ind),n);
x(sub2ind([numel(ind),n],1:numel(ind),ind))=1;

Resources