How to duplicate all inner columns of a matrix and sum pairs of columns in Matlab - matlab

Suppose I have a matrix A
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
How do I duplicate the inner columns of A to get a new matrix B
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
Notice the first and last column of A were left alone. Then I need to sum pairs of rows together to get another matrix C:
3 5 7 9
3 5 7 9
3 5 7 9
3 5 7 9
3 5 7 9
The size of my matrices will not always be 5x5 and the elements will not always be so nice, but the matrix will always be square.
I do not need to generate or output matrix B. That was just simply how I initially thought of obtaining my final matrix C.
My goal is to be reasonably efficient, so I would like to accomplish this without a for loop.
How do I accomplish this for arbitrary matrix size nxn ?

Very simple . .
C = A(:,2:end) + A(:,1:end-1)

Related

How do I convert a list into a matrix in KDB?

I have a list of the form:
1 2 3 4
I'd like to convert it into a square matrix:
1 2
3 4
Which I think would be:
(1 2;3 4)
What's the canonical way to do this for, for n sized matrices in KDB?
You can use take
q)n: 2
q)(n; n) # 1 2 3 4
1 2
3 4
or for an m x n matrix:
q)m: 2
q)n: 3
q)(m; n) # 1 2 3 4 5 6
1 2 3
4 5 6
You can do:
n cut list
e.g.
q)3 cut til prd 3 3
0 1 2
3 4 5
6 7 8
Edit:
To insert any list into the closest n*n matrix and fill proceeding positions with NA's you can do:
q)f:{a:(ceiling sqrt b:count x); a cut x,((a*a) - b)#0N}
q)/e.g.
q)f til 10
0 1 2 3
4 5 6 7
8 9
q)

Sorting two columns of a matrix while keeping one intact in OCTAVE/MATLAB

I have this matrix:
data=[1 5402783 1
2 43359352 2
3 26118700 3
4 33091887 4
5 890931 5
6 826897 6
7 1188749 7
8 1239861 8];
I need the first column to stay as it is, sort the 2nd column (in descending order) and 'keep along' the values of the third column. If I use sort(data) it sorts all 3 columns.
I tried:
[~,idx]=sort(data(:,2),'descend');
data=data(idx,:)
but it is obviously wrong.
The output should be:
[1 43359352 2
2 33091887 4
3 26118700 3
4 5402783 1
5 1239861 8
6 1188749 7
7 890931 5
8 826897 6]
All you need to do is reassemble the data matrix in the end taking the unsorted and sorted parts:
data = [1 5402783 1
2 43359352 2
3 26118700 3
4 33091887 4
5 890931 5
6 826897 6
7 1188749 7
8 1239861 8];
[~,idx] = sort(data(:,2),'descend');
data = [data(:,1),data(idx,2:3)];

MATLAB - Frequency of an array element with a condition

I need some help please. I have an array, as shown below, 6 rows and 5 columns, none of the elements in any one row repeats. The elements are all single digit numbers.
I want to find out, per row, when a number, let's say 1 appears, I want to keep of how often the other numbers of the row appear. For example, 1 shows up 3 times in rows one, three and five. When 1 shows up, 2 shows up one time, 3 shows up two times, 4 shows up two times, 5 shows up one time, 6 shows up two times, 7 shows up one time, 8 shows up three times, and 9 shows up zero times. I want to keep a vector of this information that will look like, V = [3,1,2,2,1,2,1,3,0], by starting with a vector like N = [1,2,3,4,5,6,7,8,9]
ARRAY =
1 5 8 2 6
2 3 4 6 7
3 1 8 7 4
6 5 7 9 4
1 4 3 8 6
5 7 8 9 6
The code I have below does not give the feedback I am looking for, can someone help please? Thanks
for i=1:length(ARRAY)
for j=1:length(N)
ARRAY(i,:)==j
V(j) = sum(j)
end
end
Using indices that is in A creae a zero and one 6 * 9 matrix that [i,j] th element of it is 1 if i th row of A contains j.
Then multiply the zero and one matrix with its transpose to get desirable result:
A =[...
1 5 8 2 6
2 3 4 6 7
3 1 8 7 4
6 5 7 9 4
1 4 3 8 6
5 7 8 9 6]
% create a matrix with the size of A that each row contains the row number
rowidx = repmat((1 : size(A,1)).' , 1 , size(A , 2))
% z_o a zero and one 6 * 9 matrix that [i,j] th element of it is 1 if i th row of A contains j
z_o = full(sparse(rowidx , A, 1))
% matrix multiplication with its transpose to create desirable result. each column relates to number N
out = z_o.' * z_o
Result: each column relates to N
3 1 2 2 1 2 1 3 0
1 2 1 1 1 2 1 1 0
2 1 3 3 0 2 2 2 0
2 1 3 4 1 3 3 2 1
1 1 0 1 3 3 2 2 2
2 2 2 3 3 5 3 3 2
1 1 2 3 2 3 4 2 2
3 1 2 2 2 3 2 4 1
0 0 0 1 2 2 2 1 2
I don't understand how you are approaching the problem with your sample code but here is something that should work. This uses find, any and accumarray and in each iteration for the loop it will return a V corresponding to the ith element in N
for i=1:length(N)
rowIdx = find(any(A == N(i),2)); % Find all the rows contain N(j)
A_red = A(rowIdx,:); % Get only those rows
V = [accumarray(A_red(:),1)]'; % Count occurrences of the 9 numbers
V(end+1:9) = 0; % If some numbers don't exist place zeros on their counts
end

Remove rows containing duplicate elements

I have this example matrix:
1 2 4 5 1 3
2 3 5 6 3 4
1 2 3 4 5 6
3 2 4 6 1 5
...
I need to delete each row that contains duplicate elements. In this example I have to delete the first and second rows.
I know how to do this in a for-loop, but I don't want to use a for-loop.
Assuming A as the input matrix, you could do -
A(all(diff(sort(A,2),[],2),2),:)
Sample run -
>> A
A =
1 2 4 5 1 3
2 3 5 6 3 4
1 2 3 4 5 6
3 2 4 6 1 5
>> A(all(diff(sort(A,2),[],2),2),:)
ans =
1 2 3 4 5 6
3 2 4 6 1 5
Alternatively, if you don't mind some bsxFUN -
A(~any(sum(bsxfun(#eq,A,permute(A,[1 3 2])),2)>1,3),:)

How to create a random 3D matrix?

Is there any way of creating a 3D matrix randomly? There are ways to create random 2D matrices using randint function. Is there any inbuilt function like that?
E.g. a 4x4 matrix can be generated easily by using the randint function. What if I want to create a matrix of dimension 4x4x3?
You can use randi(imax, size1, size2, size3) function where imax refers to maximum of random integer values (mean upper bound) and 1 is lower bound. You can expand size argument to sizeN what you want.
This is an example of its usage:
>> A = randi(5, 4, 4, 3)
A(:,:,1) =
4 4 5 4
4 1 2 2
2 1 3 3
4 3 2 4
A(:,:,2) =
5 1 5 1
5 2 2 2
3 5 5 4
1 2 2 3
A(:,:,3) =
2 5 2 3
5 2 3 4
3 4 1 5
3 4 1 1
If you read the help carefully, you will notice that the randi function accepts any number of dimensions. You may do randi(10,3,3,3)
randi(10,3,3,3)
ans(:,:,1) =
9 10 3
10 7 6
2 1 10
ans(:,:,2) =
10 10 2
2 5 5
10 9 10
ans(:,:,3) =
8 1 7
10 9 8
7 10 8