average every n rows in a complex matrix - matlab

I have a big complex single matrix (9040 X 23293).
Because this matrix holds to much data for me, I want to average every n rows. For example, n can be 10 and the new matrix will be 904 X 23293.
I tried to use reshape but it does not work on complex numbers.
I would love to get some help.
Thanks,
Lauren
Thanks.
Laurn

Reshape works on complex numbers. As you did not share the code, I do'nt know what is the problem. Anyhow, if the number of rows is not multiple of 10, you can reshape first 10 * n rows and add the average of the remain rows. You can find the general solution in the following for the given complex matrix m:
fixed_num_rows = fix(size(m,1)/n);
means = mean(reshape(m(1:(fixed_num_rows * n),:), fixed_num_rows, n * size(m,2)),2);
means = [means; mean(mean(m((fixed_num_rows * n + 1):size(m,1),:)))];

Related

3D matrix Indexing using 2D matrix

Could anyone shed some light on how this for loop can be replaced by a single command in MATLAB?
for i = 1 : size(w,3)
x=w(:,:,i);
w1(i,:)=x(B(i),:);
end
clear x
Here, w is a 3D (x by y by z) matrix and B (1 by z) is a vector containing rows pertaining to each layer in w. This for loop takes about 150 seconds to execute when w is 500000 layers deep. I tried using,
Q = w(B,:,:);
Q = reshape(Q(1,:),[500000,2])';
This creates a matrix Q of size 500000 X 2 X 500000 and MATLAB threw me an error saying memory out of bound. Any help would be appreciated!
You are creating intermediate variables (such as x) and using a for loop. The core idea of the following approach is to first pre-populate the indices used and then use linear indexing to access all the elements at once. Then, we can reshape to get the desired result.
ind = [B(1)*ones(size(w,2),1) (1:size(w,2)).' 1*ones(size(w,2),1)];
ind = [ind; [B(2)*ones(size(w,2),1) (1:size(w,2)).' 2*ones(size(w,2),1)]];
ind = [ind; [B(3)*ones(size(w,2),1) (1:size(w,2)).' 3*ones(size(w,2),1)]];
lin_ind = sub2ind(size(w), ind(:,1), ind(:,2), ind(:,3));
w1 = reshape(w(lin_ind),size(w,2),size(w,3)).'
On my system, this matches with w1 computed with the loop given in your question. Note that you may need to use a for loop to pre-populate the indices. I wrote three expressions since I was experimenting with small matrices. Actually, the first three lines can be written in such a way that you don't need loops at all and it still works with any size. I will leave that up to you.

how to calculate avrage of 1st 5 rows then next 5 row likewise continue in matlab

I have .xlsx file n rows and m column. I want to calculate average of 1st 5 rows then next 5 rows likewise ( each 5 interval average) continue for my data.
If A is your matrix, what about:
m=[];
for ii=1:5:20
m(end+1)=mean(mean(A(ii:ii+4,:)));
end
does it work for you?
Here is a "hack" that should be pretty fast if A is big:
m = mean(kron(speye(size(A,1)/5),ones(1,5))*A/5,2);
You can use reshape to get blocks of 5 rows in the first dimension. If A is your matrix
m = squeeze(mean(reshape(A,5,[],size(A,2)),1));
The code works as follows
reshape the matrix to get the blocks of 5 rows in the first dimension
Compute the mean over the blocks of 5 rows.
After the mean, the first dimension is a singleton so it is better to squeeze it so the output is a 2D matrix.

Determining if any duplicate rows in two matrices in MatLab

Introduction to problem:
I'm modelling a system where i have a matrix X=([0,0,0];[0,1,0],...) where each row represent a point in 3D-space. I then choose a random row, r, and take all following rows and rotate around the point represented by r, and make a new matrix from these rows, X_rot. I now want to check whether any of the rows from X_rot is equal two any of the rows of X (i.e. two vertices on top of each other), and if that is the case refuse the rotation and try again.
Actual question:
Until now i have used the following code:
X_sim=[X;X_rot];
if numel(unique(X_sim,'rows'))==numel(X_sim);
X(r+1:N+1,:,:)=X_rot;
end
Which works, but it takes up over 50% of my running time and i were considering if anybody in here knew a more efficient way to do it, since i don't need all the information that i get from unique.
P.S. if it matters then i typically have between 100 and 1000 rows in X.
Best regards,
Morten
Additional:
My x-matrix contains N+1 rows and i have 12 different rotational operations that i can apply to the sub-matrix x_rot:
step=ceil(rand()*N);
r=ceil(rand()*12);
x_rot=x(step+1:N+1,:);
x_rot=bsxfun(#minus,x_rot,x(step,:));
x_rot=x_rot*Rot(:,:,:,r);
x_rot=bsxfun(#plus,x_rot,x(step,:));
Two possible approaches (I don't know if they are faster than using unique):
Use pdist2:
d = pdist2(X, X_rot, 'hamming'); %// 0 if rows are equal, 1 if different.
%// Any distance function will do, so try those available and choose fastest
result = any(d(:)==0);
Use bsxfun:
d = squeeze(any(bsxfun(#ne, X, permute(X_rot, [3 2 1])), 2));
result = any(d(:)==0);
result is 1 if there is a row of X equal to some row of X_rot, and 0 otherwise.
How about ismember(X_rot, X, 'rows')?

Assigning the different row to another matrix after comparing two matrices

i have two matrices
r=10,000x2
q=10,000x2
i have to find out those rows of q which are one value or both values(as it is a two column matrix) different then r and allocate them in another matrix, right now i am trying this.i cannot use isequal because i want to know those rows
which are not equal this code gives me the individual elements not the complete rows different
can anyone help please
if r(:,:)~=q(:,:)
IN= find(registeredPts(:,:)~=q(:,:))
end
You can probably do this using ismember. Is this what you want? Here you get the values from q in rows that are different from r.
q=[1,2;3,4;5,6]
r=[1,2;3,5;5,6]
x = q(sum(ismember(q,r),2) < 2,:)
x =
3 4
What this do:
ismember creates an array with 1's in the positions where q == r, and 0 in the remaining positions. sum(.., 2) takes the column sum of each of these rows. If the sum is less than 2, that row is included in the new array.
Update
If the values might differ some due to floating point arithmetic, check out ismemberf from the file exchange. I haven't tested it myself, but it looks good.

Using ranges in Matlab/Octave matrices

Let's say I want to create an 100x100 matrix of which every row
contains the elements 1-100
A = [1:100; 1:100; 1:100... n]
Obviously forming a matrix is a bad idea, because it would force me to
create 100 rows of range 1:100.
I think I could do it by taking a 'ones' array and multiplying every
row by a vector... but I'm not sure how to do it
a = (ones(100,100))*([])
??
Any tips?
You can use the repeat matrix function (repmat()). You code would then look like this:
A = repmat( 1:100, 100, 1 );
This means that you're repeating the first argument of repmat 100 times vertically and once horizontally (i.e. you leave it as is horizontally).
You could multiply a column vector of 100 1s with a row vector of 1:100.
ones(3,1)*(1:3)
ans =
1 2 3
1 2 3
1 2 3
Or you could use repmat ([edit] as Phonon wrote a few seconds before me [/edit]).
Yes, repmat is the easy solution, and even arguably the right solution. But knowing how to visualize your aim and how to create something that yields that aim will give long term benefits in MATLAB. So try other solutions. For example...
cumsum(ones(100),2)
bsxfun(#plus,zeros(100,1),1:100)
ones(100,1)*(1:100)
cell2mat(repmat({1:100},100,1))
and the boring
repmat(1:100,100,1)