matlab - create a matrix of sequential values - matlab

What's the fastest way to create a 8x8 matrix filled with 1-64 by row. The help docs say i should even be able to fill a matrix with an array, but i can't seem to make it work. I've been told it can be done more easily than i do it, but I've not seen it done. Here's an idea of what i'm looking for...
v26 =
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64
but to get it to do this, I had to do a row-by-row fill with ...
v26 = [1:8; 9:16; 17:24; 25:32; 33:40; 41:48; 49:56; 57:64]

make a sequence, then you reshape it:
m = reshape(1:64, [8 8])';
You have to transpose it in the end b/c matlab is column major.

Related

Change base of whole matrix

I want to change the base of a multiplication table to another base.
If I use
disp(dec2base((1:10).*(1:10)',7))
the numbers come flowing out individually. However I want them to stay in the exact position in the given matrix.
The numerical base is a display issue, numbers are always stored and manipulated in base 2 internally. So all you need to do is write a loop that displays the numbers in they way you want to. For example:
for ii=1:10
for jj=1:10
fprintf('%6s',dec2base(ii*jj,7));
end
fprintf('\n');
end
Output:
1 2 3 4 5 6 10 11 12 13
2 4 6 11 13 15 20 22 24 26
3 6 12 15 21 24 30 33 36 42
4 11 15 22 26 33 40 44 51 55
5 13 21 26 34 42 50 55 63 101
6 15 24 33 42 51 60 66 105 114
10 20 30 40 50 60 100 110 120 130
11 22 33 44 55 66 110 121 132 143
12 24 36 51 63 105 120 132 144 156
13 26 42 55 101 114 130 143 156 202
Storing base-7 representation of numbers as string array:
M = (1:10).*(1:10)';
out = strings(size(M));
for jj = 1:size(M,2)
for ii = 1:size(M,1)
out(ii,jj) = dec2base(M(ii,jj) ,7);
end
end

Sorting wrt to a column value in matlab [duplicate]

This question already has answers here:
Sorting entire matrix according to one column in matlab
(2 answers)
Closed 4 years ago.
I have multiple columns in my dataset and column 2 contains value from 1 till 7. I want to sort my dataset with respect to second column . Thanks in advance
The command you need is sortrows
By default this sorts with respect to the first column, but an additional argument can be used to change this to the 2nd (or 5th, 17th etc)
If A is your original array:
B = sortrows(A,2);
will give you the sorted array B w.r.t 2nd column
What did you mean by sort with respect to second column? You should be more specific or at least give us an example.
If you need a simple sort on each column use the following
A =
95 45 92 41 13 1 84
23 1 73 89 20 74 52
60 82 17 5 19 44 20
48 44 40 35 60 93 67
89 61 93 81 27 46 83
76 79 91 0 19 41 1
Sort each column of A in ascending order:
c = sort(A, 1)
c =
23 1 17 0 13 1 1
48 44 40 5 19 41 20
60 45 73 35 19 44 52
76 61 91 41 20 46 67
89 79 92 81 27 74 83
95 82 93 89 60 93 84

How to dynamically reshape matrix block-wise? [duplicate]

This question already has answers here:
Collapsing matrix into columns
(8 answers)
Closed 6 years ago.
Let's say I have A = [1:8; 11:18; 21:28; 31:38; 41:48] Now I would like to move everything from column 4 onward to the row position. How do I achieve this?
A =
1 2 3 4 5 6 7 8
11 12 13 14 15 16 17 18
21 22 23 24 25 26 27 28
31 32 33 34 35 36 37 38
41 42 43 44 45 46 47 48
to
A2 =
1 2 3 4
11 12 13 14
21 22 23 24
31 32 33 34
41 42 43 44
5 6 7 8
15 16 17 18
35 36 37 38
45 46 47 48
reshape doesn't seem to do the trick
Here's a vectorized approach with reshape and permute -
reshape(permute(reshape(a,size(a,1),4,[]),[1,3,2]),[],4)
Making it generic, we could introduce the number of columns as a parameter. Hence, let ncols be that one. So, the solution becomes -
ncols = 4
reshape(permute(reshape(a,size(a,1),ncols,[]),[1,3,2]),[],ncols)
Sample run -
>> a
a =
20 79 18 82 27 23 59 66 46 21 48 95
96 83 46 49 34 88 23 42 17 27 15 54
11 88 34 92 23 62 86 56 32 32 91 54
>> reshape(permute(reshape(a,size(a,1),4,[]),[1,3,2]),[],4)
ans =
20 79 18 82
96 83 46 49
11 88 34 92
27 23 59 66
34 88 23 42
23 62 86 56
46 21 48 95
17 27 15 54
32 32 91 54
More info on the intuition behind such a General idea for nd to nd transformation, which even though originally was meant for NumPy/Python, extends to any programming paradigm in general.
Use Matrix indexing!
B=[A(:,1:4);A(:,5:8)]
In a loop...
for ii=0:floor(size(A,2)/4)-1
B([1+5*ii:5*(ii+1)],:)=A(:,[1+4*ii:4*(ii+1)] );
end
One more... perhaps unoptimized way would be to decompose the matrix into cells row-wise, transpose the cell array then concatenate everything back together:
B = cell2mat(mat2cell(A, size(A, 1), 4 * ones((size(A, 2) / 4), 1)).');
The above first uses mat2cell to decompose the matrix into non-overlapping cells. Each cell has the same number of rows as A but the total number of columns is 4 and there are exactly size(A, 2) / 4 of them. As such, we need to indicate a vector of ones where each element is 4 and there are size(A, 2) / 4 of these to tell us the number of columns for each cell. This creates a row-wise cell array and so we transpose this cell array and merge all of the cells together into one final matrix with cell2mat.

Matlab: select submatrix from matrix by certain criteria

I have a matrix A
A=[f magic(10)]
A=
931142103 92 99 1 8 15 67 74 51 58 40
931142103 98 80 7 14 16 73 55 57 64 41
931142103 4 81 88 20 22 54 56 63 70 47
459200101 85 87 19 21 3 60 62 69 71 28
459200101 86 93 25 2 9 61 68 75 52 34
459200101 17 24 76 83 90 42 49 26 33 65
459200101 23 5 82 89 91 48 30 32 39 66
37833100 79 6 13 95 97 29 31 38 45 72
37833100 10 12 94 96 78 35 37 44 46 53
37833100 11 18 100 77 84 36 43 50 27 59
The first column are firm codes. The rest columns are firms' data, with each row referring to the firm in Column 1 in a given year. Notice that years may not be balance for every firms.
I would like to subtract sub-matrices according to the first column. For instance, for A(1:3,2:11) for 931142103:
A(1:3,2:11)
ans =
92 99 1 8 15 67 74 51 58 40
98 80 7 14 16 73 55 57 64 41
4 81 88 20 22 54 56 63 70 47
Same as 459200101 (which would be A(4:7,2:11)) and A(8:10,2:11) for 37833100.
I get a sense that the code should like this:
indices=find(A(:,1));
obs=size(A(:,1));
for i=1:obs,
if i==indices(i ??)
A{i}=A(??,2:11);
end
end
I have difficulties in indexing these complicated codes: 459200101 and 37833100 in order to gather them together. And how can I write the rows of my submatrix A{i}?
Thanks so much!
One approach with arrayfun -
%// Get unique entries from first column of A and keep the order
%// with 'stable' option i.e. don't sort
unqA1 = unique(A(:,1),'stable')
%// Use arrayfun to select each such submatrix and store as a cell
%// in a cell array, which is the final output
outA = arrayfun(#(n) A(A(:,1)==unqA1(n),:),1:numel(unqA1),'Uni',0)
Or this -
[~,~,row_idx] = unique(A(:,1),'stable')
outA = arrayfun(#(n) A(row_idx==n,:),1:max(row_idx),'Uni',0)
Finally, you can verify results with a call to celldisp(outA)
If values in column 1 always appear grouped (as in your example), you can use mat2cell as follows:
result = mat2cell(A, diff([0; find(diff(A(:,1))); size(A,1)]));
If they don't, just sort the rows of A according to column 1 before applying the above:
A = sortrows(A,1);
result = mat2cell(A, diff([0; find(diff(A(:,1))); size(A,1)]));
If you don't mind the results internally not being ordered, you can use accumarray for this:
[~,~,I] = unique(A(:,1),'stable');
partitions = accumarray(I, 1:size(A,1), [], #(I){A(I,2:end)});

Is there a way to generate a matrix in which each element is defined as 10+row_index + column_index without for loops?

I'm trying to generate a matrix in which each element is defined as 10 * row_index + column_index. The rows and columns may fluctuate up to a 9x9 matrix. For example:
11 12 13 14 15 16
21 22 23 24 25 26
31 32 33 34 35 36
41 42 43 44 45 46
51 52 53 54 55 56
The algorithm is exceedingly simple with for loops, but I've been warned that I should avoid for loops unless absolutely necessary, when dealing with matrices, because they are slower than vector/matrix operations.
What other ways are there to generate such a matrix in Matlab 2012b?
For your particular matrix, it's quite straightforward:
nRows = 4;
nCols = 5;
out = bsxfun(#plus,10*(1:nRows)',1:nCols)
out =
11 12 13 14 15
21 22 23 24 25
31 32 33 34 35
41 42 43 44 45