Home > Net >  Min and max of deviations from mean in Matlab
Min and max of deviations from mean in Matlab

Time:12-07

Intro: I need to find the greatest/smallest possible deviations from the average in some given Matlab vectors. The issue is that, due to the large dimensions of the arrays involved, I cannot explicitly construct such vectors. Therefore, I wonder whether there is a smarter way to proceed. I summarise below the procedure that I would implement if there were no memory constraints and then present my question.

(1) Consider 28 matrices in Matlab A{1},..., A{28}. For each j=1,...,28, A{j} has 4 columns. The number of rows of A{j} can be different across j=1,..., 28 and is stored in the vector r.

clear
rng default
A=cell(28,1);
r=randi(10000,28,1) 10000; (x1
for j=1:28
    A{j}=randn(r(j),4); %r(j)x4
end

(2) For each j=1,...,28, let b{j} be the r(j) x 1 vector that is obtained by summing the first two rows of A{j} and subtracting the last two rows of A{j}:

b=cell(28,1);
for j=1:28
    b{j}=A{j}(:,1) A{j}(:,2)-A{j}(:,3)-A{j}(:,4); %r(j)x1
end

(3) Let B be the R x 28 matrix that is obtained as a 28-D grid from the vectors b{1},...,b{28}:

%[ca, cb, cc, cd, ce, ...] = ndgrid(b{1}, b{2}, b{3}  , ..., b{28});
%B(:,1)=ca(:);
%B(:,2)=cb(:);
%...
%B(:,28)=...;
c=cell(28,1);
[c{:}]=ndgrid(b{:});
c=cellfun(@(x)x(:),c,'UniformOutput',false);
B=[c{:}];

Apologies for the incomplete code. As you can imagine, this is the step where I have issues as explained below.

(4) For each row of B, I compute the difference between such row and its mean value and store the results in a R x 28 matrix D:

%R=size(B,1);
%D=zeros(R,28);
%for t=1:R
%    D(t,:)=B(t,:)-mean(B(t,:)); 
%end
D=B-mean(B,2);

(5) For each j=1,...,28, I compute the min and max value of D(:,j) and store it in a matrix F

F=zeros(2,28);
for j=1:28
    F(1,j)=min(D(:,j));
    F(2,j)=max(D(:,j));
end

Question: F is the matrix that I would like to construct. However, step (3) is unfeasible due to the large r(1),..., r(28). Even a loop would take forever. Hence, I'm asking: is there a smarter way to construct F that saves me from explicitly obtaining B?

CodePudding user response:

Here is a fast solution (without using ndgrid):

F = zeros(2,28);
mx = cellfun(@max,b)
mn = cellfun(@min,b)
for k = 1: 28
    F(1,k) = min(b{k}-(b{k} sum(mx)-mx(k))/28);
    F(2,k) = max(b{k}-(b{k} sum(mn)-mn(k))/28);
end

Explanation:

Suppose matrix B to be:

B =   
   1   3   5
   1   3   6
   1   4   5
   1   4   6
   2   3   5
   2   3   6
   2   4   5
   2   4   6

So we want to compute MinB=min(B-mean(B,2)). There are 3 columns and MinB = [MinB(1) MinB(2) MinB(3)].
We begin to compute for the first column or MinB(1).
We can split the B matrix based on the values of the first column :

 B1=  
   1   3   5
   1   3   6
   1   4   5
   1   4   6

 B2= 
   2   3   5
   2   3   6
   2   4   5
   2   4   6

so MinB(1) can be computed as min(MinB1(1), MinB2(1)).
And MinB1(1) can be written as: MinB1(1) = min(1 - mean(B1, 2)).
Equivalently is can be written as: MinB1(1) = 1 - max(mean(B1, 2)).

We can write mean as sum : max(mean(B1, 2))== > max(sum(B1,2)/3).

Consider all combinations of numbers. Which combination has the maximum mean or maximum sum ? the combination that contains max of each vector of b or mx=[2 4 6]. So we have used cellfun to compute max for each vector of b. This way we don't need to compute the mean of the all combinations we just need to compute max for each vector of b and then compute the mean of that vector. That is the key point to the above solution and max can also be computed this way.

  • Related