найти ближайшие элементы в нецелочисленных массивах Matlab разного размера

У меня есть 2 матрицы t=[1,2880000] и t1=[1,143986].

Я пытаюсь выяснить, какие элементы ближе всего между этими двумя массивами. Я попробовал следующий код, который отлично работает с меньшими массивами, но не с такими большими массивами.

% create two similar sized matrix and find out difference between each element
t1_m=repmat(t1', size(t)); 
t_m=repmat(t, size(t1'));
diff_m=abs(t_m-t1_m);
ind1=find(diff_m<1e-5);

Это дает проблему нехватки памяти с repmat. Любая помощь приветствуется.


person dissw.geek9    schedule 29.04.2014    source источник
comment
Вы не можете хранить в памяти значения 2880000 x 143986. Вам нужно перебрать один из двух векторов   -  person Luis Mendo    schedule 29.04.2014


Ответы (2)


Если я правильно понял ваш вопрос, вам даны два набора чисел, и вам нужно найти пары, которые наиболее близки друг к другу.

В принципе, это квадратичная проблема, хотя ее можно свести к проблеме NlogN (во времени) с помощью сортировки (при условии, что ваши массивы «достаточно разрежены»).

позволять

  A = rand(1000,1) 
  B = rand(1100,1)

быть два набора ваших.

Мы строим помеченный сопоставленный массив C из двух

C = [A ones(size(A)) ;
     B 2*ones(size(B))]

поэтому на данный момент первый столбец C содержит элементы A (отмечены 1 во втором столбце) и элементы B (отмечены 2). Мы сортируем C так, чтобы близкие элементы закрывали друг друга

D = sortrows(C).

Теперь, если мы сравним D, у нас будет что-то вроде

>> E = abs(diff(D))

   0.000694103278079                   0
   0.000153057031699                   0
   0.000557077905541                   0
   0.001520045249172   1.000000000000000
   0.000249084264359   1.000000000000000
   0.000148379610173                   0
   0.000013761461813   1.000000000000000

что говорит нам о том, что всякий раз, когда появляется 1, мы вычисляем разницу между элементами close двух разных наборов. Таким образом, мы находим такие элементы по

  idx_good = find(E(:,1) < 1e-5 & E(:,2) == 1)

и мы записываем их как

  >> [D((idx_good),1) D((idx_good)+1)]

  ans =

   0.042652410911143   0.042659855935049
   0.060466771939828   0.060471179169894
   0.075966691690842   0.075967361294136
   0.119207259421287   0.119214541054191
   0.146514856442232   0.146514910614890
   0.205672339463963   0.205674521464760
   0.208461358751314   0.208470223305320
   0.234779913372406   0.234782640662848

который содержит элемент из A в первом столбце и элемент из B во втором столбце.

Что ж, этого недостаточно, так как мы нашли только некоторые элементы, удовлетворяющие этому свойству (в любом случае этого достаточно, если вы ищете абсолютную ближайшую пару).

Следовательно, мы должны повторить трюк, применяя растущее смещение в diff столько раз, сколько необходимо, чтобы увидеть все возможные близкие пары, которые достаточно близки. Другими словами, можно определить функцию

 diff_ext = @(m,amount) m(1:end-amount,:) - m(1+amount:end,:);

использоваться вместо diff для увеличения целочисленных значений amount, таких что

abs(diff_ext(D,amount))

допускает элементы меньше вашего порога.

Элементы, которые вы нашли, затем должны быть добавлены к множеству близких различий.

person Acorbe    schedule 29.04.2014
comment
Это хорошо работало для меньших матриц, но с большими матрицами возникала проблема с памятью. Поэтому мне пришлось использовать цикл for для вычисления. - person dissw.geek9; 30.04.2014

Вместо этого вы можете просто использовать:

% handle if t,t1 have different length
sz = min(size(t, 2), size(t1, 2));
t2 = t(1:sz);
t3 = t1(1:sz);

[dist,ind] = min(abs(t2-t3)) % ind gives you the index, dist is min-difference

Прецедент:

t=[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1];
t1=[0.4 0.5 0.6 0.7];

Ты получишь:

dist =

    0.3000


ind =

     4

Примечание: он даст вам последний индекс, если несколько индексов имеют минимальную разницу.

person herohuyongtao    schedule 29.04.2014
comment
Значения похожи на a = [0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1] и b = [0,4 0,5 0,6 0,7], так что это не работает - person dissw.geek9; 29.04.2014
comment
@ dissw.geek9 Обновил ответ. Проверьте это. - person herohuyongtao; 29.04.2014