How to select a submatrix in Matlab? - matlab

Hello and happy new year!
I have a problem, and I can't find a solution.
I need to create these 2 matrices, C from B with submatrix.
B = [ 1 2 3 4 5 6 7
9 7 5 3 1 -1 -3
4 8 16 32 64 128 256];
And I want to extract this matrix from it:
C = [ 2 3 4 5
32 64 128 256]
First I created the matrix B:
B = (1:7; 9:-2:-3; 2.^(2:8));
But with this I get an error:
C = B([1,(2:5)]; [3,(4:7)]);
Any ideas?

That's just a grammar issue.
Just try this:
C = [B(1, 2:5); B(3, 4:7)];

Related

What is this piece of code in Matlab doing

This is a snippet from a program I am trying to understand. I have changed the variable names for easier understanding. I haven't done much coding in MatLab so I can't really understand what's happening. When I kept a=magic(4) and got the output from this code I thought it was sorting or something but it doesn't seem so with the other input
a = [14 41 4 16;7 12 45 0;12 12 45 17; 3 2 1 15]
b=a(:)
c=zeros(4,4)
a is a 4x4 matrix,
b is a column vector of a,
c is a 4X4 matrix of zeros.`
for kk = 1:length(b)
c(a==b(kk)) = kk;
end
c =
1 5 9 13
2 7 11 14
7 7 11 15
4 8 12 16
if I try a=magic(4), where
a =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
then
c =
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
The answer in the comments is correct - perhaps it serves a function within the program, however out of context the code does seem pretty much pointless.
This is essentially what is happening. Suppose you have a matrix A
A = [3 4;
5 6]
Then B will look like this:
B = [3 4 5 6]
C is then created by comparing the kkth element of A to the kkth element of B. If the two are equal, then the kkth element of C will be kk.
Thus, in the example above, C will look like this:
C = [1 2;
3 4]
If, as you have found out, there are multiple entries of the same number in your original matrix A, then the final matrix C will only have the index of the last unique occurence of that number. So, if
A = [3 3;
5 6]
B = [3 3 5 6]
C = [2 2;
3 4]
The reason your first C has 7 three times is because the last position of 12 is at position 7. The reason your second C is different from your first C is because the A that it was made from is totally unique.

Total sum of a matrix

I have a 4x9 matrix, and I need to calculate the sum of all numbers in every other column of c starting with the first. Can anyone point me in the right direction? I know we have to use the function sum() but that's about it.
I used Octave rather than MATLAB, but this works for me:
A = randi(10,4,9)
B = A(:, 1:2:9)
C = sum(B)
Generate a 4x9 matrix with random numbers between 1 and 10, then create a sub-matrix with each row, and given columns 1:2:9 means starting from the first column and ending on the 9th, choose every second column, then sum up each column. Example output:
>> A = randi(10,4,9)
A =
1 3 6 8 2 8 4 8 10
3 6 10 4 6 4 6 2 8
4 3 9 2 7 10 6 9 6
8 5 3 9 3 8 4 6 10
>> B = A(:, 1:2:9)
B =
1 6 2 4 10
3 10 6 6 8
4 9 7 6 6
8 3 3 4 10
>> C = sum(B)
C =
16 28 18 20 34
You could also take the sum of matrix C using the sum() first and then select every other element from the result starting from the 1st element.
tmpC = sum(C);
result = tmpC(1:2:end)

initialize matrix index in MATLAB

I have one program with MATLAB. I have 3 variable such as a, b and c.
c is matrix with 2 columns and 10000 rows. a is row index matrix c and b is index column matrix c. For example
c=[1 2 3 4;
5 6;
7 8;
9 10;
11 12]
a=[2,4];
b=[1,2];
i want write c(a,b)=0 return c(2,1)=0 and c(4,2)=0.
c= 1 2
0 6
7 8
9 0
11 12
but return
c= 1 2
0 0
7 8
0 0
11 12
I don't use for and while.
this example is very small in matrix program c is double (3000*3000) and b, c is double(1*1085)
To me below is working-
c(a(1,1),b(1,1)) = c(a(1,2),b(1,2))=0
Use indexing to get right elements from a and b and use this to change c for more on indexing see here.
Output-
c =
1 2
0 6
7 8
9 0
11 12
EDIT
To use looping for large matrix use this-
close all;clear;clc
c=[1 2 ;
5 6;
7 8;
9 10;
11 12];
a=[2,4,3];
b=[1,2,2];
concated = [a;b];
sz = size(concated);
for i=1:sz(1,2)
ind = concated(:,i);
c(ind(1,1),ind(2,1)) = 0;
end
disp(c);
Output-
1 2
0 6
7 0
9 0
11 12

How to align vectors with asynchronous time stamp in matlab?

I would like to align and count vectors with different time stamps to count the corresponding bins.
Let's assume I have 3 matrix from [N,edges] = histcounts in the following structure. The first row represents the edges, so the bins. The second row represents the values. I would like to sum all values with the same bin.
A = [0 1 2 3 4 5;
5 5 6 7 8 5]
B = [1 2 3 4 5 6;
2 5 7 8 5 4]
C = [2 3 4 5 6 7 8;
1 2 6 7 4 3 2]
Now I want to sum all the same bins. My final result should be:
result = [0 1 2 3 4 5 6 7 8;
5 7 12 16 ...]
I could loop over all numbers, but I would like to have it fast.
You can use accumarray:
H = [A B C].'; %//' Concatenate the histograms and make them column vectors
V = [unique(H(:,1)) accumarray(H(:,1)+1, H(:,2))].'; %//' Find unique values and accumulate
V =
0 1 2 3 4 5 6 7 8
5 7 12 16 22 17 8 3 2
Note: The H(:,1)+1 is to force the bin values to be positive, otherwise MATLAB will complain. We still use the actual bins in the output V. To avoid this, as #Daniel says in the comments, use the third output of unique (See: https://stackoverflow.com/a/27783568/2732801):
H = [A B C].'; %//' stupid syntax highlighting :/
[U, ~, IU] = unique(H(:,1));
V = [U accumarray(IU, H(:,2))].';
If you're only doing it with 3 variables as you've shown then there likely aren't going to be any performance hits with looping it.
But if you are really averse to the looping idea, then you can do it using arrayfun.
rng = 0:8;
output = arrayfun(#(x)sum([A(2,A(1,:) == x), B(2,B(1,:) == x), C(2,C(1,:) == x)]), rng);
output = cat(1, rng, output);
output =
0 1 2 3 4 5 6 7 8
5 7 12 16 22 17 8 3 2
This can be beneficial for particularly large A, B, and C variables as there is no copying of data.

Repeat each row of a matrix

I have variable A of size m by n. I want to generate B of size m by m*n, such as below example.
Example:
A = [1 2 3;
4 5 6;
7 8 9]
Should result with
B = [1 2 3 4 5 6 7 8 9;
1 2 3 4 5 6 7 8 9;
1 2 3 4 5 6 7 8 9]
Is there any way to do that without using loop? m and n is variable.
You should use the repmat Matlab funtion:
B = repmat(A,M,N) creates a large matrix B consisting of an M-by-N
tiling of copies of A. The size of B is [size(A,1)*M, size(A,2)*N].
The statement repmat(A,N) creates an N-by-N tiling.
For your specific case one solution may be:
A=A';
B=repmat(A(:)',3,1);
And for the general case one solution may be:
A_aux=reshape(A',1,size(A,1)*size(A,2));
B=repmat(A_aux,size(A,1),1);
Repmat is indeed the way to go here, as mentioned by #Nerea. This solution should give the same answer as his, but personally I consider it to be a bit more elegant:
B=repmat(reshape(A',1,[]),size(A,1),1);
To include a quite fast bsxfun solution:
A = [1 2 3 4;
5 6 7 8;
9 10 11 12]
A = A.' %'
B = bsxfun(#plus,zeros(size(A,2),1),A(:).')
or use kron, but its surely slower:
A = A.'
B = kron(A(:),ones(1,size(A,2))).'
B =
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
No repmats
[m n] = size(A);
B = ones(m,1) * reshape( A.', 1, [] );
One approach
with repmat, reshape and permute combo!
out = repmat(reshape(permute(A,[3 2 1]),1,[]),size(A,1),1,1);
or Another approach without reshape but becomes a 2 liner
out1 = permute(A,[3 2 1]);
out = repmat(out1(:).',size(A,1),1,1);