Finding indices of matrices while traversing - matlab

I have a matrix:
1|2|3|4
4|5|6|7
7|8|9|10
10|11|12|13
I want to multiply the indices of this matrix with indices of another matrix of different size:
7|8|9
9|10|10
10|11|11
for these two matrices I have used the following for loops:
for x=1:4
for y=1:4
for m=1:3
for n=1:3
c=(m*x+n*y);
end
end
end
end
Is there any way to rewrite the above code without using loops? If the indices of each element can be generated in the above matrices, I think it can be done. Please help

mx = m'*x;
mx = mx(:);
ny = n'*y;
ny = ny(:);
mxe = repmat(mx, [length(ny), 1]);
nye = repmat(ny, [length(mx), 1]);
c = mxe+nye;
This will result in c containing all the values that get put in during that loop you have there (note that in your loop, value gets assigned and overwritten).

Related

How do i handle "Error using vertcat Dimensions of matrices being concatenated are not consistent" in Matlab?

So I want to concatenate an m x n matrix to obtain a 1 x mn matrix. The matrix I want to concatenate are generated from a while loop. Although the number of columns will always be 3, I however cannot tell how many rows there will be for each iteration. Also, the row sizes for each iteration may not always be the same.
The code runs in cases where the row sizes were all equal to 6, but in cases where they aren't equal I get an error:
Error using vertcat Dimensions of matrices being concatenated are not consistent.
parts of the code are as follows:
A = [];
B = [];
searchArea = 2;
for ii = 1: numel(velocity)
Do ....
while area(ii,:) < searchArea
Do ....
% COLLATE vectors for A
A = [A; [Ax(ii), Ay(ii), Az(ii)]];
Do ...
end
%# Copy the A into new variable (B) and Reshape into row vector so as to associate each row to its corresponding velocity
B = [B; reshape(A.',1,[])];
A = [];
end
Could someone please advice me on what I am doing wrong here. I would clarify further if there be need. Thanks guys!
If it's your intent that B ends up being a row vector, then you need to change this:
B = [B; reshape(A.',1,[])]; % Does vertical concatenation
to this:
B = [B reshape(A.',1,[])]; % Does horizontal concatenation (note there's no semicolon)
so that each row vector gotten from reshaping A gets added to the end of the row instead of as a new row (as the semicolon indicates).

How to concatenate smaller matrices to form a larger matrix?

I would like to concatenate 14641 number of 3X3 matrices into a matrix of size 363X363 and the large matrix must contain 121 submatrices in each row(121*3=363 columns) and 121 such rows of submatrices(121*3=363rows).I have gone through the similar questions but I didn't get the correct logic to concatenate large number of matrices.
Awaiting your suggestions. Thanks in advance.
PS: I got those 3X3 matrices from a 363X363 matrix. The following code is for splitting the single matrix into submatrices.
I=imread('photo.jpg');
B = randi([0 255],363,726,3);
B(1:numel(I)) = I;
L=B(1:363,1:363);
[al,bl]=size(L);
ImageSize=al*bl;
BlockD=3; % i assume 3x3 block
BlockSize=BlockD*BlockD;
TotalBlocks=ImageSize/BlockSize;
subL=zeros(BlockD,BlockD,TotalBlocks); %arrays of blocks.
LL=double(L);
k=1;
for i=1:BlockD:al
for j=1:BlockD:bl
subL(:,:,k)=LL(i:i+BlockD-1,j:j+BlockD-1);
k=k+1;
end
end
Now I want to concatenate all these 'subL' submatrices to form 'LL' again
Using blocproc instead of above code
I tried using blockproc function instead of the above code. I did this piece of code and is working pretty well.Thank you
I=imread('photo.jpg');
B = randi([0 255],363,726,3);
B(1:numel(I)) = I;
L=B(1:363,1:363);
q=[1 2 3 4];
fun=#(block_struct)quaternionrotate(q,block_struct.data);
LL = blockproc(L,[3 3],fun);
and the function quaternionrotate is
function [ Lrot1 ] = quaternionrotate(q,A)
qinv=quatinv(q);
B=zeros(3,1);
A1=[B A];
Lrot=quatmultiply(q,quatmultiply(A1,qinv));
Lrot(:,1)=[];
Lrot1=Lrot;
end
Finally figured this out!
% I used this to make 14641 3x3 sample matrices, you should use your own
matrix = ones(3,3);
for i = 2:14641
matrix = [matrix, i*ones(3,3)];
end
c_size = 121;
output = cell(c_size, c_size) % Make 121x121 cell matrix
% Populate the cell matrix
for i = 1:1:c_size
for j = 1:1:c_size
output(i,j) = {matrix(1:3, (i-1)*c_size*3+(j-1)*3+1 : (i-1)*c_size*3+(j-1)*3+3)};
end
end
This breaks up the 43923x3 size matrix of 363 3x3 matrices into a 121x121 cell matrix of 3x3 matrices. Now that's a tongue twister...
Either way the code does what you need! :)

matlab concatenating vectors

I'm new to MATLAB, and programming in general, and I am having difficulty accomplishing what I am sure is a very, very simple task:
I have a list of vectors v_i for i from 1 to n (n in some number), all of the same size k. I would like to create a vector v that is a "concatenation" (don't know if this is the correct terminology) of these vectors in increasing order: what I mean by this is that the first k entries of v are the k entries of v_1, the k+1 to 2k entries of v are the k entries of v_2 etc. etc. Thus v is a vector of length nk.
How should I create v?
To put this into context, here is function I've began writing (rpeakindex will just a vector, roughq would be the vector v I mentioned before):
function roughq = roughq(rpeakindex)
for i from 1 to size(rpeakindex) do
v_i = [rpeakindex(i)-30:1:rpeakindex(i)+90]
end
Any help is appreciated
Let's try two things.
First, for concatenating vectors there are a couple of methods here, but the simplest would be
h = horzcat(v_1, v_2);
The bigger problem is to enumerate all vectors with a "for" loop. If your v_n vectors are in a cell array, and they are in fact v{i}, then
h= [];
for j=1:n
h = horzcat(h, v{i});
end
Finally, if they only differ by name, then call them with
h=[];
for j=1:n
h= horzcat(h, eval(sprintf('v_%d',j));
end
Let the arrays (vectors) be:
v_1=1:10;
v_2=11:20;
v_3=21:30;
v_4=31:40;
and so on.
If they are few (e. g. 4), you can directly set then as input in the cat function:
v=cat(2,v_1,v_2,v_3,v_4)
or the horzcat function
v=horzcat(v_1,v_2,v_3,v_4)
otherwise you can use the eval function within a loop
v1=[];
for i=1:4
eval(['v1=[v1 v_' num2str(i) ']'])
end
Hope this helps.
Concatenating with horzcat is definitely an option, but since these vectors are being created in a function, it would be better to concatenate these vectors automatically in the function itself rather than write out horzcat(v1,v2,....vn) manually.
Given the function mentioned in the question, I would suggest something like this:
function v = roughq(rpeakindex)
v = zeros(121,length(rpeakindex)); %// create a 2D array of all zeros
for i = 1:size(rpeakindex)
v(:,i) = [rpeakindex(i)-30:1:rpeakindex(i)+90]; %// set result to ith column of v
end
v = v(:)'; %'//reshape v to be a single vector with the columns concatenated
end
Here's a simplified example of what's going on:
N = 3;
v = zeros(5,N);
for i = 1:N
v(:,i) = (1:5)*i;
end
v = v(:)';
Output:
v =
1 2 3 4 5 2 4 6 8 10 3 6 9 12 15
You may want to read up on MATLAB's colon operator to understand the v(:) syntax.
If you mean 2d matrix, you are using for holding vectors and each row hold vector v then you can simply use the reshape command in matlab like below:
V = [] ;
for i = 1:10
V(i,:) = randi (10,1 ,10) ;
end
V_reshpae = reshape (V, 1, numel(V)) ;

How to vectorize this Matlab loop

I need some help to vectorize the following operation since I'm a little confused.
So, I have a m-by-2 matrix A and n-by-1 vector b. I want to create a n-by-1 vector c whose entries should be the values of the second column of A whose line is given by the line where the correspondent value of b would fall...
Not sure if I was clear enough. Anyway, the code below does compute c correctly so you can understand what is my desired output. However, I want to vectorize this function since my real n and m are in the order of many thousands.
Note that values of bare non-integer and not necessarily equal to any of those in the first column of A (these ones could be non-integers too!).
m = 5; n = 10;
A = [(0:m-1)*1.1;rand(1,m)]'
b = (m-1)*rand(n,1)
[bincounts, ind] = histc(b,A(:,1))
for i = 1:n
c(i) = A(ind(i),2);
end
All you need is:
c = A(ind,2);

How can I build a Scilab / MATLAB program that averages a 3D matrix?

I need to make a scilab / MATLAB program that averages the values of a 3D matrix in cubes of a given size(N x N x N).I am eternally grateful to anyone who can help me.
Thanks in advance
In MATLAB, mat2cell and cellfun make a great team for working on N-dimensional non-overlapping blocks, as I think is the case in the question. An example scenario:
[IN]: A = [30x30x30] array
[IN]: bd = [5 5 5], size of cube
[OUT]: B = [6x6x6] array of block means
To accomplish the above, the solution is:
dims = [30 30 30]; bd = [5 5 5];
A = rand(dims);
f = floor(dims./bd);
remDims = mod(dims,bd); % handle dims that are not a multiple of block size
Ac = mat2cell(A,...
[bd(1)*ones(f(1),1); remDims(1)*ones(remDims(1)>0)], ....
[bd(2)*ones(f(2),1); remDims(2)*ones(remDims(2)>0)], ....
[bd(3)*ones(f(3),1); remDims(3)*ones(remDims(3)>0)] );
B = cellfun(#(x) mean(x(:)),Ac);
If you need a full size output with the mean values replicated, there is a straightforward solution involving the 'UniformOutput' option of cellfun followed by cell2mat.
If you want overlapping cubes and the same size output as input, you can simply do convn(A,ones(blockDims)/prod(blockDims),'same').
EDIT: Simplifications, clarity, generality and fixes.
N = 10; %Same as OP's parameter
M = 10*N;%The input matrix's size in each dimensiona, assumes M is an integer multiple of N
Mat = rand(M,M,M); % A random input matrix
avgs = zeros((M/N)^3,1); %Initializing output vector
l=1; %indexing
for i=1:M/N %indexing 1st coord
for j=1:M/N %indexing 2nd coord
for k=1:M/N % indexing third coord
temp = Mat((i-1)*N+1:i*N,(j-1)*N+1:j*N,(k-1)*N+1:k*N); %temporary copy
avg(l) = mean(temp(:)); %averaging operation on the N*N*N copy
l = l+1; %increment indexing
end
end
end
The for loops and copying can be eliminated once you get the gist of indexing.