Median for every nth values in Matlab - matlab

I don't have much experience with Matlab.
I have a row vector with 17497 elements and I would like to create a loop to get the median of every 120 values.
So, the median of value 1:120, then the next median of values 121:240 and so on.
Could somebody help me?
Thanks in advance,
Sunna

You could use accumarray
N = 17497;
data = rand(N,1);
%# array with 1,1,1,2,2,2 etc
idx = floor((0:N-1).'/120)+1;
%# create median for groups of 120 data points
%# discard the last one if needed as it's <120 points
out = accumarray(idx,data,[],#median);

I am going to assume that you simply ignore the last few elements in your row vector such that the row can be equally divided into parts of 120. You can then transform your row vector into a 120 row matrix. median can operate on this matrix directly and return the median of each column.
N = 17497;
A = randn(1,N);
newN = N - mod(N,120);
median(reshape(A(1:newN),120,[]));

Related

How to sum 3d Matrix row by interval in Matlab?

I have a 36x256x2232 3d matrix in Matlab created by M = ones(36,256,2232) and I want to reduce the size of the matrix by sum rows by interval 3. The result matrix should be 12x256x2232 and each cell should have the value 3.
I tried using reshape and sum function but I get 1x256x2232 matrix.
How can I do this without using the for-loop ?
This should do it:
M = ones(36,256,2232)
reduced = reshape(sum(reshape(M, 3,[], 256,2232), 1),[], 256, 2232);
reshape makes a 4d matrix with the given intervals
sum reduce it
second reshape transform it to 3d again
you can use also squeeze, which removes singleton dimensions:
reduced = squeeze(sum(reshape(M, 3,[], 256,2232), 1));
You can use the new-ish splitapply function (which is similar to accumarray but can handle data with multiple dimensions). This approach works even if the number of rows is not a multiple of the group size:
M = ones(4,5,2); % example data
n = 3; % group size
result = splitapply(#(x)sum(x,1), M, floor((0:size(M,1)-1).'/n)+1);

How can I improve code that finds the n-samples vector subset meeting certain criteria?

In Matlab, given a vector A (please, find it here: https://www.dropbox.com/s/otropedwxj0lki7/A.mat?dl=0 ), how could I find the n-samples vector subset with the smallest range (or standard deviation)?
I am trying a potential solution: reshaping the vector in columns, performing range of each column and selecting the smallest. However, reshape does not always works well when applied to other examples with different lengths. How could this be worked around in an easier and more efficient way?
Fs = 1000; % sampling frequency
time = round(length(A)/Fs)-1; % calculate approximated rounded total length in time
A_reshaped = reshape(A(1:time*Fs), [], time/2); % reshape A (deleting some samples at the end) in time/2 columns
D(1,:) = mean(A_reshaped);
D(2,:) = range(A_reshaped);
[~,idx] = min(D(2,:));
Value = D(1,idx);
Any help is much appreciated.
To find the n-sample with minimum range you can sort the vector and subtract the first section of the sorted vector from the last section. Then use index of the minimum to find the n-sample:
n=4
a= rand(1,10);
s= sort(a);
[~,I]=min(s(n:end)-s(1:end-n+1))
result = s(I:I+n-1)

Matlab sums and integers

Thank you for any help in advance. I have a large matrix: 1,000,000 rows and 10 columns. I would like to sum each row and create a new matrix with only the rows that sum to integers. I've tried this so far and manipulated it in many ways, but I'm stuck. How can I do this?
for k = 1:1000000
x = sum(A(k,:)) %A is my large matrix
if x-round(x,0)==0
y = [y;x]% y is my new matrix
end
end
Rather than using a for loop and continuously expanding y which is going to be extremely slow for large x arrays, you can use the second input of sum to compute the sum for each row, and then you can determine which rows sum to an integer by comparing the rounded and original versions using a very small epsilon (the proper way to compare floating-point numbers).
% Sum each row and divide by 3
row_sums = sum(x, 2) / 3;
% Determine which of the row-wise sums are integers
sum_is_integer = abs(round(row_sums) - row_sums) < eps;
% If you want the sums that were integers
y = row_sums(sum_is_integer);
% If you want a sub-matrix containing only the rows where the sums were an integer
z = x(sum_is_integer, :);

Vector and matrix comparison in MATLAB

I have vector with 5 numbers in it, and a matrix of size 6000x20, so every row has 20 numbers. I want to count how many of the 6000 rows contain all values from the vector.
As the vector is a part of a matrix which has 80'000'000 rows, each containing unique combinations, I want a fast solution (which doesn't take more than 2 days).
Thanks
With the sizes you have, a bsxfun-based approach that builds an intermediate 6000x20x5 3D-array is affordable:
v = randi(9,1,5); %// example vector
M = randi(9,6000,20); %// example matrix
t = bsxfun(#eq, M, reshape(v,1,1,[]));
result = sum(all(any(t,2),3));

multiplying large matrix elements results in infinite

I am supposed to combine all the matrix into one, which concatenate horizontally by
matrix = [matrix1 matrix2 matrix3];
now i have to find the mean of the matrix which is 32 x 2039 dimensions.
i tried looping through each row and using mean for the whole elements in that row multipled and divided by the number of elements which is 2039.
answer i get is -Inf, all the time.
help would be appreciated.
thanks
my code what i could remember in case
[r, c] = size(matrix);
for i = 1:r
rowvalues = matrix(i,[1:c]);
mean(i,1) = mean2(rowvalues); %or mean(rowvalues,2);
end
results in -Inf.
my aim is to calculate the mean of the matrix which should be 39 X 1 dimensions.
thanks
When an element of a row is -Inf, the whole row will have a mean=-Inf.
I suggest you check this with the following code:
% The indices of the occurences of -Inf in matrix
mInfIndices=(matrix==-Inf);
% Does the row contain an -Inf?
mInfInRows=sum(mInfIndices,2)>0;
disp(mInfInRows);
This way you will see which rows contain a -Inf.