Я полагаю, что возможен излишний путь, если сопоставить все ваши привязанные к сетке индексы со всеми вашими точками линейных данных. Для этого нам нужно ввести несколько измерений, чтобы сравнить 3d-массивы XX
и т. Д. С 2d-массивами X
и т. Д. Поэлементно:
Xbc = reshape(X, [1,1,1,size(X)]);
Ybc = reshape(Y, [1,1,1,size(Y)]);
Zbc = reshape(Z, [1,1,1,size(Z)]);
Эти массивы изменяются таким образом, что они транслируются с массивами XX
и т. Д. Размером [N,M,K]
(«bc» означает трансляцию). Итак, поэлементное сравнение теперь работает:
match = reshape((XX == Xbc) & (YY == Ybc) & (ZZ == Zbc), [size(XX), numel(V)]);
Этот логический массив имеет размер [N,M,K,P,Q]
, если V
имеет размер [P,Q]
. Он содержит ровно столько true
с, сколько вы хотите:
>> sum(match(:)) == numel(V)
ans =
logical
1
Итак, теперь нам нужно выбрать соответствующие индексы по первым трем измерениям и соединить их с правильным элементом V
. Нам нужна смазка для линейных и многоиндексных колен:
[ii,jj,kk,ll] = ind2sub(size(match), find(match));
Теперь все массивы с левой стороны имеют размер [numel(V), 1]
; первые три дают вам индексы в XX
и т. д., а последний дает индексы в V
.
V_inds = ll;
VV_inds = sub2ind(size(VV), ii, jj, kk);
VV(VV_inds) = V(V_inds);
Теперь почему-то я вижу только 3750 уникальных индексов среди 5000 в результате:
>> numel(VV_inds)
ans =
5000
>> numel(unique(VV_inds))
ans =
3750
Я не могу найти другую причину для этого, кроме того, что некоторые из ваших исходных точек данных перекрываются из-за повторений в значениях X
и Y
, поэтому вы не можете фактически представить их в 3d сетка уникальных точек (потому что некоторые 3d точки содержат более одной точки данных). Я считаю, что следующее доказывает это:
>> size(unique([X,Y], 'rows'))
ans =
75 2
>> size([X,Y])
ans =
100 2
Есть 100 (x,y)
пар, но только 75 уникальных. Независимо от того, как вы комбинируете их с ортогональными наборами z
точек, вы получите повторения в своих точках. Таким образом, вы либо должны отбрасывать избыточность в ваших необработанных данных, либо вам нужно найти другое представление (или взять среднее значение для конфликтующих значений).
Я думаю, что у меня есть и более эффективная версия, использующая индексы, сгенерированные unique
во время ее запуска. Обратите внимание, что я предполагаю, что вы используете meshgrid
вместо ndgrid
для генерации сеток, так что размеры результирующих массивов (а также VV
) соответствуют уникальным размерам вдоль X
, Y
и Z
соответственно.
% take the indices
[uX, ~, iX] = unique(X);
[uY, ~, iY] = unique(Y);
[uZ, ~, iZ] = unique(Z);
% generate mesh and allocate result
[XX, YY, ZZ] = ndgrid(uX, uY, uZ);
VV = NaN(size(XX));
% switch from `iX`, `iY` and `iZ` to a 2d mesh of size `[P,Q]` where `iX` and `iY` are of size `[P,1]` and `iZ` is of size `[Q,1`]:
% a.k.a. lazy repmat
iXbig = iX + 0*iZ.';
iYbig = iY + 0*iZ.';
iZbig = iZ.' + 0*iX;
% turn 3d indices into linear index into VV
VV_inds = sub2ind(size(VV), iXbig, iYbig, iZbig);
% profit
VV(VV_inds) = V;