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

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

Related

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.

Implementing matching pursuit algorithm

I have implemented matching pursuit algorithm but i m unable to get the required result.
Here is my code:
D=[1 6 11 16 21 26 31 36 41 46
2 7 12 17 22 27 32 37 42 47
3 8 13 18 23 28 33 38 43 48
4 9 14 19 24 29 34 39 44 49
5 10 15 20 25 30 35 40 45 50];
b=[6;7;8;9;10];
n=size(D);
A1=zeros(n);
R=b;
H=10;
if(H <= 0)
error('The number of iterations needs to be greater then 0')
end;
for k=1:1:H
[c,d] = max(abs(D'*R)); %//'
A1(:,d)=D(:,d);
D(:,d)=0;
y = A1\b;
R = b-A1*y;
end
Output
y=
0.8889
0
0
0
0
0
0
0
0
0.1111
I should get only non-zero value at (2,1) and other values should be zero but I'm getting 2 non-zero value. Can you please help me find out where the error is?
Thanks.
I checked with:
http://www.scholarpedia.org/article/Matching_pursuit
Your functions need to be normalized!
D = D./repmat(sum(D,1),5,1);
I get the following algorithm:
D=[1 6 11 16 21 26 31 36 41 46
2 7 12 17 22 27 32 37 42 47
3 8 13 18 23 28 33 38 43 48
4 9 14 19 24 29 34 39 44 49
5 10 15 20 25 30 35 40 45 50];
D = D./repmat(sum(D,1),5,1);
b=[6;7;8;9;10];
n=size(D);
A1=zeros(n);
R=b;
H=100;
if(H <= 0)
error('The number of iterations needs to be greater then 0')
end;
a = zeros(1,H);
G = zeros(size(D,1),H);
for k=1:1:H
ip = D'*R;
[~,d] = max(abs(ip)); %//'
G(:,k) = D(:,d);
a(k) = ip(d);
R = R-a(k)*G(:,k);
end
% recover signal:
Rrec = zeros(size(R));
for i=1:H
Rrec = Rrec + a(i)*G(:,i);
end
figure();
plot(b);
hold on;
plot(Rrec)
It approximates the signal quite well. But not with D(:,2) at first as expected. Maybe it is a starting point...
Here is the updated code. This is based on the algorithm provided at https://en.wikipedia.org/wiki/Matching_pursuit
clc;
clear all;
D=[1 6 11 16 21 26 31 36 41 46
2 7 12 17 22 27 32 37 42 47
3 8 13 18 23 28 33 38 43 48
4 9 14 19 24 29 34 39 44 49
5 10 15 20 25 30 35 40 45 50];
b=[6;7;8;9;10];
H=10;
for index=1:10
G(:,index)=D(:,index)./norm(D(:,index));
end
G1=G;
n=size(G);
R=b;
if(H <= 0)
error('The number of iterations needs to be greater then 0')
end;
if(H >size(D,2))
error('The number of iterations needs to be less than dictionary size')
end;
bIndex=1:size(G,2);
for k=H:-1:1
innerProduct=[];
for index=1:size(G,2)
innerProduct(index)=dot(R,G(:,index));
end
[c,d] = max(abs(innerProduct));
An(H-k+1)=innerProduct(d);
R = R-(An(H-k+1)*G(:,d));
G(:,d)=[];
strong(H-k+1)=bIndex(d);
bIndex(d)=[];
end
G_new=G1(:,strong);
%% reconstruction
bReconstructed=zeros(size(G_new,1),1);
for index=1:size(G_new,2)
bReconstructed(:,index) = (An(index)*G_new(:,index));
end
b_new=sum(bReconstructed,2)
Yes the atoms in the dictionary must be normalized so that the inner products of the current residual with different atoms can be compared fairly.
You may want to check my OMP implementation which also includes incremental Cholesky updates for the least square step in OMP at https://github.com/indigits/sparse-plex/blob/master/library/%2Bspx/%2Bpursuit/%2Bsingle/omp_chol.m
I have written detailed tutorial notes on OMP in my library documentation at https://sparse-plex.readthedocs.io/en/latest/book/pursuit/omp/index.html
My library sparse-plex contains a C implementation of OMP which is close to 4 times faster than fastest MATLAB implementations. See the discussion here https://sparse-plex.readthedocs.io/en/latest/book/pursuit/omp/fast_omp.html

How to rearrange each image patch into number of column vector [duplicate]

This question already has answers here:
Efficient Implementation of `im2col` and `col2im`
(2 answers)
Closed 7 years ago.
I am working on a project where i have used a image whose size is (512x512)then i have divided the whole image by 8 so that there will be 64x64 block then i have to rearrange each 8x8 image patch into a single column so that new size would be
64x4069. unable to understand how to do it.please help.
Here is my code
enter code here
a=imread('lena.png');
b=double(a);
[r,c]=size(b);
bl=8;
br=r/bl;
bc=r/bl;
It will arrange in such a order that first column would be image patch of (1:8,1:8)next column would be(9:16,9:16)likewise.
If reshape is allowed, permute is definitely allowed.
Assuming both the original and block sub-matrix are square matrices
Here is one approach
out = permute(reshape(A,blSz,size(A,1)/blSz,blSz,[]),[1 3 2 4]);
out = reshape(out,size(out,1)*size(out,1),[]);
Sample inputs:
A = randi(50,8); %// Change it with your original `512x512` matrix
blSz = 2; %// Change it to 8 for your problem
Results:
>> A
A =
31 17 18 10 33 31 43 16
20 40 31 15 34 23 42 6
46 24 10 5 32 23 13 47
1 2 37 29 48 34 31 33
24 9 13 35 11 39 30 24
22 37 46 28 36 18 28 32
24 24 14 22 12 34 44 28
39 8 39 33 6 21 14 33
>> out
out =
31 46 24 24 18 10 13 14 33 32 11 12 43 13 30 44
20 1 22 39 31 37 46 39 34 48 36 6 42 31 28 14
17 24 9 24 10 5 35 22 31 23 39 34 16 47 24 28
40 2 37 8 15 29 28 33 23 34 18 21 6 33 32 33
Using loops as OP requested
A = randi(50,8);
blSz = 2;
nBl = size(A,1)/2;
out = zeros(size(reshape(A,blSz*blSz,[])));
count = 1;
for ii = 1:nBl
for jj= 1:nBl
block = A((jj-1)*blSz + 1:(jj-1)*blSz + blSz, (ii-1)*blSz + 1:(ii-1)*blSz + blSz);
out(:,count) = block(:);
count = count + 1;
end
end
Gives the same result as above!
Alternative for im2col using vectorized approach
newOut = mat2cell(reshape(out,blSz,[]),blSz,repmat(blSz,size(out,2),1));
newOut = cell2mat(reshape(newOut,nBl,[]));

matlab - create a matrix of sequential values

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.

How to select and remove cells from a 2d matrix of cells in matlab

I have a 35x2 matrix (randomwords); and I have randomly selected 8 rows (rndm). What I need to do is remove the 8 selected rows from the randomwords matrix and save this new 27x2 matrix under a new variable heading, but I am finding this extremely difficult. I have provided my code Any help would be greatly appreciated.
target = words ([30 1 46 14 44 55 8 3 57 65 69 70 57 39 21 60 22 20 16 10 9 17 62 19 25 41 49 53 36 6 42 58 40 56 63]);
synonym = words([43 15 32 28 72 27 48 51 13 67 59 33 35 47 52 61 71 7 23 12 2 66 11 37 4 45 64 38 34 31 29 18 50 68 26]);
% assigns these elements of words into targets and synonyms. They are
% ordered so that words and synonyms are corresponding elements of
% synonyms and targets
% TO SELECT 8 RANDOM WORDS FOR THE ENCODING PHASE
randomwords = [target; synonym]'; % should be a 35x2 matrix
rndm = datasample(randomwords, 8, 1); % should select 8 random couples from the rows and none of them will be repeats
unpaired = rndm(:,2); % should select only the synonyms to form the unpaired stimuli; will be different for each run
Store the index of the removed rows in a variable, let's say removedrows and then just do:
result = randomwords;
result(removedrows,:) = [];