Home > Software design >  Matlab command unique with matrices
Matlab command unique with matrices

Time:12-22

Suppose I have a matrix B of size a x b and a cell C of size ax1. Each C{a} may is a matrix with potentially different sizes across a.

I would like to create a vector idx of size ax1 containing the integers from 1 to at most a, where idx(j)=idx(h) if

  1. B(j,:)=B(h,:);

  2. C{j}=C{h};

If I had only 1., I would do

[~,~,idx] = unique(B,'rows', 'stable');

I don't know how to introduce 2. Could you help?


Here's a code to construct an example of C

clear
rng default
u0grid_temp=0; 
u1grid_temp=randn(3,1);
u2grid_temp=randn(3,1); 
[ca, cb, cc] = ndgrid(u0grid_temp, u1grid_temp, u2grid_temp);
u0grid=ca(:);
u1grid=cb(:);
u2grid=cc(:);
sg=size(u0grid,1);
n_U_sets=3;
Ugrid=cell(1,n_U_sets);
n_columns_Ujgrid=5;
Ugrid_all=zeros(sg,n_columns_Ujgrid*n_U_sets);
for g=1:sg
    Ugrid{1}(g,:)=[u0grid(g)-u1grid(g)  Inf -Inf  0 3];
    Ugrid{2}(g,:)=[u0grid(g)-u2grid(g)  Inf -Inf  0 3]; 
    Ugrid{3}(g,:)=[Inf  -Inf  u2grid(g)-u1grid(g) 0 3]; 
    Ugrid_all(g,:)=[Ugrid{1}(g,:)  Ugrid{2}(g,:) Ugrid{3}(g,:)];
end
s_id_gridreduced_2=zeros(1, n_U_sets); 
for j=1:n_U_sets
    s_id_gridreduced_2(:,j)=size(Ugrid{j},2); 
end
sU_id_gridreduced_2=prod(s_id_gridreduced_2); 
indices_pairs = pairIndices(sU_id_gridreduced_2);
D=cell(sg,1);
for g=1:sg  
     vectors = cellfun(@(x) {x(g,:)}, Ugrid); 
     T_temp = cell(1,n_U_sets);
     [T_temp{:}] = ndgrid(vectors{:});
     T_temp = cat(n_U_sets 1, T_temp{:});
     T = reshape(T_temp,[],n_U_sets);
     D_temp=[T(indices_pairs(:,1),:) T(indices_pairs(:,2),:)]; 
     D1=D_temp(sum(D_temp(:,1:3)<=D_temp(:,4:6),2)==3, :);
     D2_temp=D_temp((sum(D_temp(:,1:3)>D_temp(:,4:6),2)==3) |... %>,>,>
        (sum(D_temp(:,1:3)>D_temp(:,4:6),2)==2 & sum(D_temp(:,1:3)==D_temp(:,4:6),2)==1) | ... %>,>,=
        (sum(D_temp(:,1:3)>D_temp(:,4:6),2)==1 & sum(D_temp(:,1:3)==D_temp(:,4:6),2)==2), :); %>,=,=
     D2=[D2_temp(:,4:6) D2_temp(:,1:3)];
     D{g}=[D1;D2];
end
C=cell(1,sg);
for g=1:sg
C{g}=NaN(size(D{g},1),1);
for r=1:size(D{g},1)
    if round(D{g}(r,1),8)>=round(D{g}(r,5) D{g}(r,6),8) || round(D{g}(r,4),8)<=round(D{g}(r,2) D{g}(r,3),8)
       C{g}(r)=1;
    else
        C{g}(r)=0; 
    end
end
end

CodePudding user response:

To compute condition 2 you can use a nested loop to compare arrays with isequal:

out = zeros(numel(C), 1);
k = 0;
for i = 1:numel(C)
  if out(i)
    continue;
  end
  k = k   1;
  out(i) = k;
  for j = i   1 : numel(C)
    if out(j)
      continue;
    end
    if isequal(C{[i, j]})
      out(j) = k;
    end
  end
end

Use unique to combine condition 1 and condition 2:

[~, ~, result] = unique ([idx(:) out(:)], 'rows', 'stable');
  • Related