I have a cube m by n by k which means i have k matrices m by n. I want to reshape it into one big matrix for example p row and q column (consider each m by n matrix as an element).
How can i do that? Can i use reshape function? for example these matrices when put together form a cube:
1 1 , 2 2 , 3 3 , ... , 16 16
1 1 2 2 3 3 16 16
in the above example, k=16, m=n=2.
i want to reshape them like this:
1 1 5 5 9 9 13 13
1 1 5 5 9 9 13 13
2 2 6 6 10 10 14 14
2 2 6 6 10 10 14 14
3 3 7 7 11 11 15 15
3 3 7 7 11 11 15 15
4 4 8 8 12 12 16 16
4 4 8 8 12 12 16 16
Assuming your input is a n by n by k*k matrix, you can achieve the desired input using:
n=2
k=4
reshape(permute(reshape(M,n,n,k,k),[1,3,2,4]),n*k,n*k);
The inner reshape splits into n by n by k by k, which directly represents the blocks.
The permute swaps the dimensions to let a reshape(...,n*k,n*k) produce the intended result.
Related
Consider a row vector A and row vector B. For example:
A = [1 2 3 7 8 10 12];
B = [1 1 2 2 2 3 5 6 6 7 7 7 8 8 10 10 10 11 12 12 12 13 15 16 18 19];
A has previously been checked to be a subset of B. By subset, I specifically mean that all elements in A can be found in B. I know that elements in A will not ever repeat. However, the elements in B are free to repeat as many or as few times as they like. I checked this condition using:
is_subset = all(ismember(A,B));
With all that out of the way, I need to know the indices of the elements of A within B including the times when these elements repeat within B. For the example A and B above, the output would be:
C = [1 2 3 4 5 6 10 11 12 13 14 15 16 17 19 20 21];
Use ismember to find the relevant logical indices. Then convert them to linear indices using find.
C = find(ismember(B,A));
You can find the difference of each element of A with B, and get the indices you want. Something like below:
A = [1 2 3 7 8 10 12];
B = [1 1 2 2 2 3 5 6 6 7 7 7 8 8 10 10 10 11 12 12 12 13 15 16 18 19];
C = [1 2 3 4 5 6 10 11 12 13 14 15 16 17 19 20 21];
tol = 10^-3 ;
N = length(A) ;
iwant = cell(N,1) ;
for i = 1:N
idx = abs(A(i)-B)<=tol ;
iwant{i} = find(idx) ;
end
iwant = [iwant{:}] ;
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)
I got a question when using pdist, it would be so many thanks if you could give me some advice. The pdist(D) usually gives the sum of the distance for the multiple dimension, however, I want to get the distance separately. For example I have a data set S which is a 10*2 matrix , I am using pdist(S(:,1)) and pdist(S(:,2)) to get the distance separately, but this seems very inefficient when the data has many dimensions. Is there any alternative way to achieve this more efficient? Thanks in advance!
Assuming you just want the absolute difference between the individual dimensions of the points then pdist is overkill. You can use the following simple function
function d = pdist_1d(S)
idx = nchoosek(1:size(S,1),2);
d = abs(S(idx(:,1),:) - S(idx(:,2),:));
end
which returns the absolute pairwise difference between all pairs of rows in S.
In this case
dist = pdist_1d(S)
gives the same result as
dist = cell2mat(arrayfun(#(dim)pdist(S(:,dim))',1:size(S,2),'UniformOutput',false));
Another option, since you're simply taking the absolute difference of the coordinates, is to use bsxfun:
>> D = randi(20, 10, 2) % generate sample data
D =
17 12
14 10
8 4
7 11
19 13
2 18
11 14
5 19
19 12
20 8
From here, we permute the data so that the coordinates (columns) extend into the 3rd dimension and the rows are in the 1st dimension for the 1st argument, and the 2nd dimension for the 2nd argument:
>> dist = bsxfun(#(x,y)abs(x-y), permute(D, [1 3 2]), permute(D, [3 1 2]))
dist =
ans(:,:,1) =
0 3 9 10 2 15 6 12 2 3
3 0 6 7 5 12 3 9 5 6
9 6 0 1 11 6 3 3 11 12
10 7 1 0 12 5 4 2 12 13
2 5 11 12 0 17 8 14 0 1
15 12 6 5 17 0 9 3 17 18
6 3 3 4 8 9 0 6 8 9
12 9 3 2 14 3 6 0 14 15
2 5 11 12 0 17 8 14 0 1
3 6 12 13 1 18 9 15 1 0
ans(:,:,2) =
0 2 8 1 1 6 2 7 0 4
2 0 6 1 3 8 4 9 2 2
8 6 0 7 9 14 10 15 8 4
1 1 7 0 2 7 3 8 1 3
1 3 9 2 0 5 1 6 1 5
6 8 14 7 5 0 4 1 6 10
2 4 10 3 1 4 0 5 2 6
7 9 15 8 6 1 5 0 7 11
0 2 8 1 1 6 2 7 0 4
4 2 4 3 5 10 6 11 4 0
This results in a 3-d symmetric matrix where
dist(p, q, d)
gives you the distance between points p and q in dimension d with
dist(p, q, d) == dist(q, p, d)
If you want the distances between p and q in all (or multiple) dimensions, you should use squeeze to put it in a vector:
>> squeeze(dist(3, 5, :))
ans =
11
9
Note that if you're using MATLAB 2016b or later (or Octave) you can create the same distance matrix without bsxfun:
dist = abs(permute(D, [1 3 2]) - permute(D, [3 1 2]))
The downside to this approach is that it creates the full symmetric matrix so you're generating each distance twice, which could potentially become a memory issue.
Say I have a matrix A whose first column contains item IDs with repetition and second column contains their weights.
A= [1 40
3 33
2 12
4 22
2 10
3 6
1 15
6 29
4 10
1 2
5 18
5 11
2 8
6 25
1 14
2 11
4 28
3 38
5 35
3 9];
I now want to find the difference of each instance of A and its associated minimum weight. For that, I make a matrix B with its first column containing the unique IDs from column 1 of A, and its column 2 containing the associated minimum weight found from column 2 of A.
B=[1 2
2 8
3 6
4 10
5 11
6 25];
Then, I want to store in column 3 of A the difference of each entry and its associated minimum weight.
A= [1 40 38
3 33 27
2 12 4
4 22 12
2 10 2
3 6 0
1 15 13
6 29 4
4 10 0
1 2 0
5 18 7
5 11 0
2 8 0
6 25 0
1 14 12
2 11 3
4 28 18
3 38 32
5 35 24
3 9 3];
This is the code I wrote to do this:
for i=1:size(A,1)
A(i,3) = A(i,1) - B(B(:,1)==A(i,2),2);
end
But this code takes a long time to execute as it needs to loop through B every time it loops through A. That is, it has a complexity of size(A) x size(B). Is there a better way to do this without using loops, that would execute faster?
You can use accumarray to first compute the minimum value in the second column of A for each unique value in the first column of A. We can then index into the result using the first column of A and compare to the second column of A to create the third column.
% Compute the mins
min_per_group = accumarray(A(:,1), A(:,2), [], #min);
% Compute the difference between the second column and the minima
A(:,3) = A(:,2) - min_per_group(A(:,1));
How to export a matrix with the first row telling names of columns
like
A=
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
export to matrix.txt
x1 x2 x3 x4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
I was checking
dlmwrite('matrix.txt',A,'delimiter',',');
But how to modify it?
Use the '-append' option:
dlmwrite('matrix.txt', {'a','b','c'});
dlmwrite('matrix.txt', [1,2,3;4,5,6], '-append');